home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 3 / CD_Magazyn_EXEC_nr_3.iso / Recent / util / mouse / FreeWheel.lha / FreeWheel / Prefs.c < prev    next >
C/C++ Source or Header  |  2000-05-26  |  5KB  |  249 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.   char *dest;
  73.   FILE *fp;
  74.   if(pg=malloc(sizeof(struct PrefsGroup)))
  75.   {
  76.     memset(pg,0,sizeof(struct PrefsGroup));
  77.     pg->Dispose=PrefsGroup_Dispose;
  78.     pg->Save=PrefsGroup_Save;
  79.     pg->GetString=PrefsGroup_GetString;
  80.     pg->GetLong=PrefsGroup_GetLong;
  81.     pg->SetString=PrefsGroup_SetString;
  82.     pg->SetLong=PrefsGroup_SetLong;
  83.     pg->GetNode=PrefsGroup_GetNode;
  84.     pg->FirstNode=NULL;
  85.     dest=pg->Name;
  86.     while(*dest++=*GroupID++);
  87.   }
  88.   if(fp=fopen(pg->Name,"rb"))
  89.   {
  90.     struct PrefsNode MyNode;
  91.     while(fread(&MyNode,sizeof(struct PrefsNode),1,fp)==1)
  92.     {
  93.       char MyString[256];
  94.       char ItemID[9]={0,0,0,0,0,0,0,0,0};
  95.       unsigned long *ptr=(unsigned long *)ItemID;
  96.       *ptr++=MyNode.Match1; *ptr++=MyNode.Match2;
  97.       if(MyNode.Type==TYPE_STRING)
  98.       {
  99.         fread(&MyString,MyNode.Data,1,fp);
  100.         pg->SetString(pg,ItemID,MyString);
  101.       }
  102.       else
  103.         pg->SetLong(pg,ItemID,MyNode.Data);
  104.     }
  105.     fclose(fp);
  106.   }
  107.   return(pg);
  108. }
  109.  
  110.  
  111. void PrefsGroup_Dispose(struct PrefsGroup *pg)
  112. {
  113.   if(pg)
  114.   {
  115.     if(pg->FirstNode)
  116.     {
  117.       struct PrefsNode *node,*next;
  118.       node=pg->FirstNode;
  119.       while(node)
  120.       {
  121.         next=node->Next;
  122.         free(node);
  123.         node=next;
  124.       }
  125.     }
  126.     free(pg);
  127.   }
  128. }
  129.  
  130.  
  131. BOOL PrefsGroup_Save(struct PrefsGroup *pg)
  132. {
  133.   FILE *fp;
  134.   if(fp=fopen(pg->Name,"wb"))
  135.   {
  136.     struct PrefsNode *pn;
  137.     size_t size;
  138.     pn=pg->FirstNode;
  139.     while(pn)
  140.     {
  141.       size=sizeof(struct PrefsNode);
  142.       if(pn->Type==TYPE_STRING)
  143.         size+=pn->Data;
  144.       fwrite(pn,size,1,fp);
  145.       pn=pn->Next;
  146.     }
  147.     fclose(fp);
  148.   }
  149.   return(FALSE);
  150. }
  151.  
  152.  
  153. char *PrefsGroup_GetString(struct PrefsGroup *pg,char *ItemID,char *def)
  154. {
  155.   struct PrefsNode *pn;
  156.   if(pn=pg->GetNode(pg,ItemID))
  157.     if(pn->Type==TYPE_STRING)
  158.       return(((char *)pn)+sizeof(struct PrefsNode));
  159.   return(def);
  160. }
  161.  
  162.  
  163. long PrefsGroup_GetLong(struct PrefsGroup *pg,char *ItemID,long def)
  164. {
  165.   struct PrefsNode *pn;
  166.   if(pn=pg->GetNode(pg,ItemID))
  167.     if(pn->Type==TYPE_LONG)
  168.       return(pn->Data);
  169.   return(def);
  170. }
  171.  
  172.  
  173. BOOL PrefsGroup_SetString(struct PrefsGroup *pg,char *ItemID,char *data)
  174. {
  175.   struct PrefsNode *pn;
  176.   char *dest;
  177.   unsigned long id1,id2;
  178.   if(pn=pg->GetNode(pg,ItemID))
  179.   {
  180.     if(pn->Prev)
  181.       pn->Prev->Next=pn->Next;
  182.     else
  183.       pg->FirstNode=pn->Next;
  184.     if(pn->Next)
  185.       pn->Next->Prev=pn->Prev;
  186.     free(pn);
  187.   }
  188.   pn=malloc(sizeof(struct PrefsNode)+1+strlen(data));
  189.   if(!(pn))
  190.     return(FALSE);
  191.   pn->Type=TYPE_STRING;
  192.   Prefs_DigestID(ItemID,&id1,&id2);
  193.   pn->Match1=id1; pn->Match2=id2;
  194.   pn->Data=strlen(data)+1;
  195.   pn->Prev=NULL;
  196.   if(pg->FirstNode)
  197.     pg->FirstNode->Prev=pn;
  198.   pn->Next=pg->FirstNode;
  199.   pg->FirstNode=pn;
  200.   dest=((char *)pn)+sizeof(struct PrefsNode);
  201.   while(*dest++=*data++);
  202.   return(TRUE);
  203. }
  204.  
  205.  
  206. BOOL PrefsGroup_SetLong(struct PrefsGroup *pg,char *ItemID,long data)
  207. {
  208.   struct PrefsNode *pn;
  209.   unsigned long id1,id2;
  210.   if(pn=pg->GetNode(pg,ItemID))
  211.   {
  212.     if(pn->Prev)
  213.       pn->Prev->Next=pn->Next;
  214.     else
  215.       pg->FirstNode=pn->Next;
  216.     if(pn->Next)
  217.       pn->Next->Prev=pn->Prev;
  218.     free(pn);
  219.   }
  220.   pn=malloc(sizeof(struct PrefsNode));
  221.   if(!(pn))
  222.     return(FALSE);
  223.   pn->Type=TYPE_LONG;
  224.   Prefs_DigestID(ItemID,&id1,&id2);
  225.   pn->Match1=id1; pn->Match2=id2;
  226.   pn->Data=data;
  227.   pn->Prev=NULL;
  228.   if(pg->FirstNode)
  229.     pg->FirstNode->Prev=pn;
  230.   pn->Next=pg->FirstNode;
  231.   pg->FirstNode=pn;
  232.   return(TRUE);
  233. }
  234.  
  235.  
  236. struct PrefsNode *PrefsGroup_GetNode(struct PrefsGroup *pg,char *ItemID)
  237. {
  238.   struct PrefsNode *pn=pg->FirstNode;
  239.   while(pn)
  240.   {
  241.     if(Prefs_MatchID(ItemID,pn->Match1,pn->Match2))
  242.       return(pn);
  243.     pn=pn->Next;
  244.   }
  245.   return(NULL);
  246. }
  247.  
  248.  
  249.