CnBuffStr.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. unit CnBuffStr;
  2. interface
  3. uses
  4. Classes, SysUtils;
  5. type
  6. TStringReader = class(TObject)
  7. private
  8. FBuffer: string;
  9. FPosition: Integer;
  10. public
  11. constructor Create(const S: string); overload;
  12. constructor Create; overload;
  13. procedure Reset(const S: string);
  14. function Seek(Offset: Integer; Origin: Word): Longint;
  15. function EoS: Boolean;
  16. procedure LoadFromFile(FileName: TFileName);
  17. procedure LoadFromStream(Stream: TStream);
  18. function Peep: Char;
  19. function At(Position: Integer): Char;
  20. function Read: Char; overload;
  21. function Read(Count: Integer): string; overload;
  22. function ReadLn: string;
  23. function SubString(Index, Count: Integer): string;
  24. procedure Unread;
  25. property Buffer: string read FBuffer;
  26. property Position: Integer read FPosition;
  27. end;
  28. TStringWriter = class(TObject)
  29. private
  30. FBuffer: string;
  31. FPosition: Integer;
  32. procedure Extend(I: Integer);
  33. function GetBuffer: string;
  34. public
  35. constructor Create(I: Integer); overload;
  36. constructor Create; overload;
  37. procedure Reset(I: Integer);
  38. procedure SaveToFile(FileName: TFileName);
  39. procedure SaveToStream(Stream: TStream);
  40. procedure Unwrite;
  41. procedure Write(Ch : Char); overload;
  42. procedure Write(const S: string); overload;
  43. procedure WriteLn; overload;
  44. procedure WriteLn(const S: string); overload;
  45. property Buffer: string read GetBuffer;
  46. end;
  47. implementation
  48. { TStringReader }
  49. function TStringReader.At(Position: Integer): Char;
  50. begin
  51. Result := PChar(FBuffer)[Position];
  52. end;
  53. constructor TStringReader.Create(const S: string);
  54. begin
  55. inherited Create();
  56. Reset(S);
  57. end;
  58. constructor TStringReader.Create;
  59. begin
  60. Create('');
  61. end;
  62. function TStringReader.EoS: Boolean;
  63. begin
  64. Result := PChar(FBuffer)[FPosition] = #0;
  65. end;
  66. procedure TStringReader.LoadFromFile(FileName: TFileName);
  67. var
  68. Stream: TStream;
  69. begin
  70. Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  71. try
  72. LoadFromStream(Stream);
  73. finally
  74. Stream.Free;
  75. end;
  76. end;
  77. procedure TStringReader.LoadFromStream(Stream: TStream);
  78. var
  79. Size: Integer;
  80. S: string;
  81. begin
  82. Size := Stream.Size - Stream.Position;
  83. SetString(S, nil, Size);
  84. Stream.Read(Pointer(S)^, Size);
  85. FBuffer := S;
  86. FPosition := 0;
  87. end;
  88. function TStringReader.Peep: Char;
  89. begin
  90. Result := PChar(FBuffer)[Position];
  91. end;
  92. function TStringReader.Read: Char;
  93. begin
  94. Result := PChar(FBuffer)[FPosition];
  95. if Result <> #0 then Inc(FPosition);
  96. end;
  97. function TStringReader.Read(Count: Integer): string;
  98. var
  99. Len: Integer;
  100. begin
  101. Len := Length(FBuffer) - FPosition;
  102. if Len > Count then Len := Count;
  103. SetString(Result, PChar(@FBuffer[FPosition + 1]), Len);
  104. Inc(FPosition, Len);
  105. end;
  106. function TStringReader.ReadLn: string;
  107. var
  108. P: LongInt;
  109. begin
  110. P := FPosition;
  111. while not (PChar(FBuffer)[P] in [#0, #13, #10]) do Inc(P);
  112. SetString(Result, PChar(@FBuffer[FPosition + 1]), P - FPosition);
  113. if PChar(FBuffer)[P] = #13 then Inc(P);
  114. if PChar(FBuffer)[P] = #10 then Inc(P);
  115. FPosition := P;
  116. end;
  117. procedure TStringReader.Reset(const S: string);
  118. begin
  119. FBuffer := S;
  120. FPosition := 0;
  121. end;
  122. function TStringReader.Seek(Offset: Integer; Origin: Word): Longint;
  123. begin
  124. case Origin of
  125. soFromBeginning: FPosition := Offset;
  126. soFromCurrent: FPosition := FPosition + Offset;
  127. soFromEnd: FPosition := Length(FBuffer) - Offset;
  128. end;
  129. if FPosition > Length(FBuffer) then
  130. FPosition := Length(FBuffer)
  131. else if FPosition < 0 then FPosition := 0;
  132. Result := FPosition;
  133. end;
  134. function TStringReader.SubString(Index, Count: Integer): string;
  135. begin
  136. Result := Copy(FBuffer, Index + 1, Count);
  137. end;
  138. procedure TStringReader.Unread;
  139. begin
  140. if FPosition > 0 then Dec(FPosition);
  141. end;
  142. { TStringWriter }
  143. constructor TStringWriter.Create(I: Integer);
  144. begin
  145. inherited Create();
  146. Reset(I);
  147. end;
  148. constructor TStringWriter.Create;
  149. begin
  150. Create(4000);
  151. end;
  152. procedure TStringWriter.Extend(I: Integer);
  153. begin
  154. if I < 4096 then I := 4096
  155. else I := I + I shr 1;
  156. SetLength(FBuffer, I);
  157. end;
  158. function TStringWriter.GetBuffer: string;
  159. begin
  160. if FPosition = Length(FBuffer) then Result := FBuffer
  161. else SetString(Result, PChar(@FBuffer[1]), FPosition);
  162. end;
  163. procedure TStringWriter.Reset(I: Integer);
  164. begin
  165. SetLength(FBuffer, I);
  166. FPosition := 0;
  167. end;
  168. procedure TStringWriter.SaveToFile(FileName: TFileName);
  169. var
  170. Stream: TStream;
  171. begin
  172. Stream := TFileStream.Create(FileName, fmCreate);
  173. try
  174. SaveToStream(Stream);
  175. finally
  176. Stream.Free;
  177. end;
  178. end;
  179. procedure TStringWriter.SaveToStream(Stream: TStream);
  180. begin
  181. Stream.WriteBuffer(Pointer(FBuffer)^, FPosition);
  182. end;
  183. procedure TStringWriter.Unwrite;
  184. begin
  185. if FPosition > 0 then Dec(FPosition);
  186. end;
  187. procedure TStringWriter.Write(const S: string);
  188. var
  189. I: Integer;
  190. begin
  191. I := FPosition + Length(S);
  192. if I > Length(FBuffer) then Extend(I);
  193. for I := 1 to Length(S) do
  194. begin
  195. PChar(FBuffer)[FPosition] := S[I];
  196. Inc(FPosition, 1);
  197. end;
  198. end;
  199. procedure TStringWriter.Write(Ch: Char);
  200. var
  201. I: Integer;
  202. begin
  203. I := FPosition + 1;
  204. if I > Length(FBuffer) then Extend(I);
  205. PChar(FBuffer)[FPosition] := Ch;
  206. Inc(FPosition);
  207. end;
  208. procedure TStringWriter.WriteLn;
  209. begin
  210. Write(#13);
  211. Write(#10);
  212. end;
  213. procedure TStringWriter.WriteLn(const S: string);
  214. begin
  215. Write(S);
  216. Write(#13);
  217. Write(#10);
  218. end;
  219. end.