SBSPSS/Utils/Libs/DaveLib/IniClass.h
2001-05-23 20:02:15 +00:00

345 lines
8.7 KiB
C++

/***********************/
/*** Daves Ini Class ***/
/***********************/
#pragma warning( disable : 4786 )
#ifndef __DAVES_INI_CLASS__
#define __DAVES_INI_CLASS__
#include <vector>
/******************************************************************************/
#define CIni_Max_Data_Size 128
/******************************************************************************/
struct sIniEntry
{
char Key[CIni_Max_Data_Size+1];
char Data[CIni_Max_Data_Size+1];
};
struct sIniGroup
{
char Name[CIni_Max_Data_Size+1+2];
std::vector<sIniEntry> Entry;
};
/******************************************************************************/
class CIni
{
public:
CIni (char *IniFile) {Import(IniFile);}
CIni () {}
int GetGroupCount() {return(IniGroup.size());}
char *GetGroupName(int i) {return(IniGroup[i].Name);}
int GetKeyCount(const char *Grp)
{
int Group=FindGroup(Grp);
return(IniGroup[Group].Entry.size());
}
char *GetKeyName(const char *Grp,int Idx)
{
int Group=FindGroup(Grp);
return(IniGroup[Group].Entry[Idx].Key);
}
/*----------------------------------------------------------------------------*/
// returns 1 of fail, 0 on success!! (Who thought that up!)
int MyStrCmp(const char *Str0,const char *Str1)
{
if (strlen(Str0)!=strlen(Str1)) return(1);
for (int Loop=0;Loop<strlen(Str0);Loop++)
{
char C0=Str0[Loop];
char C1=Str1[Loop];
if (C0>='a' && C0<='z') C0+='A'-'a';
if (C1>='a' && C1<='z') C1+='A'-'a';
if (C0!=C1) return(1);
}
return(0);
}
/*----------------------------------------------------------------------------*/
void SkipLine(char **InPtr)
{
char *Ptr=*InPtr;
while (*Ptr!='\n' && *Ptr) Ptr++;
*InPtr=Ptr;
}
/*----------------------------------------------------------------------------*/
void LoadAndImport(const char *Filename)
{
FILE *File;
int Size;
char *Script;
File=fopen(Filename,"rt");
if (!File) {printf("%s Not Found\n",Filename); return;}
fseek(File,0,SEEK_END);
Size=ftell(File);
fseek(File,0,SEEK_SET);
Script=(char*)malloc(Size+1);
memset(Script,0,Size+1);
// Load It
fread(Script,Size,1,File);
fclose(File);
Import(Script);
free(Script);
}
/*----------------------------------------------------------------------------*/
void Import(char *IniFile)
{
char GroupEntry[CIni_Max_Data_Size+1+2];
char KeyEntry[CIni_Max_Data_Size+1+2];
GroupEntry[0]=0;
ParseFindEntry(&IniFile);
while (*IniFile)
{
if (IsComment(IniFile))
{
SkipLine(&IniFile);
}
else
{
if (ParseGetEntry(&IniFile,KeyEntry))
{ // Group
strcpy(GroupEntry,KeyEntry); // Update Group buffer
StripGroupName(GroupEntry);
UpdateGroup(GroupEntry);
}
else
{ // Data
UpdateKey(GroupEntry,KeyEntry);
}
}
ParseFindEntry(&IniFile);
}
}
/*----------------------------------------------------------------------------*/
void Export(char *OutFile)
{
*OutFile=0; // Clear Output
for (int Group=0;Group<IniGroup.size();Group++)
{
if (Group) sprintf(OutFile,"%s\r\n",OutFile);
if (strlen(IniGroup[Group].Name))
sprintf(OutFile,"%s[%s]\r\n",OutFile,IniGroup[Group].Name);
for (int Entry=0;Entry<IniGroup[Group].Entry.size();Entry++)
{
if (strlen(IniGroup[Group].Entry[Entry].Data))
sprintf(OutFile,"%s%s=%s\r\n",OutFile,IniGroup[Group].Entry[Entry].Key,IniGroup[Group].Entry[Entry].Data);
}
}
}
/*----------------------------------------------------------------------------*/
char *GetData(const char *GroupEntry,const char *KeyEntry)
{
int Group=FindGroup(GroupEntry);
if (Group==-1) return(0);
int Entry=FindKey(GroupEntry,KeyEntry);
if (Entry==-1) return(0);
return(IniGroup[Group].Entry[Entry].Data);
}
/*----------------------------------------------------------------------------*/
char *GetStr(const char *GroupEntry,const char *KeyEntry)
{
char *Str=GetData(GroupEntry,KeyEntry);
return(Str);
}
/*----------------------------------------------------------------------------*/
int GetInt(const char *GroupEntry,const char *KeyEntry)
{
char *Str=GetData(GroupEntry,KeyEntry);
int Var=0;
if (Str) Var=atol(Str);
return(Var);
}
/*----------------------------------------------------------------------------*/
bool GetInt(const char *GroupEntry,const char *KeyEntry,int &Var)
{
char *Str=GetData(GroupEntry,KeyEntry);
if (!Str) return(false);
Var=atol(Str);
return(true);
}
/*----------------------------------------------------------------------------*/
int UpdateGroup(char *GroupEntry)
{
int Group=FindGroup(GroupEntry);
if (Group==-1)
{ // Doesnt exist
Group=IniGroup.size();
IniGroup.resize(Group+1);
}
strcpy(IniGroup[Group].Name,GroupEntry);
return(Group);
}
/*----------------------------------------------------------------------------*/
int UpdateKey(char *GroupEntry,char *KeyEntry)
{
// Split Key&Data
char *Ptr=KeyEntry;
while (*Ptr!='=' && *Ptr!=0) Ptr++;
if (!*Ptr) return(-1); //BAD DATA
*Ptr=0;
// If cosher, add it
int Group=UpdateGroup(GroupEntry);
int Entry=FindKey(GroupEntry,KeyEntry);
if (Entry==-1)
{ // Doesnt exist
Entry=IniGroup[Group].Entry.size();
IniGroup[Group].Entry.resize(Entry+1);
}
strcpy(IniGroup[Group].Entry[Entry].Key,KeyEntry);
KeyEntry+=strlen(KeyEntry)+1;
while (IsWhiteSpace(*KeyEntry)) KeyEntry++;
strcpy(IniGroup[Group].Entry[Entry].Data,KeyEntry);
return(Entry);
}
/*----------------------------------------------------------------------------*/
int UpdateKey(char *GroupEntry,char *KeyEntry,char *Data)
{
int Group=UpdateGroup(GroupEntry);
int Entry=FindKey(GroupEntry,KeyEntry);
if (Entry==-1)
{ // Doesnt exist
Entry=IniGroup[Group].Entry.size();
IniGroup[Group].Entry.resize(Entry+1);
}
strcpy(IniGroup[Group].Entry[Entry].Key,KeyEntry);
strcpy(IniGroup[Group].Entry[Entry].Data,Data);
return(Entry);
}
/*----------------------------------------------------------------------------*/
int UpdateKey(char *GroupEntry,char *KeyEntry,int Data)
{
char Str[32];
sprintf(Str,"%i",Data);
return(UpdateKey(GroupEntry,KeyEntry,Str));
}
/*----------------------------------------------------------------------------*/
int UpdateKey(char *GroupEntry,char *KeyEntry,float Data)
{
char Str[32];
sprintf(Str,"%f",Data);
return(UpdateKey(GroupEntry,KeyEntry,Str));
}
//private:
/*----------------------------------------------------------------------------*/
bool IsWhiteSpace(char c) {return(c==' ' || c=='\n' || c==0xa || c=='\r');}
/*----------------------------------------------------------------------------*/
bool IsGroup(char *Entry) {return(*Entry=='[');}
bool IsComment(char *Entry) {return(*Entry==';' || *Entry=='#');}
/*----------------------------------------------------------------------------*/
void StripGroupName(char *Name)
{
// Remove Last Bracket
if (Name[strlen(Name)-1]==']') Name[strlen(Name)-1]=0;
// Remove First bracket
if (*Name=='[') while (*Name) *Name++=*(Name+1);
}
/*----------------------------------------------------------------------------*/
int FindGroup(const char *GroupEntry)
{
for (int Loop=0;Loop<IniGroup.size();Loop++)
{
if (!MyStrCmp(GroupEntry,IniGroup[Loop].Name)) return(Loop);
}
return(-1);
}
/*----------------------------------------------------------------------------*/
int FindKey(const char *GroupEntry,const char *KeyEntry)
{
int Group=FindGroup(GroupEntry);;
if (Group==-1) return(-1);
for (int Loop=0;Loop<IniGroup[Group].Entry.size();Loop++)
{
if (!MyStrCmp(KeyEntry,IniGroup[Group].Entry[Loop].Key)) return(Loop);
}
return(-1);
}
/*----------------------------------------------------------------------------*/
void ParseFindEntry(char **InPtr)
{
char *Ptr=*InPtr;
while(IsWhiteSpace(*Ptr)) Ptr++;
*InPtr=Ptr;
}
/*----------------------------------------------------------------------------*/
// returns true if group
bool ParseGetEntry(char **InPtr,char *OutPtr)
{
char *Ptr=*InPtr;
bool GroupFlag;
/*
int EqFlag=1;
int ValFlag=1;
while((EqFlag || ValFlag ) && *Ptr)
{
if (!IsWhiteSpace(*Ptr))
{
if (!EqFlag) ValFlag=0;
if (*Ptr=='=') EqFlag=0;
*OutPtr++=*Ptr;
}
else
{
}
Ptr++;
}
*/
while (IsWhiteSpace(*Ptr) && *Ptr) Ptr++; // leading blanks
GroupFlag=IsGroup(Ptr);
if (GroupFlag)
{ // Group
while (!IsWhiteSpace(*Ptr) && *Ptr!='=' && *Ptr) *OutPtr++=*Ptr++;
}
else
{
while (!IsWhiteSpace(*Ptr) && *Ptr!='=' && *Ptr) *OutPtr++=*Ptr++;
while (IsWhiteSpace(*Ptr) && *Ptr) Ptr++; // Trailing blanks
*OutPtr++=*Ptr++; // Copy =
while (IsWhiteSpace(*Ptr) && *Ptr) Ptr++; // Trailing blanks
while (!IsWhiteSpace(*Ptr) && *Ptr) *OutPtr++=*Ptr++;
}
*OutPtr=0;
*InPtr=Ptr;
return(GroupFlag);
// if (*(InPtr-1)==0) InPtr--;
}
/*----------------------------------------------------------------------------*/
std::vector<sIniGroup> IniGroup;
};
#endif