home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 109
/
EnigmaAmiga109CD.iso
/
software
/
varie
/
freewheel
/
prefs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-26
|
6KB
|
252 lines
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <exec/types.h>
enum PrefsNodeTypes {TYPE_LONG,TYPE_STRING};
struct PrefsNode
{
long Match1,Match2;
enum PrefsNodeTypes Type;
struct PrefsNode *Next,*Prev;
long Data; /* String length if Type==TYPE_STRING */
};
#include "Prefs.h"
void Prefs_DigestID(char *str,unsigned long *id1,unsigned long *id2);
BOOL Prefs_MatchID(char *str,unsigned long id1,unsigned long id2);
void PrefsGroup_Dispose(struct PrefsGroup *pg);
BOOL PrefsGroup_Save(struct PrefsGroup *pg);
char *PrefsGroup_GetString(struct PrefsGroup *pg,char *ItemID,char *def);
long PrefsGroup_GetLong(struct PrefsGroup *pg,char *ItemID,long def);
BOOL PrefsGroup_SetString(struct PrefsGroup *pg,char *ItemID,char *data);
BOOL PrefsGroup_SetLong(struct PrefsGroup *pg,char *ItemID,long data);
struct PrefsNode *PrefsGroup_GetNode(struct PrefsGroup *pg,char *ItemID);
struct PrefsGroup *Prefs_GetGroup(char *GroupID);
void Prefs_DigestID(char *str,unsigned long *id1,unsigned long *id2)
{
unsigned long id; int i,l;
*id1=0; *id2=0;
l=strlen(str);
if(l>8) l=8;
if(l>4)
{
id=0;
for(i=0;i<4;++i) { id<<=8; id|=255&(*str++); }
*id1=id; l-=4; id=0;
for(i=0;i<l;++i) { id<<=8; id|=255&(*str++); }
id<<=8*(4-l); *id2=id;
}
else
{
id=0;
for(i=0;i<l;++i) { id<<=8; id|=255&(*str++); }
id<<=8*(4-l); *id1=id; *id2=0;
}
}
BOOL Prefs_MatchID(char *str,unsigned long id1,unsigned long id2)
{
unsigned long id3,id4;
Prefs_DigestID(str,&id3,&id4);
id1&=0xdfdfdfdf; id2&=0xdfdfdfdf;
id3&=0xdfdfdfdf; id4&=0xdfdfdfdf; /* Make test case-insensitive */
if(id1!=id3) return(FALSE);
if(id2!=id4) return(FALSE);
return(TRUE);
}
struct PrefsGroup *Prefs_GetGroup(char *GroupID)
{
struct PrefsGroup *pg;
unsigned long id1,id2;
int i;
char *dest;
FILE *fp;
if(pg=malloc(sizeof(struct PrefsGroup)))
{
memset(pg,0,sizeof(struct PrefsGroup));
pg->Dispose=PrefsGroup_Dispose;
pg->Save=PrefsGroup_Save;
pg->GetString=PrefsGroup_GetString;
pg->GetLong=PrefsGroup_GetLong;
pg->SetString=PrefsGroup_SetString;
pg->SetLong=PrefsGroup_SetLong;
pg->GetNode=PrefsGroup_GetNode;
pg->FirstNode=NULL;
dest=pg->Name;
while(*dest++=*GroupID++);
}
if(fp=fopen(pg->Name,"rb"))
{
struct PrefsNode MyNode;
char MyString[256];
while(fread(&MyNode,sizeof(struct PrefsNode),1,fp)==1)
{
char MyString[256];
char ItemID[9]={0,0,0,0,0,0,0,0,0};
unsigned long *ptr=(unsigned long *)ItemID;
*ptr++=MyNode.Match1; *ptr++=MyNode.Match2;
if(MyNode.Type==TYPE_STRING)
{
fread(&MyString,MyNode.Data,1,fp);
pg->SetString(pg,ItemID,MyString);
}
else
pg->SetLong(pg,ItemID,MyNode.Data);
}
fclose(fp);
}
return(pg);
}
void PrefsGroup_Dispose(struct PrefsGroup *pg)
{
if(pg)
{
if(pg->FirstNode)
{
struct PrefsNode *node,*next;
node=pg->FirstNode;
while(node)
{
next=node->Next;
free(node);
node=next;
}
}
free(pg);
}
}
BOOL PrefsGroup_Save(struct PrefsGroup *pg)
{
FILE *fp;
if(fp=fopen(pg->Name,"wb"))
{
struct PrefsNode *pn;
size_t size;
pn=pg->FirstNode;
while(pn)
{
size=sizeof(struct PrefsNode);
if(pn->Type==TYPE_STRING)
size+=pn->Data;
fwrite(pn,size,1,fp);
pn=pn->Next;
}
fclose(fp);
}
return(FALSE);
}
char *PrefsGroup_GetString(struct PrefsGroup *pg,char *ItemID,char *def)
{
struct PrefsNode *pn;
if(pn=pg->GetNode(pg,ItemID))
if(pn->Type==TYPE_STRING)
return(((char *)pn)+sizeof(struct PrefsNode));
return(def);
}
long PrefsGroup_GetLong(struct PrefsGroup *pg,char *ItemID,long def)
{
struct PrefsNode *pn;
if(pn=pg->GetNode(pg,ItemID))
if(pn->Type==TYPE_LONG)
return(pn->Data);
return(def);
}
BOOL PrefsGroup_SetString(struct PrefsGroup *pg,char *ItemID,char *data)
{
struct PrefsNode *pn;
char *dest;
unsigned long id1,id2;
if(pn=pg->GetNode(pg,ItemID))
{
if(pn->Prev)
pn->Prev->Next=pn->Next;
else
pg->FirstNode=pn->Next;
if(pn->Next)
pn->Next->Prev=pn->Prev;
free(pn);
}
pn=malloc(sizeof(struct PrefsNode)+1+strlen(data));
if(!(pn))
return(FALSE);
pn->Type=TYPE_STRING;
Prefs_DigestID(ItemID,&id1,&id2);
pn->Match1=id1; pn->Match2=id2;
pn->Data=strlen(data)+1;
pn->Prev=NULL;
if(pg->FirstNode)
pg->FirstNode->Prev=pn;
pn->Next=pg->FirstNode;
pg->FirstNode=pn;
dest=((char *)pn)+sizeof(struct PrefsNode);
while(*dest++=*data++);
return(TRUE);
}
BOOL PrefsGroup_SetLong(struct PrefsGroup *pg,char *ItemID,long data)
{
struct PrefsNode *pn;
unsigned long id1,id2;
if(pn=pg->GetNode(pg,ItemID))
{
if(pn->Prev)
pn->Prev->Next=pn->Next;
else
pg->FirstNode=pn->Next;
if(pn->Next)
pn->Next->Prev=pn->Prev;
free(pn);
}
pn=malloc(sizeof(struct PrefsNode));
if(!(pn))
return(FALSE);
pn->Type=TYPE_LONG;
Prefs_DigestID(ItemID,&id1,&id2);
pn->Match1=id1; pn->Match2=id2;
pn->Data=data;
pn->Prev=NULL;
if(pg->FirstNode)
pg->FirstNode->Prev=pn;
pn->Next=pg->FirstNode;
pg->FirstNode=pn;
return(TRUE);
}
struct PrefsNode *PrefsGroup_GetNode(struct PrefsGroup *pg,char *ItemID)
{
struct PrefsNode *pn=pg->FirstNode;
while(pn)
{
if(Prefs_MatchID(ItemID,pn->Match1,pn->Match2))
return(pn);
pn=pn->Next;
}
return(NULL);
}