home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / c / WLIB.ZIP / WFILE.H < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-12  |  10.4 KB  |  294 lines

  1. #ifndef WFileIncluded
  2. #define WFileIncluded
  3.  
  4. // copyright (c) 1992, 1993 by Paul Wheaton
  5. // 1916 Brooks #205, Missoula, MT  59801
  6. //
  7. // voice phone:  (406)543-7543
  8. // modem phone:  (406)543-1144 (2400N81)
  9. //  CompuServe:  72707,207
  10. //    Internet:  72707.207@CompuServe.com
  11.  
  12. /*
  13.  
  14. Although these routines lean on ANSI stdio functions, many of them work
  15. somewhat differently.   "File" is for binary mode and "TextFile" is for
  16. text mode. The constructor will open the file (create it if it doesn't
  17. exist).  It is the applications programmers responsibility to make sure
  18. that the filename given is valid and possible.  If the file cannot be
  19. opened, the program will be stopped.
  20.  
  21. Binary files:
  22.  
  23. Reading and writing may be done to any byte location that will fit into a
  24. long.  Writing more than a byte beyond the EOF will simply generate garbage
  25. characters from the EOF up to the point you are now writing.  Reading
  26. beyond EOF will result in a garbage read and the Read function will return
  27. False.
  28.  
  29. Text files:
  30.  
  31. After opening, the first read will be done from the beginning of the file
  32. and the first write will be done to the end of the file.
  33.  
  34. Note!: if a special buffer size has been requested and *denied* (due to
  35. lack of heap space), a beep will sound but file access will continue
  36. with the default buffer size.
  37.  
  38. */
  39.  
  40. #include <stdio.h>
  41. #include <io.h>
  42. #include <WMisc.h>
  43. #include <WVec.h>
  44.  
  45. #ifdef MAJORBBS
  46.  
  47.   Bool FileExists(const char*);
  48.  
  49. #else
  50.  
  51.   #define FileExists(FileName) (!access(FileName,0))
  52.     // returns True if the file exists
  53.  
  54. #endif
  55.  
  56.  
  57. char CurDiskDrive();
  58.  
  59. long DiskSpace(const char Drive='.');  // '.' means default drive
  60.   // the value returned is in "K" or "kilobytes" or number of 1024 byte blocks
  61.   // this is in case this library is on a computer that can handle capacity
  62.   // of more than 2 gigs that a "long" could represent.
  63.  
  64. long FileSize(const char* FileName);
  65.   // the value returned is in bytes
  66.  
  67. #define WriteThing(A) Write(&A,sizeof(A))
  68. #define ReadThing(A) Read(&A,sizeof(A))
  69.   // use only on things where the size can be properly determined with
  70.   // "sizeof".  Use only with "File" not "TextFile"
  71.  
  72. void DeleteFile(const char* FileName);
  73.   // if the file is deletable, it's deleted
  74.  
  75. const ReadAndWrite=0;
  76. const ReadOnly=1;
  77.  
  78. //enum FileShareType {xxx};
  79.  
  80. class LowLevelFile
  81.   {
  82.       FILE* FilePointer;
  83.       Bool Open;
  84.       char* GivenFileName;
  85.       char* Buf; // for future use to change the size of the buffer
  86.       void InternalInit(int);
  87.       friend class File;
  88.       friend class TextFile;
  89.       friend class RecFileRef;
  90.       friend class RecFile;
  91.     public:
  92.       LowLevelFile(const char* FileName,const char* Mode, int BufSize);
  93.       //LowLevelFile(const char* FileName,int Share,const char* Mode, int BufSize);
  94.       ~LowLevelFile() {Close();}
  95.       void Close();  // you can close the file early if you want
  96.       void Flush() {fflush(FilePointer);}
  97.         // flush your write buffers out to disk
  98.       long CurPos() {return ftell(FilePointer);}
  99.         // current file position:  where you are about to write to or read from
  100.       void Seek(long Offset) {fseek(FilePointer,Offset,0);}
  101.       void SeekBOF(){fseek(FilePointer,0,0);}
  102.       void SeekEOF(){fseek(FilePointer,0,2);}
  103.       long Size();  //  the file size in bytes
  104.       Bool EndOfFile() {return feof(FilePointer);}
  105.       #ifdef MAJORBBS
  106.         void* operator new(size_t size){return malloc(size);}
  107.         void  operator delete(void* p) {free(p);}
  108.       #endif
  109.   };
  110.  
  111. class File:public LowLevelFile
  112.   {
  113.     public:
  114.       File(const char* FileName,Bool Mode=ReadAndWrite,int BufSize=BUFSIZ);
  115.       Bool Read(void *Buffer,int Size=1);
  116.       Bool Read(ByteVector& BV,int Size=1);
  117.       void Write(const void *Buffer,int Size=1);
  118.   };
  119.  
  120. class RecFile:public LowLevelFile
  121.   {
  122.       int RecSize;
  123.     public:
  124.       RecFile(const char* FileName,int RecordSize,Bool Mode,int BufSize);
  125.       Bool Read(void *Buffer);
  126.       Bool Read(void *Buffer,int Quan);
  127.       void Seek(long RecNum);
  128.       long CurRec();  // record number
  129.       long Size();  // number of recs
  130.       void Write(const void *Buffer);
  131.       void Write(const void *Buffer,int Quan);
  132.   };
  133.  
  134. #define CreateRecFileClass(ClassName,StructType)                        \
  135.                                                                         \
  136. class ClassName;                                                        \
  137.                                                                         \
  138. class ClassName ## Ref                                                  \
  139.   {                                                                     \
  140.       ClassName* F;                                                     \
  141.       ClassName ## Ref(ClassName* XF){F=XF;}                            \
  142.       friend class ClassName;                                           \
  143.     public:                                                             \
  144.       void operator=(const StructType& X);                              \
  145.       operator StructType();                                            \
  146.       void* operator new(size_t size){return malloc(size);}             \
  147.       void  operator delete(void* p) {free(p);}                         \
  148.   };                                                                    \
  149.                                                                         \
  150. class ClassName:public RecFile                                          \
  151.   {                                                                     \
  152.     public:                                                             \
  153.       ClassName(const char* FileName,Bool Mode=ReadAndWrite,            \
  154.           int BufSize=BUFSIZ):                                          \
  155.           RecFile(FileName,sizeof(StructType),Mode,BufSize){}           \
  156.       Bool Read(StructType& X){return RecFile::Read(&X);}               \
  157.       Bool Read(StructType* X,int Q){return RecFile::Read(X,Q);}        \
  158.       void Write(const StructType& X){RecFile::Write(&X);}              \
  159.       void Write(const StructType* X,int Q){RecFile::Write(X,Q);}       \
  160.       ClassName ## Ref operator[](long RecNum)                          \
  161.         {Seek(RecNum); return ClassName ## Ref(this);}                  \
  162.   };                                                                    \
  163.                                                                         \
  164. inline void ClassName ## Ref::operator=(const StructType& X)            \
  165.   {F->Write(X);}                                                        \
  166. inline void ClassName ## Ref::operator StructType()                     \
  167.   {StructType X; F->Read(X); return X;}
  168.  
  169.  
  170. // friend void operator=(StructType& X,ClassName ## Ref R);          \
  171. //inline void operator=(StructType& X,ClassName ## Ref R)                 \
  172. //  {(R.F)->Read(X);}
  173.  
  174. #ifdef __BORLANDC__
  175.   #define FTMRO "rt"
  176.   #define FTMRW "r+t"
  177. #else
  178.   #define FTMRO "r"
  179.   #define FTMRW "r+"
  180. #endif
  181.  
  182. class TextFile:public LowLevelFile
  183.   {
  184.       Bool Started;  // used to figure out whether we're starting off appending or reading
  185.     public:
  186.       TextFile(const char* FileName,Bool Mode=ReadAndWrite,int BufSize=BUFSIZ):
  187.           LowLevelFile(FileName,((Mode==ReadOnly)?(FTMRO):(FTMRW)),BufSize)
  188.           {Started=False;}
  189.       void Seek(long Offset) {Started=True; LowLevelFile::Seek(Offset);}
  190.       Bool Read(char* S);
  191.       void Write(const char* S);
  192.       void WriteLine(const char* S="");
  193.   };
  194.  
  195. void FileCopying(File& DestFile, File& SourceFile, long Size);
  196.   // will not modify file positions before writing
  197.  
  198. void CopyFile(const char* DestFile, const char* SourceFile);
  199.   // source file must be created.  if dest file already exists,
  200.   // it will be deleted
  201.  
  202. Word CRC(File& F,long FSize);  // CRC of file starting at current pos
  203. Word CRC(File& F);  // CRC of entire file
  204.  
  205.  
  206. /*
  207.  
  208. Example of a file of records:
  209.  
  210. struct XType
  211.   {
  212.     long a,b,c;
  213.   };
  214.  
  215. CreateRecFileClass(XFile,XType);
  216.  
  217. main()
  218.   {
  219.     XType X;
  220.     XFile F("X.BIN");
  221.     F[0]=X;
  222.     X=F[0];
  223.   }
  224.  
  225. */
  226.  
  227. /*
  228.   Features to add:
  229.      1)  Make it so that a person cannot write beyond the end of their block
  230.  
  231. */
  232.  
  233. class TokenFile: public File
  234.   {
  235.       Word MaxTokens;
  236.       long FirstFreeBlock;
  237.       void GetFreeInfo(long Pos, long& Size, long& NextBlock);
  238.         // used to traverse free list
  239.       long New(long FSize);
  240.         // returns a block number that can hold "FSize" and updates the
  241.         // free list if needed
  242.       void Delete(long Pos, long Size);
  243.         // adds this info to the free list if its big enough
  244.       void SeekIndexSlot(Word Token) {File::Seek(Token*8);}
  245.       void ReadCurIndexSlot(long& Pos, long& Size);
  246.       friend Bool TokenExists(const char*,Word);
  247.       friend void ShowFreeList(const char*);
  248.     public:
  249.       TokenFile(const char* FileName, int BufSize=BUFSIZ);
  250.       long Seek(Word Token);
  251.         /*  returns the size of your object (0 if it doesn't exist).  If
  252.         object is found, file pointer is moved to your objects storage
  253.         location.  You may then read your data with any binary file type
  254.         read.  There will be nothing to stop you from reading too much */
  255.       void WritePrep(Word Token,long DataSize);
  256.         /* sets up Token with a data area of just the right size.  Any
  257.         previous data under that Token is deleted.  File pointer is left
  258.         where writing may begin */
  259.       void Delete(Word Token);
  260.         // makes the space that was taken by Token's object available
  261.       Word MaxToken(){return MaxTokens;}
  262.       Bool TokenExists(Word Token);
  263.       void Extract(Word Token,char* FileName);
  264.   };
  265.  
  266. Bool TokenExists(const char* FileName, Word Token);
  267.  
  268. void SaveBootRec(TokenFile& F,const char* CName);
  269.   // Optional...  Saves the video device boot info
  270.  
  271. /* This class inherits all of the properties of the (binary) File class.
  272. It adds the feature of being able to store many little files into one
  273. larger file.  Given a token ("access code", "key") value you may store and
  274. retrieve your data pretty much like any other binary file.
  275.  
  276. Example of writing a struct of type XType:
  277.  
  278.    XType X;
  279.    TokenFile F("DATA.BIN");
  280.    F.WritePrep(326,sizeof(X)); // you pick your own Token number and object size
  281.    F.WriteThing(X);
  282.  
  283. Example of reading the same struct:
  284.  
  285.    XType X;
  286.    TokenFile F("DATA.BIN");
  287.    if (F.Seek(326)) F.ReadThing(X);
  288.    else FatalError("cannot find my X thing in file DATA.BIN");
  289.  
  290. */
  291.  
  292.  
  293. #endif
  294.