Category : C++ Source Code
Archive   : WLIB.ZIP
Filename : WFILE.H

 
Output of file : WFILE.H contained in archive : WLIB.ZIP
#ifndef WFileIncluded
#define WFileIncluded

// copyright (c) 1992, 1993 by Paul Wheaton, Banana Programming
// 1916 Brooks #205, Missoula, MT 59801
//
// phone: (406)543-1928
// CompuServe: 72707,207
// Internet: [email protected]
// BBS: (406)543-8234 (The Montana Banana BBS)

/*

Although these routines lean on ANSI stdio functions, many of them work
somewhat differently. "File" is for binary mode and "TextFile" is for
text mode. The constructor will open the file (create it if it doesn't
exist). It is the applications programmers responsibility to make sure
that the filename given is valid and possible. If the file cannot be
opened, the program will be stopped.

Binary files:

Reading and writing may be done to any byte location that will fit into a
long. Writing more than a byte beyond the EOF will simply generate garbage
characters from the EOF up to the point you are now writing. Reading
beyond EOF will result in a garbage read and the Read function will return
False.

Text files:

After opening, the first read will be done from the beginning of the file
and the first write will be done to the end of the file.

Note!: if a special buffer size has been requested and *denied* (due to
lack of heap space), a beep will sound but file access will continue
with the default buffer size.

*/

#include
#include
#include

#ifdef MAJORBBS

Bool FileExists(const char*);

#else

#define FileExists(FileName) (!access(FileName,0))
// returns True if the file exists

#endif


char CurDiskDrive();

long DiskSpace(const char Drive='.'); // '.' means default drive
// the value returned is in "K" or "kilobytes" or number of 1024 byte blocks
// this is in case this library is on a computer that can handle capacity
// of more than 2 gigs that a "long" could represent.

long FileSize(const char* FileName);
// the value returned is in bytes

#define WriteThing(A) Write(&A,sizeof(A))
#define ReadThing(A) Read(&A,sizeof(A))
// use only on things where the size can be properly determined with
// "sizeof". Use only with "File" not "TextFile"

void DeleteFile(const char* FileName);
// if the file is deletable, it's deleted

const ReadAndWrite=0;
const ReadOnly=1;

class LowLevelFile
{
FILE* FilePointer;
Bool Open;
char* GivenFileName;
char* Buf; // for future use to change the size of the buffer
void InternalInit(int);
friend class File;
friend class TextFile;
friend class RecFileRef;
friend class RecFile;
public:
LowLevelFile(const char* FileName,const char* Mode, int BufSize);
//LowLevelFile(const char* FileName,int Share,const char* Mode, int BufSize);
~LowLevelFile() {Close();}
void Close(); // you can close the file early if you want
void Flush() {fflush(FilePointer);}
// flush your write buffers out to disk
long CurPos() {return ftell(FilePointer);}
// current file position: where you are about to write to or read from
void Seek(long Offset) {fseek(FilePointer,Offset,0);}
void SeekBOF(){fseek(FilePointer,0,0);}
void SeekEOF(){fseek(FilePointer,0,2);}
long Size(); // the file size in bytes
Bool EndOfFile() {return feof(FilePointer);}
#ifdef MAJORBBS
void* operator new(size_t size){return malloc(size);}
void operator delete(void* p) {free(p);}
#endif
};

class File:public LowLevelFile
{
public:
File(const char* FileName,Bool Mode=ReadAndWrite,int BufSize=BUFSIZ);
Bool Read(void *Buffer,int Size=1);
Bool Read(ByteVector& BV,int Size=1);
void Write(const void *Buffer,int Size=1);
};

class RecFile:public LowLevelFile
{
int RecSize;
public:
RecFile(const char* FileName,int RecordSize,Bool Mode,int BufSize);
Bool Read(void *Buffer);
Bool Read(void *Buffer,int Quan);
void Seek(long RecNum);
long CurRec(); // record number
long Size(); // number of recs
void Write(const void *Buffer);
void Write(const void *Buffer,int Quan);
};

