-
Notifications
You must be signed in to change notification settings - Fork 0
/
TextStream.pas
101 lines (88 loc) · 2.31 KB
/
TextStream.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
unit TextStream;
interface
uses System.Classes, System.SysUtils;
type
TDebugProcedure = procedure(const S: string) of object;
TTextStream = class(TObject)
private
FHost: TStream;
FOffset,FSize: Integer;
FBuffer: array[0..1023] of AnsiChar;
FEOF: Boolean;
FDebug: TDebugProcedure;
function FillBuffer: Boolean;
protected
property Host: TStream read FHost;
public
constructor Create(AHost: TStream);
destructor Destroy; override;
function ReadLn: string; overload;
function ReadLn(out Data: string): Boolean; overload;
property EOF: Boolean read FEOF;
property HostStream: TStream read FHost;
property Offset: Integer read FOffset write FOffset;
property debug: TDebugProcedure read FDebug write FDebug;
end;
implementation
{ TTextStream }
constructor TTextStream.Create(AHost: TStream);
begin
FHost := AHost;
FillBuffer;
end;
destructor TTextStream.Destroy;
begin
FHost.Free;
inherited Destroy;
end;
function TTextStream.FillBuffer: Boolean;
begin
FOffset := 0;
FSize := FHost.Read(FBuffer,SizeOf(FBuffer));
Result := FSize > 0;
FEOF := Result;
end;
function TTextStream.ReadLn(out Data: string): Boolean;
var
Len, Start: Integer;
EOLChar: AnsiChar;
s: AnsiString;
begin
Data := ''; s := '';
Result := False;
repeat
if FOffset >= FSize then
if not FillBuffer then
Exit; // no more data to read from stream -> exit
Result := True;
Start := FOffset;
while (FOffset < FSize) and (not CharinSet(FBuffer[FOffset], [#13,#10])) do
begin
Inc(FOffset);
end;
Len := FOffset - Start;
if Len > 0 then
begin
SetLength(s, Length(s) + Len);
Move(FBuffer[Start], s[Succ(Length(s)-Len)], Len);
Data := string(s);
//if assigned(FDebug) then FDebug(s);
end else
Data := '';
until FOffset <> FSize; // EOL char found
EOLChar := FBuffer[FOffset];
Inc(FOffset);
if (FOffset = FSize) then
if not FillBuffer then
Exit;
if CharInSet(FBuffer[FOffset], [#13,#10]-[EOLChar]) then begin
Inc(FOffset);
if (FOffset = FSize) then
FillBuffer;
end;
end;
function TTextStream.ReadLn: string;
begin
ReadLn(Result);
end;
end.