unit Ofile; {$I-} {Object file unit. Copyright (C) 1995 F-inc. rev 2.1 5/July/1996 Borland Delphi Object Pascal compatible. Do not use with BP7. } (**) interface (**) uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; (*************************************************************************** General Notes: If you want to override any of the functions, only do so for those that are virtual. Do not override non virtual methods! Notes v2.0: - Many virtual methods have been taken out for faster execution. For faster, buffered saving of delphi data types, use TWriter or TBufferedFileStream. See unit buffered_file_stream_unit (F-inc). - To check for errors, use the Error function (this calls IOResult) or IOResult method. v2.1: - Took out AssignFile. Directly pass the file name in create. This is more inline with Borland's own TStreamFile creation procedure and is less confusing. ***************************************************************************) Type PFile = ^File; TErrorFlag = Integer; TOFile = Class private procedure AssignFile(const AFilePath : string); {Accepts : A file path. The path to the file} public Constructor Create(const file_path: string); Destructor Destroy; Override; function Error: Boolean; {Returns true if there is an error} function IOResult: integer; {wraps the system's IOResult} {Wrapper methods} procedure Reset(Const aSize : Word); procedure ResetReadOnly(Const aSize : Word); procedure Rewrite(Const aSize : Word); //virtual; procedure Close; //virtual; function FilePos : LongInt; //virtual; procedure Seek(Const aPos : LongInt); //virtual; procedure SeekEOF; {Seeks to the end of file} {Block read/write support Returns number of bytes read/written} function BlockRead(Var Buf; Const Count : longint): longint; {virtual;} function BlockWrite(Var Buf; Const Count : longint): longint; {virtual;} {Writes/reads a string String is stored in the format [StringLength][...String...]} procedure ReadString(Var rString : String); procedure WriteString(aString : String); function GetString : string; {Writes/reads a byte} procedure ReadByte(Var rByte : Byte); procedure WriteByte(aByte : Byte); function GetByte : byte; {Writes/reads a integer} procedure ReadInteger(Var rInteger : Integer); procedure WriteInteger(aInteger : Integer); function GetInteger : Integer; {Writes/reads a integer} procedure ReadLongint(Var rLongint : Longint); procedure WriteLongint(aLongint : Longint); function GetLongint : Longint; function EOF : Boolean; {True if end of file reached} function Exists : Boolean; {True if file exists} function FileSize : LongInt; protected F : File; {The actual file variable} FName : String; {The actual file name} FPath : String; {The actual file path} FOpen : Boolean; {True if file is open} //BlockResult : longint; {BlockRead/Write result stored here} //ErrorFlag : TErrorFlag; {The error flag. 0 - no error.} //procedure UpdateErrorFlag; {Assigns IOError to ErrorFlag} //function GetErrorFlag : TErrorFlag; {Returns the value of the error flag} procedure _Reset(Const aSize : Word); virtual; {Real reset} //procedure _BlockRead(Var Buf; Const Count : word); {Default BlockRead procedure} //procedure _BlockWrite(Var Buf; Const Count : word); {Default BlockWrite prrocedure} published property Handle: File read F; {Returns a pointer to the file handle} property IsOpen: boolean read FOpen; {True if file is open} property FileName: string read FName; property FilePath: string read FPath; end; (**) implementation (**) //Uses EDosu; {/////////////////////////////////////////////////////////////} {Constructor/Destructor} {/////////////////////////////////////////////////////////////} Constructor TOFile.Create(const file_path: string); //Constructor TOFile.Create; begin Inherited Create; FOpen := False; AssignFile(file_path); end; Destructor TOFile.Destroy; begin Close; Inherited Destroy; end; {/////////////////////////////////////////////////////////////} {Misc functions} {/////////////////////////////////////////////////////////////} {function TOFile.GetHandle: PFile; begin result := @F; end;} {/////////////////////////////////////////////////////////////} {Wrapper functions} {/////////////////////////////////////////////////////////////} procedure TOFile.AssignFile(const AFilePath : String); begin Close; {Init fields} FName := ExtractFileName(AFilePath); FPath := ExtractFilePath(AFilePath); Assign(f, AFilePath); end; procedure TOFile.Reset; begin FileMode := 2; _Reset(aSize); end; procedure TOFile.ResetReadOnly; begin FileMode := 0; _Reset(aSize); end; procedure TOFile._Reset; begin Close; System.Reset(f, aSize); FOpen := True; end; procedure TOFile.Rewrite; begin Close; System.Rewrite(f, aSize); FOpen := True; end; procedure TOFile.Close; begin If IsOpen then begin System.Close(f); FOpen := False; end; end; function TOFile.FilePos : LongInt; begin FilePos := System.FilePos(f); end; procedure TOFile.Seek; begin System.Seek(f, aPos); end; procedure TOFile.SeekEOF; begin Seek(FileSize); end; function TOFile.EOF; begin Result := System.EOF(f); end; function TOFile.Exists; begin Result := FileExists(FPath + FName); end; Function TOFile.FileSize; begin Result := System.FileSize(f); end; {/////////////////////////////////////////////////////////////} {BlockRead / BlockWrite wrappers} {/////////////////////////////////////////////////////////////} {The procedurers call the virtual BlockRead and BlockWrite. These can be overriden. _BlockRead and _BlockWrite cannot.} function TOFile.BlockRead(Var Buf; Const Count: longint): longint; begin System.BlockRead(f, Buf, Count, result); end; function TOFile.BlockWrite(Var Buf; Const Count: longint): longint; begin System.BlockWrite(f, Buf, Count, result); end; {/////////////////////////////////////////////////////////////} {Write data types support} {/////////////////////////////////////////////////////////////} {/////////////////////////////////////////////////////////////} {String support} {/////////////////////////////////////////////////////////////} procedure TOFile.WriteString(aString : String); begin {Write Length + 1 bytes because the length byte is also written} BlockWrite(aString, Length(aString)); end; procedure TOFile.ReadString(Var rString : String); begin {Read length, Read string data if length is > 0} If length(rString) > 0 then BlockRead(rString, length(rString)); end; function TOFile.GetString : string; var s : string; begin ReadString(s); GetString := s; end; {/////////////////////////////////////////////////////////////} {Byte support} {/////////////////////////////////////////////////////////////} procedure TOFile.WriteByte(aByte : Byte); begin BlockWrite(aByte, SizeOf(Byte)); end; procedure TOFile.ReadByte(Var rByte : Byte); begin BlockRead(rByte, SizeOf(Byte)); end; function TOFile.GetByte : byte; var b : byte; begin ReadByte(b); GetByte := b; end; {/////////////////////////////////////////////////////////////} {Integer support} {/////////////////////////////////////////////////////////////} procedure TOFile.WriteInteger(aInteger : Integer); begin BlockWrite(aInteger, SizeOf(Integer)); end; procedure TOFile.ReadInteger(Var rInteger : Integer); begin BlockRead(rInteger, SizeOf(Integer)); end; function TOFile.GetInteger : Integer; var i : Integer; begin ReadInteger(i); GetInteger := i; end; {/////////////////////////////////////////////////////////////} {Long Integer support} {/////////////////////////////////////////////////////////////} procedure TOFile.WriteLongInt(aLongint : Longint); begin BlockWrite(aLongint, SizeOf(Longint)); end; procedure TOFile.ReadLongint(Var rLongint : Longint); begin BlockRead(rLongint, SizeOf(Longint)); end; function TOFile.GetLongint : Longint; var i : Longint; begin ReadLongint(i); GetLongint := i; end; {/////////////////////////////////////////////////////////////} {Error support} {/////////////////////////////////////////////////////////////} function TOFile.Error; begin Result := (IOResult = 0); end; function TOFile.IOResult: integer; begin result := system.IOResult; end; end.