#define CreateRecFileClass(ClassName,StructType) \
\
class ClassName; \
\
class ClassName ## Ref \
{ \
ClassName* F; \
ClassName ## Ref(ClassName* XF){F=XF;} \
friend class ClassName; \
public: \
void operator=(const StructType& X); \
operator StructType(); \
void* operator new(size_t size){return malloc(size);} \
void operator delete(void* p) {free(p);} \
}; \
\
class ClassName:public RecFile \
{ \
public: \
ClassName(const char* FileName,Bool Mode=ReadAndWrite, \
int BufSize=BUFSIZ): \
RecFile(FileName,sizeof(StructType),Mode,BufSize){} \
Bool Read(StructType& X){return RecFile::Read(&X);} \
Bool Read(StructType* X,int Q){return RecFile::Read(X,Q);} \
void Write(const StructType& X){RecFile::Write(&X);} \
void Write(const StructType* X,int Q){RecFile::Write(X,Q);} \
ClassName ## Ref operator[](long RecNum) \
{Seek(RecNum); return ClassName ## Ref(this);} \
}; \
\
inline void ClassName ## Ref::operator=(const StructType& X) \
{F->Write(X);} \
inline void ClassName ## Ref::operator StructType() \
{StructType X; F->Read(X); return X;}


// friend void operator=(StructType& X,ClassName ## Ref R); \
//inline void operator=(StructType& X,ClassName ## Ref R) \
// {(R.F)->Read(X);}

#ifdef __BORLANDC__
#define FTMRO "rt"
#define FTMRW "r+t"
#else
#define FTMRO "r"
#define FTMRW "r+"
#endif

class TextFile:public LowLevelFile
{
Bool Started; // used to figure out whether we're starting off appending or reading
public:
TextFile(const char* FileName,Bool Mode=ReadAndWrite,int BufSize=BUFSIZ):
LowLevelFile(FileName,((Mode==ReadOnly)?(FTMRO):(FTMRW)),BufSize)
{Started=False;}
void Seek(long Offset) {Started=True; LowLevelFile::Seek(Offset);}
Bool Read(char* S);
void Write(const char* S);
void WriteLine(const char* S="");
};

void SetCopyGrind(VoidFuncPtr);
// if you set this just before doing a copy, this func will be called
// periodically during the copy

void FileCopying(File& DestFile, File& SourceFile, long Size);
// will not modify file positions before writing

void CopyFile(const char* DestFile, const char* SourceFile);
// source file must be created. if dest file already exists,
// it will be deleted

Word CRC(File& F,long FSize); // CRC of file starting at current pos
Word CRC(File& F); // CRC of entire file


/*

Example of a file of records:

struct XType
{
long a,b,c;
};

CreateRecFileClass(XFile,XType);

main()
{
XType X;
XFile F("X.BIN");
F[0]=X;
X=F[0];
}

*/

/*
Features to add:
1) Make it so that a person cannot write beyond the end of their block

*/

class TokenFile: public File
{
long MaxTokens;
long FirstFreeBlock;
long NextFreeToken;
void GetFreeInfo(long Pos, long& Size, long& NextBlock);
// used to traverse free list
long FindSpace(long FSize);
// returns a block number that can hold "FSize" and updates the
// free list if needed
void Delete(long Pos, long Size);
// adds this info to the free list if its big enough
void SeekIndexSlot(long Token) {File::Seek(Token*8);}
void ReadCurIndexSlot(long& Pos, long& Size);
friend Bool TokenExists(const char*,long);
friend void ShowFreeList(const char*);
public:
TokenFile(const char* FileName, int BufSize=BUFSIZ);
long Seek(long Token);
/* returns the size of your object (0 if it doesn't exist). If
object is found, file pointer is moved to your objects storage
location. You may then read your data with any binary file type
read. There will be nothing to stop you from reading too much */
void WritePrep(long Token,long DataSize);
/* sets up Token with a data area of just the right size. Any
previous data under that Token is deleted. File pointer is left
where writing may begin */
void Delete(long Token);
// makes the space that was taken by Token's object available
long MaxToken(){return MaxTokens;}
Bool TokenExists(long Token);
void Extract(long Token,char* FileName);
long NewToken();
// will provide an unused token number
long NewToken(long DataSize);
// will allocate the space and provide an unused token number
};

Bool TokenExists(const char* FileName, long Token);

void SaveBootRec(TokenFile& F,const char* CName);
// Optional... Saves the video device boot info

/* This class inherits all of the properties of the (binary) File class.
It adds the feature of being able to store many little files into one
larger file. Given a token ("access code", "key") value you may store and
retrieve your data pretty much like any other binary file.

Example of writing a struct of type XType:

XType X;
TokenFile F("DATA.BIN");
F.WritePrep(326,sizeof(X)); // you pick your own Token number and object size
F.WriteThing(X);

Example of reading the same struct:

XType X;
TokenFile F("DATA.BIN");
if (F.Seek(326)) F.ReadThing(X);
else FatalError("cannot find my X thing in file DATA.BIN");

*/

#endif


  3 Responses to “Category : C++ Source Code
Archive   : WLIB.ZIP
Filename : WFILE.H

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/