{*******************************************************} { } { WHY not a compiler? by Y [05-04-00] } { Low level character stream unit } { } { Copyright (c) 1999-2000 CROWELL, Inc. } { All Rights Reserved. } { } {*******************************************************} unit CIOStream; {$I CDEFINES.PAS} {$IFDEF TPC} {$N+} {$ENDIF} interface uses Objects, CConstants; type {TDoubleBufStream, a low level double buffered character stream} PDoubleBufStream = ^TDoubleBufStream; TDoubleBufStream = object(TBufStream) CharsRemain: Integer; SecondBuffer: array [1..SecondBufferSize] of char; LastChar: Char; CurrentLine, CurrentPos: Integer; constructor Init(FileName: FNameStr; Mode, Size: Word); function GetChar: Char; procedure PutBack(C: Char); end; implementation {TDoubleBufStream} constructor TDoubleBufStream.Init(FileName: FNameStr; Mode, Size: Word); begin inherited Init(FileName, Mode, Size); CurrentLine := 1; CurrentPos := 0; LastChar := #0; {any char but not CR or LF} CharsRemain := 0; end; {TDoubleBufStream.Init} function TDoubleBufStream.GetChar: Char; var TempChar: Char; begin if (CharsRemain > 0) then begin TempChar := SecondBuffer[CharsRemain]; Dec(CharsRemain); end else begin {read new char} Read(TempChar, 1); if (Status = 0) then begin {update current line and position} Inc(CurrentPos); if ((TempChar = CR) and (LastChar <> LF)) or ((TempChar = LF) and (LastChar <> CR)) then begin CurrentPos := 0; Inc(CurrentLine); end; if ((TempChar = CR) and (LastChar = LF)) or ((TempChar = LF) and (LastChar = CR)) then LastChar := #0 {neither CR nor LF} else LastChar := TempChar; end; end; GetChar := TempChar; end; {TDoubleBufStream.GetChar} procedure TDoubleBufStream.PutBack(C: Char); begin if (CharsRemain >= SecondBufferSize) then Status := stNoMorePlace else begin Inc(CharsRemain); SecondBuffer[CharsRemain] := C; end; end; {TDoubleBufStream.ButBack} end {CIOStreams}.