blob: cb62603dbf06f96ac4a3a8851c9fb09795cc6a20 [file] [log] [blame]
(*
* 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;
{$I Thrift.Defines.inc}
interface
uses
{$IFDEF OLD_UNIT_NAMES}
Classes, Windows, SysUtils,
{$ELSE}
System.Classes, Winapi.Windows, System.SysUtils,
{$ENDIF}
Thrift.Configuration,
Thrift.Protocol,
Thrift.Transport,
Thrift.Stream;
type
// Generic utility for easily serializing objects into a byte array or Stream.
TSerializer = class
strict private
FStream : TMemoryStream;
FTransport : ITransport;
FProtocol : IProtocol;
public
constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol
const aTransFact : ITransportFactory = nil;
const aConfig : IThriftConfiguration = nil);
// 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
strict private
FStream : TMemoryStream;
FTransport : ITransport;
FProtocol : IProtocol;
public
constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol
const aTransFact : ITransportFactory = nil;
const aConfig : IThriftConfiguration = nil);
// 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( const aProtFact : IProtocolFactory;
const aTransFact : ITransportFactory;
const aConfig : IThriftConfiguration);
var adapter : IThriftStream;
protfact : IProtocolFactory;
begin
inherited Create;
FStream := TMemoryStream.Create;
adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
FTransport := TStreamTransportImpl.Create( nil, adapter, aConfig);
if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport);
if aProtFact <> nil
then protfact := aProtFact
else protfact := TBinaryProtocolImpl.TFactory.Create;
FProtocol := protfact.GetProtocol( FTransport);
if not FTransport.IsOpen
then FTransport.Open;
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);
FTransport.Flush;
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.
const COPY_ENTIRE_STREAM = 0;
begin
try
FStream.Size := 0;
input.Write( FProtocol);
FTransport.Flush;
aStm.CopyFrom( FStream, COPY_ENTIRE_STREAM);
finally
FStream.Size := 0; // free any allocated memory
end;
end;
{ TDeserializer }
constructor TDeserializer.Create( const aProtFact : IProtocolFactory;
const aTransFact : ITransportFactory;
const aConfig : IThriftConfiguration);
var adapter : IThriftStream;
protfact : IProtocolFactory;
begin
inherited Create;
FStream := TMemoryStream.Create;
adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
FTransport := TStreamTransportImpl.Create( adapter, nil, aConfig);
if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport);
if aProtFact <> nil
then protfact := aProtFact
else protfact := TBinaryProtocolImpl.TFactory.Create;
FProtocol := protfact.GetProtocol( FTransport);
if not FTransport.IsOpen
then FTransport.Open;
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.