914 lines
20 KiB
C++
914 lines
20 KiB
C++
#include "../../include/kfile/TrfMetaData.h"
|
|
#include <windows.h>
|
|
#include <assert.h>
|
|
#include "../../include/toolkit/safe_function.h"
|
|
|
|
using namespace trf;
|
|
|
|
|
|
void TemplateInfo::clear()
|
|
{
|
|
m_hashByName.clear();
|
|
m_fields.clear();
|
|
m_fixedSize = 0;
|
|
}
|
|
|
|
bool TemplateInfo::removeField( const char* pFieldName )
|
|
{
|
|
int index;
|
|
if ( !m_hashByName.lookup( pFieldName, index ) )
|
|
return false;
|
|
|
|
if ( m_fixedSize >= 0 )
|
|
m_fixedSize -= m_fields[ index ].fixedSize;
|
|
|
|
m_fields.erase( m_fields.begin() + index );
|
|
m_hashByName.erase( pFieldName );
|
|
return true;
|
|
}
|
|
|
|
bool TemplateInfo::addSimpleField( const char* pFieldName, int type )
|
|
{
|
|
if ( m_hashByName.has( pFieldName ) )
|
|
return false;
|
|
|
|
if ( type == Type::DICT || type == Type::TEMPLATE || (type & Type::_ARRAYMASK) != 0 )
|
|
return false;
|
|
|
|
m_fields.resize( m_fields.size()+1 );
|
|
m_fields.back().name = pFieldName;
|
|
m_fields.back().type = type;
|
|
m_fields.back().pInfo = NULL;
|
|
m_fields.back().fixedCount = -1;
|
|
m_fields.back().fixedSize = Type::getTypeSize( type );
|
|
m_hashByName.add( pFieldName, static_cast< int >( m_fields.size() )-1 );
|
|
|
|
if ( m_fixedSize >= 0 )
|
|
m_fixedSize += m_fields.back().fixedSize;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TemplateInfo::addArrayField( const char* pFieldName, int elementType, int fixedCount )
|
|
{
|
|
if ( m_hashByName.has( pFieldName ) )
|
|
return false;
|
|
|
|
m_fields.resize( m_fields.size()+1 );
|
|
m_fields.back().name = pFieldName;
|
|
m_fields.back().type = Type::getArrayType( elementType );
|
|
m_fields.back().pInfo = NULL;
|
|
|
|
if ( fixedCount > 0 )
|
|
{
|
|
m_fields.back().fixedCount = fixedCount;
|
|
m_fields.back().fixedSize = fixedCount * Type::getTypeSize( elementType );
|
|
if ( m_fixedSize >= 0 )
|
|
m_fixedSize += m_fields.back().fixedSize;
|
|
}
|
|
else
|
|
{
|
|
m_fields.back().fixedCount = -1;
|
|
m_fields.back().fixedSize = -1;
|
|
m_fixedSize = -1;
|
|
}
|
|
|
|
m_hashByName.add( pFieldName, static_cast< int >( m_fields.size() )-1 );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TemplateInfo::addTemplateField( const char* pFieldName, const TemplateInfo* pInfo )
|
|
{
|
|
if ( m_hashByName.has( pFieldName ) )
|
|
return false;
|
|
|
|
m_fields.resize( m_fields.size()+1 );
|
|
m_fields.back().name = pFieldName;
|
|
m_fields.back().type = Type::TEMPLATE;
|
|
m_fields.back().pInfo = pInfo;
|
|
m_fields.back().fixedCount = -1;
|
|
m_fields.back().fixedSize = pInfo->m_fixedSize >= 0 ? pInfo->fixedSize() : -1;
|
|
m_hashByName.add( pFieldName, static_cast< int >( m_fields.size() )-1 );
|
|
|
|
if ( m_fixedSize >= 0 && m_fields.back().fixedSize >= 0 )
|
|
m_fixedSize += m_fields.back().fixedSize;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TemplateInfo::addTemplateArrayField( const char* pFieldName, const TemplateInfo* pElementInfo, int fixedCount )
|
|
{
|
|
if ( m_hashByName.has( pFieldName ) )
|
|
return false;
|
|
|
|
m_fields.resize( m_fields.size()+1 );
|
|
m_fields.back().name = pFieldName;
|
|
m_fields.back().type = Type::TEMPLATE_ARRAY;
|
|
m_fields.back().pInfo = pElementInfo;
|
|
|
|
if ( fixedCount > 0 )
|
|
{
|
|
m_fields.back().fixedCount = fixedCount;
|
|
m_fields.back().fixedSize = pElementInfo->fixedSize() >= 0 ? fixedCount * pElementInfo->fixedSize() : -1;
|
|
if ( m_fixedSize >= 0 && m_fields.back().fixedSize >= 0 )
|
|
m_fixedSize += m_fields.back().fixedSize;
|
|
}
|
|
else
|
|
{
|
|
m_fields.back().fixedCount = -1;
|
|
m_fields.back().fixedSize = -1;
|
|
m_fixedSize = -1;
|
|
}
|
|
|
|
m_hashByName.add( pFieldName, static_cast< int >( m_fields.size() )-1 );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TemplateInfo::addDictField( const char* pFieldName )
|
|
{
|
|
if ( m_hashByName.has( pFieldName ) )
|
|
return false;
|
|
|
|
m_fields.resize( m_fields.size()+1 );
|
|
m_fields.back().name = pFieldName;
|
|
m_fields.back().type = Type::DICT;
|
|
m_fields.back().pInfo = NULL;
|
|
m_fields.back().fixedCount = -1;
|
|
m_fields.back().fixedSize = -1;
|
|
m_hashByName.add( pFieldName, static_cast< int >( m_fields.size() )-1 );
|
|
|
|
m_fixedSize = -1;
|
|
return true;
|
|
}
|
|
|
|
int TemplateInfo::calcFixedSize( int n ) const
|
|
{
|
|
int sum = 0;
|
|
for ( int i = 0; i < n; i++ )
|
|
{
|
|
int fieldFixedSize = m_fields[ i ].fixedSize;
|
|
if ( fieldFixedSize < 0 )
|
|
return -1;
|
|
sum += fieldFixedSize;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------------------------
|
|
|
|
MetaData::MetaData()
|
|
{
|
|
m_ref = 0;
|
|
}
|
|
|
|
MetaData::~MetaData()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
void MetaData::clear()
|
|
{
|
|
assert( m_ref == 0 ); // 중요. 이 메타데이터를 사용하는 filer 나 mapper 가 남아있을 경우
|
|
// 이후 그 filer/mapper 를 지울때 메모리를 제대로 반환하지 못할 수 있다.
|
|
m_hashByGUID.clear();
|
|
m_hashByName.clear();
|
|
|
|
for ( std::vector< TemplateInfo* >::iterator it = m_infos.begin(); it != m_infos.end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
m_infos.clear();
|
|
}
|
|
|
|
void MetaData::addRef() const
|
|
{
|
|
InterlockedIncrement( &m_ref ); // multi-thread 에서 cnt가 제대로 증가/감소가 되지 않아서 assert( m_ref == 0 ) 에서 오류가 발생. thread-safe 형태로 수정함. by ekflame. 090719
|
|
}
|
|
|
|
void MetaData::subRef() const
|
|
{
|
|
InterlockedDecrement( &m_ref); // multi-thread 에서 cnt가 제대로 증가/감소가 되지 않아서 assert( m_ref == 0 ) 에서 오류가 발생. thread-safe 형태로 수정함. by ekflame. 090719
|
|
}
|
|
|
|
const TemplateInfo* MetaData::getTemplateInfo( const GUID& uuidType ) const
|
|
{
|
|
TemplateInfo* pInfo;
|
|
return m_hashByGUID.lookup( uuidType, pInfo ) ? pInfo : NULL;
|
|
}
|
|
|
|
const TemplateInfo* MetaData::getTemplateInfo( const char *pName ) const
|
|
{
|
|
TemplateInfo* pInfo;
|
|
return m_hashByName.lookup( pName, pInfo ) ? pInfo : NULL;
|
|
}
|
|
|
|
TemplateInfo* MetaData::addNewTemplateInfo( const GUID& uuidType, const char* pName )
|
|
{
|
|
if ( m_hashByGUID.has( uuidType ) || m_hashByName.has( pName ) )
|
|
return NULL;
|
|
|
|
TemplateInfo* pInfo = new TemplateInfo( uuidType, pName, static_cast< int >( m_infos.size() ) );
|
|
m_hashByGUID.add( uuidType, pInfo );
|
|
m_hashByName.add( pName, pInfo );
|
|
m_infos.push_back( pInfo );
|
|
|
|
return pInfo;
|
|
}
|
|
|
|
|
|
// template parsing
|
|
|
|
|
|
namespace {
|
|
|
|
// KTOKENs
|
|
|
|
const char KTOKEN_EOF = -1;
|
|
|
|
const char KTOKEN_NAME = 1;
|
|
const char KTOKEN_INTEGER = 3;
|
|
const char KTOKEN_GUID = 5;
|
|
|
|
const char KTOKEN_OBRACE = 10;
|
|
const char KTOKEN_CBRACE = 11;
|
|
const char KTOKEN_OPAREN = 12;
|
|
const char KTOKEN_CPAREN = 13;
|
|
const char KTOKEN_OBRACKET = 14;
|
|
const char KTOKEN_CBRACKET = 15;
|
|
const char KTOKEN_OANGLE = 16;
|
|
const char KTOKEN_CANGLE = 17;
|
|
const char KTOKEN_DOT = 18;
|
|
const char KTOKEN_COMMA = 19;
|
|
const char KTOKEN_SEMICOLON = 20;
|
|
const char KTOKEN_TEMPLATE = 31;
|
|
const char KTOKEN_WORD = 40;
|
|
const char KTOKEN_DWORD = 41;
|
|
const char KTOKEN_FLOAT = 42;
|
|
const char KTOKEN_DOUBLE = 43;
|
|
const char KTOKEN_CHAR = 44;
|
|
const char KTOKEN_BYTE = 45;
|
|
const char KTOKEN_SHORT = 46;
|
|
const char KTOKEN_LONG = 47;
|
|
const char KTOKEN_VOID = 48;
|
|
const char KTOKEN_LPSTR = 49;
|
|
const char KTOKEN_STRING = 50;
|
|
const char KTOKEN_WSTRING = 51;
|
|
const char KTOKEN_ARRAY = 52;
|
|
const char KTOKEN_LLONG = 53;
|
|
const char KTOKEN_DICT = 54;
|
|
|
|
|
|
struct KTemplateToken
|
|
{
|
|
char TokenID;
|
|
std::string StrToken;
|
|
};
|
|
|
|
char tokendata[] = {
|
|
KTOKEN_OBRACE , '{'
|
|
, KTOKEN_CBRACE , '}'
|
|
, KTOKEN_OPAREN , '('
|
|
, KTOKEN_CPAREN , ')'
|
|
, KTOKEN_OBRACKET , '['
|
|
, KTOKEN_CBRACKET , ']'
|
|
, KTOKEN_OANGLE , '<'
|
|
, KTOKEN_CANGLE , '>'
|
|
, KTOKEN_DOT , '.'
|
|
, KTOKEN_COMMA , ','
|
|
, KTOKEN_SEMICOLON , ';'
|
|
};
|
|
|
|
char reserved_id[] = {
|
|
KTOKEN_TEMPLATE // template
|
|
, KTOKEN_WORD // word
|
|
, KTOKEN_SHORT // short
|
|
, KTOKEN_DWORD // dword
|
|
, KTOKEN_LONG // long
|
|
, KTOKEN_LLONG // long long
|
|
, KTOKEN_FLOAT // float
|
|
, KTOKEN_DOUBLE // double
|
|
, KTOKEN_CHAR // char
|
|
, KTOKEN_BYTE // byte
|
|
, KTOKEN_STRING // string
|
|
, KTOKEN_WSTRING // wide string
|
|
, KTOKEN_DICT // dict
|
|
};
|
|
|
|
char *reserved_word[] = {
|
|
"template"
|
|
,"word"
|
|
,"short"
|
|
,"dword"
|
|
,"long"
|
|
,"int64"
|
|
,"float"
|
|
,"double"
|
|
,"char"
|
|
,"byte"
|
|
,"string"
|
|
,"wstring"
|
|
,"dict"
|
|
};
|
|
|
|
char whitespacechr[] = {
|
|
'\n', '\r', ' ', '\t'
|
|
|
|
};
|
|
/*
|
|
, KTOKEN_NAME ,
|
|
, KTOKEN_INTEGER ,
|
|
, KTOKEN_GUID ,
|
|
, KTOKEN_ARRAY
|
|
*/
|
|
|
|
bool getNextChar( KStream &stream, char *c, int &linecount )
|
|
{
|
|
char chr;
|
|
while ( 1 )
|
|
{
|
|
nextchar:
|
|
if ( stream.Read( &chr, 1 ) )
|
|
{
|
|
if ( chr == '\n' ) ++linecount;
|
|
for ( int i=0 ; i<_countof(whitespacechr) ; i++ )
|
|
if ( chr == whitespacechr[i] ) goto nextchar;
|
|
*c = chr;
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
}
|
|
|
|
bool getNextWord( KStream &stream, char *c, bool &isWhiteSpace, int &linecount )
|
|
{
|
|
char chr;
|
|
isWhiteSpace = false;
|
|
while ( 1 )
|
|
{
|
|
if ( stream.Read( &chr, 1 ) )
|
|
{
|
|
for ( int i=0 ; i<_countof(whitespacechr) ; i++ )
|
|
{
|
|
if ( chr == whitespacechr[i] )
|
|
{
|
|
if ( chr == '\n' ) ++linecount;
|
|
isWhiteSpace = true;
|
|
*c = chr;
|
|
return true;
|
|
}
|
|
}
|
|
*c = chr;
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
}
|
|
|
|
void checkReservedWord( KTemplateToken &token )
|
|
{
|
|
for ( int i=0 ; i<_countof(reserved_id) ; ++i )
|
|
{
|
|
if ( strcmp( token.StrToken.c_str(), reserved_word[i] ) == 0 )
|
|
{
|
|
token.TokenID = reserved_id[i];
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool skipline( KStream &stream, int &linecount )
|
|
{
|
|
char chr;
|
|
while ( 1 )
|
|
{
|
|
if ( stream.Read( &chr, 1 ) )
|
|
{
|
|
if ( chr == '\n' )
|
|
{
|
|
++linecount;
|
|
return true;
|
|
}
|
|
}
|
|
else return false;
|
|
}
|
|
}
|
|
|
|
bool skiptocomment( KStream &stream, int &linecount )
|
|
{
|
|
char chr;
|
|
while ( 1 )
|
|
{
|
|
if ( stream.Read( &chr, 1 ) )
|
|
{
|
|
if ( chr == '\n' )
|
|
++linecount;
|
|
if ( chr == '*' )
|
|
{
|
|
stream.Read( &chr, 1 );
|
|
if ( chr == '/' )
|
|
return true;
|
|
else stream.Seek( -1, KStream::seekCur );
|
|
}
|
|
}
|
|
else return false;
|
|
}
|
|
}
|
|
|
|
bool getNextToken( KStream &stream, KTemplateToken &token, int &linecount )
|
|
{
|
|
char c;
|
|
std::string name;
|
|
while ( 1 )
|
|
{
|
|
if ( getNextChar( stream, &c, linecount ) == false ) return false;
|
|
for ( int i=0 ; i<_countof(tokendata)/2 ; i++ )
|
|
{
|
|
if ( tokendata[i*2+1] == c )
|
|
{
|
|
token.TokenID = tokendata[i*2];
|
|
return true;
|
|
}
|
|
}
|
|
|
|
name += c;
|
|
unsigned short pos = static_cast<unsigned short>(stream.Tell());
|
|
bool ws;
|
|
if ( getNextWord( stream, &c, ws, linecount ) == false )
|
|
{
|
|
token.TokenID = KTOKEN_NAME;
|
|
token.StrToken = name;
|
|
return false;
|
|
}
|
|
|
|
std::string tempname = name;
|
|
tempname += c;
|
|
if ( strcmp( tempname.c_str(), "//" ) == 0 )
|
|
{
|
|
name = "";
|
|
if ( skipline( stream, linecount ) == false ) return false;
|
|
continue;
|
|
}
|
|
if ( strcmp( tempname.c_str(), "/*") == 0 )
|
|
{
|
|
name = "";
|
|
if ( skiptocomment( stream, linecount ) == false ) return false;
|
|
continue;
|
|
}
|
|
stream.Seek( pos, KStream::seekSet );
|
|
|
|
while ( 1 )
|
|
{
|
|
pos = static_cast<unsigned short>(stream.Tell());
|
|
if ( getNextWord( stream, &c, ws, linecount ) == false )
|
|
{
|
|
token.TokenID = KTOKEN_NAME;
|
|
token.StrToken = name;
|
|
return false;
|
|
}
|
|
if ( ws ) // word end
|
|
{
|
|
token.TokenID = KTOKEN_NAME;
|
|
token.StrToken = name;
|
|
checkReservedWord( token );
|
|
return true;
|
|
}
|
|
for ( int i=0 ; i<_countof(tokendata)/2 ; i++ )
|
|
{
|
|
if ( tokendata[i*2+1] == c )
|
|
{
|
|
stream.Seek( pos, KStream::seekSet );
|
|
token.TokenID = KTOKEN_NAME;
|
|
token.StrToken = name;
|
|
checkReservedWord( token );
|
|
return true;
|
|
}
|
|
}
|
|
name += c;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool findToken( KStream &stream, char *tokenlist, int tokencount, KTemplateToken &found_token, int &linecount )
|
|
{
|
|
KTemplateToken token;
|
|
bool loop = true;
|
|
while ( loop )
|
|
{
|
|
loop = getNextToken( stream, token, linecount );
|
|
for ( int i=0 ; i<tokencount ; i++ )
|
|
{
|
|
if ( tokenlist[i] == token.TokenID )
|
|
{
|
|
found_token = token;
|
|
return loop;
|
|
}
|
|
}
|
|
}
|
|
found_token.TokenID = KTOKEN_EOF;
|
|
return loop;
|
|
}
|
|
|
|
unsigned long ahtoi( const char *str, int count )
|
|
{
|
|
unsigned long result = 0;
|
|
unsigned long hex = 1;
|
|
for ( int i=count-1 ; i>=0 ; i-- )
|
|
{
|
|
if ( str[i] >= 'A' && str[i] <= 'F' )
|
|
result += (str[i]-'A'+10) * hex;
|
|
else if ( str[i] >= 'a' && str[i] <= 'f' )
|
|
result += (str[i]-'a'+10) * hex;
|
|
else result += (str[i]-'0') * hex;
|
|
hex *= 16;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
unsigned short ahtos( const char *str, int count )
|
|
{
|
|
unsigned result = 0;
|
|
unsigned short hex = 1;
|
|
for ( int i=count-1 ; i>=0 ; i-- )
|
|
{
|
|
if ( str[i] >= 'A' && str[i] <= 'F' )
|
|
result += ((str[i]-'A'+10) * hex);
|
|
else if ( str[i] >= 'a' && str[i] <= 'f' )
|
|
result += ((str[i]-'a'+10) * hex);
|
|
else result += ((str[i]-'0') * hex);
|
|
hex *= 16;
|
|
}
|
|
return (unsigned short)result;
|
|
}
|
|
|
|
unsigned char ahtoc( const char *str, int count )
|
|
{
|
|
unsigned result = 0;
|
|
unsigned char hex = 1;
|
|
for ( int i=count-1 ; i>=0 ; i-- )
|
|
{
|
|
if ( str[i] >= 'A' && str[i] <= 'F' )
|
|
result += ((str[i]-'A'+10) * hex);
|
|
else if ( str[i] >= 'a' && str[i] <= 'f' )
|
|
result += ((str[i]-'a'+10) * hex);
|
|
else result += ((str[i]-'0') * hex);
|
|
hex *= 16;
|
|
}
|
|
return (unsigned char)result;
|
|
}
|
|
|
|
bool GetTemplateInfo( MetaData* pMetaData, KStream& stream, int& linecount )
|
|
{
|
|
TemplateInfo* pInfo = NULL;
|
|
|
|
KTemplateToken token;
|
|
bool loop = true;
|
|
|
|
int stage = 0;
|
|
|
|
std::string var_name;
|
|
char var_type_token = 0;
|
|
int var_array_count = 0;
|
|
const TemplateInfo *tinfo = NULL;
|
|
|
|
std::string strTemplateName;
|
|
GUID uuidTemplate;
|
|
int i = 0;
|
|
|
|
int token_count[] = { 1, 1, 1, 1, 1, 14, 1, 2, 2, 1, 1 };
|
|
char token_list[][14] = {
|
|
{ KTOKEN_TEMPLATE },// template start
|
|
{ KTOKEN_OBRACE }, // guid start
|
|
{ KTOKEN_NAME }, // guid
|
|
{ KTOKEN_CBRACE }, // guid end
|
|
{ KTOKEN_OBRACE }, // member start
|
|
{ KTOKEN_CBRACE, KTOKEN_NAME, KTOKEN_WORD, KTOKEN_SHORT, KTOKEN_DWORD, KTOKEN_LONG, KTOKEN_LLONG,
|
|
KTOKEN_FLOAT, KTOKEN_DOUBLE, KTOKEN_CHAR, KTOKEN_BYTE, KTOKEN_STRING, KTOKEN_WSTRING, KTOKEN_DICT }, // member type
|
|
{ KTOKEN_NAME }, // member name
|
|
{ KTOKEN_OBRACKET, KTOKEN_SEMICOLON }, // member sentence end or array start
|
|
{ KTOKEN_CBRACKET, KTOKEN_NAME }, // array count
|
|
{ KTOKEN_CBRACKET }, // array end
|
|
{ KTOKEN_NAME }, // template name
|
|
};
|
|
|
|
while (loop)
|
|
{
|
|
loop = findToken( stream, token_list[stage], token_count[stage], token, linecount );
|
|
|
|
if ( token.TokenID == KTOKEN_EOF )
|
|
{
|
|
if ( stage != 0 )
|
|
{
|
|
|
|
#ifdef _DEBUG
|
|
char msg[128];
|
|
s_sprintf( msg, _countof( msg ), "Parser Error line at %d", linecount );
|
|
MessageBox( NULL, msg, "Parser Error", MB_OK | MB_ICONERROR );
|
|
#endif
|
|
}
|
|
return false;
|
|
}
|
|
|
|
switch( stage )
|
|
{
|
|
case 0: // template start
|
|
stage = 10;
|
|
break;
|
|
|
|
case 1: // guid start ex>{3C1EC6CB-A0FD-4998-B420-778A55B57744}
|
|
stage = 2;
|
|
break;
|
|
|
|
case 2: // guid name
|
|
if ( token.StrToken.size() == 36 )
|
|
{
|
|
uuidTemplate.Data1 = ahtoi( token.StrToken.substr(0, 8).c_str(), 8 );
|
|
uuidTemplate.Data2 = ahtos( token.StrToken.substr(9, 4).c_str(), 4 );
|
|
uuidTemplate.Data3 = ahtos( token.StrToken.substr(14,4).c_str(), 4 );
|
|
for ( i=0 ; i<2 ; i++ )
|
|
{
|
|
uuidTemplate.Data4[i] = ahtoc( token.StrToken.substr( 19+i*2, 2 ).c_str(), 2 );
|
|
}
|
|
for ( i=2 ; i<8 ; i++ )
|
|
{
|
|
uuidTemplate.Data4[i] = ahtoc( token.StrToken.substr( 24+(i-2)*2, 2 ).c_str(), 2 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
{
|
|
#ifdef _DEBUG
|
|
char msg[128];
|
|
s_sprintf( msg, _countof( msg ), "Parser Error line at %d", linecount );
|
|
MessageBox( NULL, msg, "Parser Error", MB_OK | MB_ICONERROR );
|
|
#endif
|
|
}
|
|
return false;
|
|
}
|
|
|
|
stage = 3;
|
|
break;
|
|
|
|
case 3: // guid end
|
|
pInfo = pMetaData->addNewTemplateInfo( uuidTemplate, strTemplateName.c_str() );
|
|
stage = 4;
|
|
break;
|
|
|
|
case 4: // member start
|
|
stage = 5;
|
|
break;
|
|
|
|
case 5: // member declare
|
|
switch( token.TokenID )
|
|
{
|
|
case KTOKEN_CBRACE: // end declare template
|
|
return loop;
|
|
case KTOKEN_NAME:
|
|
tinfo = pMetaData->getTemplateInfo( token.StrToken.c_str() );
|
|
if ( pInfo != NULL && tinfo == NULL )
|
|
{
|
|
// check recursive format
|
|
if ( strcmp( token.StrToken.c_str(), pInfo->name() ) == 0 )
|
|
{
|
|
tinfo = pInfo;
|
|
}
|
|
else
|
|
{
|
|
{
|
|
#ifdef _DEBUG
|
|
char msg[128];
|
|
s_sprintf( msg, _countof( msg ), "Parser Error line at %d", linecount );
|
|
MessageBox( NULL, msg, "Parser Error", MB_OK | MB_ICONERROR );
|
|
#endif
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
var_type_token = KTOKEN_TEMPLATE;
|
|
var_array_count = 0;
|
|
stage = 6;
|
|
break;
|
|
case KTOKEN_WORD:
|
|
case KTOKEN_SHORT:
|
|
case KTOKEN_DWORD:
|
|
case KTOKEN_LONG:
|
|
case KTOKEN_LLONG:
|
|
case KTOKEN_FLOAT:
|
|
case KTOKEN_DOUBLE:
|
|
case KTOKEN_CHAR:
|
|
case KTOKEN_BYTE:
|
|
case KTOKEN_STRING:
|
|
case KTOKEN_WSTRING:
|
|
case KTOKEN_DICT:
|
|
tinfo = NULL;
|
|
var_type_token = token.TokenID;
|
|
var_array_count = 0;
|
|
stage = 6;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 6: // member name
|
|
var_name = token.StrToken;
|
|
stage = 7;
|
|
break;
|
|
|
|
case 7: // sentence end or array
|
|
{
|
|
int classid = Type::_NONE;
|
|
switch( token.TokenID )
|
|
{
|
|
case KTOKEN_SEMICOLON: // end sentence
|
|
|
|
switch( var_type_token )
|
|
{
|
|
case KTOKEN_TEMPLATE:
|
|
if ( var_array_count )
|
|
classid = Type::TEMPLATE_ARRAY;
|
|
else
|
|
classid = Type::TEMPLATE;
|
|
break;
|
|
|
|
case KTOKEN_WORD:
|
|
case KTOKEN_SHORT:
|
|
if ( var_array_count )
|
|
classid = Type::SHORT_ARRAY;
|
|
else
|
|
classid = Type::SHORT;
|
|
break;
|
|
|
|
case KTOKEN_DWORD:
|
|
case KTOKEN_LONG:
|
|
if ( var_array_count )
|
|
classid = Type::LONG_ARRAY;
|
|
else
|
|
classid = Type::LONG;
|
|
break;
|
|
|
|
case KTOKEN_LLONG:
|
|
if ( var_array_count )
|
|
classid = Type::LLONG_ARRAY;
|
|
else
|
|
classid = Type::LLONG;
|
|
break;
|
|
|
|
case KTOKEN_DOUBLE:
|
|
if ( var_array_count )
|
|
classid = Type::DOUBLE_ARRAY;
|
|
else
|
|
classid = Type::DOUBLE;
|
|
break;
|
|
|
|
case KTOKEN_FLOAT:
|
|
if ( var_array_count )
|
|
classid = Type::FLOAT_ARRAY;
|
|
else
|
|
classid = Type::FLOAT;
|
|
break;
|
|
|
|
case KTOKEN_BYTE:
|
|
case KTOKEN_CHAR:
|
|
if ( var_array_count )
|
|
classid = Type::CHAR_ARRAY;
|
|
else
|
|
classid = Type::CHAR;
|
|
break;
|
|
|
|
case KTOKEN_STRING:
|
|
if ( var_array_count )
|
|
classid = Type::STRING_ARRAY;
|
|
else
|
|
classid = Type::STRING;
|
|
var_array_count = -1;
|
|
break;
|
|
|
|
case KTOKEN_WSTRING:
|
|
if ( var_array_count )
|
|
classid = Type::WSTRING_ARRAY;
|
|
else
|
|
classid = Type::WSTRING;
|
|
var_array_count = -1;
|
|
break;
|
|
|
|
case KTOKEN_DICT:
|
|
classid = Type::DICT;
|
|
break;
|
|
}
|
|
|
|
if ( pInfo != NULL )
|
|
{
|
|
if ( tinfo == NULL )
|
|
{
|
|
if ( Type::isSimpleArrayType( classid ) )
|
|
pInfo->addArrayField( var_name.c_str(), Type::getElementType( classid ), var_array_count );
|
|
else if ( classid == Type::DICT )
|
|
pInfo->addDictField( var_name.c_str() );
|
|
else
|
|
pInfo->addSimpleField( var_name.c_str(), classid );
|
|
}
|
|
else
|
|
{
|
|
const TemplateInfo* pMInfo = pMetaData->getTemplateInfo( tinfo->id() );
|
|
if ( classid == Type::TEMPLATE_ARRAY )
|
|
pInfo->addTemplateArrayField( var_name.c_str(), pMInfo, var_array_count );
|
|
else
|
|
pInfo->addTemplateField( var_name.c_str(), pMInfo );
|
|
}
|
|
}
|
|
|
|
stage = 5;
|
|
break;
|
|
|
|
case KTOKEN_OBRACKET:
|
|
var_array_count = 0;
|
|
stage = 8;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 8: // array count
|
|
switch( token.TokenID )
|
|
{
|
|
case KTOKEN_CBRACKET:
|
|
|
|
var_array_count = -1;
|
|
stage = 7;
|
|
break;
|
|
|
|
case KTOKEN_NAME:
|
|
|
|
if ( pInfo != NULL )
|
|
{
|
|
if ( isdigit(token.StrToken.c_str()[0]) ) // constant number
|
|
{
|
|
var_array_count = atoi( token.StrToken.c_str() );
|
|
if ( var_array_count == 0 )
|
|
{
|
|
#ifdef _DEBUG
|
|
char msg[128];
|
|
s_sprintf( msg, _countof( msg ), "Constant Size Cannot be 0 Error line at %d", linecount );
|
|
MessageBox( NULL, msg, "Parser Error", MB_OK | MB_ICONERROR );
|
|
#endif
|
|
}
|
|
}
|
|
else // variable count
|
|
{
|
|
if ( pInfo->indexBy( token.StrToken.c_str() ) != -1 )
|
|
{
|
|
pInfo->removeField( token.StrToken.c_str() );
|
|
}
|
|
var_array_count = -1;
|
|
}
|
|
if ( var_array_count == 0 )
|
|
{
|
|
#ifdef _DEBUG
|
|
char msg[128];
|
|
s_sprintf( msg, _countof( msg ), "Constant Size Cannot be 0 Error line at %d", linecount );
|
|
MessageBox( NULL, msg, "Parser Error", MB_OK | MB_ICONERROR );
|
|
#endif
|
|
}
|
|
}
|
|
stage = 9;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 9: // end array
|
|
stage = 7;
|
|
break;
|
|
|
|
case 10: // template name
|
|
strTemplateName = token.StrToken.c_str();
|
|
stage = 1;
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool MetaData::importTML( KStream& stream )
|
|
{
|
|
bool loop = true;
|
|
int nLineCount = 1;
|
|
while ( loop )
|
|
{
|
|
loop = GetTemplateInfo( this, stream, nLineCount );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool trf::IsTRFStream( KStream& stream )
|
|
{
|
|
int idStr;
|
|
stream.Read( &idStr, sizeof(idStr) );
|
|
stream.Seek( -int(sizeof(idStr)), KStream::seekCur );
|
|
return idStr == 'FRTB';
|
|
}
|