THRIFT-4318 Delphi performance improvements
Client: Delphi
Patch: Jens Geyer

This closes #1348
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index 5dfb14e..d20eb2f 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -44,16 +44,20 @@
 
 type
   ITransport = interface
-    ['{A4A9FC37-D620-44DC-AD21-662D16364CE4}']
+    ['{DB84961E-8BB3-4532-99E1-A8C7AC2300F7}']
     function GetIsOpen: Boolean;
     property IsOpen: Boolean read GetIsOpen;
     function Peek: Boolean;
     procedure Open;
     procedure Close;
-    function Read(var buf: TBytes; off: Integer; len: Integer): Integer;
-    function ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer;
+    function Read(var buf: TBytes; off: Integer; len: Integer): Integer; overload;
+    function Read(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload;
+    function ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer; overload;
+    function ReadAll(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload;
     procedure Write( const buf: TBytes); overload;
     procedure Write( const buf: TBytes; off: Integer; len: Integer); overload;
+    procedure Write( const pBuf : Pointer; off, len : Integer); overload;
+    procedure Write( const pBuf : Pointer; len : Integer); overload;
     procedure Flush;
   end;
 
@@ -64,10 +68,14 @@
     function Peek: Boolean; virtual;
     procedure Open(); virtual; abstract;
     procedure Close(); virtual; abstract;
-    function Read(var buf: TBytes; off: Integer; len: Integer): Integer; virtual; abstract;
-    function ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer; virtual;
-    procedure Write( const buf: TBytes); overload; virtual;
-    procedure Write( const buf: TBytes; off: Integer; len: Integer); overload; virtual; abstract;
+    function Read(var buf: TBytes; off: Integer; len: Integer): Integer; overload; inline;
+    function Read(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload; virtual; abstract;
+    function ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer;  overload; inline;
+    function ReadAll(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload; virtual;
+    procedure Write( const buf: TBytes); overload; inline;
+    procedure Write( const buf: TBytes; off: Integer; len: Integer); overload; inline;
+    procedure Write( const pBuf : Pointer; len : Integer); overload; inline;
+    procedure Write( const pBuf : Pointer; off, len : Integer); overload; virtual; abstract;
     procedure Flush; virtual;
   end;
 
@@ -135,8 +143,8 @@
     function GetIsOpen: Boolean; override;
     procedure Open(); override;
     procedure Close(); override;
-    function Read( var buf: TBytes; off: Integer; len: Integer): Integer; override;
-    procedure Write( const buf: TBytes; off: Integer; len: Integer); override;
+    function  Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
+    procedure Write( const pBuf : Pointer; off, len : Integer); override;
     procedure Flush; override;
 
     procedure SetConnectionTimeout(const Value: Integer);
@@ -193,8 +201,8 @@
     SLEEP_TIME = 200;
 {$ENDIF}
   protected
-    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
-    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
+    procedure Write( const pBuf : Pointer; offset, count: Integer); override;
+    function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override;
     procedure Open; override;
     procedure Close; override;
     procedure Flush; override;
@@ -233,8 +241,8 @@
     procedure Open; override;
     procedure Close; override;
     procedure Flush; override;
-    function Read(var buf: TBytes; off: Integer; len: Integer): Integer; override;
-    procedure Write( const buf: TBytes; off: Integer; len: Integer); override;
+    function  Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
+    procedure Write( const pBuf : Pointer; off, len : Integer); override;
     constructor Create( const AInputStream : IThriftStream; const AOutputStream : IThriftStream);
     destructor Destroy; override;
   end;
@@ -246,8 +254,8 @@
     FReadBuffer : TMemoryStream;
     FWriteBuffer : TMemoryStream;
   protected
-    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
-    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
+    procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override;
+    function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override;
     procedure Open;  override;
     procedure Close; override;
     procedure Flush; override;
@@ -299,8 +307,8 @@
   public
     procedure Open(); override;
     procedure Close(); override;
-    function Read(var buf: TBytes; off: Integer; len: Integer): Integer; override;
-    procedure Write( const buf: TBytes; off: Integer; len: Integer); override;
+    function  Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
+    procedure Write( const pBuf : Pointer; off, len : Integer); override;
     constructor Create( const ATransport : IStreamTransport ); overload;
     constructor Create( const ATransport : IStreamTransport; ABufSize: Integer); overload;
     property UnderlyingTransport: ITransport read GetUnderlyingTransport;
@@ -377,8 +385,8 @@
     function GetIsOpen: Boolean; override;
 
     procedure Close(); override;
-    function Read(var buf: TBytes; off: Integer; len: Integer): Integer; override;
-    procedure Write( const buf: TBytes; off: Integer; len: Integer); override;
+    function  Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
+    procedure Write( const pBuf : Pointer; off, len : Integer); override;
     procedure Flush; override;
   end;
 
@@ -404,24 +412,41 @@
   Result := IsOpen;
 end;
 
-function TTransportImpl.ReadAll( var buf: TBytes; off, len: Integer): Integer;
-var
-  got : Integer;
-  ret : Integer;
+function TTransportImpl.Read(var buf: TBytes; off: Integer; len: Integer): Integer;
 begin
-  got := 0;
-  while got < len do begin
-    ret := Read( buf, off + got, len - got);
-    if ret > 0 
-    then Inc( got, ret)
-    else raise TTransportExceptionNotOpen.Create( 'Cannot read, Remote side has closed' );
-  end;
-  Result := got;
+  result := Read( @buf[0], Length(buf), off, len);
+end;
+
+function TTransportImpl.ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer;
+begin
+  result := ReadAll( @buf[0], Length(buf), off, len);
 end;
 
 procedure TTransportImpl.Write( const buf: TBytes);
 begin
-  Self.Write( buf, 0, Length(buf) );
+  Write( @buf[0], 0, Length(buf));
+end;
+
+procedure TTransportImpl.Write( const buf: TBytes; off: Integer; len: Integer);
+begin
+  Write( @buf[0], off, len);
+end;
+
+function TTransportImpl.ReadAll(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
+var ret : Integer;
+begin
+  result := 0;
+  while result < len do begin
+    ret := Read( pBuf, buflen, off + result, len - result);
+    if ret > 0
+    then Inc( result, ret)
+    else raise TTransportExceptionNotOpen.Create( 'Cannot read, Remote side has closed' );
+  end;
+end;
+
+procedure TTransportImpl.Write( const pBuf : Pointer; len : Integer);
+begin
+  Self.Write( pBuf, 0, len);
 end;
 
 { THTTPClientImpl }
@@ -501,14 +526,14 @@
   // nothing to do
 end;
 
-function THTTPClientImpl.Read( var buf: TBytes; off, len: Integer): Integer;
+function THTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
 begin
   if FInputStream = nil then begin
     raise TTransportExceptionNotOpen.Create('No request has been sent');
   end;
 
   try
-    Result := FInputStream.Read( buf, off, len )
+    Result := FInputStream.Read( pBuf, buflen, off, len)
   except
     on E: Exception
     do raise TTransportExceptionUnknown.Create(E.Message);
@@ -550,9 +575,9 @@
   FReadTimeout := Value
 end;
 
-procedure THTTPClientImpl.Write( const buf: TBytes; off, len: Integer);
+procedure THTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer);
 begin
-  FOutputStream.Write( buf, off, len);
+  FOutputStream.Write( pBuf, off, len);
 end;
 
 { TTransportException }
@@ -931,7 +956,7 @@
   // nothing to do
 end;
 
-function TBufferedStreamImpl.Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
+function TBufferedStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
 var
   nRead : Integer;
   tempbuf : TBytes;
@@ -954,7 +979,7 @@
 
       if FReadBuffer.Position < FReadBuffer.Size then begin
         nRead  := Min( FReadBuffer.Size - FReadBuffer.Position, count);
-        Inc( Result, FReadBuffer.Read( Pointer(@buffer[offset])^, nRead));
+        Inc( Result, FReadBuffer.Read( PByteArray(pBuf)^[offset], nRead));
         Dec( count, nRead);
         Inc( offset, nRead);
       end;
@@ -979,12 +1004,12 @@
   end;
 end;
 
-procedure TBufferedStreamImpl.Write( const buffer: TBytes; offset: Integer; count: Integer);
+procedure TBufferedStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: Integer);
 begin
   inherited;
   if count > 0 then begin
     if IsOpen then begin
-      FWriteBuffer.Write( Pointer(@buffer[offset])^, count );
+      FWriteBuffer.Write( PByteArray(pBuf)^[offset], count );
       if FWriteBuffer.Size > FBufSize then begin
         Flush;
       end;
@@ -1043,22 +1068,22 @@
 
 end;
 
-function TStreamTransportImpl.Read(var buf: TBytes; off, len: Integer): Integer;
+function TStreamTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
 begin
   if FInputStream = nil then begin
     raise TTransportExceptionNotOpen.Create('Cannot read from null inputstream' );
   end;
 
-  Result := FInputStream.Read( buf, off, len );
+  Result := FInputStream.Read( pBuf,buflen, off, len );
 end;
 
-procedure TStreamTransportImpl.Write(const buf: TBytes; off, len: Integer);
+procedure TStreamTransportImpl.Write( const pBuf : Pointer; off, len : Integer);
 begin
   if FOutputStream = nil then begin
     raise TTransportExceptionNotOpen.Create('Cannot write to null outputstream' );
   end;
 
-  FOutputStream.Write( buf, off, len );
+  FOutputStream.Write( pBuf, off, len );
 end;
 
 { TBufferedTransportImpl }
@@ -1114,18 +1139,18 @@
   FTransport.Open
 end;
 
-function TBufferedTransportImpl.Read(var buf: TBytes; off, len: Integer): Integer;
+function TBufferedTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
 begin
   Result := 0;
   if FInputBuffer <> nil then begin
-    Result := FInputBuffer.Read( buf, off, len );
+    Result := FInputBuffer.Read( pBuf,buflen, off, len );
   end;
 end;
 
-procedure TBufferedTransportImpl.Write(const buf: TBytes; off, len: Integer);
+procedure TBufferedTransportImpl.Write( const pBuf : Pointer; off, len : Integer);
 begin
   if FOutputBuffer <> nil then begin
-    FOutputBuffer.Write( buf, off, len );
+    FOutputBuffer.Write( pBuf, off, len );
   end;
 end;
 
@@ -1222,24 +1247,21 @@
   FTransport.Open;
 end;
 
-function TFramedTransportImpl.Read(var buf: TBytes; off, len: Integer): Integer;
-var
-  got : Integer;
+function TFramedTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
 begin
-  if FReadBuffer <> nil then begin
-    if len > 0
-    then got := FReadBuffer.Read( Pointer(@buf[off])^, len )
-    else got := 0;
-	
-    if got > 0 then begin
-      Result := got;
+  if len > (buflen-off)
+  then len := buflen-off;
+
+  if (FReadBuffer <> nil) and (len > 0) then begin
+    result := FReadBuffer.Read( PByteArray(pBuf)^[off], len);
+    if result > 0 then begin
       Exit;
     end;
   end;
 
   ReadFrame;
   if len > 0
-  then Result := FReadBuffer.Read( Pointer(@buf[off])^, len)
+  then Result := FReadBuffer.Read( PByteArray(pBuf)^[off], len)
   else Result := 0;
 end;
 
@@ -1264,10 +1286,10 @@
   FReadBuffer.Position := 0;
 end;
 
-procedure TFramedTransportImpl.Write(const buf: TBytes; off, len: Integer);
+procedure TFramedTransportImpl.Write( const pBuf : Pointer; off, len : Integer);
 begin
   if len > 0
-  then FWriteBuffer.Write( Pointer(@buf[off])^, len );
+  then FWriteBuffer.Write( PByteArray(pBuf)^[off], len );
 end;
 
 { TFramedTransport.TFactory }
@@ -1447,7 +1469,7 @@
 {$ENDIF}
 
 {$IFDEF OLD_SOCKETS}
-function TTcpSocketStreamImpl.Read(var buffer: TBytes; offset, count: Integer): Integer;
+function TTcpSocketStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
 // old sockets version
 var wfd : TWaitForData;
     wsaError,
@@ -1462,7 +1484,7 @@
   else msecs := DEFAULT_THRIFT_TIMEOUT;
 
   result := 0;
-  pDest := Pointer(@buffer[offset]);
+  pDest := @(PByteArray(pBuf)^[offset]);
   while count > 0 do begin
 
     while TRUE do begin
@@ -1513,7 +1535,7 @@
   end;
 end;
 
-procedure TTcpSocketStreamImpl.Write(const buffer: TBytes; offset, count: Integer);
+procedure TTcpSocketStreamImpl.Write( const pBuf : Pointer; offset, count: Integer);
 // old sockets version
 var bCanWrite, bError : Boolean;
     retval, wsaError : Integer;
@@ -1537,12 +1559,12 @@
   if bError or not bCanWrite
   then raise TTransportExceptionUnknown.Create('unknown error');
 
-  FTcpClient.SendBuf( Pointer(@buffer[offset])^, count);
+  FTcpClient.SendBuf( PByteArray(pBuf)^[offset], count);
 end;
 
 {$ELSE}
 
-function TTcpSocketStreamImpl.Read(var buffer: TBytes; offset, count: Integer): Integer;
+function TTcpSocketStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
 // new sockets version
 var nBytes : Integer;
     pDest : PByte;
@@ -1550,7 +1572,7 @@
   inherited;
 
   result := 0;
-  pDest := Pointer(@buffer[offset]);
+  pDest := @(PByteArray(pBuf)^[offset]);
   while count > 0 do begin
     nBytes := FTcpClient.Read(pDest^, count);
     if nBytes = 0 then Exit;
@@ -1579,7 +1601,7 @@
     SetLength(Result, Length(Result) - 1024 + len);
 end;
 
-procedure TTcpSocketStreamImpl.Write(const buffer: TBytes; offset, count: Integer);
+procedure TTcpSocketStreamImpl.Write( const pBuf : Pointer; offset, count: Integer);
 // new sockets version
 begin
   inherited;
@@ -1587,7 +1609,7 @@
   if not FTcpClient.IsOpen
   then raise TTransportExceptionNotOpen.Create('not open');
 
-  FTcpClient.Write(buffer[offset], count);
+  FTcpClient.Write( PByteArray(pBuf)^[offset], count);
 end;
 
 {$ENDIF}