void KeyValues::AddSubKey(KeyValues *pSubkey) { Assert(pSubkey->m_pPeer == NULL); if (m_pSub == NULL) { m_pSub = pSubkey; } else { KeyValues *pTempDat = m_pSub; while (pTempDat->GetNextKey() != NULL) pTempDat = pTempDat->GetNextKey(); pTempDat->SetNextKey(pSubkey); } }
void KeyValues::AppendIncludedKeys(CUtlVector<KeyValues *> &includedKeys) { int includeCount = includedKeys.Count(); for (int i = 0; i < includeCount; i++) { KeyValues *kv = includedKeys[i]; Assert(kv); KeyValues *insertSpot = this; while (insertSpot->GetNextKey()) { insertSpot = insertSpot->GetNextKey(); } insertSpot->SetNextKey(kv); } }
bool CCompiledKeyValuesReader::CreateInPlaceFromData( KeyValues& head, const FileInfo_t& info ) { int first = info.nFirstIndex; int num = info.nCount; KeyValues *root = NULL; KeyValues *tail = NULL; CUtlRBTree< CreateHelper_t, int > helper( 0, 0, CreateHelper_t::Less ); for ( int i = 0; i < num; ++i ) { int offset = first + i; KVInfo_t& info = m_Data[ offset ]; if ( info.GetParent() != -1 ) { CreateHelper_t search; search.index = info.GetParent(); int idx = helper.Find( search ); if ( idx == helper.InvalidIndex() ) { return false; } KeyValues *parent = helper[ idx ].kv; Assert( parent ); KeyValues *sub = new KeyValues( m_StringTable.Lookup( info.key ) ); if ( !info.IsSubTree() ) { sub->SetStringValue(m_StringTable.Lookup( info.value ) ); } if ( !parent->GetFirstSubKey() ) { parent->AddSubKey( sub ); } else { KeyValues *last = helper[ idx ].tail; last->SetNextKey( sub ); } helper[ idx ].tail = sub; CreateHelper_t insert; insert.index = offset; insert.kv = sub; insert.tail = NULL; helper.Insert( insert ); } else { if ( !root ) { root = &head; root->SetName( m_StringTable.Lookup( info.key ) ); tail = root; CreateHelper_t insert; insert.index = offset; insert.kv = root; insert.tail = NULL; helper.Insert( insert ); } else { CreateHelper_t insert; insert.index = offset; insert.kv = new KeyValues( m_StringTable.Lookup( info.key ) ); insert.tail = NULL; helper.Insert( insert ); tail->SetNextKey( insert.kv ); tail = insert.kv; } } } return true; }
bool KeyValues::LoadFromBuffer(char const *resourceName, CUtlBuffer &buf, IFileSystem *pFileSystem, const char *pPathID) { KeyValues *pPreviousKey = NULL; KeyValues *pCurrentKey = this; CUtlVector<KeyValues *> includedKeys; CUtlVector<KeyValues *> baseKeys; bool wasQuoted; g_KeyValuesErrorStack.SetFilename(resourceName); do { const char *s = ReadToken(buf, wasQuoted); if (!buf.IsValid() || !s || *s == 0) break; if (!Q_stricmp(s, "#include")) { s = ReadToken(buf, wasQuoted); if (!s || *s == 0) { g_KeyValuesErrorStack.ReportError("#include is NULL "); } else { ParseIncludedKeys(resourceName, s, pFileSystem, pPathID, includedKeys); } continue; } else if (!Q_stricmp(s, "#base")) { s = ReadToken(buf, wasQuoted); if (!s || *s == 0) { g_KeyValuesErrorStack.ReportError("#base is NULL "); } else { ParseIncludedKeys(resourceName, s, pFileSystem, pPathID, baseKeys); } continue; } if (!pCurrentKey) { pCurrentKey = new KeyValues(s); Assert(pCurrentKey); pCurrentKey->UsesEscapeSequences(m_bHasEscapeSequences != 0); if (pPreviousKey) { pPreviousKey->SetNextKey(pCurrentKey); } } else { pCurrentKey->SetName(s); } s = ReadToken(buf, wasQuoted); if (s && *s == '{' && !wasQuoted) { pCurrentKey->RecursiveLoadFromBuffer(resourceName, buf); } else { g_KeyValuesErrorStack.ReportError("LoadFromBuffer: missing {"); } pPreviousKey = pCurrentKey; pCurrentKey = NULL; } while (buf.IsValid()); AppendIncludedKeys(includedKeys); { for (int i = includedKeys.Count() - 1; i > 0; i--) { KeyValues *kv = includedKeys[i]; kv->deleteThis(); } } MergeBaseKeys(baseKeys); { for (int i = baseKeys.Count() - 1; i >= 0; i--) { KeyValues *kv = baseKeys[i]; kv->deleteThis(); } } g_KeyValuesErrorStack.SetFilename(""); return true; }