JD2022-TU1/main/extern/Camcam/LIBS/Mixer/IniFileManager.cpp

794 lines
No EOL
18 KiB
C++
Raw Blame History

#include "SCENE.h"
extern void SaveDBGInfo(char *text);
void INIFILE::saveVariable(FILE* file , u32 ID, u32 indent)
{
if(variables[ID].child==-1)
{
for(u32 i=0; i<indent; i++)
{
fprintf(file, "\t");
}
fprintf(file, "%s = %s\n", strrchr(variables[ID].name, '.')+1, variables[ID].value);
}
else
{
for(u32 i=0; i<indent; i++)
{
fprintf(file, "\t");
}
fprintf(file, "[%s]\n", strrchr(variables[ID].name, '.')+1);
u32 currentChild = variables[ID].child;
do
{
saveVariable(file, currentChild, indent+1);
currentChild = variables[currentChild].next;
}
while(currentChild!=-1);
for(u32 i=0; i<indent; i++)
{
fprintf(file, "\t");
}
fprintf(file, "[/%s]\n", strrchr(variables[ID].name, '.')+1);
}
}
void INIFILE::saveVariableInBuffer(char **buffer, int *len, int *pos, u32 ID, u32 indent)
{
int stringLen;
char *varName = strrchr(variables[ID].name, '.')+1;
if(variables[ID].child==-1)
{
stringLen = *pos + indent + strlen(varName) + strlen(variables[ID].value) + 5;
if (*len < stringLen)
{
while (*len < stringLen) *len += 1024;
*buffer = (char *)CC_realloc(*buffer, *len);
}
for(u32 i=0; i<indent; i++) sprintf(*buffer + *pos, "\t");
sprintf(*buffer + *pos, "%s = %s\n", varName, variables[ID].value);
*len -= (int)strlen(*buffer + *pos); *pos += (int)strlen(*buffer + *pos);
}
else
{
stringLen = *pos + indent + strlen(varName) + 5;
if (*len < stringLen)
{
while (*len < stringLen) *len += 1024;
*buffer = (char *)CC_realloc(*buffer, *len);
}
for(u32 i=0; i<indent; i++) sprintf(*buffer + *pos, "\t");
sprintf(*buffer + *pos, "[%s]\n", varName);
*len -= (int)strlen(*buffer + *pos); *pos += (int)strlen(*buffer + *pos);
u32 currentChild = variables[ID].child;
do
{
saveVariableInBuffer(buffer, len, pos, currentChild, indent+1);
currentChild = variables[currentChild].next;
}
while(currentChild!=-1);
stringLen = *pos + indent + strlen(varName) + 5;
if (*len < stringLen)
{
while (*len < stringLen) *len += 1024;
*buffer = (char *)CC_realloc(*buffer, *len);
}
for(u32 i=0; i<indent; i++) sprintf(*buffer + *pos, "\t");
sprintf(*buffer + *pos, "[/%s]\n", varName);
*len -= (int)strlen(*buffer + *pos); *pos += (int)strlen(*buffer + *pos);
}
}
void INIFILE::Init()
{
memset(this, 0, sizeof(*this));
variableDico.Init();
maxVariables = 32;
variables = (INI_VARIABLE*)CC_malloc(maxVariables*sizeof(INI_VARIABLE));
memset(variables, 0, maxVariables*sizeof(INI_VARIABLE));
firstEmptyCell = 0;
root = -1;
for(u32 i=0; i<maxVariables; i++)
{
variables[i].parent = -1;
variables[i].child = -1;
variables[i].prev = i-1;
variables[i].next = i+1;
variables[i].value = 0;
variables[i].name = 0;
variables[i].uid = -1;
}
variables[0].prev = -1;
variables[maxVariables-1].next = -1;
}
void INIFILE::Destroy()
{
variableDico.Destroy();
if(variables)
{
for(u32 i=0; i<maxVariables; i++)
{
variables[i].Destroy();
}
CC_free(variables);
variables = 0;
}
}
u32 INIFILE::addVariable(char * parent, char * variable, char* value, bool useDecoder)
{
// Hook that strings!
//WSDecodeCCMEntry decode(&parent, &variable, &value, useDecoder);
if(parent && *parent && variableDico.IsExist(parent)==-1) return -1;
u32 ID;
UnicID mUID;
if(variable && *variable && variableDico.IsExist(variable)!=-1)
{
delVariable(variable);
}
//augmenter la taille du tableau si plus de cellules vides
if(firstEmptyCell==-1)
{
variables = (INI_VARIABLE*)CC_realloc(variables, 2*maxVariables*sizeof(INI_VARIABLE));
//INI_VARIABLE *variablesNew = (INI_VARIABLE*)CC_malloc(2*maxVariables*sizeof(INI_VARIABLE));
//memset(variablesNew, 0, 2*maxVariables*sizeof(INI_VARIABLE));
//memcpy(variablesNew, variables, maxVariables*sizeof(INI_VARIABLE));
//CC_free(variables);
//variables = variablesNew;
firstEmptyCell = maxVariables;
for(u32 i=maxVariables; i<2*maxVariables; i++)
{
variables[i].parent = -1;
variables[i].child = -1;
variables[i].prev = i-1;
variables[i].next = i+1;
variables[i].value = 0;
variables[i].name = 0;
variables[i].uid = -1;
}
variables[maxVariables].prev = -1;
variables[2*maxVariables-1].next = -1;
maxVariables *= 2;
}
variableDico.GetUnic(&mUID,variable);
ID = firstEmptyCell;
variableDico.mpst_Dico[mUID].AssociatedValue = ID;
firstEmptyCell = variables[firstEmptyCell].next;
if (firstEmptyCell != -1)
variables[firstEmptyCell].prev = -1;
variables[ID].uid = mUID;
u32 IDParent;
UnicID mUIDParent;
if(parent && *parent)
{
variableDico.GetUnic(&mUIDParent,parent);
IDParent = variableDico.mpst_Dico[mUIDParent].AssociatedValue;
if(variables[IDParent].child==-1)
{
variables[IDParent].child = ID;
variables[ID].parent = IDParent;
variables[ID].prev = -1;
variables[ID].next = -1;
variables[ID].child = -1;
}
else
{
u32 currentChild = variables[IDParent].child;
u32 lastChild = variables[IDParent].child;
while(currentChild!=-1)
{
lastChild = currentChild;
currentChild = variables[currentChild].next;
}
variables[ID].parent = -1;
variables[ID].child = -1;
variables[ID].next = -1;
variables[ID].prev = lastChild;
variables[lastChild].next = ID;
/***
variables[ID].next = variables[IDParent].child;
variables[variables[IDParent].child].prev = ID;
variables[variables[IDParent].child].parent = -1;
variables[IDParent].child = ID;
variables[ID].parent = IDParent;
variables[ID].prev = -1;
variables[ID].child = -1;
***/
}
}
else
{
u32 currentChild = root;
u32 lastChild = root;
while(currentChild!=-1)
{
lastChild = currentChild;
currentChild = variables[currentChild].next;
}
variables[ID].parent = -1;
variables[ID].child = -1;
variables[ID].next = -1;
variables[ID].prev = lastChild;
if (lastChild!=-1)
{
variables[lastChild].next = ID;
}
if (root==-1)
{
root = ID;
}
/***
variables[ID].parent = -1;
variables[ID].prev = -1;
variables[ID].child = -1;
if (root!=-1)
{
variables[root].prev = ID;
}
variables[ID].next = root;
root = ID;
***/
}
/*
if (variables[ID].value)
{
CC_free(variables[ID].value);
variables[ID].value = 0;
}
*/
if(value)
{
//variables[ID].value = (char*)ZeroAlloc(strlen(value)+1);
variables[ID].value = (char*)ZeroRealloc(variables[ID].value, strlen(value)+1);
memcpy(variables[ID].value, value, strlen(value));
variables[ID].value[strlen(value)] = 0;
}
else
{
variables[ID].value = (char*)ZeroRealloc(variables[ID].value, 1);
variables[ID].value[0] = 0;
}
/*
if (variables[ID].name)
{
CC_free(variables[ID].name);
variables[ID].name = 0;
}
*/
if(variable)
{
//variables[ID].name = (char*)ZeroAlloc(strlen(variable)+1);
variables[ID].name = (char*)ZeroRealloc(variables[ID].name, strlen(variable)+1);
memcpy(variables[ID].name, variable, strlen(variable));
variables[ID].name[strlen(variable)] = 0;
}
else
{
variables[ID].name = (char*)ZeroRealloc(variables[ID].name, 1);
variables[ID].name[0] = 0;
}
return ID;
}
void INIFILE::delVariable(char * variable)
{
//*
u32 ID;
UnicID mUID;
if(variable && *variable && variableDico.IsExist(variable)!=-1)
{
variableDico.GetUnic(&mUID,variable);
ID = variableDico.mpst_Dico[mUID].AssociatedValue;
//suppression des enfants de la variable
if(variables[ID].child!=-1)
{
u32 currentChild = variables[ID].child;
char childName[2048] = "";
do
{
variableDico.GetName(&(variables[currentChild].uid), childName);
delVariable(childName);
currentChild = variables[currentChild].next;
}
while(currentChild!=-1);
variables[ID].child = -1;
}
//d<>connexion de la variable
if(root==ID)
{
root = variables[ID].next;
}
if (variables[ID].parent!=-1)
{
variables[variables[ID].parent].child = variables[ID].next;
variables[ID].parent = -1;
}
if (variables[ID].next!=-1)
{
variables[variables[ID].next].prev = variables[ID].prev;
}
if (variables[ID].prev!=-1)
{
variables[variables[ID].prev].next = variables[ID].next;
variables[ID].prev = -1;
}
//vidage de la variable
variableDico.DelWord(variable);
variables[ID].uid = -1;
variables[ID].value[0] = 0;
variables[ID].name[0] = 0;
//ajout de cette cellule comme premiere cellule vide
variables[ID].next = firstEmptyCell;
if (firstEmptyCell != -1)
variables[firstEmptyCell].prev = ID;
firstEmptyCell = ID;
int a = 1;
}
//*/
/*
u32 ID;
UnicID mUID;
if(variable && *variable && variableDico.IsExist(variable)!=-1)
{
variableDico.GetUnic(&mUID,variable);
ID = variableDico.mpst_Dico[mUID].AssociatedValue;
if(root==ID)
{
root = variables[ID].next;
}
variables[ID].value[0] = 0;
variables[ID].name[0] = 0;
if (variables[ID].parent!=-1)
{
variables[variables[ID].parent].child = variables[ID].next;
}
if (variables[ID].next!=-1)
{
variables[variables[ID].next].prev = variables[ID].prev;
}
if (variables[ID].prev!=-1)
{
variables[variables[ID].prev].next = variables[ID].next;
}
if(variables[ID].child!=-1)
{
u32 currentChild = variables[ID].child;
char childName[2048] = "";
do
{
variableDico.GetName(&(variables[currentChild].uid), childName);
delVariable(childName);
currentChild = variables[currentChild].next;
}
while(currentChild!=-1);
}
variables[ID].next = firstEmptyCell;
variables[firstEmptyCell].prev = ID;
variables[ID].prev = -1;
firstEmptyCell = ID;
variables[ID].parent = variables[ID].child = -1;
variableDico.DelWord(variable);
variables[ID].uid = -1;
}
//*/
}
u32 WORLD::LoadIniFile(char *filename, int forceCreate)
{
u32 ID;
UnicID mUID;
char *contents = NULL;
long fileLen = 0;
char c;
long pos = 0;
int read;
int fileOK = 0;
char *dicoName = filename;
#ifdef USER_MODE
char finenameX[1024];
sprintf(finenameX, "%sx", filename);
filename = finenameX;
#endif
fileLen = lengthOfFile(filename);
if (fileLen >= 0)
{
contents = (char*)CC_malloc(fileLen+1);
#ifndef USER_MODE
// Read contents from file
FILE* file;
file = CC_fopen(filename,"rt");
if(!file)
return -1;
while(read = fread(&c, 1, 1, file))
{
contents[pos++] = c;
};
contents[pos] = 0;
#else
// Read from file and decode into contents
FILE* file = CC_fopen(filename,"rb");
if(!file)
return -1;
char buffer[512];
char *contentsPtr = contents;
extern char *xorBase;
while ((read = fread(buffer, 1, 512, file)))
{
size_t processLen, xorLen = read;
char *xorStr, *buffPtr = buffer;
while (xorLen)
{
processLen = (xorLen > 32) ? 32 : xorLen;
xorStr = xorBase;
for (int i=0; i<processLen; i++, buffPtr++, xorStr++,contentsPtr++)
*contentsPtr = *buffPtr ^ *xorStr;
xorLen -= processLen;
}
}
*contentsPtr = 0;
#endif
CC_fclose(file);
fileOK = 1;
}
if (!fileOK && !forceCreate)
return -1;
if (IniFileDico.IsExist(dicoName) != -1)
{
IniFileDico.GetUnic(&mUID,dicoName);
ID = IniFileDico.mpst_Dico[mUID].AssociatedValue;
IniFiles[ID].Destroy();
IniFiles[ID].Init();
} else
{
IniFileDico.GetUnic(&mUID,dicoName);
for (ID = 0; ID < MAX_INIFILES && IniFiles[ID].variables; ID++);
if (ID >= MAX_INIFILES) return -1;
IniFileDico.mpst_Dico[mUID].AssociatedValue = ID;
IniFiles[ID].Init();
}
if (!fileOK)
return ID;
long deb = 0;
char** stack = (char**)ZeroAlloc(1*sizeof(char*));
stack[0] = (char*)ZeroAlloc(1);
u32 parent = 1;
u32 lastVarID = -1;
while(contents[deb])
{
int lineType = 1; //pa de commencement ou de fin de variable
long ptr = 0;
long endVarName = -1;
long beginVarName = -1;
while(contents[deb+ptr] && contents[deb+ptr]!='\n' && contents[deb+ptr]!='\r')
{
if(beginVarName==-1 && contents[deb+ptr]=='[')
{
if(contents[deb+ptr+1]!='/')
{
beginVarName = deb + ptr +1;
lineType = 3;
}
else
{
lineType = 4;
}
}
if(beginVarName==-1 && contents[deb+ptr]!='\t')
{
beginVarName = deb + ptr;
}
if(endVarName==-1 && contents[deb+ptr]=='=')
{
lineType = 2;
endVarName = deb+ptr-2;
}
ptr++;
}
if (lineType==3)
{
endVarName = deb+ptr-2;
stack = (char**)CC_realloc(stack, (parent+1)*sizeof(char*));
stack[parent] = (char*)ZeroAlloc(strlen(stack[parent-1])+1+endVarName-beginVarName+1+1);
strcpy(stack[parent], stack[parent-1]);
stack[parent][strlen(stack[parent-1])] = 0;
strcat(stack[parent], ".\0");
strncat(stack[parent], contents+beginVarName, endVarName-beginVarName+1);
stack[parent][strlen(stack[parent-1])+1+endVarName-beginVarName+1] = 0;
//ajout du bloc comme variable parent
IniFiles[ID].addVariable(stack[parent-1], stack[parent], "", 0);
parent++;
}
if (lineType==2)
{
//ajout de la variable
char* variable = (char*)ZeroAlloc(strlen(stack[parent-1])+1+endVarName-beginVarName+1+1);
strcpy(variable, stack[parent-1]);
variable[strlen(stack[parent-1])] = 0;
strcat(variable, ".\0");
strncat(variable, contents+beginVarName, endVarName-beginVarName+1);
variable[strlen(stack[parent-1])+1+endVarName-beginVarName+1] = 0;
char* value = (char*)ZeroAlloc((deb+ptr-1)-(endVarName+4)+1+1);
strncpy(value, contents+endVarName+4, (deb+ptr-1)-(endVarName+4)+1);
value[(deb+ptr-1)-(endVarName+4)+1] = 0;
lastVarID = IniFiles[ID].addVariable(stack[parent-1], variable, value, 0);
CC_free(variable);
CC_free(value);
}
if (lineType==1 && lastVarID == -1)
{
void API_RESTART(char* luaFileToBoot);
// ccm file corrupted, delete it and restar
DeleteFile(filename);
API_RESTART(NULL);
return -1;
//*(u32 *)0 = *(u32 *)4; //<-- CRASH!!!
}
if (lineType==1 && lastVarID!=-1)
{
//ajout de la variable avec concat<61>nation de la valeur pr<70>c<EFBFBD>dente
int len = strlen(IniFiles[ID].variables[lastVarID].value);
IniFiles[ID].variables[lastVarID].value = (char*)CC_realloc(IniFiles[ID].variables[lastVarID].value, len+deb+ptr-1-(deb-1)+1+1);
strncat(IniFiles[ID].variables[lastVarID].value, contents+deb-1, deb+ptr-1-(deb-1)+1);
}
if (lineType==4)
{
parent--;
CC_free(stack[parent]);
stack[parent] = 0;
}
//contents[deb+ptr] = 0;
deb += ptr;
if (contents[deb] == '\r') deb++;
if (contents[deb] == '\n') deb++;
}
if (stack[0]) CC_free(stack[0]);
CC_free(stack);
return ID;
}
u32 WORLD::SaveIniFile(char *filename)
{
u32 ID;
UnicID mUID;
if (IniFileDico.IsExist(filename) != -1)
{
IniFileDico.GetUnic(&mUID,filename);
ID = IniFileDico.mpst_Dico[mUID].AssociatedValue;
u32 currentChild = IniFiles[ID].root;
#ifdef USER_MODE
char finenameX[1024];
sprintf(finenameX, "%sx", filename);
filename = finenameX;
#endif
if (currentChild == -1)
{
DeleteFile(filename);
} else
{
#ifndef USER_MODE
FILE* file = CC_fopen(filename,"wt");
if(!file) return -1;
while(currentChild!=-1)
{
IniFiles[ID].saveVariable(file, currentChild, 0);
currentChild = IniFiles[ID].variables[currentChild].next;
}
#else
FILE* file = CC_fopen(filename,"wb");
if(!file) return -1;
int len = 1024;
char *buffer = (char *)CC_malloc(len);
int pos = 0;
extern char *xorBase;
while(currentChild!=-1)
{
IniFiles[ID].saveVariableInBuffer(&buffer, &len, &pos, currentChild, 0);
buffer[pos] = 0;
currentChild = IniFiles[ID].variables[currentChild].next;
}
size_t processLen, xorLen = strlen(buffer);
char *xorStr, *buffPtr = buffer;
while (xorLen)
{
processLen = (xorLen > 32) ? 32 : xorLen;
xorStr = xorBase;
for (int i=0; i<processLen; i++, buffPtr++, xorStr++)
*buffPtr = *buffPtr ^ *xorStr;
xorLen -= processLen;
}
fwrite(buffer, 1, pos, file);
CC_free(buffer);
#endif
CC_fclose(file);
}
return 0;
}
return -1;
}
u32 WORLD::DestroyIniFile(char *fileName)
{
u32 ID;
UnicID mUID;
if (IniFileDico.IsExist(fileName) != -1)
{
IniFileDico.GetUnic(&mUID,fileName);
ID = IniFileDico.mpst_Dico[mUID].AssociatedValue;
IniFiles[ID].Destroy();
IniFileDico.DelWord(fileName);
return 0;
}
return -1;
}
bool WORLD::GetIniValue(char* iniFilename, char* iniVarname)
{
return WORLD::GetIniValue(iniFilename, iniVarname, "\0", 0);
}
bool WORLD::GetIniValue(char* iniFilename, char* iniVarname, char* iniValueDest)
{
return WORLD::GetIniValue(iniFilename, iniVarname, "\0", iniValueDest);
}
bool WORLD::GetIniValue(char* iniFilename, char* iniVarname, char* iniVarDefaultValue, char* iniValueDest)
{
if (IniFileDico.IsExist(iniFilename) == -1 && LoadIniFile(iniFilename) == -1)
{
char errorMsg [256];
_snprintf(errorMsg, 255, __FUNCTION__"-error: File not found: %s", iniFilename);
SaveDBGInfo(errorMsg);
if (iniValueDest) strcpy(iniValueDest, iniVarDefaultValue);
return false;
}
u32 ID;
UnicID mUID;
IniFileDico.GetUnic(&mUID,iniFilename);
ID = IniFileDico.mpst_Dico[mUID].AssociatedValue;
INIFILE* inifile = &IniFiles[ID];
char* completedVarname = (char*)ZeroAlloc(1+1+strlen(iniVarname));
completedVarname[0] = '.';
if(iniVarname[0]!='.')
{
strcat(completedVarname, iniVarname);
completedVarname[strlen(iniVarname)+1] = 0;
}
else
{
strcpy(completedVarname, iniVarname);
}
if(inifile->variableDico.IsExist(completedVarname)!=-1)
{
if (iniValueDest)
{
inifile->variableDico.GetUnic(&mUID,completedVarname);
ID = inifile->variableDico.mpst_Dico[mUID].AssociatedValue;
strcpy(iniValueDest, inifile->variables[ID].value);
return true;
}
else
{
inifile->variableDico.GetUnic(&mUID,completedVarname);
ID = inifile->variableDico.mpst_Dico[mUID].AssociatedValue;
return (strcmp(inifile->variables[ID].value, "1")==0);
}
}
if (iniValueDest) strcpy(iniValueDest, iniVarDefaultValue);
CC_free(completedVarname);
return false;
}
/* This function saves a variable value in a ini file */
bool WORLD::SetIniValue(char* filename, char* iniVarname, char* newValue)
{
u32 ID;
UnicID mUID;
if(*filename==0 || *iniVarname==0) return false;
if (IniFileDico.IsExist(filename) == -1 && LoadIniFile(filename, 1) == -1)
return false;
IniFileDico.GetUnic(&mUID,filename);
ID = IniFileDico.mpst_Dico[mUID].AssociatedValue;
char* completedVarname = (char*)ZeroAlloc(1+1+strlen(iniVarname));
completedVarname[0] = '.';
if(iniVarname[0]!='.')
{
strcat(completedVarname, iniVarname);
completedVarname[strlen(iniVarname)+1] = 0;
}
else
{
strcpy(completedVarname, iniVarname);
}
char* posPtr = strrchr(completedVarname, '.');
int pos = posPtr-completedVarname;
char* parent = (char*)ZeroAlloc(pos+1);
bool ret;
strncpy(parent, completedVarname, pos);
parent[pos] = 0;
if(IniFiles[ID].variableDico.IsExist(parent)!=-1 || *parent==0)
{
IniFiles[ID].addVariable(parent, completedVarname, newValue);
ret = true;
}
else
{
ret = false;
}
CC_free(parent);
CC_free(completedVarname);
return ret;
}