X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2Fxparser.pas;h=d0f0d3af202bef33b10715f495e13db098ce7dd3;hb=223356cbae3197afc861efa6241c4ae91bd92885;hp=d8b600dbc1d6340a0a16c9b8017dfde7bd9f401a;hpb=ee55194b1f1e2a8721038eff788b64534393661c;p=d2df-sdl.git diff --git a/src/shared/xparser.pas b/src/shared/xparser.pas index d8b600d..d0f0d3a 100644 --- a/src/shared/xparser.pas +++ b/src/shared/xparser.pas @@ -102,8 +102,14 @@ type // ////////////////////////////////////////////////////////////////////////// // 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' @@ -587,7 +593,12 @@ end; // ////////////////////////////////////////////////////////////////////////// // 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; @@ -596,23 +607,35 @@ constructor TFileTextParser.Create (st: TStream; loadToken: Boolean=true); 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;