uses\r
Classes,\r
SysUtils,\r
+ Math,\r
Sockets,\r
Generics.Collections,\r
Thrift.Collections,\r
private\r
FStream : IThriftStream;\r
FBufSize : Integer;\r
- FBuffer : TMemoryStream;\r
+ FReadBuffer : TMemoryStream;\r
+ FWriteBuffer : TMemoryStream;\r
protected\r
procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;\r
function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;\r
begin\r
Flush;\r
FStream := nil;\r
- FBuffer.Free;\r
- FBuffer := nil;\r
+\r
+ FReadBuffer.Free;\r
+ FReadBuffer := nil;\r
+\r
+ FWriteBuffer.Free;\r
+ FWriteBuffer := nil;\r
end;\r
\r
constructor TBufferedStreamImpl.Create( const AStream: IThriftStream; ABufSize: Integer);\r
begin\r
FStream := AStream;\r
FBufSize := ABufSize;\r
- FBuffer := TMemoryStream.Create;\r
+ FReadBuffer := TMemoryStream.Create;\r
+ FWriteBuffer := TMemoryStream.Create;\r
end;\r
\r
destructor TBufferedStreamImpl.Destroy;\r
begin\r
if IsOpen then\r
begin\r
- len := FBuffer.Size;\r
+ len := FWriteBuffer.Size;\r
if len > 0 then\r
begin\r
SetLength( buf, len );\r
- FBuffer.Position := 0;\r
- FBuffer.Read( Pointer(@buf[0])^, len );\r
+ FWriteBuffer.Position := 0;\r
+ FWriteBuffer.Read( Pointer(@buf[0])^, len );\r
FStream.Write( buf, 0, len );\r
end;\r
- FBuffer.Clear;\r
+ FWriteBuffer.Clear;\r
end;\r
end;\r
\r
function TBufferedStreamImpl.IsOpen: Boolean;\r
begin\r
- Result := (FBuffer <> nil) and ( FStream <> nil);\r
+ Result := (FWriteBuffer <> nil)\r
+ and (FReadBuffer <> nil)\r
+ and (FStream <> nil);\r
end;\r
\r
procedure TBufferedStreamImpl.Open;\r
begin\r
inherited;\r
Result := 0;\r
- if count > 0 then\r
+ if IsOpen then\r
begin\r
- if IsOpen then\r
- begin\r
- if FBuffer.Position >= FBuffer.Size then\r
+ while count > 0 do begin\r
+\r
+ if FReadBuffer.Position >= FReadBuffer.Size then\r
begin\r
- FBuffer.Clear;\r
+ FReadBuffer.Clear;\r
SetLength( tempbuf, FBufSize);\r
nRead := FStream.Read( tempbuf, 0, FBufSize );\r
- if nRead > 0 then\r
- begin\r
- FBuffer.WriteBuffer( Pointer(@tempbuf[0])^, nRead );\r
- FBuffer.Position := 0;\r
- end;\r
+ if nRead = 0 then Break; // avoid infinite loop\r
+\r
+ FReadBuffer.WriteBuffer( Pointer(@tempbuf[0])^, nRead );\r
+ FReadBuffer.Position := 0;\r
end;\r
\r
- if FBuffer.Position < FBuffer.Size then\r
+ if FReadBuffer.Position < FReadBuffer.Size then\r
begin\r
- Result := FBuffer.Read( Pointer(@buffer[offset])^, count );\r
+ nRead := Min( FReadBuffer.Size - FReadBuffer.Position, count);\r
+ Inc( Result, FReadBuffer.Read( Pointer(@buffer[offset])^, nRead));\r
+ Dec( count, nRead);\r
+ Inc( offset, nRead);\r
end;\r
end;\r
end;\r
\r
if IsOpen then\r
begin\r
- len := FBuffer.Size;\r
+ len := FReadBuffer.Size;\r
end;\r
\r
SetLength( Result, len);\r
\r
if len > 0 then\r
begin\r
- FBuffer.Position := 0;\r
- FBuffer.Read( Pointer(@Result[0])^, len );\r
+ FReadBuffer.Position := 0;\r
+ FReadBuffer.Read( Pointer(@Result[0])^, len );\r
end;\r
end;\r
\r
begin\r
if IsOpen then\r
begin\r
- FBuffer.Write( Pointer(@buffer[offset])^, count );\r
- if FBuffer.Size > FBufSize then\r
+ FWriteBuffer.Write( Pointer(@buffer[offset])^, count );\r
+ if FWriteBuffer.Size > FBufSize then\r
begin\r
Flush;\r
end;\r