home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 41 / IOPROG_41.ISO / soft / c++ / CDBFILE.ZIP / cdbfile.h < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-10  |  7.8 KB  |  201 lines

  1. /****************************************************************************/
  2. /*********    CDBFile, a dBase III / .DBF file handling object    ***********/
  3. /****************************************************************************/
  4. /*
  5.   
  6.     Copyright (C) 1997 HervΘ GOURMELON, ENSSAT
  7.     gourmelon@enssat.fr
  8.     http://www.enssat.fr
  9.  
  10. This library is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU Library General Public
  12. License as published by the Free Software Foundation; either
  13. version 2 of the License, or (at your option) any later version.
  14.  
  15. This library is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18. Library General Public License for more details.
  19.  
  20. You should have received a copy of the GNU Library General Public
  21. License along with this library (COPYING2.TXT); if not, write to the
  22. Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
  23. MA 02139, USA.
  24.  
  25. */
  26.  
  27.  
  28. // If a boolean type BOOL is not already defined, remove the comment slashes
  29. // in front of the following line:
  30.  typedef enum BOOL {FALSE, TRUE};
  31.  
  32.  
  33. /* The records will be stored as a dynamic list of raw character strings,
  34. in the same format as in the file. I could have converted them into fully-
  35. blown data structures or classes, but genericity implies dynamic structures, 
  36. which are known to be memory consuming. */
  37.  
  38. struct rec 
  39. {    char* Contents;        //raw character string 
  40.     BOOL ModifFlag;        // Indicates whether that record has been modified 
  41.     unsigned long RecordNumber;    // Position of the record within the file 
  42.     struct rec *Next;        // Points to the next record in the list 
  43.     struct rec *Previous;    // Points to the previous record in the list 
  44. };
  45.  
  46. typedef struct rec Record;
  47.  
  48.  
  49. /* The type and the number of fields are stored once and for all in a 
  50. dynamic list, which will be referred to by the functions which will
  51. decode and read the values stored in the records. This dynamic list
  52. is in fact a dynamic ring, as we consider that the "Next" field of the
  53. last element in the list points to the head of the list.*/
  54. class CField
  55. {
  56. private :
  57.     
  58. char             Name[11];        // field name in ASCII zero-filled 
  59. char             Type;            // field type in ASCII 
  60. unsigned char    Length;            // field length in binary 
  61. unsigned char     DecCount;        // field decimal count in binary 
  62. unsigned char    FieldNumber;    // field number within the record 
  63. unsigned short    Offset;            // field offset within the character string 
  64. CField*            Next;            // Next field in the list 
  65.  
  66.  
  67. public :
  68. CField();
  69. CField(char* NName,char NType,unsigned char NLength,unsigned char NDecCount,
  70.                         unsigned char FieldNum);
  71. ~CField();
  72. char* GetName()             {    return Name;    }
  73. void SetName(char* NewName)    {    strcpy(Name, NewName);    }
  74. char GetType()                {    return Type;    }
  75. void SetType(char NewType)    {    Type=NewType;    }
  76. unsigned char GetLength()    {    return Length;    }
  77. void SetLength(unsigned char NewLength)    {    Length=NewLength;    }
  78. unsigned char GetDecCount()                {    return DecCount;    }
  79. void SetDecCount(unsigned char NewDecCount)    {    DecCount=NewDecCount;    }
  80. unsigned char GetFieldNumber()                {    return FieldNumber;    }
  81. void SetFieldNumber(unsigned char NewFieldNumber)     
  82.                                         {    FieldNumber=NewFieldNumber;    }
  83. unsigned short GetOffset()                {    return Offset;    }
  84. void SetOffset(unsigned short NewOffset)    {    Offset=NewOffset;    }
  85. CField* GetNext()                {    return Next;    }
  86. void SetNext(CField* NextField)    {    Next=NextField;    }
  87.  
  88. CField* GetField(char* FieldName, CField* Start=NULL)
  89. {    // Pass the name of the field for argument 
  90.     if (Start==NULL) Start=this;    /* NULL is passed for the initial call of
  91.                                     this  recursive function in the program */
  92.     else 
  93.         if (Start==this) return NULL;    /* We've checked all the elements of 
  94.                                     the dynamic ring: none matches FieldName */
  95.     if (strcmp(FieldName, Name)!=0) 
  96.         return Next->GetField(FieldName, Start); /* Proceed to next element */
  97.     else
  98.         return this;    /* FieldName matches Name */
  99. }    
  100.     
  101.                             
  102. CField* GetField(unsigned short Number, CField* Start=NULL)    
  103. {     // Pass the number of the field for argument 
  104.     if (Start==NULL) Start=this;    /* NULL is passed for the initial call of
  105.                                     this  recursive function in the program */
  106.     else 
  107.         if (Start==this) return NULL;    /* We've checked all the elements of 
  108.                                     the dynamic ring: none matches Number */
  109.     if (Number!=FieldNumber) 
  110.         return Next->GetField(Number, Start); /* Proceed to next element */
  111.     else
  112.         return this;    /* Number matches FieldNumber */
  113. }    
  114.  
  115.                             
  116. unsigned short GetNumberOfFields(CField* Start=NULL, unsigned short i=0);
  117.  
  118.  
  119. };
  120.  
  121.  
  122.  
  123. class CDBFile
  124. {
  125. private :
  126.  
  127. char PathName[256];            // Path name for the dBase III file 
  128. FILE *FileHandle;            // Handler for the dBase III file 
  129. unsigned short HeaderSize;    // Length of header structure 
  130. unsigned short FieldCount;    // Number of fields in each record 
  131. unsigned long RecordCount;    // Number of records in the file 
  132. BOOL ModifiedFlag;            // Indicates whether the data has been modified 
  133. BOOL FullFileInMemory;        // Indicates whether the entire file is loaded 
  134. unsigned short RecordLength;    // Length of the record strings 
  135.  
  136. Record* RecordList;    // Head of the list of records 
  137. Record*    CurrentRec;    // Current record pointed in the list
  138. CField* FirstField;    // Head of the list of fields 
  139.  
  140. public:
  141.  
  142. CDBFile();
  143. CDBFile(char* Path);
  144. ~CDBFile();
  145. BOOL IsOpen()    { return (BOOL)(FileHandle!=NULL); }
  146. BOOL Clean();
  147. BOOL OpenFile(char* Path);
  148. BOOL CloseFile();
  149. unsigned long LoadFileToMemory();
  150. unsigned long WriteAllToFile(char *Path=NULL);
  151. unsigned long WriteModified();
  152. void SortOn(unsigned short Criterium1/*, unsigned short Criterium2*/);
  153. void* GetFieldValue(char* Field);
  154. void* GetFieldValue(unsigned short FieldNum);
  155. void GetAtRecord(unsigned long RecordNum) { CurrentRec=GetRecord(RecordNum); }
  156. unsigned long GetRecordNum() {    if (CurrentRec) 
  157.                                     return CurrentRec->RecordNumber;
  158.                                 else return 0L;}
  159. BOOL GetNextRecord()      { if (CurrentRec) { CurrentRec=CurrentRec->Next; return TRUE;}
  160.                             else return FALSE; }
  161. BOOL GetPreviousRecord()  { if (CurrentRec) { CurrentRec=CurrentRec->Previous; return TRUE;}
  162.                             else return FALSE; }
  163. void LoadRecord(unsigned long RecordNum)  { CurrentRec=ReadRecord(RecordNum);
  164.                                                      Append(CurrentRec); }
  165. void DeleteCurrentRec()        { DeleteRecord(CurrentRec);}
  166. void CreateAndAppend()        { CurrentRec=CreateNewRecord();
  167.                                 Append(CurrentRec);}    
  168. void ClearAllRecords();        
  169. void AddField(CField* NewField);  /* NOT IMPLEMENTED YET. Any volunteers ? */
  170. void SetFieldValue(char* Field, void* Value);
  171. void SetFieldValue(unsigned short FieldNum, void* Value);
  172. void DumpCurrentContents(int i, char* String);
  173. unsigned char GetFieldDecCount(unsigned short NumField)
  174.         { return (FirstField->GetField(NumField))->GetDecCount(); } 
  175. char GetFieldType(unsigned short NumField) 
  176.         { return (FirstField->GetField(NumField))->GetType(); } 
  177. unsigned short GetFieldCount()    { return FieldCount; }
  178. unsigned long GetRecordCount()    { return RecordCount; }
  179. void DeleteVoidPointer(void* Pointer, unsigned short Field);
  180. void DeleteVoidPointer(void* Pointer, char* Field);
  181.  
  182. private:
  183. BOOL WriteRecord(Record* Current, unsigned long RecNum);
  184. BOOL Swap(Record* Rec1, Record* Rec2);
  185. BOOL IsBigger(void *v1, void *v2, CField* Criterium);
  186. BOOL IsSmaller(void *v1, void *v2, CField* Criterium);
  187. Record* ReadRecord(unsigned long RecNum);
  188. Record* CreateNewRecord();
  189. Record* GetRecord(unsigned long RecordNum);
  190. void Append(Record* Rec, Record* Tail=NULL);
  191. void* GetFieldValue(Record* Rec, CField* Field);
  192. void SetFieldValue(Record* Rec, CField* Field, void* Value);
  193. void DeleteRecord(Record *Rec);
  194. void SortAllRecords(Record *Head, Record *Tail,
  195.                          CField* Criter1/*,CField* Criter2*/);
  196. BOOL WriteHeader(char* Path=NULL);
  197. void DeleteVoidPointer(void* Pointer, CField* Field);
  198.  
  199. };
  200.  
  201.