blob: 8fa60085441d3644f5893097cfa93225d15d2eba [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.
*)
{$SCOPEDENUMS ON}
unit Thrift.Protocol;
interface
uses
Classes,
SysUtils,
Contnrs,
Thrift.Stream,
Thrift.Collections,
Thrift.Transport;
type
TType = (
Stop = 0,
Void = 1,
Bool_ = 2,
Byte_ = 3,
Double_ = 4,
I16 = 6,
I32 = 8,
I64 = 10,
String_ = 11,
Struct = 12,
Map = 13,
Set_ = 14,
List = 15
);
TMessageType = (
Call = 1,
Reply = 2,
Exception = 3,
Oneway = 4
);
IProtocol = interface;
IStruct = interface;
IProtocolFactory = interface
['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
function GetProtocol( trans: ITransport): IProtocol;
end;
TThriftStringBuilder = class( TStringBuilder)
public
function Append(const Value: TBytes): TStringBuilder; overload;
function Append(const Value: IThriftContainer): TStringBuilder; overload;
end;
TProtocolException = class( Exception )
public
const
UNKNOWN : Integer = 0;
INVALID_DATA : Integer = 1;
NEGATIVE_SIZE : Integer = 2;
SIZE_LIMIT : Integer = 3;
BAD_VERSION : Integer = 4;
NOT_IMPLEMENTED : Integer = 5;
protected
FType : Integer;
public
constructor Create; overload;
constructor Create( type_: Integer ); overload;
constructor Create( type_: Integer; const msg: string); overload;
end;
IMap = interface
['{30531D97-7E06-4233-B800-C3F53CCD23E7}']
function GetKeyType: TType;
procedure SetKeyType( Value: TType);
function GetValueType: TType;
procedure SetValueType( Value: TType);
function GetCount: Integer;
procedure SetCount( Value: Integer);
property KeyType: TType read GetKeyType write SetKeyType;
property ValueType: TType read GetValueType write SetValueType;
property Count: Integer read GetCount write SetCount;
end;
TMapImpl = class( TInterfacedObject, IMap)
private
FValueType: TType;
FKeyType: TType;
FCount: Integer;
protected
function GetKeyType: TType;
procedure SetKeyType( Value: TType);
function GetValueType: TType;
procedure SetValueType( Value: TType);
function GetCount: Integer;
procedure SetCount( Value: Integer);
public
constructor Create( AValueType: TType; AKeyType: TType; ACount: Integer); overload;
constructor Create; overload;
end;
IList = interface
['{6763E1EA-A934-4472-904F-0083980B9B87}']
function GetElementType: TType;
procedure SetElementType( Value: TType);
function GetCount: Integer;
procedure SetCount( Value: Integer);
property ElementType: TType read GetElementType write SetElementType;
property Count: Integer read GetCount write SetCount;
end;
TListImpl = class( TInterfacedObject, IList)
private
FElementType: TType;
FCount : Integer;
protected
function GetElementType: TType;
procedure SetElementType( Value: TType);
function GetCount: Integer;
procedure SetCount( Value: Integer);
public
constructor Create( AElementType: TType; ACount: Integer); overload;
constructor Create; overload;
end;
ISet = interface
['{A8671700-7514-4C1E-8A05-62786872005F}']
function GetElementType: TType;
procedure SetElementType( Value: TType);
function GetCount: Integer;
procedure SetCount( Value: Integer);
property ElementType: TType read GetElementType write SetElementType;
property Count: Integer read GetCount write SetCount;
end;
TSetImpl = class( TInterfacedObject, ISet)
private
FCount: Integer;
FElementType: TType;
protected
function GetElementType: TType;
procedure SetElementType( Value: TType);
function GetCount: Integer;
procedure SetCount( Value: Integer);
public
constructor Create( AElementType: TType; ACount: Integer); overload;
constructor Create; overload;
end;
IMessage = interface
['{9E368B4A-B1FA-43E7-8CF5-56C66D256CA7}']
function GetName: string;
procedure SetName( const Value: string);
function GetType: TMessageType;
procedure SetType( Value: TMessageType);
function GetSeqID: Integer;
procedure SetSeqID( Value: Integer);
property Name: string read GetName write SetName;
property Type_: TMessageType read GetType write SetType;
property SeqID: Integer read GetSeqID write SetSeqID;
end;
TMessageImpl = class( TInterfacedObject, IMessage )
private
FName: string;
FMessageType: TMessageType;
FSeqID: Integer;
protected
function GetName: string;
procedure SetName( const Value: string);
function GetType: TMessageType;
procedure SetType( Value: TMessageType);
function GetSeqID: Integer;
procedure SetSeqID( Value: Integer);
public
property Name: string read FName write FName;
property Type_: TMessageType read FMessageType write FMessageType;
property SeqID: Integer read FSeqID write FSeqID;
constructor Create( AName: string; AMessageType: TMessageType; ASeqID: Integer); overload;
constructor Create; overload;
end;
IField = interface
['{F0D43BE5-7883-442E-83FF-0580CC632B72}']
function GetName: string;
procedure SetName( const Value: string);
function GetType: TType;
procedure SetType( Value: TType);
function GetId: SmallInt;
procedure SetId( Value: SmallInt);
property Name: string read GetName write SetName;
property Type_: TType read GetType write SetType;
property Id: SmallInt read GetId write SetId;
end;
TFieldImpl = class( TInterfacedObject, IField)
private
FName : string;
FType : TType;
FId : SmallInt;
protected
function GetName: string;
procedure SetName( const Value: string);
function GetType: TType;
procedure SetType( Value: TType);
function GetId: SmallInt;
procedure SetId( Value: SmallInt);
public
constructor Create( const AName: string; const AType: TType; AId: SmallInt); overload;
constructor Create; overload;
end;
TProtocolUtil = class
public
class procedure Skip( prot: IProtocol; type_: TType);
end;
IProtocol = interface
['{FD95C151-1527-4C96-8134-B902BFC4B4FC}']
function GetTransport: ITransport;
procedure WriteMessageBegin( message: IMessage);
procedure WriteMessageEnd;
procedure WriteStructBegin(struc: IStruct);
procedure WriteStructEnd;
procedure WriteFieldBegin(field: IField);
procedure WriteFieldEnd;
procedure WriteFieldStop;
procedure WriteMapBegin(map: IMap);
procedure WriteMapEnd;
procedure WriteListBegin( list: IList);
procedure WriteListEnd();
procedure WriteSetBegin( set_: ISet );
procedure WriteSetEnd();
procedure WriteBool( b: Boolean);
procedure WriteByte( b: ShortInt);
procedure WriteI16( i16: SmallInt);
procedure WriteI32( i32: Integer);
procedure WriteI64( i64: Int64);
procedure WriteDouble( d: Double);
procedure WriteString( const s: string );
procedure WriteAnsiString( const s: AnsiString);
procedure WriteBinary( const b: TBytes);
function ReadMessageBegin: IMessage;
procedure ReadMessageEnd();
function ReadStructBegin: IStruct;
procedure ReadStructEnd;
function ReadFieldBegin: IField;
procedure ReadFieldEnd();
function ReadMapBegin: IMap;
procedure ReadMapEnd();
function ReadListBegin: IList;
procedure ReadListEnd();
function ReadSetBegin: ISet;
procedure ReadSetEnd();
function ReadBool: Boolean;
function ReadByte: ShortInt;
function ReadI16: SmallInt;
function ReadI32: Integer;
function ReadI64: Int64;
function ReadDouble:Double;
function ReadBinary: TBytes;
function ReadString: string;
function ReadAnsiString: AnsiString;
property Transport: ITransport read GetTransport;
end;
TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
protected
FTrans : ITransport;
function GetTransport: ITransport;
public
procedure WriteMessageBegin( message: IMessage); virtual; abstract;
procedure WriteMessageEnd; virtual; abstract;
procedure WriteStructBegin(struc: IStruct); virtual; abstract;
procedure WriteStructEnd; virtual; abstract;
procedure WriteFieldBegin(field: IField); virtual; abstract;
procedure WriteFieldEnd; virtual; abstract;
procedure WriteFieldStop; virtual; abstract;
procedure WriteMapBegin(map: IMap); virtual; abstract;
procedure WriteMapEnd; virtual; abstract;
procedure WriteListBegin( list: IList); virtual; abstract;
procedure WriteListEnd(); virtual; abstract;
procedure WriteSetBegin( set_: ISet ); virtual; abstract;
procedure WriteSetEnd(); virtual; abstract;
procedure WriteBool( b: Boolean); virtual; abstract;
procedure WriteByte( b: ShortInt); virtual; abstract;
procedure WriteI16( i16: SmallInt); virtual; abstract;
procedure WriteI32( i32: Integer); virtual; abstract;
procedure WriteI64( i64: Int64); virtual; abstract;
procedure WriteDouble( d: Double); virtual; abstract;
procedure WriteString( const s: string ); virtual;
procedure WriteAnsiString( const s: AnsiString); virtual;
procedure WriteBinary( const b: TBytes); virtual; abstract;
function ReadMessageBegin: IMessage; virtual; abstract;
procedure ReadMessageEnd(); virtual; abstract;
function ReadStructBegin: IStruct; virtual; abstract;
procedure ReadStructEnd; virtual; abstract;
function ReadFieldBegin: IField; virtual; abstract;
procedure ReadFieldEnd(); virtual; abstract;
function ReadMapBegin: IMap; virtual; abstract;
procedure ReadMapEnd(); virtual; abstract;
function ReadListBegin: IList; virtual; abstract;
procedure ReadListEnd(); virtual; abstract;
function ReadSetBegin: ISet; virtual; abstract;
procedure ReadSetEnd(); virtual; abstract;
function ReadBool: Boolean; virtual; abstract;
function ReadByte: ShortInt; virtual; abstract;
function ReadI16: SmallInt; virtual; abstract;
function ReadI32: Integer; virtual; abstract;
function ReadI64: Int64; virtual; abstract;
function ReadDouble:Double; virtual; abstract;
function ReadBinary: TBytes; virtual; abstract;
function ReadString: string; virtual;
function ReadAnsiString: AnsiString; virtual;
property Transport: ITransport read GetTransport;
constructor Create( trans: ITransport );
end;
IBase = interface
['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
function ToString: string;
procedure Read( iprot: IProtocol);
procedure Write( iprot: IProtocol);
end;
IStruct = interface
['{5DCE39AA-C916-4BC7-A79B-96A0C36B2220}']
procedure SetName(const Value: string);
function GetName: string;
property Name: string read GetName write SetName;
end;
TStructImpl = class( TInterfacedObject, IStruct )
private
FName: string;
protected
function GetName: string;
procedure SetName(const Value: string);
public
constructor Create( const AName: string);
end;
TBinaryProtocolImpl = class( TProtocolImpl )
protected
const
VERSION_MASK : Cardinal = $ffff0000;
VERSION_1 : Cardinal = $80010000;
protected
FStrictRead : Boolean;
FStrictWrite : Boolean;
FReadLength : Integer;
FCheckReadLength : Boolean;
private
function ReadAll( var buf: TBytes; off: Integer; len: Integer ): Integer;
function ReadStringBody( size: Integer): string;
procedure CheckReadLength( len: Integer );
public
type
TFactory = class( TInterfacedObject, IProtocolFactory)
protected
FStrictRead : Boolean;
FStrictWrite : Boolean;
public
function GetProtocol(trans: ITransport): IProtocol;
constructor Create( AStrictRead, AStrictWrite: Boolean ); overload;
constructor Create; overload;
end;
constructor Create( trans: ITransport); overload;
constructor Create( trans: ITransport; strictRead: Boolean; strictWrite: Boolean); overload;
procedure WriteMessageBegin( message: IMessage); override;
procedure WriteMessageEnd; override;
procedure WriteStructBegin(struc: IStruct); override;
procedure WriteStructEnd; override;
procedure WriteFieldBegin(field: IField); override;
procedure WriteFieldEnd; override;
procedure WriteFieldStop; override;
procedure WriteMapBegin(map: IMap); override;
procedure WriteMapEnd; override;
procedure WriteListBegin( list: IList); override;
procedure WriteListEnd(); override;
procedure WriteSetBegin( set_: ISet ); override;
procedure WriteSetEnd(); override;
procedure WriteBool( b: Boolean); override;
procedure WriteByte( b: ShortInt); override;
procedure WriteI16( i16: SmallInt); override;
procedure WriteI32( i32: Integer); override;
procedure WriteI64( i64: Int64); override;
procedure WriteDouble( d: Double); override;
procedure WriteBinary( const b: TBytes); override;
function ReadMessageBegin: IMessage; override;
procedure ReadMessageEnd(); override;
function ReadStructBegin: IStruct; override;
procedure ReadStructEnd; override;
function ReadFieldBegin: IField; override;
procedure ReadFieldEnd(); override;
function ReadMapBegin: IMap; override;
procedure ReadMapEnd(); override;
function ReadListBegin: IList; override;
procedure ReadListEnd(); override;
function ReadSetBegin: ISet; override;
procedure ReadSetEnd(); override;
function ReadBool: Boolean; override;
function ReadByte: ShortInt; override;
function ReadI16: SmallInt; override;
function ReadI32: Integer; override;
function ReadI64: Int64; override;
function ReadDouble:Double; override;
function ReadBinary: TBytes; override;
procedure SetReadLength( readLength: Integer );
end;
implementation
function ConvertInt64ToDouble( n: Int64): Double;
begin
ASSERT( SizeOf(n) = SizeOf(Result));
System.Move( n, Result, SizeOf(Result));
end;
function ConvertDoubleToInt64( d: Double): Int64;
begin
ASSERT( SizeOf(d) = SizeOf(Result));
System.Move( d, Result, SizeOf(Result));
end;
{ TFieldImpl }
constructor TFieldImpl.Create(const AName: string; const AType: TType;
AId: SmallInt);
begin
FName := AName;
FType := AType;
FId := AId;
end;
constructor TFieldImpl.Create;
begin
FName := '';
FType := Low(TType);
FId := 0;
end;
function TFieldImpl.GetId: SmallInt;
begin
Result := FId;
end;
function TFieldImpl.GetName: string;
begin
Result := FName;
end;
function TFieldImpl.GetType: TType;
begin
Result := FType;
end;
procedure TFieldImpl.SetId(Value: SmallInt);
begin
FId := Value;
end;
procedure TFieldImpl.SetName(const Value: string);
begin
FName := Value;
end;
procedure TFieldImpl.SetType(Value: TType);
begin
FType := Value;
end;
{ TProtocolImpl }
constructor TProtocolImpl.Create(trans: ITransport);
begin
inherited Create;
FTrans := trans;
end;
function TProtocolImpl.GetTransport: ITransport;
begin
Result := FTrans;
end;
function TProtocolImpl.ReadAnsiString: AnsiString;
var
b : TBytes;
len : Integer;
begin
Result := '';
b := ReadBinary;
len := Length( b );
if len > 0 then
begin
SetLength( Result, len);
System.Move( b[0], Pointer(Result)^, len );
end;
end;
function TProtocolImpl.ReadString: string;
begin
Result := TEncoding.UTF8.GetString( ReadBinary );
end;
procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
var
b : TBytes;
len : Integer;
begin
len := Length(s);
SetLength( b, len);
if len > 0 then
begin
System.Move( Pointer(s)^, b[0], len );
end;
WriteBinary( b );
end;
procedure TProtocolImpl.WriteString(const s: string);
var
b : TBytes;
begin
b := TEncoding.UTF8.GetBytes(s);
WriteBinary( b );
end;
{ TProtocolUtil }
class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
begin
end;
{ TStructImpl }
constructor TStructImpl.Create(const AName: string);
begin
inherited Create;
FName := AName;
end;
function TStructImpl.GetName: string;
begin
Result := FName;
end;
procedure TStructImpl.SetName(const Value: string);
begin
FName := Value;
end;
{ TMapImpl }
constructor TMapImpl.Create(AValueType, AKeyType: TType; ACount: Integer);
begin
inherited Create;
FValueType := AValueType;
FKeyType := AKeyType;
FCount := ACount;
end;
constructor TMapImpl.Create;
begin
end;
function TMapImpl.GetCount: Integer;
begin
Result := FCount;
end;
function TMapImpl.GetKeyType: TType;
begin
Result := FKeyType;
end;
function TMapImpl.GetValueType: TType;
begin
Result := FValueType;
end;
procedure TMapImpl.SetCount(Value: Integer);
begin
FCount := Value;
end;
procedure TMapImpl.SetKeyType(Value: TType);
begin
FKeyType := Value;
end;
procedure TMapImpl.SetValueType(Value: TType);
begin
FValueType := Value;
end;
{ IMessage }
constructor TMessageImpl.Create(AName: string; AMessageType: TMessageType;
ASeqID: Integer);
begin
inherited Create;
FName := AName;
FMessageType := AMessageType;
FSeqID := ASeqID;
end;
constructor TMessageImpl.Create;
begin
inherited;
end;
function TMessageImpl.GetName: string;
begin
Result := FName;
end;
function TMessageImpl.GetSeqID: Integer;
begin
Result := FSeqID;
end;
function TMessageImpl.GetType: TMessageType;
begin
Result := FMessageType;
end;
procedure TMessageImpl.SetName(const Value: string);
begin
FName := Value;
end;
procedure TMessageImpl.SetSeqID(Value: Integer);
begin
FSeqID := Value;
end;
procedure TMessageImpl.SetType(Value: TMessageType);
begin
FMessageType := Value;
end;
{ ISet }
constructor TSetImpl.Create( AElementType: TType; ACount: Integer);
begin
inherited Create;
FCount := ACount;
FElementType := AElementType;
end;
constructor TSetImpl.Create;
begin
end;
function TSetImpl.GetCount: Integer;
begin
Result := FCount;
end;
function TSetImpl.GetElementType: TType;
begin
Result := FElementType;
end;
procedure TSetImpl.SetCount(Value: Integer);
begin
FCount := Value;
end;
procedure TSetImpl.SetElementType(Value: TType);
begin
FElementType := Value;
end;
{ IList }
constructor TListImpl.Create( AElementType: TType; ACount: Integer);
begin
inherited Create;
FCount := ACount;
FElementType := AElementType;
end;
constructor TListImpl.Create;
begin
end;
function TListImpl.GetCount: Integer;
begin
Result := FCount;
end;
function TListImpl.GetElementType: TType;
begin
Result := FElementType;
end;
procedure TListImpl.SetCount(Value: Integer);
begin
FCount := Value;
end;
procedure TListImpl.SetElementType(Value: TType);
begin
FElementType := Value;
end;
{ TBinaryProtocolImpl }
constructor TBinaryProtocolImpl.Create( trans: ITransport);
begin
Create( trans, False, True);
end;
procedure TBinaryProtocolImpl.CheckReadLength(len: Integer);
begin
if FCheckReadLength then
begin
Dec( FReadLength, len);
if FReadLength < 0 then
begin
raise Exception.Create( 'Message length exceeded: ' + IntToStr( len ) );
end;
end;
end;
constructor TBinaryProtocolImpl.Create(trans: ITransport; strictRead,
strictWrite: Boolean);
begin
inherited Create( trans );
FStrictRead := strictRead;
FStrictWrite := strictWrite;
end;
function TBinaryProtocolImpl.ReadAll( var buf: TBytes; off,
len: Integer): Integer;
begin
CheckReadLength( len );
Result := FTrans.ReadAll( buf, off, len );
end;
function TBinaryProtocolImpl.ReadBinary: TBytes;
var
size : Integer;
buf : TBytes;
begin
size := ReadI32;
CheckReadLength( size );
SetLength( buf, size );
FTrans.ReadAll( buf, 0, size);
Result := buf;
end;
function TBinaryProtocolImpl.ReadBool: Boolean;
begin
Result := ReadByte = 1;
end;
function TBinaryProtocolImpl.ReadByte: ShortInt;
var
bin : TBytes;
begin
SetLength( bin, 1);
ReadAll( bin, 0, 1 );
Result := ShortInt( bin[0]);
end;
function TBinaryProtocolImpl.ReadDouble: Double;
begin
Result := ConvertInt64ToDouble( ReadI64 )
end;
function TBinaryProtocolImpl.ReadFieldBegin: IField;
var
field : IField;
begin
field := TFieldImpl.Create;
field.Type_ := TType( ReadByte);
if ( field.Type_ <> TType.Stop ) then
begin
field.Id := ReadI16;
end;
Result := field;
end;
procedure TBinaryProtocolImpl.ReadFieldEnd;
begin
end;
function TBinaryProtocolImpl.ReadI16: SmallInt;
var
i16in : TBytes;
begin
SetLength( i16in, 2 );
ReadAll( i16in, 0, 2);
Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
end;
function TBinaryProtocolImpl.ReadI32: Integer;
var
i32in : TBytes;
begin
SetLength( i32in, 4 );
ReadAll( i32in, 0, 4);
Result := Integer(
((i32in[0] and $FF) shl 24) or
((i32in[1] and $FF) shl 16) or
((i32in[2] and $FF) shl 8) or
(i32in[3] and $FF));
end;
function TBinaryProtocolImpl.ReadI64: Int64;
var
i64in : TBytes;
begin
SetLength( i64in, 8);
ReadAll( i64in, 0, 8);
Result :=
(Int64( i64in[0] and $FF) shl 56) or
(Int64( i64in[1] and $FF) shl 48) or
(Int64( i64in[2] and $FF) shl 40) or
(Int64( i64in[3] and $FF) shl 32) or
(Int64( i64in[4] and $FF) shl 24) or
(Int64( i64in[5] and $FF) shl 16) or
(Int64( i64in[6] and $FF) shl 8) or
(Int64( i64in[7] and $FF));
end;
function TBinaryProtocolImpl.ReadListBegin: IList;
var
list : IList;
begin
list := TListImpl.Create;
list.ElementType := TType( ReadByte );
list.Count := ReadI32;
Result := list;
end;
procedure TBinaryProtocolImpl.ReadListEnd;
begin
end;
function TBinaryProtocolImpl.ReadMapBegin: IMap;
var
map : IMap;
begin
map := TMapImpl.Create;
map.KeyType := TType( ReadByte );
map.ValueType := TType( ReadByte );
map.Count := ReadI32;
Result := map;
end;
procedure TBinaryProtocolImpl.ReadMapEnd;
begin
end;
function TBinaryProtocolImpl.ReadMessageBegin: IMessage;
var
size : Integer;
version : Integer;
message : IMessage;
begin
message := TMessageImpl.Create;
size := ReadI32;
if (size < 0) then
begin
version := size and Integer( VERSION_MASK);
if ( version <> Integer( VERSION_1)) then
begin
raise TProtocolException.Create(TProtocolException.BAD_VERSION, 'Bad version in ReadMessageBegin: ' + IntToStr(version) );
end;
message.Type_ := TMessageType( size and $000000ff);
message.Name := ReadString;
message.SeqID := ReadI32;
end else
begin
if FStrictRead then
begin
raise TProtocolException.Create( TProtocolException.BAD_VERSION, 'Missing version in readMessageBegin, old client?' );
end;
message.Name := ReadStringBody( size );
message.Type_ := TMessageType( ReadByte );
message.SeqID := ReadI32;
end;
Result := message;
end;
procedure TBinaryProtocolImpl.ReadMessageEnd;
begin
inherited;
end;
function TBinaryProtocolImpl.ReadSetBegin: ISet;
var
set_ : ISet;
begin
set_ := TSetImpl.Create;
set_.ElementType := TType( ReadByte );
set_.Count := ReadI32;
Result := set_;
end;
procedure TBinaryProtocolImpl.ReadSetEnd;
begin
end;
function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
var
buf : TBytes;
begin
CheckReadLength( size );
SetLength( buf, size );
FTrans.ReadAll( buf, 0, size );
Result := TEncoding.UTF8.GetString( buf);
end;
function TBinaryProtocolImpl.ReadStructBegin: IStruct;
begin
Result := TStructImpl.Create('');
end;
procedure TBinaryProtocolImpl.ReadStructEnd;
begin
inherited;
end;
procedure TBinaryProtocolImpl.SetReadLength(readLength: Integer);
begin
FReadLength := readLength;
FCheckReadLength := True;
end;
procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
begin
WriteI32( Length(b));
FTrans.Write(b, 0, Length( b));
end;
procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
begin
if b then
begin
WriteByte( 1 );
end else
begin
WriteByte( 0 );
end;
end;
procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
var
a : TBytes;
begin
SetLength( a, 1);
a[0] := Byte( b );
FTrans.Write( a, 0, 1 );
end;
procedure TBinaryProtocolImpl.WriteDouble(d: Double);
begin
WriteI64(ConvertDoubleToInt64(d));
end;
procedure TBinaryProtocolImpl.WriteFieldBegin(field: IField);
begin
WriteByte(ShortInt(field.Type_));
WriteI16(field.ID);
end;
procedure TBinaryProtocolImpl.WriteFieldEnd;
begin
end;
procedure TBinaryProtocolImpl.WriteFieldStop;
begin
WriteByte(ShortInt(TType.Stop));
end;
procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
var
i16out : TBytes;
begin
SetLength( i16out, 2);
i16out[0] := Byte($FF and (i16 shr 8));
i16out[1] := Byte($FF and i16);
FTrans.Write( i16out );
end;
procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
var
i32out : TBytes;
begin
SetLength( i32out, 4);
i32out[0] := Byte($FF and (i32 shr 24));
i32out[1] := Byte($FF and (i32 shr 16));
i32out[2] := Byte($FF and (i32 shr 8));
i32out[3] := Byte($FF and i32);
FTrans.Write( i32out, 0, 4);
end;
procedure TBinaryProtocolImpl.WriteI64(i64: Int64);
var
i64out : TBytes;
begin
SetLength( i64out, 8);
i64out[0] := Byte($FF and (i64 shr 56));
i64out[1] := Byte($FF and (i64 shr 48));
i64out[2] := Byte($FF and (i64 shr 40));
i64out[3] := Byte($FF and (i64 shr 32));
i64out[4] := Byte($FF and (i64 shr 24));
i64out[5] := Byte($FF and (i64 shr 16));
i64out[6] := Byte($FF and (i64 shr 8));
i64out[7] := Byte($FF and i64);
FTrans.Write( i64out, 0, 8);
end;
procedure TBinaryProtocolImpl.WriteListBegin(list: IList);
begin
WriteByte(ShortInt(list.ElementType));
WriteI32(list.Count);
end;
procedure TBinaryProtocolImpl.WriteListEnd;
begin
end;
procedure TBinaryProtocolImpl.WriteMapBegin(map: IMap);
begin
WriteByte(ShortInt(map.KeyType));
WriteByte(ShortInt(map.ValueType));
WriteI32(map.Count);
end;
procedure TBinaryProtocolImpl.WriteMapEnd;
begin
end;
procedure TBinaryProtocolImpl.WriteMessageBegin( message: IMessage);
var
version : Cardinal;
begin
if FStrictWrite then
begin
version := VERSION_1 or Cardinal( message.Type_);
WriteI32( Integer( version) );
WriteString( message.Name);
WriteI32(message.SeqID);
end else
begin
WriteString(message.Name);
WriteByte(ShortInt(message.Type_));
WriteI32(message.SeqID);
end;
end;
procedure TBinaryProtocolImpl.WriteMessageEnd;
begin
end;
procedure TBinaryProtocolImpl.WriteSetBegin(set_: ISet);
begin
WriteByte(ShortInt(set_.ElementType));
WriteI32(set_.Count);
end;
procedure TBinaryProtocolImpl.WriteSetEnd;
begin
end;
procedure TBinaryProtocolImpl.WriteStructBegin(struc: IStruct);
begin
end;
procedure TBinaryProtocolImpl.WriteStructEnd;
begin
end;
{ TProtocolException }
constructor TProtocolException.Create;
begin
inherited Create('');
FType := UNKNOWN;
end;
constructor TProtocolException.Create(type_: Integer);
begin
inherited Create('');
FType := type_;
end;
constructor TProtocolException.Create(type_: Integer; const msg: string);
begin
inherited Create( msg );
FType := type_;
end;
{ TThriftStringBuilder }
function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
begin
Result := Append( string( RawByteString(Value)) );
end;
function TThriftStringBuilder.Append(
const Value: IThriftContainer): TStringBuilder;
begin
Result := Append( Value.ToString );
end;
{ TBinaryProtocolImpl.TFactory }
constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
begin
FStrictRead := AStrictRead;
FStrictWrite := AStrictWrite;
end;
constructor TBinaryProtocolImpl.TFactory.Create;
begin
Create( False, True )
end;
function TBinaryProtocolImpl.TFactory.GetProtocol(trans: ITransport): IProtocol;
begin
Result := TBinaryProtocolImpl.Create( trans );
end;
end.