{+--------------------------------------------------------------------------+ | Class: TLineStream | Created: 8.97 | Author: Martin Waldenburg | Copyright 1997, all rights reserved. | Description: TLineStream gives a buffered access to the lines of a file. | Every line must end with CRLF. Don't forget to flush the | Memory after writing. | Version: 1.2 | State: FreeWare | Disclaimer: | This is provided as is, expressly without a warranty of any kind. | You use it at your own risc. +--------------------------------------------------------------------------+} unit mwLineStream; interface uses SysUtils, Classes; type TLineStream = class(TFileStream) private fLineStart: PChar; fMaxMemorySize:Longint; fMaxLineSize:Longint; fMemorySize: LongInt; fLineSize:Longint; fMemory:PChar; fLine: PChar; fFileEof:Boolean; fMemoryPos: LongInt; fEof:Boolean; function GetMemoryFull:Boolean; procedure SetMaxLineSize(NewValue:Longint); procedure SetMaxMemorySize(NewValue:Longint); protected public constructor create(Const FileName: string; Mode: Word); destructor destroy;override; procedure FillMemory; function ReadLine:PChar; procedure WriteLine(NewLine: String); procedure FlushMemory; procedure Reset; property MaxMemorySize:Longint read fMaxMemorySize write SetMaxMemorySize; property MaxLineSize:Longint read fMaxLineSize write SetMaxLineSize; property Memory:PChar read fMemory write fMemory; property MemoryFull:Boolean read GetMemoryFull; property FileEof:Boolean read fFileEof; property Eof:Boolean read fEof write fEof; published end; { TLineStream } implementation constructor TLineStream.create(Const FileName: string; Mode: Word); var fHandle: Integer; begin if not FileExists(FileName) then begin fHandle:= FileCreate(FileName); FileClose(fHandle); end; inherited create(FileName, Mode); fEof:= False; fFileEof:= False; MaxMemorySize:= 65535; fMemorySize:= 0; fMemoryPos:= 0; MaxLineSize:= 4096; Position:= 0; end; { create } destructor TLineStream.destroy; begin ReallocMem(fMemory, 0); ReallocMem(fLine, 0); inherited destroy; end; { destroy } procedure TLineStream.SetMaxMemorySize(NewValue:Longint); begin fMaxMemorySize:= NewValue; ReallocMem(fMemory, fMaxMemorySize +1); end; { SetMaxMemorySize } procedure TLineStream.SetMaxLineSize(NewValue:Longint); begin fMaxLineSize:= NewValue; ReallocMem(fLine, fMaxLineSize +1); end; { SetMaxLineSize } procedure TLineStream.FillMemory; var Readed: LongInt; begin Readed:= Read(fMemory^, fMaxMemorySize); fMemorySize:= Readed; if Readed = 0 then fFileEof:= True; if fMemorySize > 0 then while fMemory[fMemorySize -2] <> #13 do dec(fMemorySize); fMemory[fMemorySize]:= #0; Position:= Position -Readed + fMemorySize +1; fLineStart:= fMemory; end; { FillMemory } function TLineStream.GetMemoryFull:Boolean; begin if fMemorySize > 0 then Result:= True else Result:= False; end; { GetMemoryFull } function TLineStream.ReadLine:PChar; var Run: PChar; begin if (fMemorySize = 0) and not FileEof then FillMemory; if fMemorySize > 0 then begin Run:= fLineStart; while Run^ <> #13 do inc(Run); fLineSize:= Run - fLineStart; inc(Run, 2); StrLCopy(fLine, fLineStart, fLineSize); fLine[fLineSize]:= #0; Result:= fLine; fLineStart:= Run; Case Run^ of #0: FillMemory end; end; if fMemorySize = 0 then fEof:= True; end; { ReadLine } procedure TLineStream.WriteLine(NewLine: String); var Count, Pos: Longint; begin NewLine:= NewLine + #13#10; Count:= Length(NewLine); if (fMemoryPos >= 0) and (Count >= 0) then begin Pos := fMemoryPos + Count; if Pos > 0 then begin if Pos > FMaxMemorySize then begin FlushMemory; end; StrECopy((fMemory + fMemoryPos), PChar(NewLine)); fMemoryPos:= fMemoryPos + Count; fMemory[fMemoryPos]:= #0; end; end; end; { WriteLine } procedure TLineStream.FlushMemory; begin Write(fMemory^, fMemoryPos); fMemoryPos:= 0; end; { FlushMemory } procedure TLineStream.Reset; begin fEof:= False; fFileEof:= False; fMemorySize:= 0; fMemoryPos:= 0; Position:= 0; end; { Reset } end.