// StringProperty.cpp: implementation of the CStringProperty class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "StringProperty.h" #include "utils.h" #define TRACE 0?0: CDictionary CStringPropertySection::m_Dictionary; CStringPropertySection::CStringPropertySection() { m_UsedItems=0; // make this an array and re-alloc it - like the CDPA ! Gosh. m_ItemSize=RUN_SIZE; m_Items=new LINKSTRING[m_ItemSize]; } // // Finds the Value from the KEY, returns NULL if the KEY isn't used. // LPCTSTR CStringPropertySection::Get(LPCTSTR szPropID) { int iEntry; if( Find( szPropID, &iEntry ) ) return (LPCTSTR)m_Items[iEntry].pszValue; return NULL; } #define _MEM_DEBUG #ifdef _MEM_DEBUG DWORD g_KeyAlloc; DWORD g_ValueAlloc; #endif // // Associats a value (perhaps new) to a given key. // BOOL CStringPropertySection::Set(LPCTSTR szPropID, LPCTSTR szValue) { int iEntry; if( Find( szPropID, &iEntry ) == FALSE ) { if( m_UsedItems == m_ItemSize ) { // re allocate the buffer bigger. m_ItemSize*=2; PLINKSTRING pNew=new LINKSTRING[m_ItemSize]; CopyMemory(pNew, m_Items, sizeof(LINKSTRING) * m_UsedItems ); delete m_Items; m_Items=pNew; } iEntry=m_UsedItems++; m_Items[iEntry].idKey=m_Dictionary.GetID( szPropID ); } else { delete m_Items[iEntry].pszValue; } DWORD dwLen=lstrlen(szValue)+1; #ifdef _MEM_DEBUG g_ValueAlloc+=dwLen; #endif m_Items[iEntry].pszValue=new TCHAR[dwLen]; CopyMemory( m_Items[iEntry].pszValue, szValue, dwLen*sizeof(TCHAR) ); return TRUE; } // // Finds a string in the table. // The KEY of the thing you are finding // An OUT pointer to the LINKSTRING structure // which item in the LINKSTRING structure can be used. // BOOL CStringPropertySection::Find( LPCTSTR szPropID, int * pEntry) { UINT uiPropID = m_Dictionary.GetID( szPropID ); // this is the ID for this string. for(UINT i=0;icbUsed; for( int i=0;ipszKey[i], szPropID) == 0 ) return pFound->ID[i]; } // // If we have space in this run, use it up. // if( used < DIC_RUN_SIZE ) break; // Next bucket pFoundPointer=&pFound->pNext; pFound=*pFoundPointer; } if( pFound == NULL ) { pFound = new LINKDICSTRING; ZeroMemory( pFound, sizeof(LINKDICSTRING) ); *pFoundPointer=pFound; TRACE(TEXT("Dic at 0x%08x\n"), pFound ); } // // Make the ID out of the bucket we are in, and the item we're adding. // int iEntry=pFound->cbUsed++; pFound->ID[iEntry]=hash<<8 | iNumber; #ifdef _MEM_DEBUG g_ValueAlloc+=dwStrLen; #endif pFound->pszKey[iEntry]=new TCHAR[dwStrLen]; CopyMemory( pFound->pszKey[iEntry], szPropID, dwStrLen*sizeof(TCHAR) ); return pFound->ID[iEntry]; } LPCTSTR CDictionary::GetString(UINT ID) { int iBucket=ID >> 8; // for( int iBucket=0;iBucketcbUsed; for( int i=0;iID[i] == ID ) return pLinkString->pszKey[i]; } pLinkString=( pLinkString->pNext ); } } return 0; } // // Case insensitive hash. // DWORD CDictionary::Hash( LPCTSTR szString, DWORD dwStrLen ) { TCHAR szChar=toupper( *szString ); return (dwStrLen * szChar) % DIC_TABLE_SIZE; } CDictionary::~CDictionary() { Purge(); } void CDictionary::Purge() { for(int i=0;icbUsed;ti++) { pEntry->ID[ti]=0; delete pEntry->pszKey[ti]; pEntry->pszKey[ti]=NULL; } pNext= pEntry->pNext; TRACE(TEXT("Dic @ 0x%08x\n"), pEntry ); delete pEntry; pEntry=pNext; } m_Table[i]=NULL; } }