| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- unit CnBuffStr;
- interface
- uses
- Classes, SysUtils;
- type
- TStringReader = class(TObject)
- private
- FBuffer: string;
- FPosition: Integer;
- public
- constructor Create(const S: string); overload;
- constructor Create; overload;
- procedure Reset(const S: string);
- function Seek(Offset: Integer; Origin: Word): Longint;
- function EoS: Boolean;
- procedure LoadFromFile(FileName: TFileName);
- procedure LoadFromStream(Stream: TStream);
- function Peep: Char;
- function At(Position: Integer): Char;
- function Read: Char; overload;
- function Read(Count: Integer): string; overload;
- function ReadLn: string;
- function SubString(Index, Count: Integer): string;
- procedure Unread;
- property Buffer: string read FBuffer;
- property Position: Integer read FPosition;
- end;
- TStringWriter = class(TObject)
- private
- FBuffer: string;
- FPosition: Integer;
- procedure Extend(I: Integer);
- function GetBuffer: string;
- public
- constructor Create(I: Integer); overload;
- constructor Create; overload;
- procedure Reset(I: Integer);
- procedure SaveToFile(FileName: TFileName);
- procedure SaveToStream(Stream: TStream);
- procedure Unwrite;
- procedure Write(Ch : Char); overload;
- procedure Write(const S: string); overload;
- procedure WriteLn; overload;
- procedure WriteLn(const S: string); overload;
- property Buffer: string read GetBuffer;
- end;
- implementation
- { TStringReader }
- function TStringReader.At(Position: Integer): Char;
- begin
- Result := PChar(FBuffer)[Position];
- end;
- constructor TStringReader.Create(const S: string);
- begin
- inherited Create();
- Reset(S);
- end;
- constructor TStringReader.Create;
- begin
- Create('');
- end;
- function TStringReader.EoS: Boolean;
- begin
- Result := PChar(FBuffer)[FPosition] = #0;
- end;
- procedure TStringReader.LoadFromFile(FileName: TFileName);
- var
- Stream: TStream;
- begin
- Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
- try
- LoadFromStream(Stream);
- finally
- Stream.Free;
- end;
- end;
- procedure TStringReader.LoadFromStream(Stream: TStream);
- var
- Size: Integer;
- S: string;
- begin
- Size := Stream.Size - Stream.Position;
- SetString(S, nil, Size);
- Stream.Read(Pointer(S)^, Size);
- FBuffer := S;
- FPosition := 0;
- end;
- function TStringReader.Peep: Char;
- begin
- Result := PChar(FBuffer)[Position];
- end;
- function TStringReader.Read: Char;
- begin
- Result := PChar(FBuffer)[FPosition];
- if Result <> #0 then Inc(FPosition);
- end;
- function TStringReader.Read(Count: Integer): string;
- var
- Len: Integer;
- begin
- Len := Length(FBuffer) - FPosition;
- if Len > Count then Len := Count;
- SetString(Result, PChar(@FBuffer[FPosition + 1]), Len);
- Inc(FPosition, Len);
- end;
- function TStringReader.ReadLn: string;
- var
- P: LongInt;
- begin
- P := FPosition;
- while not (PChar(FBuffer)[P] in [#0, #13, #10]) do Inc(P);
- SetString(Result, PChar(@FBuffer[FPosition + 1]), P - FPosition);
- if PChar(FBuffer)[P] = #13 then Inc(P);
- if PChar(FBuffer)[P] = #10 then Inc(P);
- FPosition := P;
- end;
- procedure TStringReader.Reset(const S: string);
- begin
- FBuffer := S;
- FPosition := 0;
- end;
- function TStringReader.Seek(Offset: Integer; Origin: Word): Longint;
- begin
- case Origin of
- soFromBeginning: FPosition := Offset;
- soFromCurrent: FPosition := FPosition + Offset;
- soFromEnd: FPosition := Length(FBuffer) - Offset;
- end;
- if FPosition > Length(FBuffer) then
- FPosition := Length(FBuffer)
- else if FPosition < 0 then FPosition := 0;
- Result := FPosition;
- end;
- function TStringReader.SubString(Index, Count: Integer): string;
- begin
- Result := Copy(FBuffer, Index + 1, Count);
- end;
- procedure TStringReader.Unread;
- begin
- if FPosition > 0 then Dec(FPosition);
- end;
- { TStringWriter }
- constructor TStringWriter.Create(I: Integer);
- begin
- inherited Create();
- Reset(I);
- end;
- constructor TStringWriter.Create;
- begin
- Create(4000);
- end;
- procedure TStringWriter.Extend(I: Integer);
- begin
- if I < 4096 then I := 4096
- else I := I + I shr 1;
- SetLength(FBuffer, I);
- end;
- function TStringWriter.GetBuffer: string;
- begin
- if FPosition = Length(FBuffer) then Result := FBuffer
- else SetString(Result, PChar(@FBuffer[1]), FPosition);
- end;
- procedure TStringWriter.Reset(I: Integer);
- begin
- SetLength(FBuffer, I);
- FPosition := 0;
- end;
- procedure TStringWriter.SaveToFile(FileName: TFileName);
- var
- Stream: TStream;
- begin
- Stream := TFileStream.Create(FileName, fmCreate);
- try
- SaveToStream(Stream);
- finally
- Stream.Free;
- end;
- end;
- procedure TStringWriter.SaveToStream(Stream: TStream);
- begin
- Stream.WriteBuffer(Pointer(FBuffer)^, FPosition);
- end;
- procedure TStringWriter.Unwrite;
- begin
- if FPosition > 0 then Dec(FPosition);
- end;
- procedure TStringWriter.Write(const S: string);
- var
- I: Integer;
- begin
- I := FPosition + Length(S);
- if I > Length(FBuffer) then Extend(I);
- for I := 1 to Length(S) do
- begin
- PChar(FBuffer)[FPosition] := S[I];
- Inc(FPosition, 1);
- end;
- end;
- procedure TStringWriter.Write(Ch: Char);
- var
- I: Integer;
- begin
- I := FPosition + 1;
- if I > Length(FBuffer) then Extend(I);
- PChar(FBuffer)[FPosition] := Ch;
- Inc(FPosition);
- end;
- procedure TStringWriter.WriteLn;
- begin
- Write(#13);
- Write(#10);
- end;
- procedure TStringWriter.WriteLn(const S: string);
- begin
- Write(S);
- Write(#13);
- Write(#10);
- end;
- end.
|