diff --git a/src/shared/xparser.pas b/src/shared/xparser.pas
index d8b600dbc1d6340a0a16c9b8017dfde7bd9f401a..d0f0d3af202bef33b10715f495e13db098ce7dd3 100644 (file)
--- a/src/shared/xparser.pas
+++ b/src/shared/xparser.pas
// ////////////////////////////////////////////////////////////////////////// //
type
TFileTextParser = class(TTextParser)
+ private
+ const BufSize = 65536;
+
private
mFile: TStream;
+ mBuffer: PChar;
+ mBufLen: Integer;
+ mBufPos: Integer;
protected
procedure loadNextChar (); override; // loads next char into mNextChar; #0 means 'eof'
// ////////////////////////////////////////////////////////////////////////// //
constructor TFileTextParser.Create (const fname: AnsiString; loadToken: Boolean=true);
begin
+ mBuffer := nil;
mFile := openDiskFileRO(fname);
+ GetMem(mBuffer, BufSize);
+ mBufPos := 0;
+ mBufLen := mFile.Read(mBuffer^, BufSize);
+ if (mBufLen < 0) then raise Exception.Create('TFileTextParser: read error');
inherited Create(loadToken);
end;
begin
if (st = nil) then raise Exception.Create('cannot create parser for nil stream');
mFile := st;
+ GetMem(mBuffer, BufSize);
+ mBufPos := 0;
+ mBufLen := mFile.Read(mBuffer^, BufSize);
+ if (mBufLen < 0) then raise Exception.Create('TFileTextParser: read error');
inherited Create(loadToken);
end;
destructor TFileTextParser.Destroy ();
begin
+ if (mBuffer <> nil) then FreeMem(mBuffer);
mFile.Free();
inherited;
end;
procedure TFileTextParser.loadNextChar ();
-var
- rd: Integer;
begin
- rd := mFile.Read(mNextChar, 1);
- if (rd = 0) then begin mNextChar := #0; exit; end;
+ if (mBufLen = 0) then begin mNextChar := #0; exit; end;
+ if (mBufPos >= mBufLen) then
+ begin
+ mBufLen := mFile.Read(mBuffer^, BufSize);
+ if (mBufLen < 0) then raise Exception.Create('TFileTextParser: read error');
+ if (mBufLen = 0) then begin mNextChar := #0; exit; end;
+ mBufPos := 0;
+ end;
+ assert(mBufPos < mBufLen);
+ mNextChar := mBuffer[mBufPos];
+ Inc(mBufPos);
if (mNextChar = #0) then mNextChar := ' ';
end;