THRIFT-1691 Serializer/deserializer support for Delphi 
Patch: Jens Geyer


git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1384105 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/delphi/src/Thrift.Serializer.pas b/lib/delphi/src/Thrift.Serializer.pas
new file mode 100644
index 0000000..a81cef0
--- /dev/null
+++ b/lib/delphi/src/Thrift.Serializer.pas
@@ -0,0 +1,223 @@
+(*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *)
+unit Thrift.Serializer;
+
+interface
+
+uses
+  Classes, Windows, SysUtils,
+  Thrift.Protocol,
+  Thrift.Transport,
+  Thrift.Stream;
+
+
+type
+  // Generic utility for easily serializing objects into a byte array or Stream.
+  TSerializer = class
+  private
+    FStream    : TMemoryStream;
+    FTransport : ITransport;
+    FProtocol  : IProtocol;
+
+  public
+    // Create a new TSerializer that uses the TBinaryProtocol by default.
+    constructor Create;  overload;
+
+    // Create a new TSerializer.
+    // It will use the TProtocol specified by the factory that is passed in.
+    constructor Create( const factory : IProtocolFactory);  overload;
+
+    // DTOR
+    destructor Destroy;  override;
+
+    // Serialize the Thrift object.
+    function  Serialize( const input : IBase) : TBytes;  overload;
+    procedure Serialize( const input : IBase; const aStm : TStream);  overload;
+  end;
+
+
+  // Generic utility for easily deserializing objects from byte array or Stream.
+  TDeserializer = class
+  private
+    FStream    : TMemoryStream;
+    FTransport : ITransport;
+    FProtocol  : IProtocol;
+
+  public
+    // Create a new TDeserializer that uses the TBinaryProtocol by default.
+    constructor Create;  overload;
+
+    // Create a new TDeserializer.
+    // It will use the TProtocol specified by the factory that is passed in.
+    constructor Create( const factory : IProtocolFactory);  overload;
+
+    // DTOR
+    destructor Destroy;  override;
+
+    // Deserialize the Thrift object data.
+    procedure Deserialize( const input : TBytes; const target : IBase);  overload;
+    procedure Deserialize( const input : TStream; const target : IBase);  overload;
+  end;
+
+
+
+implementation
+
+
+{ TSerializer }
+
+
+constructor TSerializer.Create();
+// Create a new TSerializer that uses the TBinaryProtocol by default.
+begin
+  Create( TBinaryProtocolImpl.TFactory.Create);
+end;
+
+
+constructor TSerializer.Create( const factory : IProtocolFactory);
+// Create a new TSerializer.
+// It will use the TProtocol specified by the factory that is passed in.
+var adapter : IThriftStream;
+begin
+  inherited Create;
+  FStream    := TMemoryStream.Create;
+  adapter    := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
+  FTransport := TStreamTransportImpl.Create( nil, adapter);
+  FProtocol  := factory.GetProtocol( FTransport);
+end;
+
+
+destructor TSerializer.Destroy;
+begin
+  try
+    FProtocol  := nil;
+    FTransport := nil;
+    FreeAndNil( FStream);
+  finally
+    inherited Destroy;
+  end;
+end;
+
+
+function TSerializer.Serialize( const input : IBase) : TBytes;
+// Serialize the Thrift object into a byte array. The process is simple,
+// just clear the byte array output, write the object into it, and grab the
+// raw bytes.
+var iBytes : Int64;
+begin
+  try
+    FStream.Size := 0;
+    input.Write( FProtocol);
+    SetLength( result, FStream.Size);
+    iBytes := Length(result);
+    if iBytes > 0
+    then Move( FStream.Memory^, result[0], iBytes);
+  finally
+    FStream.Size := 0;  // free any allocated memory
+  end;
+end;
+
+
+procedure TSerializer.Serialize( const input : IBase; const aStm : TStream);
+// Serialize the Thrift object into a byte array. The process is simple,
+// just clear the byte array output, write the object into it, and grab the
+// raw bytes. 
+var iBytes : Int64;
+const COPY_ENTIRE_STREAM = 0;
+begin
+  try
+    FStream.Size := 0;
+    input.Write( FProtocol);
+    aStm.CopyFrom( FStream, COPY_ENTIRE_STREAM);
+  finally
+    FStream.Size := 0;  // free any allocated memory
+  end;
+end;
+
+
+{ TDeserializer }
+
+
+constructor TDeserializer.Create();
+// Create a new TDeserializer that uses the TBinaryProtocol by default.
+begin
+  Create( TBinaryProtocolImpl.TFactory.Create);
+end;
+
+
+constructor TDeserializer.Create( const factory : IProtocolFactory);
+// Create a new TDeserializer.
+// It will use the TProtocol specified by the factory that is passed in.
+var adapter : IThriftStream;
+begin
+  inherited Create;
+  FStream    := TMemoryStream.Create;
+  adapter    := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
+  FTransport := TStreamTransportImpl.Create( adapter, nil);
+  FProtocol  := factory.GetProtocol( FTransport);
+end;
+
+
+destructor TDeserializer.Destroy;
+begin
+  try
+    FProtocol  := nil;
+    FTransport := nil;
+    FreeAndNil( FStream);
+  finally
+    inherited Destroy;
+  end;
+end;
+
+
+procedure TDeserializer.Deserialize( const input : TBytes; const target : IBase);
+// Deserialize the Thrift object data from the byte array.
+var iBytes : Int64;
+begin
+  try
+    iBytes := Length(input);
+    FStream.Size := iBytes;
+    if iBytes > 0
+    then Move( input[0], FStream.Memory^, iBytes);
+
+    target.Read( FProtocol);
+  finally
+    FStream.Size := 0;  // free any allocated memory
+  end;
+end;
+
+
+procedure TDeserializer.Deserialize( const input : TStream; const target : IBase);
+// Deserialize the Thrift object data from the byte array.
+const COPY_ENTIRE_STREAM = 0;
+var before : Int64;
+begin
+  try
+    before := FStream.Position;
+    FStream.CopyFrom( input, COPY_ENTIRE_STREAM);
+    FStream.Position := before;
+    target.Read( FProtocol);
+  finally
+    FStream.Size := 0;  // free any allocated memory
+  end;
+end;
+
+
+end.
+