THRIFT-5765 Extra override for WriteBinary() to avoid unnecessary memory allocations when using COM types
Client: Delphi
Patch: JensG
diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas
index 80f1ce5..a8ad53a 100644
--- a/lib/delphi/src/Thrift.Protocol.Compact.pas
+++ b/lib/delphi/src/Thrift.Protocol.Compact.pas
@@ -176,6 +176,7 @@
     procedure WriteI64( const i64: Int64); override;
     procedure WriteDouble( const dub: Double); override;
     procedure WriteBinary( const b: TBytes); overload; override;
+    procedure WriteBinary( const bytes : IThriftBytes); overload; override;
     procedure WriteUuid( const uuid: TGuid); override;
 
   private  // unit visible stuff
@@ -542,6 +543,14 @@
   Transport.Write( b);
 end;
 
+
+procedure TCompactProtocolImpl.WriteBinary( const bytes : IThriftBytes);
+begin
+  WriteVarint32( Cardinal(bytes.Count));
+  Transport.Write( bytes.QueryRawDataPtr, 0, bytes.Count);
+end;
+
+
 procedure TCompactProtocolImpl.WriteUuid( const uuid: TGuid);
 var network : TGuid;  // in network order (Big Endian)
 begin
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 4c02d3f..fd92da9 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -443,6 +443,7 @@
     procedure WriteI64( const i64: Int64); override;
     procedure WriteDouble( const d: Double); override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteBinary( const bytes : IThriftBytes); overload; override;
     procedure WriteUuid( const uuid: TGuid); override;
 
     function ReadMessageBegin: TThriftMessage; override;
@@ -509,6 +510,7 @@
     procedure WriteString( const s: string ); override;
     procedure WriteAnsiString( const s: AnsiString); override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteBinary( const bytes : IThriftBytes); overload; override;
     procedure WriteUuid( const uuid: TGuid); override;
 
     function ReadMessageBegin: TThriftMessage; override;
@@ -749,6 +751,8 @@
 
 
 procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
+// This implementation works, but is rather inefficient due to the extra memory allocation
+// Consider overwriting this for your transport implementation
 var tmp : TBytes;
 begin
   SetLength( tmp, bytes.Count);
@@ -1114,6 +1118,14 @@
   if iLen > 0 then FTrans.Write(b, 0, iLen);
 end;
 
+procedure TBinaryProtocolImpl.WriteBinary( const bytes : IThriftBytes);
+var iLen : Integer;
+begin
+  iLen := bytes.Count;
+  WriteI32( iLen);
+  if iLen > 0 then FTrans.Write( bytes.QueryRawDataPtr, 0, iLen);
+end;
+
 procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
 var network : TGuid;  // in network order (Big Endian)
 begin
@@ -1518,6 +1530,12 @@
 end;
 
 
+procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes);
+begin
+  FWrappedProtocol.WriteBinary( bytes);
+end;
+
+
 procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
 begin
   FWrappedProtocol.WriteUuid( uuid);
diff --git a/lib/delphi/test/serializer/TestSerializer.Tests.pas b/lib/delphi/test/serializer/TestSerializer.Tests.pas
index 91ced8a..e6a309e 100644
--- a/lib/delphi/test/serializer/TestSerializer.Tests.pas
+++ b/lib/delphi/test/serializer/TestSerializer.Tests.pas
@@ -332,7 +332,7 @@
     sAscii : AnsiString;
 begin
   sAscii := 'ABC/xzy';
-  bytes  := TEncoding.ASCII.GetBytes(sAscii);
+  bytes  := TEncoding.ASCII.GetBytes(string(sAscii));
 
   one := TThriftBytesImpl.Create( PAnsiChar(sAscii), Length(sAscii));
   two := TThriftBytesImpl.Create( bytes, TRUE);