home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / varie / freewheel / prefs.c < prev    next >
C/C++ Source or Header  |  1999-12-26  |  6KB  |  252 lines

  1.  
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5.  
  6. #include <exec/types.h>
  7.  
  8. enum PrefsNodeTypes {TYPE_LONG,TYPE_STRING};
  9. struct PrefsNode
  10. {
  11.   long Match1,Match2;
  12.   enum PrefsNodeTypes Type;
  13.   struct PrefsNode *Next,*Prev;
  14.   long Data; /* String length if Type==TYPE_STRING */
  15. };
  16.  
  17.  
  18. #include "Prefs.h"
  19.  
  20. void Prefs_DigestID(char *str,unsigned long *id1,unsigned long *id2);
  21. BOOL Prefs_MatchID(char *str,unsigned long id1,unsigned long id2);
  22.  
  23. void PrefsGroup_Dispose(struct PrefsGroup *pg);
  24. BOOL PrefsGroup_Save(struct PrefsGroup *pg);
  25. char *PrefsGroup_GetString(struct PrefsGroup *pg,char *ItemID,char *def);
  26. long PrefsGroup_GetLong(struct PrefsGroup *pg,char *ItemID,long def);
  27. BOOL PrefsGroup_SetString(struct PrefsGroup *pg,char *ItemID,char *data);
  28. BOOL PrefsGroup_SetLong(struct PrefsGroup *pg,char *ItemID,long data);
  29.  
  30. struct PrefsNode *PrefsGroup_GetNode(struct PrefsGroup *pg,char *ItemID);
  31.  
  32. struct PrefsGroup *Prefs_GetGroup(char *GroupID);
  33.  
  34. void Prefs_DigestID(char *str,unsigned long *id1,unsigned long *id2)
  35. {
  36.   unsigned long id; int i,l;
  37.   *id1=0; *id2=0;
  38.   l=strlen(str);
  39.   if(l>8) l=8;
  40.   if(l>4)
  41.   {
  42.     id=0;
  43.     for(i=0;i<4;++i) { id<<=8; id|=255&(*str++); }
  44.     *id1=id; l-=4; id=0;
  45.     for(i=0;i<l;++i) { id<<=8; id|=255&(*str++); }
  46.     id<<=8*(4-l); *id2=id;
  47.   }
  48.   else
  49.   {
  50.     id=0;
  51.     for(i=0;i<l;++i) { id<<=8; id|=255&(*str++); }
  52.     id<<=8*(4-l); *id1=id; *id2=0;
  53.   }
  54. }
  55.  
  56.  
  57. BOOL Prefs_MatchID(char *str,unsigned long id1,unsigned long id2)
  58. {
  59.   unsigned long id3,id4;
  60.   Prefs_DigestID(str,&id3,&id4);
  61.   id1&=0xdfdfdfdf; id2&=0xdfdfdfdf;
  62.   id3&=0xdfdfdfdf; id4&=0xdfdfdfdf; /* Make test case-insensitive */
  63.   if(id1!=id3) return(FALSE);
  64.   if(id2!=id4) return(FALSE);
  65.   return(TRUE);
  66. }
  67.  
  68.  
  69. struct PrefsGroup *Prefs_GetGroup(char *GroupID)
  70. {
  71.   struct PrefsGroup *pg;
  72.   unsigned long id1,id2;
  73.   int i;
  74.   char *dest;
  75.   FILE *fp;
  76.   if(pg=malloc(sizeof(struct PrefsGroup)))
  77.   {
  78.     memset(pg,0,sizeof(struct PrefsGroup));
  79.     pg->Dispose=PrefsGroup_Dispose;
  80.     pg->Save=PrefsGroup_Save;
  81.     pg->GetString=PrefsGroup_GetString;
  82.     pg->GetLong=PrefsGroup_GetLong;
  83.     pg->SetString=PrefsGroup_SetString;
  84.     pg->SetLong=PrefsGroup_SetLong;
  85.     pg->GetNode=PrefsGroup_GetNode;
  86.     pg->FirstNode=NULL;
  87.     dest=pg->Name;
  88.     while(*dest++=*GroupID++);
  89.   }
  90.   if(fp=fopen(pg->Name,"rb"))
  91.   {
  92.     struct PrefsNode MyNode;
  93.     char MyString[256];
  94.     while(fread(&MyNode,sizeof(struct PrefsNode),1,fp)==1)
  95.     {
  96.       char MyString[256];
  97.       char ItemID[9]={0,0,0,0,0,0,0,0,0};
  98.       unsigned long *ptr=(unsigned long *)ItemID;
  99.       *ptr++=MyNode.Match1; *ptr++=MyNode.Match2;
  100.       if(MyNode.Type==TYPE_STRING)
  101.       {
  102.         fread(&MyString,MyNode.Data,1,fp);
  103.         pg->SetString(pg,ItemID,MyString);
  104.       }
  105.       else
  106.         pg->SetLong(pg,ItemID,MyNode.Data);
  107.     }
  108.     fclose(fp);
  109.   }
  110.   return(pg);
  111. }
  112.  
  113.  
  114. void PrefsGroup_Dispose(struct PrefsGroup *pg)
  115. {
  116.   if(pg)
  117.   {
  118.     if(pg->FirstNode)
  119.     {
  120.       struct PrefsNode *node,*next;
  121.       node=pg->FirstNode;
  122.       while(node)
  123.       {
  124.         next=node->Next;
  125.         free(node);
  126.         node=next;
  127.       }
  128.     }
  129.     free(pg);
  130.   }
  131. }
  132.  
  133.  
  134. BOOL PrefsGroup_Save(struct PrefsGroup *pg)
  135. {
  136.   FILE *fp;
  137.   if(fp=fopen(pg->Name,"wb"))
  138.   {
  139.     struct PrefsNode *pn;
  140.     size_t size;
  141.     pn=pg->FirstNode;
  142.     while(pn)
  143.     {
  144.       size=sizeof(struct PrefsNode);
  145.       if(pn->Type==TYPE_STRING)
  146.         size+=pn->Data;
  147.       fwrite(pn,size,1,fp);
  148.       pn=pn->Next;
  149.     }
  150.     fclose(fp);
  151.   }
  152.   return(FALSE);
  153. }
  154.  
  155.  
  156. char *PrefsGroup_GetString(struct PrefsGroup *pg,char *ItemID,char *def)
  157. {
  158.   struct PrefsNode *pn;
  159.   if(pn=pg->GetNode(pg,ItemID))
  160.     if(pn->Type==TYPE_STRING)
  161.       return(((char *)pn)+sizeof(struct PrefsNode));
  162.   return(def);
  163. }
  164.  
  165.  
  166. long PrefsGroup_GetLong(struct PrefsGroup *pg,char *ItemID,long def)
  167. {
  168.   struct PrefsNode *pn;
  169.   if(pn=pg->GetNode(pg,ItemID))
  170.     if(pn->Type==TYPE_LONG)
  171.       return(pn->Data);
  172.   return(def);
  173. }
  174.  
  175.  
  176. BOOL PrefsGroup_SetString(struct PrefsGroup *pg,char *ItemID,char *data)
  177. {
  178.   struct PrefsNode *pn;
  179.   char *dest;
  180.   unsigned long id1,id2;
  181.   if(pn=pg->GetNode(pg,ItemID))
  182.   {
  183.     if(pn->Prev)
  184.       pn->Prev->Next=pn->Next;
  185.     else
  186.       pg->FirstNode=pn->Next;
  187.     if(pn->Next)
  188.       pn->Next->Prev=pn->Prev;
  189.     free(pn);
  190.   }
  191.   pn=malloc(sizeof(struct PrefsNode)+1+strlen(data));
  192.   if(!(pn))
  193.     return(FALSE);
  194.   pn->Type=TYPE_STRING;
  195.   Prefs_DigestID(ItemID,&id1,&id2);
  196.   pn->Match1=id1; pn->Match2=id2;
  197.   pn->Data=strlen(data)+1;
  198.   pn->Prev=NULL;
  199.   if(pg->FirstNode)
  200.     pg->FirstNode->Prev=pn;
  201.   pn->Next=pg->FirstNode;
  202.   pg->FirstNode=pn;
  203.   dest=((char *)pn)+sizeof(struct PrefsNode);
  204.   while(*dest++=*data++);
  205.   return(TRUE);
  206. }
  207.  
  208.  
  209. BOOL PrefsGroup_SetLong(struct PrefsGroup *pg,char *ItemID,long data)
  210. {
  211.   struct PrefsNode *pn;
  212.   unsigned long id1,id2;
  213.   if(pn=pg->GetNode(pg,ItemID))
  214.   {
  215.     if(pn->Prev)
  216.       pn->Prev->Next=pn->Next;
  217.     else
  218.       pg->FirstNode=pn->Next;
  219.     if(pn->Next)
  220.       pn->Next->Prev=pn->Prev;
  221.     free(pn);
  222.   }
  223.   pn=malloc(sizeof(struct PrefsNode));
  224.   if(!(pn))
  225.     return(FALSE);
  226.   pn->Type=TYPE_LONG;
  227.   Prefs_DigestID(ItemID,&id1,&id2);
  228.   pn->Match1=id1; pn->Match2=id2;
  229.   pn->Data=data;
  230.   pn->Prev=NULL;
  231.   if(pg->FirstNode)
  232.     pg->FirstNode->Prev=pn;
  233.   pn->Next=pg->FirstNode;
  234.   pg->FirstNode=pn;
  235.   return(TRUE);
  236. }
  237.  
  238.  
  239. struct PrefsNode *PrefsGroup_GetNode(struct PrefsGroup *pg,char *ItemID)
  240. {
  241.   struct PrefsNode *pn=pg->FirstNode;
  242.   while(pn)
  243.   {
  244.     if(Prefs_MatchID(ItemID,pn->Match1,pn->Match2))
  245.       return(pn);
  246.     pn=pn->Next;
  247.   }
  248.   return(NULL);
  249. }
  250.  
  251.  
  252.