blob: 24f6791450592078f6ea8332cd4af02c8998b450 [file] [log] [blame]
Jens Geyerd5436f52014-10-03 19:50:38 +02001(*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19
20{$SCOPEDENUMS ON}
21
22unit Thrift.Protocol;
23
24interface
25
26uses
27 Classes,
28 SysUtils,
29 Contnrs,
30 Thrift.Stream,
31 Thrift.Collections,
32 Thrift.Transport;
33
34type
35
36 TType = (
37 Stop = 0,
38 Void = 1,
39 Bool_ = 2,
40 Byte_ = 3,
41 Double_ = 4,
42 I16 = 6,
43 I32 = 8,
44 I64 = 10,
45 String_ = 11,
46 Struct = 12,
47 Map = 13,
48 Set_ = 14,
49 List = 15
50 );
51
52 TMessageType = (
53 Call = 1,
54 Reply = 2,
55 Exception = 3,
56 Oneway = 4
57 );
58
Jens Geyerf0e63312015-03-01 18:47:49 +010059const
60 VALID_TTYPES = [
61 TType.Stop, TType.Void,
62 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
63 TType.Struct, TType.Map, TType.Set_, TType.List
64 ];
65
66 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
67
Jens Geyerd47fcdd2015-07-09 22:05:18 +020068const
69 DEFAULT_RECURSION_LIMIT = 64;
70
Jens Geyerf0e63312015-03-01 18:47:49 +010071type
Jens Geyerd5436f52014-10-03 19:50:38 +020072 IProtocol = interface;
Jens Geyer17c3ad92017-09-05 20:31:27 +020073
74 TThriftMessage = record
75 Name: string;
76 Type_: TMessageType;
77 SeqID: Integer;
78 end;
79
80 TThriftStruct = record
81 Name: string;
82 end;
83
84 TThriftField = record
85 Name: string;
86 Type_: TType;
87 Id: SmallInt;
88 end;
89
90 TThriftList = record
91 ElementType: TType;
92 Count: Integer;
93 end;
94
95 TThriftMap = record
96 KeyType: TType;
97 ValueType: TType;
98 Count: Integer;
99 end;
100
101 TThriftSet = record
102 ElementType: TType;
103 Count: Integer;
104 end;
105
106
Jens Geyerd5436f52014-10-03 19:50:38 +0200107
108 IProtocolFactory = interface
109 ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
110 function GetProtocol( const trans: ITransport): IProtocol;
111 end;
112
113 TThriftStringBuilder = class( TStringBuilder)
114 public
115 function Append(const Value: TBytes): TStringBuilder; overload;
116 function Append(const Value: IThriftContainer): TStringBuilder; overload;
117 end;
118
119 TProtocolException = class( Exception )
120 public
121 const // TODO(jensg): change into enum
Jens Geyere0e32402016-04-20 21:50:48 +0200122 UNKNOWN = 0;
123 INVALID_DATA = 1;
124 NEGATIVE_SIZE = 2;
125 SIZE_LIMIT = 3;
126 BAD_VERSION = 4;
127 NOT_IMPLEMENTED = 5;
128 DEPTH_LIMIT = 6;
Jens Geyerd5436f52014-10-03 19:50:38 +0200129 protected
Jens Geyere0e32402016-04-20 21:50:48 +0200130 constructor HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +0200131 public
Jens Geyere0e32402016-04-20 21:50:48 +0200132 // purposefully hide inherited constructor
133 class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
134 class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
135 class function Create( type_: Integer): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
136 class function Create( type_: Integer; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
Jens Geyerd5436f52014-10-03 19:50:38 +0200137 end;
138
Jens Geyere0e32402016-04-20 21:50:48 +0200139 // Needed to remove deprecation warning
140 TProtocolExceptionSpecialized = class abstract (TProtocolException)
141 public
142 constructor Create(const Msg: string);
143 end;
144
145 TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized);
146 TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized);
147 TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized);
148 TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized);
149 TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized);
150 TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized);
151 TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized);
152
Jens Geyerd5436f52014-10-03 19:50:38 +0200153
154 TProtocolUtil = class
155 public
156 class procedure Skip( prot: IProtocol; type_: TType);
157 end;
158
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200159 IProtocolRecursionTracker = interface
160 ['{29CA033F-BB56-49B1-9EE3-31B1E82FC7A5}']
161 // no members yet
162 end;
163
164 TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRecursionTracker)
165 protected
166 FProtocol : IProtocol;
167 public
168 constructor Create( prot : IProtocol);
169 destructor Destroy; override;
170 end;
171
Jens Geyerd5436f52014-10-03 19:50:38 +0200172 IProtocol = interface
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200173 ['{602A7FFB-0D9E-4CD8-8D7F-E5076660588A}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200174 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200175 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200176 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200177 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200178 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200179 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200180 procedure WriteFieldEnd;
181 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200182 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200183 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200184 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200185 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200186 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200187 procedure WriteSetEnd();
188 procedure WriteBool( b: Boolean);
189 procedure WriteByte( b: ShortInt);
190 procedure WriteI16( i16: SmallInt);
191 procedure WriteI32( i32: Integer);
192 procedure WriteI64( const i64: Int64);
193 procedure WriteDouble( const d: Double);
194 procedure WriteString( const s: string );
195 procedure WriteAnsiString( const s: AnsiString);
196 procedure WriteBinary( const b: TBytes);
197
Jens Geyer17c3ad92017-09-05 20:31:27 +0200198 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200199 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200200 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200201 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200202 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200203 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200204 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200205 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200206 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200207 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200208 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200209 procedure ReadSetEnd();
210 function ReadBool: Boolean;
211 function ReadByte: ShortInt;
212 function ReadI16: SmallInt;
213 function ReadI32: Integer;
214 function ReadI64: Int64;
215 function ReadDouble:Double;
216 function ReadBinary: TBytes;
217 function ReadString: string;
218 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200219
220 procedure SetRecursionLimit( value : Integer);
221 function GetRecursionLimit : Integer;
222 function NextRecursionLevel : IProtocolRecursionTracker;
223 procedure IncrementRecursionDepth;
224 procedure DecrementRecursionDepth;
225
Jens Geyerd5436f52014-10-03 19:50:38 +0200226 property Transport: ITransport read GetTransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200227 property RecursionLimit : Integer read GetRecursionLimit write SetRecursionLimit;
Jens Geyerd5436f52014-10-03 19:50:38 +0200228 end;
229
230 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
231 protected
232 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200233 FRecursionLimit : Integer;
234 FRecursionDepth : Integer;
235
236 procedure SetRecursionLimit( value : Integer);
237 function GetRecursionLimit : Integer;
238 function NextRecursionLevel : IProtocolRecursionTracker;
239 procedure IncrementRecursionDepth;
240 procedure DecrementRecursionDepth;
241
Jens Geyerd5436f52014-10-03 19:50:38 +0200242 function GetTransport: ITransport;
243 public
Jens Geyer17c3ad92017-09-05 20:31:27 +0200244 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200245 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200246 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200247 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200248 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200249 procedure WriteFieldEnd; virtual; abstract;
250 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200251 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200252 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200253 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200254 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200255 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200256 procedure WriteSetEnd(); virtual; abstract;
257 procedure WriteBool( b: Boolean); virtual; abstract;
258 procedure WriteByte( b: ShortInt); virtual; abstract;
259 procedure WriteI16( i16: SmallInt); virtual; abstract;
260 procedure WriteI32( i32: Integer); virtual; abstract;
261 procedure WriteI64( const i64: Int64); virtual; abstract;
262 procedure WriteDouble( const d: Double); virtual; abstract;
263 procedure WriteString( const s: string ); virtual;
264 procedure WriteAnsiString( const s: AnsiString); virtual;
265 procedure WriteBinary( const b: TBytes); virtual; abstract;
266
Jens Geyer17c3ad92017-09-05 20:31:27 +0200267 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200268 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200269 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200270 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200271 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200272 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200273 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200274 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200275 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200276 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200277 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200278 procedure ReadSetEnd(); virtual; abstract;
279 function ReadBool: Boolean; virtual; abstract;
280 function ReadByte: ShortInt; virtual; abstract;
281 function ReadI16: SmallInt; virtual; abstract;
282 function ReadI32: Integer; virtual; abstract;
283 function ReadI64: Int64; virtual; abstract;
284 function ReadDouble:Double; virtual; abstract;
285 function ReadBinary: TBytes; virtual; abstract;
286 function ReadString: string; virtual;
287 function ReadAnsiString: AnsiString; virtual;
288
289 property Transport: ITransport read GetTransport;
290
291 constructor Create( trans: ITransport );
292 end;
293
294 IBase = interface
295 ['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
296 function ToString: string;
297 procedure Read( const iprot: IProtocol);
298 procedure Write( const iprot: IProtocol);
299 end;
300
Jens Geyerd5436f52014-10-03 19:50:38 +0200301
302 TBinaryProtocolImpl = class( TProtocolImpl )
303 protected
304 const
305 VERSION_MASK : Cardinal = $ffff0000;
306 VERSION_1 : Cardinal = $80010000;
307 protected
308 FStrictRead : Boolean;
309 FStrictWrite : Boolean;
310
311 private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200312 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200313 function ReadStringBody( size: Integer): string;
314
315 public
316
317 type
318 TFactory = class( TInterfacedObject, IProtocolFactory)
319 protected
320 FStrictRead : Boolean;
321 FStrictWrite : Boolean;
322 public
323 function GetProtocol( const trans: ITransport): IProtocol;
324 constructor Create( AStrictRead, AStrictWrite: Boolean ); overload;
325 constructor Create; overload;
326 end;
327
328 constructor Create( const trans: ITransport); overload;
329 constructor Create( const trans: ITransport; strictRead: Boolean; strictWrite: Boolean); overload;
330
Jens Geyer17c3ad92017-09-05 20:31:27 +0200331 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200332 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200333 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200334 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200335 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200336 procedure WriteFieldEnd; override;
337 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200338 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200339 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200340 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200341 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200342 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200343 procedure WriteSetEnd(); override;
344 procedure WriteBool( b: Boolean); override;
345 procedure WriteByte( b: ShortInt); override;
346 procedure WriteI16( i16: SmallInt); override;
347 procedure WriteI32( i32: Integer); override;
348 procedure WriteI64( const i64: Int64); override;
349 procedure WriteDouble( const d: Double); override;
350 procedure WriteBinary( const b: TBytes); override;
351
Jens Geyer17c3ad92017-09-05 20:31:27 +0200352 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200353 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200354 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200355 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200356 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200357 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200358 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200359 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200360 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200361 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200362 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200363 procedure ReadSetEnd(); override;
364 function ReadBool: Boolean; override;
365 function ReadByte: ShortInt; override;
366 function ReadI16: SmallInt; override;
367 function ReadI32: Integer; override;
368 function ReadI64: Int64; override;
369 function ReadDouble:Double; override;
370 function ReadBinary: TBytes; override;
371
372 end;
373
374
375 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
376 providing a way to author concise concrete decorator subclasses. The decorator
377 does not (and should not) modify the behaviour of the enclosed TProtocol
378
379 See p.175 of Design Patterns (by Gamma et al.)
380 }
381 TProtocolDecorator = class( TProtocolImpl)
382 private
383 FWrappedProtocol : IProtocol;
384
385 public
386 // Encloses the specified protocol.
387 // All operations will be forward to the given protocol. Must be non-null.
388 constructor Create( const aProtocol : IProtocol);
389
Jens Geyer17c3ad92017-09-05 20:31:27 +0200390 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200391 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200392 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200393 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200394 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200395 procedure WriteFieldEnd; override;
396 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200397 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200398 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200399 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200400 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200401 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200402 procedure WriteSetEnd(); override;
403 procedure WriteBool( b: Boolean); override;
404 procedure WriteByte( b: ShortInt); override;
405 procedure WriteI16( i16: SmallInt); override;
406 procedure WriteI32( i32: Integer); override;
407 procedure WriteI64( const i64: Int64); override;
408 procedure WriteDouble( const d: Double); override;
409 procedure WriteString( const s: string ); override;
410 procedure WriteAnsiString( const s: AnsiString); override;
411 procedure WriteBinary( const b: TBytes); override;
412
Jens Geyer17c3ad92017-09-05 20:31:27 +0200413 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200414 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200415 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200416 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200417 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200418 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200419 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200420 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200421 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200422 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200423 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200424 procedure ReadSetEnd(); override;
425 function ReadBool: Boolean; override;
426 function ReadByte: ShortInt; override;
427 function ReadI16: SmallInt; override;
428 function ReadI32: Integer; override;
429 function ReadI64: Int64; override;
430 function ReadDouble:Double; override;
431 function ReadBinary: TBytes; override;
432 function ReadString: string; override;
433 function ReadAnsiString: AnsiString; override;
434 end;
435
436
437type
438 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200439 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
440 // Called before reading arguments.
441 procedure PreRead;
442 // Called between reading arguments and calling the handler.
443 procedure PostRead;
444 // Called between calling the handler and writing the response.
445 procedure PreWrite;
446 // Called after writing the response.
447 procedure PostWrite;
448 // Called when an oneway (async) function call completes successfully.
449 procedure OnewayComplete;
450 // Called if the handler throws an undeclared exception.
451 procedure UnhandledError( const e : Exception);
452 // Called when a client has finished request-handling to clean up
453 procedure CleanupContext;
454 end;
455
456
457 IProcessorEvents = interface
458 ['{A8661119-657C-447D-93C5-512E36162A45}']
459 // Called when a client is about to call the processor.
460 procedure Processing( const transport : ITransport);
461 // Called on any service function invocation
462 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
463 // Called when a client has finished request-handling to clean up
464 procedure CleanupContext;
465 end;
466
467
468 IProcessor = interface
469 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200470 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200471 end;
472
Jens Geyerd5436f52014-10-03 19:50:38 +0200473
Jens Geyer17c3ad92017-09-05 20:31:27 +0200474procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
475procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
476procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
477procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
478procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
479procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
480
Jens Geyerd5436f52014-10-03 19:50:38 +0200481
482implementation
483
484function ConvertInt64ToDouble( const n: Int64): Double;
485begin
486 ASSERT( SizeOf(n) = SizeOf(Result));
487 System.Move( n, Result, SizeOf(Result));
488end;
489
490function ConvertDoubleToInt64( const d: Double): Int64;
491begin
492 ASSERT( SizeOf(d) = SizeOf(Result));
493 System.Move( d, Result, SizeOf(Result));
494end;
495
Jens Geyerd5436f52014-10-03 19:50:38 +0200496
Jens Geyerd5436f52014-10-03 19:50:38 +0200497
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200498{ TProtocolRecursionTrackerImpl }
499
500constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
501begin
502 inherited Create;
503
504 // storing the pointer *after* the (successful) increment is important here
505 prot.IncrementRecursionDepth;
506 FProtocol := prot;
507end;
508
509destructor TProtocolRecursionTrackerImpl.Destroy;
510begin
511 try
512 // we have to release the reference iff the pointer has been stored
513 if FProtocol <> nil then begin
514 FProtocol.DecrementRecursionDepth;
515 FProtocol := nil;
516 end;
517 finally
518 inherited Destroy;
519 end;
520end;
521
Jens Geyerd5436f52014-10-03 19:50:38 +0200522{ TProtocolImpl }
523
524constructor TProtocolImpl.Create(trans: ITransport);
525begin
526 inherited Create;
527 FTrans := trans;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200528 FRecursionLimit := DEFAULT_RECURSION_LIMIT;
529 FRecursionDepth := 0;
530end;
531
532procedure TProtocolImpl.SetRecursionLimit( value : Integer);
533begin
534 FRecursionLimit := value;
535end;
536
537function TProtocolImpl.GetRecursionLimit : Integer;
538begin
539 result := FRecursionLimit;
540end;
541
542function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
543begin
544 result := TProtocolRecursionTrackerImpl.Create(Self);
545end;
546
547procedure TProtocolImpl.IncrementRecursionDepth;
548begin
549 if FRecursionDepth < FRecursionLimit
550 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200551 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200552end;
553
554procedure TProtocolImpl.DecrementRecursionDepth;
555begin
556 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200557end;
558
559function TProtocolImpl.GetTransport: ITransport;
560begin
561 Result := FTrans;
562end;
563
564function TProtocolImpl.ReadAnsiString: AnsiString;
565var
566 b : TBytes;
567 len : Integer;
568begin
569 Result := '';
570 b := ReadBinary;
571 len := Length( b );
572 if len > 0 then
573 begin
574 SetLength( Result, len);
575 System.Move( b[0], Pointer(Result)^, len );
576 end;
577end;
578
579function TProtocolImpl.ReadString: string;
580begin
581 Result := TEncoding.UTF8.GetString( ReadBinary );
582end;
583
584procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
585var
586 b : TBytes;
587 len : Integer;
588begin
589 len := Length(s);
590 SetLength( b, len);
591 if len > 0 then
592 begin
593 System.Move( Pointer(s)^, b[0], len );
594 end;
595 WriteBinary( b );
596end;
597
598procedure TProtocolImpl.WriteString(const s: string);
599var
600 b : TBytes;
601begin
602 b := TEncoding.UTF8.GetBytes(s);
603 WriteBinary( b );
604end;
605
606{ TProtocolUtil }
607
608class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200609var field : TThriftField;
610 map : TThriftMap;
611 set_ : TThriftSet;
612 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200613 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200614 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200615begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200616 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200617 case type_ of
618 // simple types
619 TType.Bool_ : prot.ReadBool();
620 TType.Byte_ : prot.ReadByte();
621 TType.I16 : prot.ReadI16();
622 TType.I32 : prot.ReadI32();
623 TType.I64 : prot.ReadI64();
624 TType.Double_ : prot.ReadDouble();
625 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
626
627 // structured types
628 TType.Struct : begin
629 prot.ReadStructBegin();
630 while TRUE do begin
631 field := prot.ReadFieldBegin();
632 if (field.Type_ = TType.Stop) then Break;
633 Skip(prot, field.Type_);
634 prot.ReadFieldEnd();
635 end;
636 prot.ReadStructEnd();
637 end;
638
639 TType.Map : begin
640 map := prot.ReadMapBegin();
641 for i := 0 to map.Count-1 do begin
642 Skip(prot, map.KeyType);
643 Skip(prot, map.ValueType);
644 end;
645 prot.ReadMapEnd();
646 end;
647
648 TType.Set_ : begin
649 set_ := prot.ReadSetBegin();
650 for i := 0 to set_.Count-1
651 do Skip( prot, set_.ElementType);
652 prot.ReadSetEnd();
653 end;
654
655 TType.List : begin
656 list := prot.ReadListBegin();
657 for i := 0 to list.Count-1
658 do Skip( prot, list.ElementType);
659 prot.ReadListEnd();
660 end;
661
662 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100663 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200664 end;
665end;
666
Jens Geyerd5436f52014-10-03 19:50:38 +0200667
668{ TBinaryProtocolImpl }
669
670constructor TBinaryProtocolImpl.Create( const trans: ITransport);
671begin
672 //no inherited
673 Create( trans, False, True);
674end;
675
676constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead,
677 strictWrite: Boolean);
678begin
679 inherited Create( trans );
680 FStrictRead := strictRead;
681 FStrictWrite := strictWrite;
682end;
683
Jens Geyer17c3ad92017-09-05 20:31:27 +0200684function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200685begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200686 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200687end;
688
689function TBinaryProtocolImpl.ReadBinary: TBytes;
690var
691 size : Integer;
692 buf : TBytes;
693begin
694 size := ReadI32;
695 SetLength( buf, size );
696 FTrans.ReadAll( buf, 0, size);
697 Result := buf;
698end;
699
700function TBinaryProtocolImpl.ReadBool: Boolean;
701begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200702 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200703end;
704
705function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200706begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200707 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200708end;
709
710function TBinaryProtocolImpl.ReadDouble: Double;
711begin
712 Result := ConvertInt64ToDouble( ReadI64 )
713end;
714
Jens Geyer17c3ad92017-09-05 20:31:27 +0200715function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200716begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200717 Init( result, '', TType( ReadByte), 0);
718 if ( result.Type_ <> TType.Stop ) then begin
719 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200720 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200721end;
722
723procedure TBinaryProtocolImpl.ReadFieldEnd;
724begin
725
726end;
727
728function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200729var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200730begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200731 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200732 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
733end;
734
735function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200736var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200737begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200738 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200739
740 Result := Integer(
741 ((i32in[0] and $FF) shl 24) or
742 ((i32in[1] and $FF) shl 16) or
743 ((i32in[2] and $FF) shl 8) or
744 (i32in[3] and $FF));
745
746end;
747
748function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200749var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200750begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200751 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200752 Result :=
753 (Int64( i64in[0] and $FF) shl 56) or
754 (Int64( i64in[1] and $FF) shl 48) or
755 (Int64( i64in[2] and $FF) shl 40) or
756 (Int64( i64in[3] and $FF) shl 32) or
757 (Int64( i64in[4] and $FF) shl 24) or
758 (Int64( i64in[5] and $FF) shl 16) or
759 (Int64( i64in[6] and $FF) shl 8) or
760 (Int64( i64in[7] and $FF));
761end;
762
Jens Geyer17c3ad92017-09-05 20:31:27 +0200763function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200764begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200765 result.ElementType := TType(ReadByte);
766 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200767end;
768
769procedure TBinaryProtocolImpl.ReadListEnd;
770begin
771
772end;
773
Jens Geyer17c3ad92017-09-05 20:31:27 +0200774function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200775begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200776 result.KeyType := TType(ReadByte);
777 result.ValueType := TType(ReadByte);
778 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200779end;
780
781procedure TBinaryProtocolImpl.ReadMapEnd;
782begin
783
784end;
785
Jens Geyer17c3ad92017-09-05 20:31:27 +0200786function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200787var
788 size : Integer;
789 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200790begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200791 Init( result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200792 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200793 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200794 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200795 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200796 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +0200797 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200798 result.Type_ := TMessageType( size and $000000ff);
799 result.Name := ReadString;
800 result.SeqID := ReadI32;
801 end
802 else begin
803 if FStrictRead then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200804 raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
Jens Geyerd5436f52014-10-03 19:50:38 +0200805 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200806 result.Name := ReadStringBody( size );
807 result.Type_ := TMessageType( ReadByte );
808 result.SeqID := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200809 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200810end;
811
812procedure TBinaryProtocolImpl.ReadMessageEnd;
813begin
814 inherited;
815
816end;
817
Jens Geyer17c3ad92017-09-05 20:31:27 +0200818function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200819begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200820 result.ElementType := TType(ReadByte);
821 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200822end;
823
824procedure TBinaryProtocolImpl.ReadSetEnd;
825begin
826
827end;
828
829function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
830var
831 buf : TBytes;
832begin
833 SetLength( buf, size );
834 FTrans.ReadAll( buf, 0, size );
835 Result := TEncoding.UTF8.GetString( buf);
836end;
837
Jens Geyer17c3ad92017-09-05 20:31:27 +0200838function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200839begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200840 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200841end;
842
843procedure TBinaryProtocolImpl.ReadStructEnd;
844begin
845 inherited;
846
847end;
848
849procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
850var iLen : Integer;
851begin
852 iLen := Length(b);
853 WriteI32( iLen);
854 if iLen > 0 then FTrans.Write(b, 0, iLen);
855end;
856
857procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
858begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200859 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200860 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +0200861 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200862 WriteByte( 0 );
863 end;
864end;
865
866procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +0200867begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200868 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200869end;
870
871procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
872begin
873 WriteI64(ConvertDoubleToInt64(d));
874end;
875
Jens Geyer17c3ad92017-09-05 20:31:27 +0200876procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200877begin
878 WriteByte(ShortInt(field.Type_));
879 WriteI16(field.ID);
880end;
881
882procedure TBinaryProtocolImpl.WriteFieldEnd;
883begin
884
885end;
886
887procedure TBinaryProtocolImpl.WriteFieldStop;
888begin
889 WriteByte(ShortInt(TType.Stop));
890end;
891
892procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200893var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200894begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200895 i16out[0] := Byte($FF and (i16 shr 8));
896 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200897 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200898end;
899
900procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200901var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200902begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200903 i32out[0] := Byte($FF and (i32 shr 24));
904 i32out[1] := Byte($FF and (i32 shr 16));
905 i32out[2] := Byte($FF and (i32 shr 8));
906 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200907 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200908end;
909
910procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200911var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200912begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200913 i64out[0] := Byte($FF and (i64 shr 56));
914 i64out[1] := Byte($FF and (i64 shr 48));
915 i64out[2] := Byte($FF and (i64 shr 40));
916 i64out[3] := Byte($FF and (i64 shr 32));
917 i64out[4] := Byte($FF and (i64 shr 24));
918 i64out[5] := Byte($FF and (i64 shr 16));
919 i64out[6] := Byte($FF and (i64 shr 8));
920 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200921 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200922end;
923
Jens Geyer17c3ad92017-09-05 20:31:27 +0200924procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200925begin
926 WriteByte(ShortInt(list.ElementType));
927 WriteI32(list.Count);
928end;
929
930procedure TBinaryProtocolImpl.WriteListEnd;
931begin
932
933end;
934
Jens Geyer17c3ad92017-09-05 20:31:27 +0200935procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200936begin
937 WriteByte(ShortInt(map.KeyType));
938 WriteByte(ShortInt(map.ValueType));
939 WriteI32(map.Count);
940end;
941
942procedure TBinaryProtocolImpl.WriteMapEnd;
943begin
944
945end;
946
Jens Geyer17c3ad92017-09-05 20:31:27 +0200947procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200948var
949 version : Cardinal;
950begin
951 if FStrictWrite then
952 begin
953 version := VERSION_1 or Cardinal( msg.Type_);
954 WriteI32( Integer( version) );
955 WriteString( msg.Name);
956 WriteI32( msg.SeqID);
957 end else
958 begin
959 WriteString( msg.Name);
960 WriteByte(ShortInt( msg.Type_));
961 WriteI32( msg.SeqID);
962 end;
963end;
964
965procedure TBinaryProtocolImpl.WriteMessageEnd;
966begin
967
968end;
969
Jens Geyer17c3ad92017-09-05 20:31:27 +0200970procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +0200971begin
972 WriteByte(ShortInt(set_.ElementType));
973 WriteI32(set_.Count);
974end;
975
976procedure TBinaryProtocolImpl.WriteSetEnd;
977begin
978
979end;
980
Jens Geyer17c3ad92017-09-05 20:31:27 +0200981procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200982begin
983
984end;
985
986procedure TBinaryProtocolImpl.WriteStructEnd;
987begin
988
989end;
990
991{ TProtocolException }
992
Jens Geyere0e32402016-04-20 21:50:48 +0200993constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +0200994begin
Jens Geyere0e32402016-04-20 21:50:48 +0200995 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +0200996end;
997
Jens Geyere0e32402016-04-20 21:50:48 +0200998class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +0200999begin
Jens Geyere0e32402016-04-20 21:50:48 +02001000 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001001end;
1002
Jens Geyere0e32402016-04-20 21:50:48 +02001003class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001004begin
Jens Geyere0e32402016-04-20 21:50:48 +02001005 Result := TProtocolExceptionUnknown.Create('');
1006end;
1007
1008class function TProtocolException.Create(type_: Integer): TProtocolException;
1009begin
1010{$WARN SYMBOL_DEPRECATED OFF}
1011 Result := Create(type_, '');
1012{$WARN SYMBOL_DEPRECATED DEFAULT}
1013end;
1014
1015class function TProtocolException.Create(type_: Integer; const msg: string): TProtocolException;
1016begin
1017 case type_ of
1018 INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1019 NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1020 SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1021 BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1022 NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1023 DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
1024 else
1025 Result := TProtocolExceptionUnknown.Create(msg);
1026 end;
1027end;
1028
1029{ TProtocolExceptionSpecialized }
1030
1031constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1032begin
1033 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001034end;
1035
1036{ TThriftStringBuilder }
1037
1038function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
1039begin
1040 Result := Append( string( RawByteString(Value)) );
1041end;
1042
1043function TThriftStringBuilder.Append(
1044 const Value: IThriftContainer): TStringBuilder;
1045begin
1046 Result := Append( Value.ToString );
1047end;
1048
1049{ TBinaryProtocolImpl.TFactory }
1050
1051constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
1052begin
1053 inherited Create;
1054 FStrictRead := AStrictRead;
1055 FStrictWrite := AStrictWrite;
1056end;
1057
1058constructor TBinaryProtocolImpl.TFactory.Create;
1059begin
1060 //no inherited;
1061 Create( False, True )
1062end;
1063
1064function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1065begin
1066 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1067end;
1068
1069
1070{ TProtocolDecorator }
1071
1072constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1073begin
1074 ASSERT( aProtocol <> nil);
1075 inherited Create( aProtocol.Transport);
1076 FWrappedProtocol := aProtocol;
1077end;
1078
1079
Jens Geyer17c3ad92017-09-05 20:31:27 +02001080procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001081begin
1082 FWrappedProtocol.WriteMessageBegin( msg);
1083end;
1084
1085
1086procedure TProtocolDecorator.WriteMessageEnd;
1087begin
1088 FWrappedProtocol.WriteMessageEnd;
1089end;
1090
1091
Jens Geyer17c3ad92017-09-05 20:31:27 +02001092procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001093begin
1094 FWrappedProtocol.WriteStructBegin( struc);
1095end;
1096
1097
1098procedure TProtocolDecorator.WriteStructEnd;
1099begin
1100 FWrappedProtocol.WriteStructEnd;
1101end;
1102
1103
Jens Geyer17c3ad92017-09-05 20:31:27 +02001104procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001105begin
1106 FWrappedProtocol.WriteFieldBegin( field);
1107end;
1108
1109
1110procedure TProtocolDecorator.WriteFieldEnd;
1111begin
1112 FWrappedProtocol.WriteFieldEnd;
1113end;
1114
1115
1116procedure TProtocolDecorator.WriteFieldStop;
1117begin
1118 FWrappedProtocol.WriteFieldStop;
1119end;
1120
1121
Jens Geyer17c3ad92017-09-05 20:31:27 +02001122procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001123begin
1124 FWrappedProtocol.WriteMapBegin( map);
1125end;
1126
1127
1128procedure TProtocolDecorator.WriteMapEnd;
1129begin
1130 FWrappedProtocol.WriteMapEnd;
1131end;
1132
1133
Jens Geyer17c3ad92017-09-05 20:31:27 +02001134procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001135begin
1136 FWrappedProtocol.WriteListBegin( list);
1137end;
1138
1139
1140procedure TProtocolDecorator.WriteListEnd();
1141begin
1142 FWrappedProtocol.WriteListEnd();
1143end;
1144
1145
Jens Geyer17c3ad92017-09-05 20:31:27 +02001146procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001147begin
1148 FWrappedProtocol.WriteSetBegin( set_);
1149end;
1150
1151
1152procedure TProtocolDecorator.WriteSetEnd();
1153begin
1154 FWrappedProtocol.WriteSetEnd();
1155end;
1156
1157
1158procedure TProtocolDecorator.WriteBool( b: Boolean);
1159begin
1160 FWrappedProtocol.WriteBool( b);
1161end;
1162
1163
1164procedure TProtocolDecorator.WriteByte( b: ShortInt);
1165begin
1166 FWrappedProtocol.WriteByte( b);
1167end;
1168
1169
1170procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1171begin
1172 FWrappedProtocol.WriteI16( i16);
1173end;
1174
1175
1176procedure TProtocolDecorator.WriteI32( i32: Integer);
1177begin
1178 FWrappedProtocol.WriteI32( i32);
1179end;
1180
1181
1182procedure TProtocolDecorator.WriteI64( const i64: Int64);
1183begin
1184 FWrappedProtocol.WriteI64( i64);
1185end;
1186
1187
1188procedure TProtocolDecorator.WriteDouble( const d: Double);
1189begin
1190 FWrappedProtocol.WriteDouble( d);
1191end;
1192
1193
1194procedure TProtocolDecorator.WriteString( const s: string );
1195begin
1196 FWrappedProtocol.WriteString( s);
1197end;
1198
1199
1200procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1201begin
1202 FWrappedProtocol.WriteAnsiString( s);
1203end;
1204
1205
1206procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1207begin
1208 FWrappedProtocol.WriteBinary( b);
1209end;
1210
1211
Jens Geyer17c3ad92017-09-05 20:31:27 +02001212function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001213begin
1214 result := FWrappedProtocol.ReadMessageBegin;
1215end;
1216
1217
1218procedure TProtocolDecorator.ReadMessageEnd();
1219begin
1220 FWrappedProtocol.ReadMessageEnd();
1221end;
1222
1223
Jens Geyer17c3ad92017-09-05 20:31:27 +02001224function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001225begin
1226 result := FWrappedProtocol.ReadStructBegin;
1227end;
1228
1229
1230procedure TProtocolDecorator.ReadStructEnd;
1231begin
1232 FWrappedProtocol.ReadStructEnd;
1233end;
1234
1235
Jens Geyer17c3ad92017-09-05 20:31:27 +02001236function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001237begin
1238 result := FWrappedProtocol.ReadFieldBegin;
1239end;
1240
1241
1242procedure TProtocolDecorator.ReadFieldEnd();
1243begin
1244 FWrappedProtocol.ReadFieldEnd();
1245end;
1246
1247
Jens Geyer17c3ad92017-09-05 20:31:27 +02001248function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001249begin
1250 result := FWrappedProtocol.ReadMapBegin;
1251end;
1252
1253
1254procedure TProtocolDecorator.ReadMapEnd();
1255begin
1256 FWrappedProtocol.ReadMapEnd();
1257end;
1258
1259
Jens Geyer17c3ad92017-09-05 20:31:27 +02001260function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001261begin
1262 result := FWrappedProtocol.ReadListBegin;
1263end;
1264
1265
1266procedure TProtocolDecorator.ReadListEnd();
1267begin
1268 FWrappedProtocol.ReadListEnd();
1269end;
1270
1271
Jens Geyer17c3ad92017-09-05 20:31:27 +02001272function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001273begin
1274 result := FWrappedProtocol.ReadSetBegin;
1275end;
1276
1277
1278procedure TProtocolDecorator.ReadSetEnd();
1279begin
1280 FWrappedProtocol.ReadSetEnd();
1281end;
1282
1283
1284function TProtocolDecorator.ReadBool: Boolean;
1285begin
1286 result := FWrappedProtocol.ReadBool;
1287end;
1288
1289
1290function TProtocolDecorator.ReadByte: ShortInt;
1291begin
1292 result := FWrappedProtocol.ReadByte;
1293end;
1294
1295
1296function TProtocolDecorator.ReadI16: SmallInt;
1297begin
1298 result := FWrappedProtocol.ReadI16;
1299end;
1300
1301
1302function TProtocolDecorator.ReadI32: Integer;
1303begin
1304 result := FWrappedProtocol.ReadI32;
1305end;
1306
1307
1308function TProtocolDecorator.ReadI64: Int64;
1309begin
1310 result := FWrappedProtocol.ReadI64;
1311end;
1312
1313
1314function TProtocolDecorator.ReadDouble:Double;
1315begin
1316 result := FWrappedProtocol.ReadDouble;
1317end;
1318
1319
1320function TProtocolDecorator.ReadBinary: TBytes;
1321begin
1322 result := FWrappedProtocol.ReadBinary;
1323end;
1324
1325
1326function TProtocolDecorator.ReadString: string;
1327begin
1328 result := FWrappedProtocol.ReadString;
1329end;
1330
1331
1332function TProtocolDecorator.ReadAnsiString: AnsiString;
1333begin
1334 result := FWrappedProtocol.ReadAnsiString;
1335end;
1336
1337
Jens Geyer17c3ad92017-09-05 20:31:27 +02001338{ Init helper functions }
1339
1340procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1341begin
1342 rec.Name := AName;
1343 rec.Type_ := AMessageType;
1344 rec.SeqID := ASeqID;
1345end;
1346
1347
1348procedure Init( var rec : TThriftStruct; const AName: string = '');
1349begin
1350 rec.Name := AName;
1351end;
1352
1353
1354procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1355begin
1356 rec.Name := AName;
1357 rec.Type_ := AType;
1358 rec.Id := AId;
1359end;
1360
1361
1362procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1363begin
1364 rec.ValueType := AValueType;
1365 rec.KeyType := AKeyType;
1366 rec.Count := ACount;
1367end;
1368
1369
1370procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1371begin
1372 rec.Count := ACount;
1373 rec.ElementType := AElementType;
1374end;
1375
1376
1377procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1378begin
1379 rec.Count := ACount;
1380 rec.ElementType := AElementType;
1381end;
1382
1383
1384
1385
Jens Geyerd5436f52014-10-03 19:50:38 +02001386
1387end.
1388