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.
+