unit uRODLLineStream; {----------------------------------------------------------------------------} { RemObjects SDK Library - CodeGen2 } { } { compiler: Delphi 5 and up, Kylix 2 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the RemObjects SDK } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$IFNDEF MSWINDOWS} {$I ../RemObjects.inc} {$ELSE} {$I ..\RemObjects.inc} {$ENDIF} interface uses Classes, SysUtils; type {$IFDEF UNICODE} TROStringStream = class(TStream) private FDataString: string; FPosition: Integer; protected procedure SetSize(NewSize: Longint); override; public constructor Create(const AString: string); function Read(var Buffer; Count: Longint): Longint; override; function ReadString(Count: Longint): string; function Seek(Offset: Longint; Origin: Word): Longint; override; function Write(const Buffer; Count: Longint): Longint; override; procedure WriteString(const AString: string); property DataString: string read FDataString; end; {$ELSE} TROStringStream = TStringStream; {$ENDIF} TLineStream = class(TROStringStream) private function GetEof: Boolean; public function ReadLine: string; procedure WriteLine(const line: string); procedure Clear; property Eof: Boolean read GetEof; end; implementation {$IFDEF UNICODE} { TROStringStream } constructor TROStringStream.Create(const AString: string); begin inherited Create; FDataString := AString; end; function TROStringStream.Read(var Buffer; Count: Integer): Longint; begin Result := Length(FDataString) - FPosition; if Result > Count then Result := Count; Move(PChar(@FDataString[FPosition + 1])^, Buffer, Result * SizeOf(Char)); Inc(FPosition, Result); end; function TROStringStream.ReadString(Count: Integer): string; var Len: Integer; begin Len := Length(FDataString) - FPosition; if Len > Count then Len := Count; SetString(Result, PChar(@FDataString[FPosition + 1]), Len); Inc(FPosition, Len); end; function TROStringStream.Seek(Offset: Integer; Origin: Word): Longint; begin case Origin of soFromBeginning: FPosition := Offset; soFromCurrent: FPosition := FPosition + Offset; soFromEnd: FPosition := Length(FDataString) - Offset; end; if FPosition > Length(FDataString) then FPosition := Length(FDataString) else if FPosition < 0 then FPosition := 0; Result := FPosition; end; procedure TROStringStream.SetSize(NewSize: Integer); begin SetLength(FDataString, NewSize); if FPosition > NewSize then FPosition := NewSize; end; function TROStringStream.Write(const Buffer; Count: Integer): Longint; begin Result := Count; SetLength(FDataString, (FPosition + Result)); Move(Buffer, PChar(@FDataString[FPosition + 1])^, Result * SizeOf(Char)); Inc(FPosition, Result); end; procedure TROStringStream.WriteString(const AString: string); begin Write(PChar(AString)^, Length(AString)); end; {$ENDIF} { TLineStream } procedure TLineStream.Clear; begin Size := 0; end; function TLineStream.GetEof: Boolean; begin Result := Position = Size; end; function TLineStream.ReadLine: string; var I: Integer; begin I := Position; while (I < Size-1) and (DataString[I+1] <> #13) and (DataString[I+2] <> #10) do Inc(I); if I = Size-1 then begin Result := ReadString(I-Position+1); end else begin Result := ReadString(I-Position+2); // Do not eat the carriage return end; Result := TrimRight(Result); if Pos('////',Trim(Result)) = 1 then Result := ReadLine; end; procedure TLineStream.WriteLine(const line: string); begin WriteString(line + #13#10); end; end.