2009-02-10 18:37:48 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "strmap.h"
|
|
|
|
|
|
|
|
hqStrMap* create_instance( int extrabytes, int dup )
|
|
|
|
{
|
|
|
|
hqStrMap* strmap = calloc( 1, sizeof(hqStrMap) );
|
|
|
|
strmap->FDoDuplicate = dup;
|
|
|
|
strmap->FExtraLen = extrabytes;
|
|
|
|
strmap->FRecordLen = sizeof(char*) + sizeof(int) + extrabytes;
|
|
|
|
strmap->FList = NULL;
|
|
|
|
return strmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
hqStrMap* Strmap_Create( int extrabytes, int dup )
|
|
|
|
{
|
|
|
|
return create_instance( extrabytes, dup );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Strmap_FillFromChain( hqStrMap* strmap, char *strchain, void *data )
|
|
|
|
{
|
|
|
|
while ( *strchain ) {
|
|
|
|
size_t len = strlen( strchain );
|
|
|
|
StrMap_AddStrLen( strmap, strchain, len, data );
|
|
|
|
strchain += len+1;
|
|
|
|
data = (char*)data + strmap->FExtraLen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hqStrMap* Strmap_CreateFromChain( int extrabytes, char *strchain, void *data )
|
|
|
|
{
|
|
|
|
hqStrMap* strmap = create_instance( extrabytes, 0 );
|
|
|
|
Strmap_FillFromChain( strmap, strchain, data );
|
|
|
|
StrMap_ShrinkMem( strmap );
|
|
|
|
return strmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_Destroy( hqStrMap* strmap )
|
|
|
|
{
|
|
|
|
if ( strmap->FDoDuplicate )
|
|
|
|
StrMap_TrimClear( strmap, 0 );
|
|
|
|
if ( strmap->FList )
|
|
|
|
free( strmap->FList );
|
|
|
|
|
|
|
|
free(strmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_AddString( hqStrMap* strmap, const char *str, void *data )
|
|
|
|
{
|
|
|
|
StrMap_AddStrLen( strmap, str, strlen(str), data );
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_AddStrLen( hqStrMap* strmap, const char *str, size_t len, void *data )
|
|
|
|
{
|
|
|
|
const char *Rec;
|
|
|
|
if ( strmap->FCount >= strmap->FCapacity ) {
|
|
|
|
int delta = (strmap->FCapacity > 64) ? strmap->FCapacity / 4 : 16;
|
|
|
|
StrMap_SetCapacity( strmap, strmap->FCapacity + delta );
|
|
|
|
}
|
|
|
|
Rec = strmap->FList + strmap->FCount * strmap->FRecordLen;
|
|
|
|
*(const char**)Rec = str;
|
|
|
|
*(int*)(Rec + sizeof(char*)) = len;
|
|
|
|
if (data) {
|
|
|
|
void *recdata = (void*)(Rec + sizeof(char*) + sizeof(int));
|
|
|
|
memcpy( recdata, data, strmap->FExtraLen );
|
|
|
|
}
|
|
|
|
++ strmap->FCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_ShrinkMem( hqStrMap* strmap )
|
|
|
|
{
|
|
|
|
StrMap_SetCapacity( strmap, strmap->FCount );
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_Trim( hqStrMap* strmap, int NewCount )
|
|
|
|
{
|
|
|
|
strmap->FCount = NewCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_TrimClear( hqStrMap* strmap, int NewCount )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char *Rec = strmap->FList + NewCount * strmap->FRecordLen;
|
|
|
|
for (i=NewCount; i < strmap->FCount; i++) {
|
|
|
|
free( *(char**)Rec );
|
|
|
|
Rec += strmap->FRecordLen;
|
|
|
|
}
|
|
|
|
strmap->FCount = NewCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StrMap_SetCapacity( hqStrMap* strmap, int NewCapacity )
|
|
|
|
{
|
|
|
|
strmap->FCapacity = NewCapacity;
|
|
|
|
if ( strmap->FCount > strmap->FCapacity )
|
|
|
|
strmap->FCount = strmap->FCapacity;
|
|
|
|
strmap->FList = (char*) realloc( strmap->FList,
|
|
|
|
strmap->FCapacity * strmap->FRecordLen );
|
|
|
|
}
|
|
|
|
|
|
|
|
int StrMap_IndexOf( hqStrMap* strmap, const char *str, void **data )
|
|
|
|
{
|
|
|
|
return StrMap_LenIndexOf( strmap, str, strlen(str), data );
|
|
|
|
}
|
|
|
|
|
|
|
|
int StrMap_LenIndexOf( hqStrMap* strmap, const char *str, size_t len, void **data )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char *Rec = strmap->FList;
|
|
|
|
for (i=0; i<strmap->FCount; i++) {
|
|
|
|
int recLen = *(int*)(Rec + sizeof(char*));
|
2010-08-10 18:23:10 +00:00
|
|
|
if (recLen==len && strnicmp( str, *(char**)Rec, recLen )==0 ) {
|
2009-02-10 18:37:48 +00:00
|
|
|
*data = (Rec + sizeof(char*) + sizeof(int));
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
Rec += strmap->FRecordLen;
|
|
|
|
}
|
|
|
|
*data = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* StrMap_GetString( hqStrMap* strmap, int index, int *len, void **data )
|
|
|
|
{
|
|
|
|
char *Rec = strmap->FList + index * strmap->FRecordLen;
|
|
|
|
*len = *(int*)(Rec + sizeof(char*));
|
|
|
|
if (data!=NULL && strmap->FExtraLen>0)
|
|
|
|
*data = (Rec + sizeof(char*) + sizeof(int));
|
|
|
|
return *(char**)Rec;
|
|
|
|
}
|
|
|
|
|