326 lines
7.6 KiB
C++
326 lines
7.6 KiB
C++
#include <memory.h>
|
|
#include "stdio.h"
|
|
#include "stdlib.h"
|
|
#include "DICO.h"
|
|
//#include "xmmintrin.h"
|
|
|
|
void REnumWords(u32 CurrentIndex, char *pCurrentString);
|
|
void EnumWords(void (*CLBK)(char *String,void *UserParam),void *UserParam);
|
|
|
|
|
|
static char UNIC_Dico_ConvertTable_Upper[256];
|
|
static char UNIC_Dico_ConvertTable[256];
|
|
static u32 ConverterIsInit = 0;
|
|
|
|
void static_verify(void)
|
|
{
|
|
if (!ConverterIsInit)
|
|
{
|
|
ConverterIsInit = 1;
|
|
for (int i = 0 ; i < 256 ; i ++ )
|
|
{
|
|
UNIC_Dico_ConvertTable_Upper[i] = UNIC_Dico_ConvertTable[i] = i;
|
|
if (i == '\\') UNIC_Dico_ConvertTable_Upper[i] = '/';
|
|
if ((i >= 'a') && (i <= 'z')) UNIC_Dico_ConvertTable_Upper[i] = (i-'a') + 'A';
|
|
}
|
|
}
|
|
}
|
|
|
|
void UNIC_Dico::Init(void)
|
|
{
|
|
static_verify();
|
|
mu32_DicoSize = 1024;
|
|
if (mpst_Dico) free(mpst_Dico);
|
|
mpst_Dico = (tdst_Dico_Node *) malloc(mu32_DicoSize * sizeof(tdst_Dico_Node));
|
|
memset(mpst_Dico, 0,mu32_DicoSize * sizeof(tdst_Dico_Node));
|
|
mu32_DicoInc = 1;
|
|
IsCaseSensitive = 0;
|
|
NoSpace = 0;
|
|
};
|
|
void UNIC_Dico::Destroy(void)
|
|
{
|
|
if(mpst_Dico)
|
|
{
|
|
free(mpst_Dico);
|
|
mpst_Dico = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
void UNIC_Dico::REnumWords(u32 CurrentIndex, char *pBaseString , char *pCurrentString , u32 EnumDeleted)
|
|
{
|
|
*pCurrentString = mpst_Dico[CurrentIndex].Value;
|
|
if ((*pCurrentString == 0) && CurrentIndex && (EnumDeleted || !mpst_Dico[CurrentIndex].IsDeleted))
|
|
{
|
|
CLBK(pBaseString,UserParam);
|
|
}
|
|
if (mpst_Dico[CurrentIndex].NextMatch)
|
|
{
|
|
REnumWords(mpst_Dico[CurrentIndex].NextMatch, pBaseString , pCurrentString + 1,EnumDeleted);
|
|
}
|
|
for (u32 i = 0 ; i < UNIC_Dico_HValue ; i++)
|
|
{
|
|
if (mpst_Dico[CurrentIndex].NextNotMatch[i])
|
|
{
|
|
REnumWords(mpst_Dico[CurrentIndex].NextNotMatch[i] , pBaseString , pCurrentString,EnumDeleted);
|
|
}
|
|
}
|
|
}
|
|
void UNIC_Dico::EnumWordsBaseString(void (*CLBKA)(char *String,void *UserParam),void *UserParamA,char *BaseString,u32 EnumDeleted )
|
|
{
|
|
if (CLBKA && mpst_Dico)
|
|
{
|
|
char Construc[2048];
|
|
sprintf(Construc,"%s",BaseString);
|
|
char *string = Construc;
|
|
u32 ulCurrentDico;
|
|
ulCurrentDico = 0;
|
|
do
|
|
{
|
|
char ValueToTest;
|
|
ValueToTest = *string;
|
|
if (!IsCaseSensitive)
|
|
{
|
|
if ((ValueToTest >= 'a') && (ValueToTest <= 'z')) ValueToTest = 'A' + ValueToTest - 'a';
|
|
if (ValueToTest == '\\') ValueToTest = '/';
|
|
}
|
|
if (NoSpace && (ValueToTest == ' ')) ValueToTest = 0;
|
|
|
|
if(mpst_Dico[ulCurrentDico].Value == ValueToTest)
|
|
{
|
|
string++;
|
|
ulCurrentDico = mpst_Dico[ulCurrentDico].NextMatch;
|
|
}
|
|
else
|
|
ulCurrentDico = mpst_Dico[ulCurrentDico].NextNotMatch[ValueToTest & (UNIC_Dico_HValue - 1)]; /* fast H */
|
|
} while(ulCurrentDico && *string );
|
|
|
|
CLBK = CLBKA;
|
|
UserParam = UserParamA;
|
|
REnumWords(ulCurrentDico, Construc , string , EnumDeleted);
|
|
}
|
|
}
|
|
void UNIC_Dico::EnumWords(void (*CLBKA)(char *String,void *UserParam),void *UserParamA,u32 EnumDeleted)
|
|
{
|
|
if (CLBKA && mpst_Dico)
|
|
{
|
|
char Construc[2048];
|
|
CLBK = CLBKA;
|
|
UserParam = UserParamA;
|
|
REnumWords(0, Construc , Construc , EnumDeleted);
|
|
}
|
|
}
|
|
|
|
u32 UNIC_Dico::DelWord(char *_psz_Word) // Returns the UNIC ID
|
|
{
|
|
if(!mpst_Dico) return 0;
|
|
if(!*_psz_Word) return 0;
|
|
|
|
u32 Exist;
|
|
Exist = IsExist(_psz_Word);
|
|
if (Exist != -1)
|
|
{
|
|
mpst_Dico[Exist].IsDeleted = 1;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u32 UNIC_Dico::AddWord(char *_psz_Word) // Returns the UNIC ID
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
char *SaveString;
|
|
u32 ulCurrentDico, StoppedPlace, NewDicoNode;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if(!mpst_Dico) Init();
|
|
if(!*_psz_Word) return 0;
|
|
|
|
u32 Exist;
|
|
Exist = IsExist(_psz_Word);
|
|
if (Exist != -1) return Exist;
|
|
|
|
Exist = IsExist(_psz_Word,1);
|
|
if (Exist != -1)
|
|
{
|
|
/* Recretate it if allready here */
|
|
mpst_Dico[Exist].IsDeleted = 0;
|
|
return Exist;
|
|
}
|
|
|
|
SaveString = _psz_Word;
|
|
ulCurrentDico = 0;
|
|
do
|
|
{
|
|
StoppedPlace = ulCurrentDico;
|
|
if(mpst_Dico[ulCurrentDico].Value == *_psz_Word)
|
|
{
|
|
if(!*(_psz_Word++))
|
|
{
|
|
return ulCurrentDico; /* Already exist */
|
|
}
|
|
ulCurrentDico = mpst_Dico[ulCurrentDico].NextMatch;
|
|
}
|
|
else
|
|
ulCurrentDico = mpst_Dico[ulCurrentDico].NextNotMatch[*_psz_Word & (UNIC_Dico_HValue - 1)]; /* fast H */
|
|
} while(ulCurrentDico);
|
|
|
|
NewDicoNode = u32_GetANode();
|
|
mpst_Dico[StoppedPlace].NextNotMatch[*_psz_Word & (UNIC_Dico_HValue - 1)] = NewDicoNode;
|
|
while(*_psz_Word)
|
|
{
|
|
mpst_Dico[NewDicoNode].AssociatedValue = 0;
|
|
mpst_Dico[NewDicoNode].Value = *(_psz_Word++);
|
|
mpst_Dico[NewDicoNode].NextMatch = u32_GetANode();
|
|
NewDicoNode = mpst_Dico[NewDicoNode].NextMatch;
|
|
mpst_Dico[NewDicoNode].AssociatedValue = 0;
|
|
mpst_Dico[NewDicoNode].Value = 0;
|
|
}
|
|
/* test */
|
|
/*if(IsExist(SaveString) == -1)
|
|
SaveString = SaveString;*/
|
|
|
|
return NewDicoNode;
|
|
}
|
|
u32 UNIC_Dico::IsExist(char *string,u32 DeletedOnly )
|
|
{
|
|
/*~~~~~~~~~~~~~~*/
|
|
u32 ulCurrentDico;
|
|
/*~~~~~~~~~~~~~~*/
|
|
|
|
if(!*string) return -1;
|
|
if (!mpst_Dico) return -1;
|
|
|
|
char *pConverter;
|
|
|
|
static_verify();
|
|
if (!IsCaseSensitive)
|
|
pConverter = (char *)UNIC_Dico_ConvertTable_Upper;
|
|
else
|
|
pConverter = (char *)UNIC_Dico_ConvertTable;
|
|
pConverter[' '] = ' ';
|
|
if (NoSpace) pConverter[' '] = 0;
|
|
|
|
ulCurrentDico = 0;
|
|
do
|
|
{
|
|
char ValueToTest = pConverter[*(string)];
|
|
//_mm_prefetch((char*)&mpst_Dico[ulCurrentDico].NextNotMatch[ValueToTest & (UNIC_Dico_HValue - 1)],_MM_HINT_NTA);
|
|
|
|
if(mpst_Dico[ulCurrentDico].Value == ValueToTest)
|
|
{
|
|
if(!ValueToTest)
|
|
{
|
|
if (DeletedOnly)
|
|
{
|
|
if (mpst_Dico[ulCurrentDico].IsDeleted)
|
|
return ulCurrentDico;
|
|
else
|
|
return -1;
|
|
} else
|
|
{
|
|
if (mpst_Dico[ulCurrentDico].IsDeleted)
|
|
return -1;
|
|
else
|
|
return ulCurrentDico;
|
|
}
|
|
}
|
|
string++;
|
|
ulCurrentDico = mpst_Dico[ulCurrentDico].NextMatch;
|
|
}
|
|
else
|
|
ulCurrentDico = mpst_Dico[ulCurrentDico].NextNotMatch[ValueToTest & (UNIC_Dico_HValue - 1)]; /* fast H */
|
|
} while(ulCurrentDico);
|
|
return -1;
|
|
}
|
|
|
|
u32 UNIC_Dico::FindKey(u32 CurrentIndex,char *string, u32 ValueToFind)
|
|
{
|
|
if(!mpst_Dico) return -1;
|
|
if ((CurrentIndex == ValueToFind) && (mpst_Dico[CurrentIndex].Value == 0))
|
|
{
|
|
*string = 0;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
u32 Ret;
|
|
if (mpst_Dico[CurrentIndex].NextMatch)
|
|
{
|
|
*(string ++) = mpst_Dico[CurrentIndex].Value;
|
|
Ret = FindKey(mpst_Dico[CurrentIndex].NextMatch,string, ValueToFind);
|
|
if (Ret == 0) return 0;
|
|
string--;
|
|
*(string) = 0;
|
|
}
|
|
for (u32 i = 0 ; i < UNIC_Dico_HValue ; i++)
|
|
{
|
|
if (mpst_Dico[CurrentIndex].NextNotMatch[i])
|
|
{
|
|
if (FindKey(mpst_Dico[CurrentIndex].NextNotMatch[i], string, ValueToFind) == 0) return 0;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
u32 UNIC_Dico::GetWord(char *string, u32 ValueToFind)
|
|
{
|
|
u32 res = FindKey(0,string, ValueToFind);
|
|
return res;
|
|
}
|
|
|
|
u32 UNIC_Dico::u32_GetANode()
|
|
{
|
|
if(!mpst_Dico) Init();
|
|
if(mu32_DicoInc == mu32_DicoSize)
|
|
{
|
|
mpst_Dico = (tdst_Dico_Node *) realloc(mpst_Dico, (mu32_DicoSize + 1024) * sizeof(tdst_Dico_Node));
|
|
memset(mpst_Dico + mu32_DicoSize, 0,1024 * sizeof(tdst_Dico_Node));
|
|
mu32_DicoSize += 1024;
|
|
}
|
|
|
|
memset( &mpst_Dico[mu32_DicoInc], 0,sizeof(tdst_Dico_Node));
|
|
return mu32_DicoInc++;
|
|
}
|
|
|
|
|
|
|
|
u32 UNIC_Dico::GetUnic(/* OUT */ UnicID *ID,/* IN */ char *Name)
|
|
{
|
|
u32 AsVa;
|
|
char Converted[2048];
|
|
AsVa = 0;
|
|
while (*Name)
|
|
{
|
|
Converted[AsVa] = *Name;
|
|
if (!IsCaseSensitive)
|
|
{
|
|
if ((Converted[AsVa] >= 'a') && (Converted[AsVa] <= 'z')) Converted[AsVa] = 'A' + Converted[AsVa] - 'a';
|
|
if (Converted[AsVa] == '\\') Converted[AsVa] = '/';
|
|
}
|
|
if (NoSpace && (Converted[AsVa] == ' ')) Converted[AsVa] = 0;
|
|
AsVa++;
|
|
Name++;
|
|
}
|
|
Converted[AsVa] = 0;
|
|
AsVa = IsExist((char*)Converted);
|
|
if (AsVa == -1)
|
|
{
|
|
*ID = AddWord((char*)Converted);
|
|
return *ID;
|
|
} else
|
|
{
|
|
*ID = AsVa;
|
|
return AsVa;
|
|
}
|
|
}
|
|
|
|
u32 UNIC_Dico::GetName(/* IN */ UnicID *ID,/* OUT */ char *Name)
|
|
{
|
|
*Name = 0;
|
|
return GetWord(Name,*ID);
|
|
}
|