mysticbbs/mdl/m_fileio.pas

834 lines
18 KiB
ObjectPascal
Raw Normal View History

2013-05-08 23:12:32 -07:00
Unit m_FileIO;
2012-02-13 15:48:14 -08:00
{$I M_OPS.PAS}
Interface
{ FILE ACCESS FUNCTIONS }
Function ioReset (Var F: File; RecSize: Word; Mode: Byte) : Boolean;
Function ioReWrite (Var F: File; RecSize: Word; Mode: Byte) : Boolean;
Function ioSeek (Var F: File; FPos: LongInt) : Boolean;
Function ioRead (Var F: File; Var Rec) : Boolean;
Function ioWrite (Var F: File; Var Rec) : Boolean;
Function ioBlockRead (Var F: File; Var Rec; dSize: LongInt; Var Res: LongInt) : Boolean;
Function ioBlockWrite (Var F: File; Var Rec; dSize: LongInt; Var Res: LongInt) : Boolean;
{ FILE MANIPULATION FUNCTIONS }
Function FileExist (Str: String) : Boolean;
Function FileErase (Str: String) : Boolean;
Function JustFileName (Str: String) : String;
Function JustFile (Str: String) : String;
Function JustFileExt (Str: String) : String;
Function JustPath (Str: String) : String;
2013-03-22 20:17:15 -07:00
Function WildMatch (WildCard, FName: String; IgnoreCase: Boolean) : Boolean;
Function DirCreate (Str: String) : Boolean;
2012-03-03 19:08:30 -08:00
Function DirExists (Str: String) : Boolean;
2012-02-13 15:48:14 -08:00
Function DirSlash (Str: String) : String;
2013-03-31 22:08:04 -07:00
Function DirLast (CurPath: String) : String;
2012-02-24 06:04:34 -08:00
Function DirChange (Dir: String) : Boolean;
Procedure DirClean (Path: String; Exempt: String);
2013-03-18 22:46:10 -07:00
Function DirFiles (Str: String) : LongInt;
2012-02-24 06:04:34 -08:00
Function FileRename (OldFN, NewFN: String) : Boolean;
Function FileCopy (Source, Target: String) : Boolean;
2012-08-16 20:09:22 -07:00
Function FileFind (FN: String) : String;
2012-08-17 11:37:57 -07:00
Function FileByteSize (FN: String) : Int64;
2013-04-06 20:58:33 -07:00
Function FileNewExt (FN, NewExt: String) : String;
2013-09-07 11:37:02 -07:00
Procedure FileAppend (F1, F2: String);
2012-02-13 15:48:14 -08:00
{ GLOBAL FILEIO VARIABLES AND CONSTANTS }
Var
ioCode : LongInt;
Const
fmReadOnly = 0;
fmWriteOnly = 1;
fmReadWrite = 2;
fmDenyAll = 16;
fmDenyWrite = 32;
fmDenyRead = 48;
fmDenyNone = 64;
fmNoInherit = 128;
fmRWDN = 66;
fmRWDR = 50;
fmRWDW = 34;
2013-05-08 23:12:32 -07:00
{ STREAMING CLASS OPTIONS }
2012-02-13 15:48:14 -08:00
Const
2013-05-08 23:12:32 -07:00
MaxFileBufferSize = 64 * 1024;
2012-02-13 15:48:14 -08:00
Type
2013-05-08 23:12:32 -07:00
TFileBufferOpenType = (
2012-02-13 15:48:14 -08:00
fmOpen,
fmOpenCreate,
fmCreate
);
2013-05-08 23:12:32 -07:00
PFileBufferRec = ^TFileBufferRec;
TFileBufferRec = Array[0..MaxFileBufferSize - 1] of Char;
TFileBuffer = Class
2013-05-20 02:35:24 -07:00
RecSize : LongInt;
2013-05-08 23:12:32 -07:00
BufSize : LongInt;
Buffer : PFileBufferRec;
BufRead : LongInt;
BufStart : LongInt;
BufEnd : LongInt;
BufPos : LongInt;
InFile : File;
BufEOF : Boolean;
BufDirty : Boolean;
IsOpened : Boolean;
Constructor Create (BufferSize: LongInt);
2012-02-13 15:48:14 -08:00
Destructor Destroy; Override;
2013-05-08 23:12:32 -07:00
2013-05-20 02:35:24 -07:00
Function OpenStream (FN: String; RS: LongInt; OpenType: TFileBufferOpenType; OpenMode: Byte) : Boolean;
2013-05-08 23:12:32 -07:00
Procedure CloseStream;
2013-05-20 02:35:24 -07:00
Function ReadChar : Char;
// Function ReadLine : String;
Procedure ReadBlock (Var Buf; Size: LongInt; Var Count: LongInt); Overload;
Procedure ReadBlock (Var Buf; Size: LongInt); Overload;
Procedure ReadRecord (Var Buf);
Procedure SeekRecord (RP: LongInt);
Procedure SeekRaw ( FP : LongInt);
Procedure WriteBlock (Var Buf; Size: LongInt);
Procedure WriteRecord (Var Buf);
Function FilePosRaw : LongInt;
Function FilePosRecord : LongInt;
Function FileSizeRaw : LongInt;
Function FileSizeRecord : LongInt;
Function EOF : Boolean;
2013-05-08 23:12:32 -07:00
Procedure FillBuffer;
Procedure FlushBuffer;
2012-02-13 15:48:14 -08:00
End;
Implementation
Uses
2013-05-20 02:35:24 -07:00
{$IFDEF WINDOWS} // FileErase (FPC Erase) hardly EVER WORKS
2013-03-18 22:46:10 -07:00
Windows,
{$ENDIF}
2012-02-13 15:48:14 -08:00
DOS,
m_Types,
2012-02-24 06:04:34 -08:00
m_Strings,
2012-02-13 15:48:14 -08:00
m_DateTime;
Const
2013-05-20 02:35:24 -07:00
ioRetries = 20;
ioWaitTime = 100;
2012-02-13 15:48:14 -08:00
Function ioReset (Var F: File; RecSize: Word; Mode: Byte) : Boolean;
Var
Count : Word;
Begin
FileMode := Mode;
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
2013-03-18 22:46:10 -07:00
{$I-} Reset (F, RecSize); {$I+}
2012-02-13 15:48:14 -08:00
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
2013-03-18 22:46:10 -07:00
Result := (ioCode = 0);
2012-02-13 15:48:14 -08:00
End;
Function ioReWrite (Var F: File; RecSize: Word; Mode: Byte) : Boolean;
Var
Count : Word;
Begin
FileMode := Mode;
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
ReWrite (F, RecSize);
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
ioReWrite := (ioCode = 0);
End;
Function ioSeek (Var F: File; FPos: LongInt) : Boolean;
Var
Count : Word;
Begin
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
2013-04-06 20:58:33 -07:00
{$I-} Seek (F, FPos); {$I+}
2012-02-13 15:48:14 -08:00
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
ioSeek := (ioCode = 0);
End;
Function ioBlockRead (Var F: File; Var Rec; dSize: LongInt; Var Res: LongInt) : Boolean;
Var
Count : Word;
Begin
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
BlockRead (F, Rec, dSize, Res);
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
ioBlockRead := (ioCode = 0);
End;
Function ioBlockWrite (Var F: File; Var Rec; dSize: LongInt; Var Res: LongInt) : Boolean;
Var
Count : Word;
Begin
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
BlockWrite (F, Rec, dSize, Res);
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
ioBlockWrite := (ioCode = 0);
End;
Function ioRead (Var F: File; Var Rec) : Boolean;
Var
Count : Word;
Begin
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
2013-04-06 20:58:33 -07:00
{$I-} BlockRead (F, Rec, 1); {$I+}
2012-02-13 15:48:14 -08:00
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
ioRead := (ioCode = 0);
End;
Function ioWrite (Var F: File; Var Rec) : Boolean;
Var
Count : Word;
Begin
Count := 0;
ioCode := 5;
While (Count < ioRetries) and (ioCode = 5) Do Begin
BlockWrite (F, Rec, 1);
ioCode := IoResult;
Inc (Count);
If ioCode = 5 Then WaitMS(ioWaitTime);
End;
ioWrite := (ioCode = 0);
End;
2012-02-24 06:04:34 -08:00
Function FileCopy (Source, Target: String) : Boolean;
Var
SF : File;
TF : File;
BRead : LongInt;
BWrite : LongInt;
FileBuf : Array[1..4096] of Char;
Begin
2012-07-23 20:02:19 -07:00
Result := False;
FileMode := 66;
2012-02-24 06:04:34 -08:00
Assign (SF, Source);
{$I-} Reset(SF, 1); {$I+}
If IOResult <> 0 Then Exit;
Assign (TF, Target);
{$I-} ReWrite(TF, 1); {$I+}
If IOResult <> 0 then Exit;
Repeat
BlockRead (SF, FileBuf, SizeOf(FileBuf), BRead);
BlockWrite (TF, FileBuf, BRead, BWrite);
Until (BRead = 0) or (BRead <> BWrite);
Close(SF);
Close(TF);
Result := BRead = BWrite;
End;
Function FileRename (OldFN, NewFN: String) : Boolean;
Var
OldF : File;
Begin
Assign (OldF, NewFN);
{$I-} Erase (OldF); {$I+}
If IoResult = 0 Then;
Assign (OldF, OldFN);
{$I-} ReName (OldF, NewFN); {$I+}
Result := (IoResult = 0);
End;
Function DirCreate (Str: String) : Boolean;
Var
Count : Byte;
CurDir : String;
Prefix : String;
Begin
Result := True;
Prefix := '';
Str := DirSlash(Str);
If DirExists(Str) Then Exit;
Count := Pos(PathSep, Str);
While (Count > 0) Do Begin
CurDir := Copy(Str, 1, Count);
Delete (Str, 1, Count);
Prefix := Prefix + CurDir;
If Not DirExists(Prefix) Then Begin
{$I-} MkDIR (Prefix); {$I+}
If IoResult <> 0 Then Begin
Result := False;
Exit;
End;
End;
Count := Pos(PathSep, Str);
End;
End;
2012-02-24 06:04:34 -08:00
Procedure DirClean (Path: String; Exempt: String);
Var
DirInfo: SearchRec;
Begin
FindFirst(Path + '*', Archive, DirInfo);
While DosError = 0 Do Begin
If strUpper(Exempt) <> strUpper(DirInfo.Name) Then
FileErase(Path + DirInfo.Name);
FindNext(DirInfo);
End;
FindClose(DirInfo);
End;
Function DirChange (Dir: String) : Boolean;
Begin
While Dir[Length(Dir)] = PathSep Do Dec(Dir[0]);
Dir := Dir + PathSep;
{$I-} ChDir(Dir); {$I+}
Result := IoResult = 0;
End;
2012-02-13 15:48:14 -08:00
Function DirSlash (Str: String) : String;
Begin
If Copy(Str, Length(Str), 1) <> PathSep Then
Str := Str + PathSep;
Result := Str;
End;
2013-03-31 22:08:04 -07:00
Function DirLast (CurPath: String) : String;
Begin
If CurPath[Length(CurPath)] = PathSep Then
Delete (CurPath, Length(CurPath), 1);
While (CurPath[Length(CurPath)] <> PathSep) and (CurPath <> '') Do
Delete (CurPath, Length(CurPath), 1);
Result := DirSlash(CurPath);
End;
2012-02-13 15:48:14 -08:00
Function JustPath (Str: String) : String;
Var
Count : Byte;
Begin
For Count := Ord(Str[0]) DownTo 1 Do
If (Str[Count] = '/') or (Str[Count] = '\') Then Begin
Delete (Str, Count + 1, 255);
Break;
End;
Result := Str;
End;
Function JustFile (Str: String) : String;
Var
Count : Byte;
Begin
2012-07-23 20:02:19 -07:00
For Count := Length(Str) DownTo 1 Do
2012-02-13 15:48:14 -08:00
If (Str[Count] = '/') or (Str[Count] = '\') Then Begin
Delete (Str, 1, Count);
Break;
End;
Result := Str;
End;
Function JustFileName (Str: String) : String;
Var
Temp : Byte;
Begin
Temp := Pos ('.', Str);
If Temp > 0 Then
Delete (Str, Temp, Ord(Str[0]));
Result := Str;
End;
Function JustFileExt (Str: String) : String;
Var
Temp : Byte;
Begin
Result := '';
For Temp := Length(Str) DownTo 1 Do
If Str[Temp] = '.' Then Begin
Result := Copy(Str, Temp + 1, Length(Str));
Exit;
End;
End;
2013-03-22 20:17:15 -07:00
Function WildMatch (WildCard, FName: String; IgnoreCase: Boolean) : Boolean;
Begin
Result := False;
If FName = '' Then Exit;
If IgnoreCase Then Begin
WildCard := strUpper(WildCard);
FName := strUpper(FName);
End;
Case Wildcard[1] of
'*' : Begin
If FName[1] = '.' Then Exit;
If Length(Wildcard) = 1 Then Result := True;
If (Length(Wildcard) > 1) and (Wildcard[2] = '.') and (Length(FName) > 0) Then
Result := WildMatch(Copy(Wildcard, 3, Length(Wildcard) - 2), Copy(FName, Pos('.', FName) + 1, Length(FName)-Pos('.', FName)), False);
End;
'?' : If Ord(Wildcard[0]) = 1 Then
Result := True
Else
Result := WildMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1), False);
Else
If FName[1] = Wildcard[1] Then
If Length(Wildcard) > 1 Then
Result := WildMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1), False)
Else
Result := (Length(FName) = 1) And (Length(Wildcard) = 1);
End;
End;
2013-03-18 22:46:10 -07:00
{$IFDEF WINDOWS}
Function FileErase (Str: String) : Boolean;
Begin
Str := Str + #0;
Result := Windows.DeleteFile(PChar(@Str[1]));
End;
{$ELSE}
2012-02-13 15:48:14 -08:00
Function FileErase (Str: String) : Boolean;
Var
F : File;
Begin
2013-03-18 22:46:10 -07:00
{$I-}
2012-02-24 06:31:31 -08:00
2013-03-18 22:46:10 -07:00
Assign (F, Str);
Erase (F);
2012-02-13 15:48:14 -08:00
2013-03-18 22:46:10 -07:00
Result := IoResult = 0;
2012-02-13 15:48:14 -08:00
End;
2013-03-18 22:46:10 -07:00
{$ENDIF}
2012-02-13 15:48:14 -08:00
Function FileExist (Str: String) : Boolean;
Var
DF : File;
Attr : Word;
Begin
Assign (DF, Str);
GetFattr (DF, Attr);
Result := (DosError = 0) and (Attr And Directory = 0);
End;
2012-03-03 19:08:30 -08:00
Function DirExists (Str: String) : Boolean;
2012-02-13 15:48:14 -08:00
Var
F : File;
Attr : Word;
Begin
Result := False;
If Str = '' Then Exit;
While Str[Length(Str)] = PathSep Do Dec(Str[0]);
Str := Str + PathSep + '.';
Assign (F, Str);
GetFAttr (F, Attr);
Result := ((Attr And Directory) = Directory);
End;
2013-05-08 23:12:32 -07:00
Function FileFind (FN: String) : String;
Var
Dir : SearchRec;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
Result := FN;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FindFirst (JustPath(FN) + '*', AnyFile, Dir);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
While DosError = 0 Do Begin
If strUpper(Dir.Name) = strUpper(JustFile(FN)) Then Begin
Result := JustPath(FN) + Dir.Name;
Break;
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FindNext(Dir);
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FindClose(Dir);
2012-02-13 15:48:14 -08:00
End;
2013-05-08 23:12:32 -07:00
Function FileByteSize (FN: String) : Int64;
Var
Dir : SearchRec;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
Result := 0;
FindFirst (FN, AnyFile, Dir);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
If DosError = 0 Then Result := Dir.Size;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FindClose(Dir);
2012-02-13 15:48:14 -08:00
End;
2013-05-08 23:12:32 -07:00
Function DirFiles (Str: String) : LongInt;
Var
DirInfo : SearchRec;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
Result := 0;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FindFirst (Str + '*', AnyFile, DirInfo);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
While DosError = 0 Do Begin
If DirInfo.Attr And Directory = 0 Then
Inc (Result);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FindNext(DirInfo);
2012-02-13 15:48:14 -08:00
End;
2013-05-08 23:12:32 -07:00
FindClose (DirInfo);
2012-02-13 15:48:14 -08:00
End;
2013-05-08 23:12:32 -07:00
Function FileNewExt (FN, NewExt: String) : String;
Var
Temp : Byte;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
For Temp := Length(FN) DownTo 1 Do
If FN[Temp] = '.' Then Begin
Result := Copy(FN, 1, Temp) + NewExt;
Exit;
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
Result := FN + '.' + NewExt;
2012-02-13 15:48:14 -08:00
End;
2013-09-07 11:37:02 -07:00
Procedure FileAppend (F1, F2: String);
Var
BufIn,
BufOut : Array[1..8*1024] of Char;
TF1 : Text;
TF2 : Text;
Str : String;
Begin
Assign (TF1, F1);
{$I-} Reset(TF1); {$I+}
If IoResult <> 0 Then Exit;
SetTextBuf (TF1, BufIn);
Assign (TF2, F2);
{$I-} Append(TF2); {$I+}
If (IoResult = 2) Then
ReWrite (TF2);
SetTextBuf (TF2, BufOut);
While Not Eof(TF1) Do Begin
ReadLn (TF1, Str);
WriteLn (TF2, Str);
End;
Close (TF1);
Close (TF2);
End;
2013-05-08 23:12:32 -07:00
{ FILE STREAMING FUNCTIONS }
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
Constructor TFileBuffer.Create (BufferSize: LongInt);
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
Inherited Create;
2013-05-20 02:35:24 -07:00
RecSize := 1;
2013-05-08 23:12:32 -07:00
BufSize := BufferSize;
BufStart := 0;
BufEnd := 0;
BufPos := 0;
BufEOF := False;
BufRead := 0;
Buffer := NIL;
BufDirty := False;
IsOpened := False;
2012-02-13 15:48:14 -08:00
End;
2013-05-08 23:12:32 -07:00
Destructor TFileBuffer.Destroy;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
If IsOpened Then CloseStream;
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
Function TFileBuffer.OpenStream (FN: String; RS: LongInt; OpenType: TFileBufferOpenType; OpenMode: Byte) : Boolean;
2012-02-13 15:48:14 -08:00
Begin
2013-05-20 02:35:24 -07:00
Result := False;
RecSize := RS;
2013-05-08 23:12:32 -07:00
If IsOpened Then CloseStream;
Assign (InFile, FN);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
Case OpenType of
fmOpen : If Not ioReset (InFile, 1, OpenMode) Then Exit;
fmOpenCreate : If Not ioReset (InFile, 1, OpenMode) Then
If Not FileExist(FN) Then Begin
If Not ioReWrite (InFile, 1, OpenMode) Then Exit;
End Else
Exit;
fmCreate : If Not ioReWrite (InFile, 1, OpenMode) Then Exit;
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
GetMem (Buffer, BufSize);
2012-02-13 15:48:14 -08:00
FillBuffer;
2013-05-08 23:12:32 -07:00
BufDirty := False;
IsOpened := True;
Result := True;
2012-02-13 15:48:14 -08:00
End;
2013-05-08 23:12:32 -07:00
Procedure TFileBuffer.CloseStream;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
If IsOpened Then Begin
2012-02-13 15:48:14 -08:00
If BufDirty Then FlushBuffer;
2013-05-08 23:12:32 -07:00
System.Close (InFile);
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
If Assigned(Buffer) Then Begin
FreeMem (Buffer, BufSize);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
Buffer := NIL;
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
IsOpened := False;
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
Function TFileBuffer.FilePosRaw : LongInt;
Begin
Result := BufStart + BufPos;
End;
Function TFileBuffer.FilePosRecord : LongInt;
2012-02-13 15:48:14 -08:00
Begin
2013-05-20 02:35:24 -07:00
Result := (BufStart + BufPos) DIV RecSize;
2013-05-08 23:12:32 -07:00
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
Procedure TFileBuffer.FillBuffer;
Var
Start : LongInt;
Begin
Start := System.FilePos(InFile);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
System.BlockRead (InFile, Buffer^[0], BufSize, BufRead);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
BufStart := Start;
BufEnd := Start + BufRead;
BufPos := 0;
BufEOF := System.EOF(InFile);
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
Function TFileBuffer.ReadChar : Char;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
If BufPos >= BufSize Then FillBuffer;
2012-02-13 15:48:14 -08:00
2013-05-20 02:35:24 -07:00
Result := Buffer^[BufPos];
2013-05-08 23:12:32 -07:00
Inc (BufPos);
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
(*
Function TFileBuffer.ReadLine : String;
Var
Ch : Char;
Begin
Result := '';
While Not Self.EOF Do Begin
Ch := Self.ReadChar;
If LineEnding[1] = Ch Then Begin
If Length(LineEnding) = 1 Then Break;
Ch := Self.ReadChar;
If LineEnding[2] = Ch Then Break;
Result := Result + LineEnding[1];
End;
Result := Result + Ch;
End;
End;
*)
Procedure TFileBuffer.ReadRecord (Var Buf);
Begin
Self.ReadBlock (Buf, RecSize);
End;
Procedure TFileBuffer.SeekRecord (RP: LongInt);
Begin
Self.SeekRaw (RP * RecSize);
End;
Procedure TFileBuffer.WriteBlock (Var Buf; Size: LongInt);
2012-02-13 15:48:14 -08:00
Var
2013-05-08 23:12:32 -07:00
Offset : LongInt;
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
If BufPos + Size > BufSize Then Begin
2012-02-13 15:48:14 -08:00
Offset := BufSize - BufPos;
If Offset > 0 Then
2013-05-08 23:12:32 -07:00
Move(Buf, Buffer^[BufPos], Offset);
2012-02-13 15:48:14 -08:00
FlushBuffer;
FillBuffer;
2013-05-08 23:12:32 -07:00
Move (TFileBufferRec(Buf)[Offset], Buffer^[BufPos], Size - Offset);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
BufPos := BufPos + Size - Offset;
2012-02-13 15:48:14 -08:00
End Else Begin
2013-05-08 23:12:32 -07:00
Move (Buf, Buffer^[BufPos], Size);
Inc (BufPos, Size);
2012-02-13 15:48:14 -08:00
End;
2012-02-26 04:45:21 -08:00
2013-05-08 23:12:32 -07:00
If BufPos > BufEnd Then BufEnd := BufPos;
If BufPos > BufRead Then BufRead := BufPos;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
BufDirty := True;
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
Procedure TFileBuffer.WriteRecord (Var Buf);
Begin
Self.WriteBlock (Buf, RecSize);
End;
Procedure TFileBuffer.ReadBlock (Var Buf; Size: LongInt);
2012-02-13 15:48:14 -08:00
Var
2013-05-08 23:12:32 -07:00
Res : LongInt;
2012-02-13 15:48:14 -08:00
Begin
2013-05-20 02:35:24 -07:00
Self.ReadBlock (Buf, Size, Res);
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
Procedure TFileBuffer.ReadBlock (Var Buf; Size: LongInt; Var Count: LongInt);
2012-02-13 15:48:14 -08:00
Begin
2013-05-08 23:12:32 -07:00
If BufPos + Size >= BufRead Then Begin
If BufDirty Then FlushBuffer;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
If Size > BufSize Then Size := BufSize;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
System.Seek(InFile, BufStart + BufPos);
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
FillBuffer;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
If BufRead < Size Then Size := BufRead;
End;
2012-02-13 15:48:14 -08:00
2013-05-08 23:12:32 -07:00
Move (Buffer^[BufPos], Buf, Size);
Inc (BufPos, Size);
2013-05-08 23:12:32 -07:00
Count := Size;
2012-02-13 15:48:14 -08:00
End;
2013-05-20 02:35:24 -07:00
Procedure TFileBuffer.SeekRaw (FP : LongInt);
2012-08-16 20:09:22 -07:00
Begin
2013-05-08 23:12:32 -07:00
If (FP >= BufStart) and (FP < BufEnd) Then
BufPos := (BufEnd - (BufEnd - FP)) - BufStart
Else Begin
If BufDirty Then FlushBuffer;
2012-08-16 20:09:22 -07:00
2013-05-08 23:12:32 -07:00
System.Seek(InFile, FP);
2012-08-16 20:09:22 -07:00
2013-05-08 23:12:32 -07:00
FillBuffer;
2012-08-16 20:09:22 -07:00
End;
End;
2013-05-08 23:12:32 -07:00
Function TFileBuffer.EOF : Boolean;
2012-08-17 11:37:57 -07:00
Begin
2013-05-20 02:35:24 -07:00
Result := (BufStart + BufPos >= BufEnd) and BufEOF;
End;
Function TFileBuffer.FileSizeRaw : LongInt;
Begin
If BufDirty Then FlushBuffer;
Result := System.FileSize(InFile);
2012-08-17 11:37:57 -07:00
End;
2013-05-20 02:35:24 -07:00
Function TFileBuffer.FileSizeRecord : LongInt;
2013-03-18 22:46:10 -07:00
Begin
2013-05-20 02:35:24 -07:00
If BufDirty Then FlushBuffer;
Result := System.FileSize(InFile) DIV RecSize;
2013-03-18 22:46:10 -07:00
End;
2013-05-08 23:12:32 -07:00
Procedure TFileBuffer.FlushBuffer;
2013-04-06 20:58:33 -07:00
Var
2013-05-08 23:12:32 -07:00
Res : LongInt;
2013-04-06 20:58:33 -07:00
Begin
2013-05-08 23:12:32 -07:00
System.Seek (InFile, BufStart);
System.BlockWrite (InFile, Buffer^, BufRead, Res);
2013-04-06 20:58:33 -07:00
2013-05-08 23:12:32 -07:00
BufDirty := False;
2013-04-06 20:58:33 -07:00
End;
2012-08-17 11:37:57 -07:00
End.