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

This closes #1348
diff --git a/lib/delphi/src/Thrift.Stream.pas b/lib/delphi/src/Thrift.Stream.pas
index 7c448d8..1d357c3 100644
--- a/lib/delphi/src/Thrift.Stream.pas
+++ b/lib/delphi/src/Thrift.Stream.pas
@@ -38,9 +38,11 @@
 type
 
   IThriftStream = interface
-    ['{732621B3-F697-4D76-A1B0-B4DD5A8E4018}']
-    procedure Write( const buffer: TBytes; offset: Integer; count: Integer);
-    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
+    ['{2A77D916-7446-46C1-8545-0AEC0008DBCA}']
+    procedure Write( const buffer: TBytes; offset: Integer; count: Integer);  overload;
+    procedure Write( const pBuf : Pointer; offset: Integer; count: Integer);  overload;
+    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;  overload;
+    function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;  overload;
     procedure Open;
     procedure Close;
     procedure Flush;
@@ -50,10 +52,12 @@
 
   TThriftStreamImpl = class( TInterfacedObject, IThriftStream)
   private
-    procedure CheckSizeAndOffset( const buffer: TBytes; offset: Integer; count: Integer);
+    procedure CheckSizeAndOffset( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer);  overload;
   protected
-    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); virtual;
-    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; virtual;
+    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); overload; inline;
+    procedure Write( const pBuf : Pointer; offset: Integer; count: Integer);  overload; virtual;
+    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; overload; inline;
+    function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; overload; virtual;
     procedure Open; virtual; abstract;
     procedure Close; virtual; abstract;
     procedure Flush; virtual; abstract;
@@ -66,8 +70,8 @@
     FStream : TStream;
     FOwnsStream : Boolean;
   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;
@@ -82,8 +86,8 @@
   private
     FStream : IStream;
   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;
@@ -127,13 +131,17 @@
   // nothing to do
 end;
 
-function TThriftStreamAdapterCOM.Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
+function TThriftStreamAdapterCOM.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
 begin
   inherited;
+
+  if count >= buflen-offset
+  then count := buflen-offset;
+
   Result := 0;
   if FStream <> nil then begin
     if count > 0 then begin
-      FStream.Read( @buffer[offset], count, @Result);
+      FStream.Read( @(PByteArray(pBuf)^[offset]), count, @Result);
     end;
   end;
 end;
@@ -162,30 +170,26 @@
   end;
 end;
 
-procedure TThriftStreamAdapterCOM.Write( const buffer: TBytes; offset: Integer; count: Integer);
+procedure TThriftStreamAdapterCOM.Write( const pBuf: Pointer; offset: Integer; count: Integer);
 var nWritten : Integer;
 begin
   inherited;
   if IsOpen then begin
     if count > 0 then begin
-      FStream.Write( @buffer[0], count, @nWritten);
+      FStream.Write( @(PByteArray(pBuf)^[offset]), count, @nWritten);
     end;
   end;
 end;
 
 { TThriftStreamImpl }
 
-procedure TThriftStreamImpl.CheckSizeAndOffset(const buffer: TBytes; offset,
-  count: Integer);
-var
-  len : Integer;
+procedure TThriftStreamImpl.CheckSizeAndOffset( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer);
 begin
   if count > 0 then begin
-    len := Length( buffer );
-    if (offset < 0) or ( offset >= len) then begin
+    if (offset < 0) or ( offset >= buflen) then begin
       raise ERangeError.Create( SBitsIndexError );
     end;
-    if count > len then begin
+    if count > buflen then begin
       raise ERangeError.Create( SBitsIndexError );
     end;
   end;
@@ -193,13 +197,23 @@
 
 function TThriftStreamImpl.Read(var buffer: TBytes; offset, count: Integer): Integer;
 begin
+  Result := Read( @buffer[0], Length(buffer), offset, count);
+end;
+
+function TThriftStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
+begin
   Result := 0;
-  CheckSizeAndOffset( buffer, offset, count );
+  CheckSizeAndOffset( pBuf, buflen, offset, count );
 end;
 
 procedure TThriftStreamImpl.Write(const buffer: TBytes; offset, count: Integer);
 begin
-  CheckSizeAndOffset( buffer, offset, count );
+  Write( @buffer[0], offset, count);
+end;
+
+procedure TThriftStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: Integer);
+begin
+  CheckSizeAndOffset( pBuf, offset+count, offset, count);
 end;
 
 { TThriftStreamAdapterDelphi }
@@ -241,14 +255,16 @@
   // nothing to do
 end;
 
-function TThriftStreamAdapterDelphi.Read(var buffer: TBytes; offset,
-  count: Integer): Integer;
+function TThriftStreamAdapterDelphi.Read(const pBuf : Pointer; const buflen : Integer; offset, count: Integer): Integer;
 begin
   inherited;
-  Result := 0;
-  if count > 0 then begin
-    Result := FStream.Read( Pointer(@buffer[offset])^, count)
-  end;
+
+  if count >= buflen-offset
+  then count := buflen-offset;
+
+  if count > 0
+  then Result := FStream.Read( PByteArray(pBuf)^[offset], count)
+  else Result := 0;
 end;
 
 function TThriftStreamAdapterDelphi.ToArray: TBytes;
@@ -276,12 +292,11 @@
   end
 end;
 
-procedure TThriftStreamAdapterDelphi.Write(const buffer: TBytes; offset,
-  count: Integer);
+procedure TThriftStreamAdapterDelphi.Write(const pBuf : Pointer; offset, count: Integer);
 begin
   inherited;
   if count > 0 then begin
-    FStream.Write( Pointer(@buffer[offset])^, count)
+    FStream.Write( PByteArray(pBuf)^[offset], count)
   end;
 end;