blob: 47e88fe67b08ddc05e88292bb2123dcc5055af42 [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,
Jens Geyer606f1ef2018-04-09 23:09:41 +020030 Thrift.Exception,
Jens Geyerd5436f52014-10-03 19:50:38 +020031 Thrift.Stream,
Jens Geyer8f7487e2019-05-09 22:21:32 +020032 Thrift.Utils,
Jens Geyerd5436f52014-10-03 19:50:38 +020033 Thrift.Collections,
34 Thrift.Transport;
35
36type
37
38 TType = (
39 Stop = 0,
40 Void = 1,
41 Bool_ = 2,
42 Byte_ = 3,
43 Double_ = 4,
44 I16 = 6,
45 I32 = 8,
46 I64 = 10,
47 String_ = 11,
48 Struct = 12,
49 Map = 13,
50 Set_ = 14,
51 List = 15
52 );
53
54 TMessageType = (
55 Call = 1,
56 Reply = 2,
57 Exception = 3,
58 Oneway = 4
59 );
60
Jens Geyerf0e63312015-03-01 18:47:49 +010061const
62 VALID_TTYPES = [
63 TType.Stop, TType.Void,
64 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
65 TType.Struct, TType.Map, TType.Set_, TType.List
66 ];
67
68 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
69
Jens Geyerd47fcdd2015-07-09 22:05:18 +020070const
71 DEFAULT_RECURSION_LIMIT = 64;
72
Jens Geyerf0e63312015-03-01 18:47:49 +010073type
Jens Geyerd5436f52014-10-03 19:50:38 +020074 IProtocol = interface;
Jens Geyer17c3ad92017-09-05 20:31:27 +020075
76 TThriftMessage = record
77 Name: string;
78 Type_: TMessageType;
79 SeqID: Integer;
80 end;
81
82 TThriftStruct = record
83 Name: string;
84 end;
85
86 TThriftField = record
87 Name: string;
88 Type_: TType;
89 Id: SmallInt;
90 end;
91
92 TThriftList = record
93 ElementType: TType;
94 Count: Integer;
95 end;
96
97 TThriftMap = record
98 KeyType: TType;
99 ValueType: TType;
100 Count: Integer;
101 end;
102
103 TThriftSet = record
104 ElementType: TType;
105 Count: Integer;
106 end;
107
108
Jens Geyerd5436f52014-10-03 19:50:38 +0200109
110 IProtocolFactory = interface
111 ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
112 function GetProtocol( const trans: ITransport): IProtocol;
113 end;
114
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100115 TProtocolException = class abstract( TException)
Jens Geyerd5436f52014-10-03 19:50:38 +0200116 public
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100117 type TExceptionType = (
118 UNKNOWN = 0,
119 INVALID_DATA = 1,
120 NEGATIVE_SIZE = 2,
121 SIZE_LIMIT = 3,
122 BAD_VERSION = 4,
123 NOT_IMPLEMENTED = 5,
124 DEPTH_LIMIT = 6
125 );
Jens Geyerd5436f52014-10-03 19:50:38 +0200126 protected
Jens Geyere0e32402016-04-20 21:50:48 +0200127 constructor HiddenCreate(const Msg: string);
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100128 class function GetType: TExceptionType; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200129 public
Jens Geyere0e32402016-04-20 21:50:48 +0200130 // purposefully hide inherited constructor
131 class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
132 class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100133 class function Create( aType: TExceptionType): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
134 class function Create( aType: TExceptionType; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
135 property Type_: TExceptionType read GetType;
Jens Geyerd5436f52014-10-03 19:50:38 +0200136 end;
137
Jens Geyere0e32402016-04-20 21:50:48 +0200138 // Needed to remove deprecation warning
139 TProtocolExceptionSpecialized = class abstract (TProtocolException)
140 public
141 constructor Create(const Msg: string);
142 end;
143
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100144 TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized)
145 protected
146 class function GetType: TProtocolException.TExceptionType; override;
147 end;
148
149 TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized)
150 protected
151 class function GetType: TProtocolException.TExceptionType; override;
152 end;
153
154 TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized)
155 protected
156 class function GetType: TProtocolException.TExceptionType; override;
157 end;
158
159 TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized)
160 protected
161 class function GetType: TProtocolException.TExceptionType; override;
162 end;
163
164 TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized)
165 protected
166 class function GetType: TProtocolException.TExceptionType; override;
167 end;
168
169 TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized)
170 protected
171 class function GetType: TProtocolException.TExceptionType; override;
172 end;
173
174 TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized)
175 protected
176 class function GetType: TProtocolException.TExceptionType; override;
177 end;
178
Jens Geyere0e32402016-04-20 21:50:48 +0200179
Jens Geyerd5436f52014-10-03 19:50:38 +0200180
181 TProtocolUtil = class
182 public
183 class procedure Skip( prot: IProtocol; type_: TType);
184 end;
185
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200186 IProtocolRecursionTracker = interface
187 ['{29CA033F-BB56-49B1-9EE3-31B1E82FC7A5}']
188 // no members yet
189 end;
190
191 TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRecursionTracker)
192 protected
193 FProtocol : IProtocol;
194 public
195 constructor Create( prot : IProtocol);
196 destructor Destroy; override;
197 end;
198
Jens Geyerd5436f52014-10-03 19:50:38 +0200199 IProtocol = interface
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200200 ['{602A7FFB-0D9E-4CD8-8D7F-E5076660588A}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200201 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200202 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200203 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200204 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200205 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200206 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200207 procedure WriteFieldEnd;
208 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200209 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200210 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200211 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200212 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200213 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200214 procedure WriteSetEnd();
215 procedure WriteBool( b: Boolean);
216 procedure WriteByte( b: ShortInt);
217 procedure WriteI16( i16: SmallInt);
218 procedure WriteI32( i32: Integer);
219 procedure WriteI64( const i64: Int64);
220 procedure WriteDouble( const d: Double);
221 procedure WriteString( const s: string );
222 procedure WriteAnsiString( const s: AnsiString);
223 procedure WriteBinary( const b: TBytes);
224
Jens Geyer17c3ad92017-09-05 20:31:27 +0200225 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200226 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200227 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200228 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200229 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200230 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200231 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200232 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200233 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200234 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200235 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200236 procedure ReadSetEnd();
237 function ReadBool: Boolean;
238 function ReadByte: ShortInt;
239 function ReadI16: SmallInt;
240 function ReadI32: Integer;
241 function ReadI64: Int64;
242 function ReadDouble:Double;
243 function ReadBinary: TBytes;
244 function ReadString: string;
245 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200246
247 procedure SetRecursionLimit( value : Integer);
248 function GetRecursionLimit : Integer;
249 function NextRecursionLevel : IProtocolRecursionTracker;
250 procedure IncrementRecursionDepth;
251 procedure DecrementRecursionDepth;
252
Jens Geyerd5436f52014-10-03 19:50:38 +0200253 property Transport: ITransport read GetTransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200254 property RecursionLimit : Integer read GetRecursionLimit write SetRecursionLimit;
Jens Geyerd5436f52014-10-03 19:50:38 +0200255 end;
256
257 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
258 protected
259 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200260 FRecursionLimit : Integer;
261 FRecursionDepth : Integer;
262
263 procedure SetRecursionLimit( value : Integer);
264 function GetRecursionLimit : Integer;
265 function NextRecursionLevel : IProtocolRecursionTracker;
266 procedure IncrementRecursionDepth;
267 procedure DecrementRecursionDepth;
268
Jens Geyerd5436f52014-10-03 19:50:38 +0200269 function GetTransport: ITransport;
270 public
Jens Geyer17c3ad92017-09-05 20:31:27 +0200271 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200272 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200273 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200274 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200275 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200276 procedure WriteFieldEnd; virtual; abstract;
277 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200278 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200279 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200280 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200281 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200282 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200283 procedure WriteSetEnd(); virtual; abstract;
284 procedure WriteBool( b: Boolean); virtual; abstract;
285 procedure WriteByte( b: ShortInt); virtual; abstract;
286 procedure WriteI16( i16: SmallInt); virtual; abstract;
287 procedure WriteI32( i32: Integer); virtual; abstract;
288 procedure WriteI64( const i64: Int64); virtual; abstract;
289 procedure WriteDouble( const d: Double); virtual; abstract;
290 procedure WriteString( const s: string ); virtual;
291 procedure WriteAnsiString( const s: AnsiString); virtual;
292 procedure WriteBinary( const b: TBytes); virtual; abstract;
293
Jens Geyer17c3ad92017-09-05 20:31:27 +0200294 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200295 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200296 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200297 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200298 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200299 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200300 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200301 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200302 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200303 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200304 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200305 procedure ReadSetEnd(); virtual; abstract;
306 function ReadBool: Boolean; virtual; abstract;
307 function ReadByte: ShortInt; virtual; abstract;
308 function ReadI16: SmallInt; virtual; abstract;
309 function ReadI32: Integer; virtual; abstract;
310 function ReadI64: Int64; virtual; abstract;
311 function ReadDouble:Double; virtual; abstract;
312 function ReadBinary: TBytes; virtual; abstract;
313 function ReadString: string; virtual;
314 function ReadAnsiString: AnsiString; virtual;
315
316 property Transport: ITransport read GetTransport;
317
318 constructor Create( trans: ITransport );
319 end;
320
Jens Geyer8f7487e2019-05-09 22:21:32 +0200321 IBase = interface( ISupportsToString)
322 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200323 procedure Read( const iprot: IProtocol);
324 procedure Write( const iprot: IProtocol);
325 end;
326
Jens Geyerd5436f52014-10-03 19:50:38 +0200327
328 TBinaryProtocolImpl = class( TProtocolImpl )
329 protected
330 const
331 VERSION_MASK : Cardinal = $ffff0000;
332 VERSION_1 : Cardinal = $80010000;
333 protected
334 FStrictRead : Boolean;
335 FStrictWrite : Boolean;
336
337 private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200338 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200339 function ReadStringBody( size: Integer): string;
340
341 public
342
343 type
344 TFactory = class( TInterfacedObject, IProtocolFactory)
345 protected
346 FStrictRead : Boolean;
347 FStrictWrite : Boolean;
348 public
349 function GetProtocol( const trans: ITransport): IProtocol;
350 constructor Create( AStrictRead, AStrictWrite: Boolean ); overload;
351 constructor Create; overload;
352 end;
353
354 constructor Create( const trans: ITransport); overload;
355 constructor Create( const trans: ITransport; strictRead: Boolean; strictWrite: Boolean); overload;
356
Jens Geyer17c3ad92017-09-05 20:31:27 +0200357 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200358 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200359 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200360 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200361 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200362 procedure WriteFieldEnd; override;
363 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200364 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200365 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200366 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200367 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200368 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200369 procedure WriteSetEnd(); override;
370 procedure WriteBool( b: Boolean); override;
371 procedure WriteByte( b: ShortInt); override;
372 procedure WriteI16( i16: SmallInt); override;
373 procedure WriteI32( i32: Integer); override;
374 procedure WriteI64( const i64: Int64); override;
375 procedure WriteDouble( const d: Double); override;
376 procedure WriteBinary( const b: TBytes); override;
377
Jens Geyer17c3ad92017-09-05 20:31:27 +0200378 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200379 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200380 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200381 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200382 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200383 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200384 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200385 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200386 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200387 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200388 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200389 procedure ReadSetEnd(); override;
390 function ReadBool: Boolean; override;
391 function ReadByte: ShortInt; override;
392 function ReadI16: SmallInt; override;
393 function ReadI32: Integer; override;
394 function ReadI64: Int64; override;
395 function ReadDouble:Double; override;
396 function ReadBinary: TBytes; override;
397
398 end;
399
400
401 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
402 providing a way to author concise concrete decorator subclasses. The decorator
403 does not (and should not) modify the behaviour of the enclosed TProtocol
404
405 See p.175 of Design Patterns (by Gamma et al.)
406 }
407 TProtocolDecorator = class( TProtocolImpl)
408 private
409 FWrappedProtocol : IProtocol;
410
411 public
412 // Encloses the specified protocol.
413 // All operations will be forward to the given protocol. Must be non-null.
414 constructor Create( const aProtocol : IProtocol);
415
Jens Geyer17c3ad92017-09-05 20:31:27 +0200416 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200417 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200418 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200419 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200420 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200421 procedure WriteFieldEnd; override;
422 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200423 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200424 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200425 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200426 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200427 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200428 procedure WriteSetEnd(); override;
429 procedure WriteBool( b: Boolean); override;
430 procedure WriteByte( b: ShortInt); override;
431 procedure WriteI16( i16: SmallInt); override;
432 procedure WriteI32( i32: Integer); override;
433 procedure WriteI64( const i64: Int64); override;
434 procedure WriteDouble( const d: Double); override;
435 procedure WriteString( const s: string ); override;
436 procedure WriteAnsiString( const s: AnsiString); override;
437 procedure WriteBinary( const b: TBytes); override;
438
Jens Geyer17c3ad92017-09-05 20:31:27 +0200439 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200440 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200441 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200442 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200443 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200444 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200445 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200446 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200447 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200448 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200449 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200450 procedure ReadSetEnd(); override;
451 function ReadBool: Boolean; override;
452 function ReadByte: ShortInt; override;
453 function ReadI16: SmallInt; override;
454 function ReadI32: Integer; override;
455 function ReadI64: Int64; override;
456 function ReadDouble:Double; override;
457 function ReadBinary: TBytes; override;
458 function ReadString: string; override;
459 function ReadAnsiString: AnsiString; override;
460 end;
461
462
463type
464 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200465 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
466 // Called before reading arguments.
467 procedure PreRead;
468 // Called between reading arguments and calling the handler.
469 procedure PostRead;
470 // Called between calling the handler and writing the response.
471 procedure PreWrite;
472 // Called after writing the response.
473 procedure PostWrite;
474 // Called when an oneway (async) function call completes successfully.
475 procedure OnewayComplete;
476 // Called if the handler throws an undeclared exception.
477 procedure UnhandledError( const e : Exception);
478 // Called when a client has finished request-handling to clean up
479 procedure CleanupContext;
480 end;
481
482
483 IProcessorEvents = interface
484 ['{A8661119-657C-447D-93C5-512E36162A45}']
485 // Called when a client is about to call the processor.
486 procedure Processing( const transport : ITransport);
487 // Called on any service function invocation
488 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
489 // Called when a client has finished request-handling to clean up
490 procedure CleanupContext;
491 end;
492
493
494 IProcessor = interface
495 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200496 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200497 end;
498
Jens Geyerd5436f52014-10-03 19:50:38 +0200499
Jens Geyer17c3ad92017-09-05 20:31:27 +0200500procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
501procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
502procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
503procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
504procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
505procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
506
Jens Geyerd5436f52014-10-03 19:50:38 +0200507
508implementation
509
510function ConvertInt64ToDouble( const n: Int64): Double;
511begin
512 ASSERT( SizeOf(n) = SizeOf(Result));
513 System.Move( n, Result, SizeOf(Result));
514end;
515
516function ConvertDoubleToInt64( const d: Double): Int64;
517begin
518 ASSERT( SizeOf(d) = SizeOf(Result));
519 System.Move( d, Result, SizeOf(Result));
520end;
521
Jens Geyerd5436f52014-10-03 19:50:38 +0200522
Jens Geyerd5436f52014-10-03 19:50:38 +0200523
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200524{ TProtocolRecursionTrackerImpl }
525
526constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
527begin
528 inherited Create;
529
530 // storing the pointer *after* the (successful) increment is important here
531 prot.IncrementRecursionDepth;
532 FProtocol := prot;
533end;
534
535destructor TProtocolRecursionTrackerImpl.Destroy;
536begin
537 try
538 // we have to release the reference iff the pointer has been stored
539 if FProtocol <> nil then begin
540 FProtocol.DecrementRecursionDepth;
541 FProtocol := nil;
542 end;
543 finally
544 inherited Destroy;
545 end;
546end;
547
Jens Geyerd5436f52014-10-03 19:50:38 +0200548{ TProtocolImpl }
549
550constructor TProtocolImpl.Create(trans: ITransport);
551begin
552 inherited Create;
553 FTrans := trans;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200554 FRecursionLimit := DEFAULT_RECURSION_LIMIT;
555 FRecursionDepth := 0;
556end;
557
558procedure TProtocolImpl.SetRecursionLimit( value : Integer);
559begin
560 FRecursionLimit := value;
561end;
562
563function TProtocolImpl.GetRecursionLimit : Integer;
564begin
565 result := FRecursionLimit;
566end;
567
568function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
569begin
570 result := TProtocolRecursionTrackerImpl.Create(Self);
571end;
572
573procedure TProtocolImpl.IncrementRecursionDepth;
574begin
575 if FRecursionDepth < FRecursionLimit
576 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200577 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200578end;
579
580procedure TProtocolImpl.DecrementRecursionDepth;
581begin
582 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200583end;
584
585function TProtocolImpl.GetTransport: ITransport;
586begin
587 Result := FTrans;
588end;
589
590function TProtocolImpl.ReadAnsiString: AnsiString;
591var
592 b : TBytes;
593 len : Integer;
594begin
595 Result := '';
596 b := ReadBinary;
597 len := Length( b );
598 if len > 0 then
599 begin
600 SetLength( Result, len);
601 System.Move( b[0], Pointer(Result)^, len );
602 end;
603end;
604
605function TProtocolImpl.ReadString: string;
606begin
607 Result := TEncoding.UTF8.GetString( ReadBinary );
608end;
609
610procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
611var
612 b : TBytes;
613 len : Integer;
614begin
615 len := Length(s);
616 SetLength( b, len);
617 if len > 0 then
618 begin
619 System.Move( Pointer(s)^, b[0], len );
620 end;
621 WriteBinary( b );
622end;
623
624procedure TProtocolImpl.WriteString(const s: string);
625var
626 b : TBytes;
627begin
628 b := TEncoding.UTF8.GetBytes(s);
629 WriteBinary( b );
630end;
631
632{ TProtocolUtil }
633
634class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200635var field : TThriftField;
636 map : TThriftMap;
637 set_ : TThriftSet;
638 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200639 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200640 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200641begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200642 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200643 case type_ of
644 // simple types
645 TType.Bool_ : prot.ReadBool();
646 TType.Byte_ : prot.ReadByte();
647 TType.I16 : prot.ReadI16();
648 TType.I32 : prot.ReadI32();
649 TType.I64 : prot.ReadI64();
650 TType.Double_ : prot.ReadDouble();
651 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
652
653 // structured types
654 TType.Struct : begin
655 prot.ReadStructBegin();
656 while TRUE do begin
657 field := prot.ReadFieldBegin();
658 if (field.Type_ = TType.Stop) then Break;
659 Skip(prot, field.Type_);
660 prot.ReadFieldEnd();
661 end;
662 prot.ReadStructEnd();
663 end;
664
665 TType.Map : begin
666 map := prot.ReadMapBegin();
667 for i := 0 to map.Count-1 do begin
668 Skip(prot, map.KeyType);
669 Skip(prot, map.ValueType);
670 end;
671 prot.ReadMapEnd();
672 end;
673
674 TType.Set_ : begin
675 set_ := prot.ReadSetBegin();
676 for i := 0 to set_.Count-1
677 do Skip( prot, set_.ElementType);
678 prot.ReadSetEnd();
679 end;
680
681 TType.List : begin
682 list := prot.ReadListBegin();
683 for i := 0 to list.Count-1
684 do Skip( prot, list.ElementType);
685 prot.ReadListEnd();
686 end;
687
688 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100689 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200690 end;
691end;
692
Jens Geyerd5436f52014-10-03 19:50:38 +0200693
694{ TBinaryProtocolImpl }
695
696constructor TBinaryProtocolImpl.Create( const trans: ITransport);
697begin
698 //no inherited
699 Create( trans, False, True);
700end;
701
702constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead,
703 strictWrite: Boolean);
704begin
705 inherited Create( trans );
706 FStrictRead := strictRead;
707 FStrictWrite := strictWrite;
708end;
709
Jens Geyer17c3ad92017-09-05 20:31:27 +0200710function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200711begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200712 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200713end;
714
715function TBinaryProtocolImpl.ReadBinary: TBytes;
716var
717 size : Integer;
718 buf : TBytes;
719begin
720 size := ReadI32;
721 SetLength( buf, size );
722 FTrans.ReadAll( buf, 0, size);
723 Result := buf;
724end;
725
726function TBinaryProtocolImpl.ReadBool: Boolean;
727begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200728 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200729end;
730
731function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200732begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200733 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200734end;
735
736function TBinaryProtocolImpl.ReadDouble: Double;
737begin
738 Result := ConvertInt64ToDouble( ReadI64 )
739end;
740
Jens Geyer17c3ad92017-09-05 20:31:27 +0200741function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200742begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200743 Init( result, '', TType( ReadByte), 0);
744 if ( result.Type_ <> TType.Stop ) then begin
745 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200746 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200747end;
748
749procedure TBinaryProtocolImpl.ReadFieldEnd;
750begin
751
752end;
753
754function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200755var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200756begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200757 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200758 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
759end;
760
761function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200762var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200763begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200764 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200765
766 Result := Integer(
767 ((i32in[0] and $FF) shl 24) or
768 ((i32in[1] and $FF) shl 16) or
769 ((i32in[2] and $FF) shl 8) or
770 (i32in[3] and $FF));
771
772end;
773
774function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200775var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200776begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200777 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200778 Result :=
779 (Int64( i64in[0] and $FF) shl 56) or
780 (Int64( i64in[1] and $FF) shl 48) or
781 (Int64( i64in[2] and $FF) shl 40) or
782 (Int64( i64in[3] and $FF) shl 32) or
783 (Int64( i64in[4] and $FF) shl 24) or
784 (Int64( i64in[5] and $FF) shl 16) or
785 (Int64( i64in[6] and $FF) shl 8) or
786 (Int64( i64in[7] and $FF));
787end;
788
Jens Geyer17c3ad92017-09-05 20:31:27 +0200789function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200790begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200791 result.ElementType := TType(ReadByte);
792 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200793end;
794
795procedure TBinaryProtocolImpl.ReadListEnd;
796begin
797
798end;
799
Jens Geyer17c3ad92017-09-05 20:31:27 +0200800function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200801begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200802 result.KeyType := TType(ReadByte);
803 result.ValueType := TType(ReadByte);
804 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200805end;
806
807procedure TBinaryProtocolImpl.ReadMapEnd;
808begin
809
810end;
811
Jens Geyer17c3ad92017-09-05 20:31:27 +0200812function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200813var
814 size : Integer;
815 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200816begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200817 Init( result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200818 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200819 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200820 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200821 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200822 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +0200823 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200824 result.Type_ := TMessageType( size and $000000ff);
825 result.Name := ReadString;
826 result.SeqID := ReadI32;
827 end
828 else begin
829 if FStrictRead then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200830 raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
Jens Geyerd5436f52014-10-03 19:50:38 +0200831 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200832 result.Name := ReadStringBody( size );
833 result.Type_ := TMessageType( ReadByte );
834 result.SeqID := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200835 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200836end;
837
838procedure TBinaryProtocolImpl.ReadMessageEnd;
839begin
840 inherited;
841
842end;
843
Jens Geyer17c3ad92017-09-05 20:31:27 +0200844function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200845begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200846 result.ElementType := TType(ReadByte);
847 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200848end;
849
850procedure TBinaryProtocolImpl.ReadSetEnd;
851begin
852
853end;
854
855function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
856var
857 buf : TBytes;
858begin
859 SetLength( buf, size );
860 FTrans.ReadAll( buf, 0, size );
861 Result := TEncoding.UTF8.GetString( buf);
862end;
863
Jens Geyer17c3ad92017-09-05 20:31:27 +0200864function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200865begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200866 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200867end;
868
869procedure TBinaryProtocolImpl.ReadStructEnd;
870begin
871 inherited;
872
873end;
874
875procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
876var iLen : Integer;
877begin
878 iLen := Length(b);
879 WriteI32( iLen);
880 if iLen > 0 then FTrans.Write(b, 0, iLen);
881end;
882
883procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
884begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200885 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200886 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +0200887 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200888 WriteByte( 0 );
889 end;
890end;
891
892procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +0200893begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200894 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200895end;
896
897procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
898begin
899 WriteI64(ConvertDoubleToInt64(d));
900end;
901
Jens Geyer17c3ad92017-09-05 20:31:27 +0200902procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200903begin
904 WriteByte(ShortInt(field.Type_));
905 WriteI16(field.ID);
906end;
907
908procedure TBinaryProtocolImpl.WriteFieldEnd;
909begin
910
911end;
912
913procedure TBinaryProtocolImpl.WriteFieldStop;
914begin
915 WriteByte(ShortInt(TType.Stop));
916end;
917
918procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200919var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200920begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200921 i16out[0] := Byte($FF and (i16 shr 8));
922 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200923 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200924end;
925
926procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200927var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200928begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200929 i32out[0] := Byte($FF and (i32 shr 24));
930 i32out[1] := Byte($FF and (i32 shr 16));
931 i32out[2] := Byte($FF and (i32 shr 8));
932 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200933 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200934end;
935
936procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200937var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200938begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200939 i64out[0] := Byte($FF and (i64 shr 56));
940 i64out[1] := Byte($FF and (i64 shr 48));
941 i64out[2] := Byte($FF and (i64 shr 40));
942 i64out[3] := Byte($FF and (i64 shr 32));
943 i64out[4] := Byte($FF and (i64 shr 24));
944 i64out[5] := Byte($FF and (i64 shr 16));
945 i64out[6] := Byte($FF and (i64 shr 8));
946 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200947 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200948end;
949
Jens Geyer17c3ad92017-09-05 20:31:27 +0200950procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200951begin
952 WriteByte(ShortInt(list.ElementType));
953 WriteI32(list.Count);
954end;
955
956procedure TBinaryProtocolImpl.WriteListEnd;
957begin
958
959end;
960
Jens Geyer17c3ad92017-09-05 20:31:27 +0200961procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200962begin
963 WriteByte(ShortInt(map.KeyType));
964 WriteByte(ShortInt(map.ValueType));
965 WriteI32(map.Count);
966end;
967
968procedure TBinaryProtocolImpl.WriteMapEnd;
969begin
970
971end;
972
Jens Geyer17c3ad92017-09-05 20:31:27 +0200973procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200974var
975 version : Cardinal;
976begin
977 if FStrictWrite then
978 begin
979 version := VERSION_1 or Cardinal( msg.Type_);
980 WriteI32( Integer( version) );
981 WriteString( msg.Name);
982 WriteI32( msg.SeqID);
983 end else
984 begin
985 WriteString( msg.Name);
986 WriteByte(ShortInt( msg.Type_));
987 WriteI32( msg.SeqID);
988 end;
989end;
990
991procedure TBinaryProtocolImpl.WriteMessageEnd;
992begin
993
994end;
995
Jens Geyer17c3ad92017-09-05 20:31:27 +0200996procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +0200997begin
998 WriteByte(ShortInt(set_.ElementType));
999 WriteI32(set_.Count);
1000end;
1001
1002procedure TBinaryProtocolImpl.WriteSetEnd;
1003begin
1004
1005end;
1006
Jens Geyer17c3ad92017-09-05 20:31:27 +02001007procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001008begin
1009
1010end;
1011
1012procedure TBinaryProtocolImpl.WriteStructEnd;
1013begin
1014
1015end;
1016
1017{ TProtocolException }
1018
Jens Geyere0e32402016-04-20 21:50:48 +02001019constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001020begin
Jens Geyere0e32402016-04-20 21:50:48 +02001021 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001022end;
1023
Jens Geyere0e32402016-04-20 21:50:48 +02001024class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001025begin
Jens Geyere0e32402016-04-20 21:50:48 +02001026 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001027end;
1028
Jens Geyere0e32402016-04-20 21:50:48 +02001029class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001030begin
Jens Geyere0e32402016-04-20 21:50:48 +02001031 Result := TProtocolExceptionUnknown.Create('');
1032end;
1033
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001034class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001035begin
1036{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001037 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001038{$WARN SYMBOL_DEPRECATED DEFAULT}
1039end;
1040
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001041class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001042begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001043 case aType of
1044 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1045 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1046 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1047 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1048 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1049 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001050 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001051 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001052 Result := TProtocolExceptionUnknown.Create(msg);
1053 end;
1054end;
1055
1056{ TProtocolExceptionSpecialized }
1057
1058constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1059begin
1060 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001061end;
1062
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001063{ specialized TProtocolExceptions }
1064
1065class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1066begin
1067 result := TExceptionType.UNKNOWN;
1068end;
1069
1070class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1071begin
1072 result := TExceptionType.INVALID_DATA;
1073end;
1074
1075class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1076begin
1077 result := TExceptionType.NEGATIVE_SIZE;
1078end;
1079
1080class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1081begin
1082 result := TExceptionType.SIZE_LIMIT;
1083end;
1084
1085class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1086begin
1087 result := TExceptionType.BAD_VERSION;
1088end;
1089
1090class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1091begin
1092 result := TExceptionType.NOT_IMPLEMENTED;
1093end;
1094
1095class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1096begin
1097 result := TExceptionType.DEPTH_LIMIT;
1098end;
1099
Jens Geyerd5436f52014-10-03 19:50:38 +02001100{ TBinaryProtocolImpl.TFactory }
1101
1102constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
1103begin
1104 inherited Create;
1105 FStrictRead := AStrictRead;
1106 FStrictWrite := AStrictWrite;
1107end;
1108
1109constructor TBinaryProtocolImpl.TFactory.Create;
1110begin
1111 //no inherited;
1112 Create( False, True )
1113end;
1114
1115function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1116begin
1117 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1118end;
1119
1120
1121{ TProtocolDecorator }
1122
1123constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1124begin
1125 ASSERT( aProtocol <> nil);
1126 inherited Create( aProtocol.Transport);
1127 FWrappedProtocol := aProtocol;
1128end;
1129
1130
Jens Geyer17c3ad92017-09-05 20:31:27 +02001131procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001132begin
1133 FWrappedProtocol.WriteMessageBegin( msg);
1134end;
1135
1136
1137procedure TProtocolDecorator.WriteMessageEnd;
1138begin
1139 FWrappedProtocol.WriteMessageEnd;
1140end;
1141
1142
Jens Geyer17c3ad92017-09-05 20:31:27 +02001143procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001144begin
1145 FWrappedProtocol.WriteStructBegin( struc);
1146end;
1147
1148
1149procedure TProtocolDecorator.WriteStructEnd;
1150begin
1151 FWrappedProtocol.WriteStructEnd;
1152end;
1153
1154
Jens Geyer17c3ad92017-09-05 20:31:27 +02001155procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001156begin
1157 FWrappedProtocol.WriteFieldBegin( field);
1158end;
1159
1160
1161procedure TProtocolDecorator.WriteFieldEnd;
1162begin
1163 FWrappedProtocol.WriteFieldEnd;
1164end;
1165
1166
1167procedure TProtocolDecorator.WriteFieldStop;
1168begin
1169 FWrappedProtocol.WriteFieldStop;
1170end;
1171
1172
Jens Geyer17c3ad92017-09-05 20:31:27 +02001173procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001174begin
1175 FWrappedProtocol.WriteMapBegin( map);
1176end;
1177
1178
1179procedure TProtocolDecorator.WriteMapEnd;
1180begin
1181 FWrappedProtocol.WriteMapEnd;
1182end;
1183
1184
Jens Geyer17c3ad92017-09-05 20:31:27 +02001185procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001186begin
1187 FWrappedProtocol.WriteListBegin( list);
1188end;
1189
1190
1191procedure TProtocolDecorator.WriteListEnd();
1192begin
1193 FWrappedProtocol.WriteListEnd();
1194end;
1195
1196
Jens Geyer17c3ad92017-09-05 20:31:27 +02001197procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001198begin
1199 FWrappedProtocol.WriteSetBegin( set_);
1200end;
1201
1202
1203procedure TProtocolDecorator.WriteSetEnd();
1204begin
1205 FWrappedProtocol.WriteSetEnd();
1206end;
1207
1208
1209procedure TProtocolDecorator.WriteBool( b: Boolean);
1210begin
1211 FWrappedProtocol.WriteBool( b);
1212end;
1213
1214
1215procedure TProtocolDecorator.WriteByte( b: ShortInt);
1216begin
1217 FWrappedProtocol.WriteByte( b);
1218end;
1219
1220
1221procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1222begin
1223 FWrappedProtocol.WriteI16( i16);
1224end;
1225
1226
1227procedure TProtocolDecorator.WriteI32( i32: Integer);
1228begin
1229 FWrappedProtocol.WriteI32( i32);
1230end;
1231
1232
1233procedure TProtocolDecorator.WriteI64( const i64: Int64);
1234begin
1235 FWrappedProtocol.WriteI64( i64);
1236end;
1237
1238
1239procedure TProtocolDecorator.WriteDouble( const d: Double);
1240begin
1241 FWrappedProtocol.WriteDouble( d);
1242end;
1243
1244
1245procedure TProtocolDecorator.WriteString( const s: string );
1246begin
1247 FWrappedProtocol.WriteString( s);
1248end;
1249
1250
1251procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1252begin
1253 FWrappedProtocol.WriteAnsiString( s);
1254end;
1255
1256
1257procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1258begin
1259 FWrappedProtocol.WriteBinary( b);
1260end;
1261
1262
Jens Geyer17c3ad92017-09-05 20:31:27 +02001263function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001264begin
1265 result := FWrappedProtocol.ReadMessageBegin;
1266end;
1267
1268
1269procedure TProtocolDecorator.ReadMessageEnd();
1270begin
1271 FWrappedProtocol.ReadMessageEnd();
1272end;
1273
1274
Jens Geyer17c3ad92017-09-05 20:31:27 +02001275function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001276begin
1277 result := FWrappedProtocol.ReadStructBegin;
1278end;
1279
1280
1281procedure TProtocolDecorator.ReadStructEnd;
1282begin
1283 FWrappedProtocol.ReadStructEnd;
1284end;
1285
1286
Jens Geyer17c3ad92017-09-05 20:31:27 +02001287function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001288begin
1289 result := FWrappedProtocol.ReadFieldBegin;
1290end;
1291
1292
1293procedure TProtocolDecorator.ReadFieldEnd();
1294begin
1295 FWrappedProtocol.ReadFieldEnd();
1296end;
1297
1298
Jens Geyer17c3ad92017-09-05 20:31:27 +02001299function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001300begin
1301 result := FWrappedProtocol.ReadMapBegin;
1302end;
1303
1304
1305procedure TProtocolDecorator.ReadMapEnd();
1306begin
1307 FWrappedProtocol.ReadMapEnd();
1308end;
1309
1310
Jens Geyer17c3ad92017-09-05 20:31:27 +02001311function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001312begin
1313 result := FWrappedProtocol.ReadListBegin;
1314end;
1315
1316
1317procedure TProtocolDecorator.ReadListEnd();
1318begin
1319 FWrappedProtocol.ReadListEnd();
1320end;
1321
1322
Jens Geyer17c3ad92017-09-05 20:31:27 +02001323function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001324begin
1325 result := FWrappedProtocol.ReadSetBegin;
1326end;
1327
1328
1329procedure TProtocolDecorator.ReadSetEnd();
1330begin
1331 FWrappedProtocol.ReadSetEnd();
1332end;
1333
1334
1335function TProtocolDecorator.ReadBool: Boolean;
1336begin
1337 result := FWrappedProtocol.ReadBool;
1338end;
1339
1340
1341function TProtocolDecorator.ReadByte: ShortInt;
1342begin
1343 result := FWrappedProtocol.ReadByte;
1344end;
1345
1346
1347function TProtocolDecorator.ReadI16: SmallInt;
1348begin
1349 result := FWrappedProtocol.ReadI16;
1350end;
1351
1352
1353function TProtocolDecorator.ReadI32: Integer;
1354begin
1355 result := FWrappedProtocol.ReadI32;
1356end;
1357
1358
1359function TProtocolDecorator.ReadI64: Int64;
1360begin
1361 result := FWrappedProtocol.ReadI64;
1362end;
1363
1364
1365function TProtocolDecorator.ReadDouble:Double;
1366begin
1367 result := FWrappedProtocol.ReadDouble;
1368end;
1369
1370
1371function TProtocolDecorator.ReadBinary: TBytes;
1372begin
1373 result := FWrappedProtocol.ReadBinary;
1374end;
1375
1376
1377function TProtocolDecorator.ReadString: string;
1378begin
1379 result := FWrappedProtocol.ReadString;
1380end;
1381
1382
1383function TProtocolDecorator.ReadAnsiString: AnsiString;
1384begin
1385 result := FWrappedProtocol.ReadAnsiString;
1386end;
1387
1388
Jens Geyer17c3ad92017-09-05 20:31:27 +02001389{ Init helper functions }
1390
1391procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1392begin
1393 rec.Name := AName;
1394 rec.Type_ := AMessageType;
1395 rec.SeqID := ASeqID;
1396end;
1397
1398
1399procedure Init( var rec : TThriftStruct; const AName: string = '');
1400begin
1401 rec.Name := AName;
1402end;
1403
1404
1405procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1406begin
1407 rec.Name := AName;
1408 rec.Type_ := AType;
1409 rec.Id := AId;
1410end;
1411
1412
1413procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1414begin
1415 rec.ValueType := AValueType;
1416 rec.KeyType := AKeyType;
1417 rec.Count := ACount;
1418end;
1419
1420
1421procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1422begin
1423 rec.Count := ACount;
1424 rec.ElementType := AElementType;
1425end;
1426
1427
1428procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1429begin
1430 rec.Count := ACount;
1431 rec.ElementType := AElementType;
1432end;
1433
1434
1435
1436
Jens Geyerd5436f52014-10-03 19:50:38 +02001437
1438end.
1439