1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 12:06:07 +08:00

Update CKeyValues3Table & CKV3MemberName

This commit is contained in:
GAMMACASE
2025-08-04 20:22:40 +03:00
parent c89d081679
commit 20208f41c5
2 changed files with 132 additions and 49 deletions

View File

@ -347,7 +347,7 @@ struct KV3BinaryBlob_t
class CKV3MemberName
{
public:
inline CKV3MemberName(const char* pszString): m_nHashCode(), m_pszString("")
inline CKV3MemberName(const char* pszString, UtlSymLargeId_t symid = UTL_INVAL_SYMBOL_LARGE ): m_nHashCode(), m_SymId( symid ), m_pszString("")
{
if (!pszString || !pszString[0])
return;
@ -356,14 +356,16 @@ public:
m_pszString = pszString;
}
inline CKV3MemberName(): m_nHashCode(), m_pszString("") {}
inline CKV3MemberName( CUtlStringToken nHashCode, const char* pszString = ""): m_nHashCode(nHashCode), m_pszString(pszString) {}
inline CKV3MemberName(): m_nHashCode(), m_SymId( UTL_INVAL_SYMBOL_LARGE ), m_pszString("") {}
inline CKV3MemberName( CUtlStringToken nHashCode, const char* pszString = "", UtlSymLargeId_t symid = UTL_INVAL_SYMBOL_LARGE ): m_nHashCode(nHashCode), m_SymId( symid ), m_pszString(pszString) {}
inline unsigned int GetHashCode() const { return m_nHashCode.GetHashCode(); }
inline const char* GetString() const { return m_pszString; }
inline UtlSymLargeId_t GetSymId() const { return m_SymId; }
private:
CUtlStringToken m_nHashCode;
UtlSymLargeId_t m_SymId;
const char* m_pszString;
};
@ -777,12 +779,17 @@ class CKeyValues3Table
public:
enum
{
MEMBER_FLAG_EXTERNAL_NAME = (1 << 0)
MEMBER_FLAG_EXTERNAL_NAME = (1 << 0),
MEMBER_FLAG_LARGE_SYMBOL = (1 << 1)
};
typedef CUtlStringToken Hash_t;
typedef KeyValues3* Member_t;
typedef const char* Name_t;
union Name_t
{
const char *m_String;
UtlSymLargeId_t m_SymId;
};
typedef uint8 Flags_t;
static const size_t DATA_SIZE = KV3_TABLE_MAX_FIXED_MEMBERS;
@ -800,8 +807,9 @@ public:
int GetMemberCount() const { return m_nCount; }
Member_t GetMember( KV3MemberId_t id );
const Member_t GetMember( KV3MemberId_t id ) const { return const_cast<CKeyValues3Table*>(this)->GetMember( id ); }
const Name_t GetMemberName( KV3MemberId_t id ) const;
const const char *GetMemberName( const KeyValues3 *parent, KV3MemberId_t id ) const;
const Hash_t GetMemberHash( KV3MemberId_t id ) const;
CKV3MemberName GetKV3MemberName( const KeyValues3 *parent, KV3MemberId_t id ) const;
void PurgeFastSearch();
void EnableFastSearch();
@ -824,6 +832,10 @@ public:
static constexpr size_t TotalSizeWithoutStaticData() { return sizeof(CKeyValues3Table) - sizeof(m_StaticBuffer); }
private:
void PurgeNameBuffer( KeyValues3 *parent, KV3MemberId_t id );
void StoreKeyName( KeyValues3 *parent, Name_t &out_string, Flags_t &out_flags, const char *input_string, UtlSymLargeId_t sym_id = UTL_INVAL_SYMBOL_LARGE, bool name_external = false );
int GetAllocatedChunks() const { return m_nAllocatedChunks; }
bool IsBaseStatic() { return !m_bIsDynamicallySized; }
@ -1114,7 +1126,8 @@ public:
IParsingErrorListener* GetParsingErrorListener() const { return m_pParsingErrorListener; }
void SetParsingErrorListener( IParsingErrorListener* listener ) { m_pParsingErrorListener = listener; }
const char* AllocString( const char* pString );
const char* AllocString( const char* pString, UtlSymLargeId_t *symid = NULL );
const char *LookupString( UtlSymLargeId_t symid ) const;
void EnableMetaData( bool bEnable );
void CopyMetaData( KV3MetaData_t* pDest, const KV3MetaData_t* pSrc );

View File

