Files
Leviathan/Library/Internal/include/kfile/TrfMetaData.h
T
2026-06-01 12:46:52 +02:00

351 lines
7.2 KiB
C++

#pragma once
// -
// - TRF : Template-based Recursive Format
// -
// - trfMetaData.h
// -
// - basic datatype and template metadata info
// -
// - 2006.2.14 by Young-Hyun Joo, nFlavor
// -
//
// - 하위호환성을 위해 long 을 32bit 로 간주한다. by Testors 2009/10/08
#include "../toolkit/khash.h"
#include "KStream.h"
#include <guiddef.h>
#include <vector>
#include <string>
#include <windows.h>
namespace trf {
struct Exception
{
Exception( int _code = 0, const char* _desc = "exception" ) { code = _code; desc = _desc; }
const char* desc;
int code;
};
struct Type
{
enum
{
_NONE = 0x00,
CHAR,
SHORT,
LONG,
LLONG,
FLOAT,
DOUBLE,
STRING,
WSTRING,
TEMPLATE,
DICT,
_ARRAYMASK = 0x80,
CHAR_ARRAY,
SHORT_ARRAY,
LONG_ARRAY,
LLONG_ARRAY,
FLOAT_ARRAY,
DOUBLE_ARRAY,
STRING_ARRAY,
WSTRING_ARRAY,
TEMPLATE_ARRAY
};
static inline int getTypeSize( int type );
static inline bool isSimpleType( int type );
static inline bool isSimpleArrayType( int type );
static inline int getArrayType( int type );
static inline int getElementType( int type );
};
class TemplateInfo
{
public:
const GUID& id() const { return m_id; }
const char* name() const { return m_strName.c_str(); }
int fixedSize() const { return m_fixedSize; }
int indexBy( const char* pName ) const { int index; return m_hashByName.lookup( pName, index ) ? index : -1; }
int count() const { return int( m_fields.size() ); }
const char* nameAt( int i ) const { return m_fields[ i ].name.c_str(); }
int typeAt( int i ) const { return m_fields[ i ].type; }
int fixedCountAt( int i ) const { return m_fields[ i ].fixedCount; }
int fixedSizeAt( int i ) const { return m_fields[ i ].fixedSize; }
const TemplateInfo* infoAt( int i ) const { return m_fields[ i ].pInfo; }
int getMetaDataIndex() const { return m_metaDataIndex; }
//
void clear();
bool removeField( const char* pFieldName );
bool addSimpleField( const char* pFieldName, int type );
bool addArrayField( const char* pFieldName, int elementType, int fixedCount = 0 );
bool addTemplateField( const char* pFieldName, const TemplateInfo* pInfo );
bool addTemplateArrayField( const char* pFieldName, const TemplateInfo* pElementInfo, int fixedCount = 0 );
bool addDictField( const char* pFieldName );
//
int calcFixedSize( int lastField ) const;
private:
friend class MetaData;
TemplateInfo( const GUID& uuidType, const char* pName, int i );
~TemplateInfo() { clear(); }
struct FieldInfo {
std::string name;
int type;
const TemplateInfo* pInfo;
int fixedCount;
int fixedSize;
};
GUID m_id;
std::string m_strName;
KHash< int, hashPr_string > m_hashByName;
std::vector< FieldInfo > m_fields;
int m_fixedSize;
int m_metaDataIndex;
};
struct ATInfo // augmented template info (TI with field limit)
{
int fieldLimit;
int fixedSize;
const TemplateInfo* pInfo;
};
class MetaData
{
public:
MetaData();
~MetaData();
void clear();
bool importTML( KStream& stream );
const TemplateInfo* getTemplateInfo( const GUID& uuidType ) const;
const TemplateInfo* getTemplateInfo( const char *pName ) const;
int getTemplateInfoCount() const { return int( m_infos.size() ); }
const TemplateInfo* getTemplateInfoAt( int i ) const { return m_infos[ i ]; }
TemplateInfo* addNewTemplateInfo( const GUID& uuidType, const char* pName );
private:
friend class Filer;
friend class Mapper;
void addRef() const;
void subRef() const;
struct hashPr_GUID
{
struct Key {
Key( const Key& _guid, bool ) { s_memcpy( &m_guid, sizeof( m_guid ), &_guid.m_guid, sizeof(m_guid) ); }
Key( const GUID& _guid ) { s_memcpy( &m_guid, sizeof( m_guid ), &_guid, sizeof(m_guid) ); }
GUID m_guid;
};
static inline unsigned int getindex( Key key, int nCapacity ) {
return ((unsigned int)key.m_guid.Data1 + key.m_guid.Data2 + key.m_guid.Data3) % nCapacity;
}
static inline bool isequal( Key key1, Key key2 ) {
return memcmp( &key1, &key2, sizeof(GUID) ) == 0;
}
static inline bool isless( Key key1, Key key2 ) {
return memcmp( &key1, &key2, sizeof(GUID) ) < 0;
}
};
KHash< TemplateInfo*, hashPr_GUID > m_hashByGUID;
KHash< TemplateInfo*, hashPr_string > m_hashByName;
std::vector< TemplateInfo* > m_infos;
volatile mutable LONG m_ref;
};
bool IsTRFStream( KStream& stream );
// ====================================================================================================================
inline int Type::getTypeSize( int type )
{
switch ( type )
{
case CHAR: return sizeof(char);
case SHORT: return sizeof(short);
case STRING:
case WSTRING:
case LONG: return sizeof(int);
case LLONG: return sizeof(long long);
case FLOAT: return sizeof(float);
case DOUBLE: return sizeof(double);
default: return -1;
}
}
inline bool Type::isSimpleType( int type )
{
switch ( type )
{
case CHAR:
case SHORT:
case LONG:
case LLONG:
case FLOAT:
case DOUBLE:
case STRING:
case WSTRING: return true;
default: return false;
}
}
inline bool Type::isSimpleArrayType( int type )
{
switch ( type )
{
case CHAR_ARRAY:
case SHORT_ARRAY:
case LONG_ARRAY:
case LLONG_ARRAY:
case FLOAT_ARRAY:
case DOUBLE_ARRAY:
case STRING_ARRAY:
case WSTRING_ARRAY: return true;
default: return false;
}
}
inline int Type::getArrayType( int type )
{
return type | Type::_ARRAYMASK;
}
inline int Type::getElementType( int type )
{
return type & ~Type::_ARRAYMASK;
}
inline TemplateInfo::TemplateInfo( const GUID& uuidType, const char* pName, int i )
: m_strName( pName )
{
m_id = uuidType;
m_fixedSize = 0;
m_metaDataIndex = i;
}
// ====================================================================================================================
#pragma pack(push,1)
struct FileHeader
{
char idstr[ 4 ];
// long headerInfoSize; // 64비트 때문에.. by Testors
int headerInfoSize;
};
struct HeaderInfo
{
short majorVersion;
short minorVersion;
};
#pragma pack(pop)
template< class T >
class SmartPtr
{
public:
SmartPtr( const T* pObj = 0 )
{
m_pObj = pObj;
if (m_pObj) ++m_pObj->m_refCount;
}
~SmartPtr()
{
if (m_pObj) m_pObj->release();
}
// Copy constructor
SmartPtr( const SmartPtr& rhs )
{
m_pObj = rhs.m_pObj;
if (m_pObj) ++m_pObj->m_refCount;
}
// Assign
SmartPtr& operator = ( const SmartPtr& rhs ) { _Copy(rhs.m_pObj); return *this; }
SmartPtr& operator = ( T* pObject ) { _Copy(pObject); return *this; }
// Conversion
operator T* () { return m_pObj; }
operator const T* () const { return m_pObj; }
const T* operator -> () const { return m_pObj; }
const T& operator * () const { return *m_pObj; }
T* operator -> () { return m_pObj; }
T& operator * () { return *m_pObj; }
// Compare
bool operator == ( const SmartPtr& ptr ) const { return m_pObj == ptr.m_pObj; }
bool operator != ( const SmartPtr& ptr ) const { return m_pObj != ptr.m_pObj; }
private:
void _Copy( T* pObj )
{
if ( pObj != m_pObj ) {
if ( m_pObj ) m_pObj->release();
m_pObj = pObj;
if ( m_pObj ) ++m_pObj->m_refCount;
}
}
const T* m_pObj;
};
} // namespace trf