JD2022-TU1/main/extern/Camcam/CCIO/IO_Dico.cpp

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);
}