@ -801,7 +801,7 @@ const char* KeyValues3::GetMemberName( KV3MemberId_t id ) const
if ( GetType() != KV3_TYPE_TABLE || id < 0 || id >= m_Data.m_pTable->GetMemberCount() )
return nullptr;
return m_Data.m_pTable->GetMemberName( id );
return m_Data.m_pTable->GetMemberName( this, id );
}
CKV3MemberName KeyValues3::GetMemberNameEx( KV3MemberId_t id ) const
@ -809,7 +809,7 @@ CKV3MemberName KeyValues3::GetMemberNameEx( KV3MemberId_t id ) const
if ( GetType() != KV3_TYPE_TABLE || id < 0 || id >= m_Data.m_pTable->GetMemberCount() )
return CKV3MemberName();
return CKV3MemberName( m_Data.m_pTable->GetMemberHash( id ), m_Data.m_pTable->GetMemberName( id ) );
return m_Data.m_pTable->GetKV3MemberName( this, id );
}
CUtlStringToken KeyValues3::GetMemberHash( KV3MemberId_t id ) const
@ -1548,11 +1548,19 @@ KeyValues3* CKeyValues3Table::GetMember( KV3MemberId_t id )
return MembersBase()[id];
}
const CKeyValues3Table::Name_t CKeyValues3Table::GetMemberName( KV3MemberId_t id ) const
const const char* CKeyValues3Table::GetMemberName( const KeyValues3 *parent, KV3MemberId_t id ) const
{
Assert( 0 <= id && id < m_nCount );
return NamesBase()[id];
Flags_t flags = FlagsBase()[id];
if((flags & MEMBER_FLAG_LARGE_SYMBOL) != 0)
{
UtlSymLargeId_t symid = NamesBase()[id].m_SymId;
return parent->GetContext()->LookupString( symid );
}
return NamesBase()[id].m_String;
}
const CKeyValues3Table::Hash_t CKeyValues3Table::GetMemberHash( KV3MemberId_t id ) const
@ -1562,6 +1570,27 @@ const CKeyValues3Table::Hash_t CKeyValues3Table::GetMemberHash( KV3MemberId_t id
return HashesBase()[id];
}
CKV3MemberName CKeyValues3Table::GetKV3MemberName( const KeyValues3 *parent, KV3MemberId_t id ) const
{
Assert( 0 <= id && id < m_nCount );
Flags_t flags = FlagsBase()[id];
UtlSymLargeId_t symid = UTL_INVAL_SYMBOL_LARGE;
const char *key_name = nullptr;
if((flags & MEMBER_FLAG_LARGE_SYMBOL) != 0)
{
symid = NamesBase()[id].m_SymId;
key_name = parent->GetContext()->LookupString( symid );
}
else
{
key_name = NamesBase()[id].m_String;
}
return CKV3MemberName( GetMemberHash( id ), key_name, symid );
}
void CKeyValues3Table::EnableFastSearch()
{
if ( m_pFastSearch )
@ -1693,24 +1722,8 @@ KV3MemberId_t CKeyValues3Table::CreateMember( KeyValues3 *parent, const CKV3Memb
members_base[curr] = parent->AllocMember();
hashes_base[curr] = name.GetHashCode();
Flags_t flags = 0;
if(name_external)
{
names_base[curr] = name.GetString();
flags |= MEMBER_FLAG_EXTERNAL_NAME;
}
else
{
auto context = parent->GetContext();
if(context)
names_base[curr] = context->AllocString( name.GetString() );
else
names_base[curr] = strdup( name.GetString() );
}
flags_base[curr] = flags;
StoreKeyName( parent, names_base[curr], flags_base[curr], name.GetString(), name.GetSymId(), name_external );
if ( m_pFastSearch && !m_pFastSearch->m_ignore )
m_pFastSearch->m_member_ids.Insert( name.GetHashCode(), curr );
@ -1720,6 +1733,52 @@ KV3MemberId_t CKeyValues3Table::CreateMember( KeyValues3 *parent, const CKV3Memb
return curr;
}
void CKeyValues3Table::StoreKeyName( KeyValues3 *parent, Name_t &out_buffer, Flags_t &out_flags, const char *input_string, UtlSymLargeId_t sym_id, bool name_external )
{
Flags_t flags = 0;
if(name_external)
{
out_buffer.m_String = input_string;
flags |= MEMBER_FLAG_EXTERNAL_NAME;
}
else
{
auto context = parent->GetContext();
if(context)
{
const char *existing_str = context->LookupString( sym_id );
if(existing_str && (existing_str == input_string || strcmp(existing_str, input_string) == 0))
{
out_buffer.m_SymId = sym_id;
flags |= MEMBER_FLAG_LARGE_SYMBOL;
}
else
{
const char *alloced_string = context->AllocString( input_string, &sym_id );
if(sym_id >= 0)
{
out_buffer.m_SymId = sym_id;
flags |= MEMBER_FLAG_LARGE_SYMBOL;
}
else
{
out_buffer.m_String = alloced_string;
}
}
}
else
{
out_buffer.m_String = strdup( input_string );
}
}
out_flags = flags;
}
void CKeyValues3Table::CopyFrom( KeyValues3 *parent, const CKeyValues3Table* src )
{
int new_size = src->GetMemberCount();
@ -1743,12 +1802,10 @@ void CKeyValues3Table::CopyFrom( KeyValues3 *parent, const CKeyValues3Table* src
for(int i = 0; i < new_size; i++)
{
flags_base[i] = src_flags_base[i] & ~MEMBER_FLAG_EXTERNAL_NAME;
if(context)
names_base[i] = context->AllocString( src_names_base[i] );
if(context && (src_flags_base[i] & MEMBER_FLAG_LARGE_SYMBOL) != 0)
StoreKeyName( parent, names_base[i], flags_base[i], context->LookupString( src_names_base[i].m_SymId ), src_names_base[i].m_SymId );
else
names_base[i] = strdup( src_names_base[i] );
StoreKeyName( parent, names_base[i], flags_base[i], src_names_base[i].m_String );
members_base[i] = parent->AllocMember();
members_base[i]->CopyFrom( src_members_base[i] );
@ -1758,6 +1815,19 @@ void CKeyValues3Table::CopyFrom( KeyValues3 *parent, const CKeyValues3Table* src
EnableFastSearch();
}
void CKeyValues3Table::PurgeNameBuffer( KeyValues3 *parent, KV3MemberId_t id )
{
auto name = NamesBase()[id];
auto flags = FlagsBase()[id];
if((flags & MEMBER_FLAG_EXTERNAL_NAME) == 0 &&
(flags & MEMBER_FLAG_LARGE_SYMBOL) == 0 &&
!parent->GetContext() && name.m_String)
{
free( (void *)name.m_String );
}
}
void CKeyValues3Table::RemoveMember( KeyValues3 *parent, KV3MemberId_t id )
{
m_nCount--;
@ -1769,10 +1839,7 @@ void CKeyValues3Table::RemoveMember( KeyValues3 *parent, KV3MemberId_t id )
parent->FreeMember( members_base[id] );
if((flags_base[id] & MEMBER_FLAG_EXTERNAL_NAME) == 0 && !parent->GetContext() && names_base[id])
{
free( (void *)names_base[id] );
}
PurgeNameBuffer( parent, id );
if ( id < m_nCount )
{
@ -1801,11 +1868,7 @@ void CKeyValues3Table::RemoveAll( KeyValues3 *parent, int new_size )
for(int i = 0; i < m_nCount; i++)
{
parent->FreeMember( members_base[i] );
if((flags_base[i] & MEMBER_FLAG_EXTERNAL_NAME) == 0 && !parent->GetContext() && names_base[i])
{
free( (void *)names_base[i] );
}
PurgeNameBuffer( parent, i );
}
m_nCount = 0;
@ -1846,10 +1909,7 @@ void CKeyValues3Table::PurgeContent( KeyValues3 *parent, bool bClearingContext )
parent->FreeMember( members_base[i] );
}
if((flags_base[i] & MEMBER_FLAG_EXTERNAL_NAME) == 0 && parent && !parent->GetContext() && names_base[i])
{
free( (void *)names_base[i] );
}
PurgeNameBuffer( parent, i );
}
m_nCount = 0;
@ -1967,9 +2027,19 @@ KeyValues3* CKeyValues3Context::Root()
return &m_KV3BaseCluster.Head()->m_Value;
}
const char* CKeyValues3Context::AllocString( const char* pString )
const char* CKeyValues3Context::AllocString( const char* pString, UtlSymLargeId_t *out_symid )
{
return m_Symbols.AddString( pString ).String();
UtlSymLargeId_t sym = m_Symbols.AddStringRaw( pString );
if(out_symid)
*out_symid = sym;
return m_Symbols.String( sym );
}
const char* CKeyValues3Context::LookupString( UtlSymLargeId_t symid ) const
{
return m_Symbols.String( symid );
}
void CKeyValues3Context::EnableMetaData( bool bEnable )