| (* | 
 |  * 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. | 
 |  |