blob: 36509ca18826b3aa34c36dc1b78bb6bbf26cba11 [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,
32 Thrift.Collections,
33 Thrift.Transport;
34
35type
36
37 TType = (
38 Stop = 0,
39 Void = 1,
40 Bool_ = 2,
41 Byte_ = 3,
42 Double_ = 4,
43 I16 = 6,
44 I32 = 8,
45 I64 = 10,
46 String_ = 11,
47 Struct = 12,
48 Map = 13,
49 Set_ = 14,
50 List = 15
51 );
52
53 TMessageType = (
54 Call = 1,
55 Reply = 2,
56 Exception = 3,
57 Oneway = 4
58 );
59
Jens Geyerf0e63312015-03-01 18:47:49 +010060const
61 VALID_TTYPES = [
62 TType.Stop, TType.Void,
63 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
64 TType.Struct, TType.Map, TType.Set_, TType.List
65 ];
66
67 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
68
Jens Geyerd47fcdd2015-07-09 22:05:18 +020069const
70 DEFAULT_RECURSION_LIMIT = 64;
71
Jens Geyerf0e63312015-03-01 18:47:49 +010072type
Jens Geyerd5436f52014-10-03 19:50:38 +020073 IProtocol = interface;
Jens Geyer17c3ad92017-09-05 20:31:27 +020074
75 TThriftMessage = record
76 Name: string;
77 Type_: TMessageType;
78 SeqID: Integer;
79 end;
80
81 TThriftStruct = record
82 Name: string;
83 end;
84
85 TThriftField = record
86 Name: string;
87 Type_: TType;
88 Id: SmallInt;
89 end;
90
91 TThriftList = record
92 ElementType: TType;
93 Count: Integer;
94 end;
95
96 TThriftMap = record
97 KeyType: TType;
98 ValueType: TType;
99 Count: Integer;
100 end;
101
102 TThriftSet = record
103 ElementType: TType;
104 Count: Integer;
105 end;
106
107
Jens Geyerd5436f52014-10-03 19:50:38 +0200108
109 IProtocolFactory = interface
110 ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
111 function GetProtocol( const trans: ITransport): IProtocol;
112 end;
113
114 TThriftStringBuilder = class( TStringBuilder)
115 public
116 function Append(const Value: TBytes): TStringBuilder; overload;
117 function Append(const Value: IThriftContainer): TStringBuilder; overload;
118 end;
119
Jens Geyer606f1ef2018-04-09 23:09:41 +0200120 TProtocolException = class( TException)
Jens Geyerd5436f52014-10-03 19:50:38 +0200121 public
122 const // TODO(jensg): change into enum
Jens Geyere0e32402016-04-20 21:50:48 +0200123 UNKNOWN = 0;
124 INVALID_DATA = 1;
125 NEGATIVE_SIZE = 2;
126 SIZE_LIMIT = 3;
127 BAD_VERSION = 4;
128 NOT_IMPLEMENTED = 5;
129 DEPTH_LIMIT = 6;
Jens Geyerd5436f52014-10-03 19:50:38 +0200130 protected
Jens Geyere0e32402016-04-20 21:50:48 +0200131 constructor HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +0200132 public
Jens Geyere0e32402016-04-20 21:50:48 +0200133 // purposefully hide inherited constructor
134 class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
135 class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
136 class function Create( type_: Integer): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
137 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 +0200138 end;
139
Jens Geyere0e32402016-04-20 21:50:48 +0200140 // Needed to remove deprecation warning
141 TProtocolExceptionSpecialized = class abstract (TProtocolException)
142 public
143 constructor Create(const Msg: string);
144 end;
145
146 TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized);
147 TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized);
148 TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized);
149 TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized);
150 TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized);
151 TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized);
152 TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized);
153
Jens Geyerd5436f52014-10-03 19:50:38 +0200154
155 TProtocolUtil = class
156 public
157 class procedure Skip( prot: IProtocol; type_: TType);
158 end;
159
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200160 IProtocolRecursionTracker = interface
161 ['{29CA033F-BB56-49B1-9EE3-31B1E82FC7A5}']
162 // no members yet
163 end;
164
165 TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRecursionTracker)
166 protected
167 FProtocol : IProtocol;
168 public
169 constructor Create( prot : IProtocol);
170 destructor Destroy; override;
171 end;
172
Jens Geyerd5436f52014-10-03 19:50:38 +0200173 IProtocol = interface
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200174 ['{602A7FFB-0D9E-4CD8-8D7F-E5076660588A}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200175 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200176 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200177 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200178 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200179 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200180 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200181 procedure WriteFieldEnd;
182 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200183 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200184 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200185 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200186 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200187 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200188 procedure WriteSetEnd();
189 procedure WriteBool( b: Boolean);
190 procedure WriteByte( b: ShortInt);
191 procedure WriteI16( i16: SmallInt);
192 procedure WriteI32( i32: Integer);
193 procedure WriteI64( const i64: Int64);
194 procedure WriteDouble( const d: Double);
195 procedure WriteString( const s: string );
196 procedure WriteAnsiString( const s: AnsiString);
197 procedure WriteBinary( const b: TBytes);
198
Jens Geyer17c3ad92017-09-05 20:31:27 +0200199 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200200 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200201 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200202 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200203 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200204 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200205 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200206 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200207 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200208 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200209 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200210 procedure ReadSetEnd();
211 function ReadBool: Boolean;
212 function ReadByte: ShortInt;
213 function ReadI16: SmallInt;
214 function ReadI32: Integer;
215 function ReadI64: Int64;
216 function ReadDouble:Double;
217 function ReadBinary: TBytes;
218 function ReadString: string;
219 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200220
221 procedure SetRecursionLimit( value : Integer);
222 function GetRecursionLimit : Integer;
223 function NextRecursionLevel : IProtocolRecursionTracker;
224 procedure IncrementRecursionDepth;
225 procedure DecrementRecursionDepth;
226
Jens Geyerd5436f52014-10-03 19:50:38 +0200227 property Transport: ITransport read GetTransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200228 property RecursionLimit : Integer read GetRecursionLimit write SetRecursionLimit;
Jens Geyerd5436f52014-10-03 19:50:38 +0200229 end;
230
231 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
232 protected
233 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200234 FRecursionLimit : Integer;
235 FRecursionDepth : Integer;
236
237 procedure SetRecursionLimit( value : Integer);
238 function GetRecursionLimit : Integer;
239 function NextRecursionLevel : IProtocolRecursionTracker;
240 procedure IncrementRecursionDepth;
241 procedure DecrementRecursionDepth;
242
Jens Geyerd5436f52014-10-03 19:50:38 +0200243 function GetTransport: ITransport;
244 public
Jens Geyer17c3ad92017-09-05 20:31:27 +0200245 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200246 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200247 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200248 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200249 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200250 procedure WriteFieldEnd; virtual; abstract;
251 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200252 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200253 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200254 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200255 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200256 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200257 procedure WriteSetEnd(); virtual; abstract;
258 procedure WriteBool( b: Boolean); virtual; abstract;
259 procedure WriteByte( b: ShortInt); virtual; abstract;
260 procedure WriteI16( i16: SmallInt); virtual; abstract;
261 procedure WriteI32( i32: Integer); virtual; abstract;
262 procedure WriteI64( const i64: Int64); virtual; abstract;
263 procedure WriteDouble( const d: Double); virtual; abstract;
264 procedure WriteString( const s: string ); virtual;
265 procedure WriteAnsiString( const s: AnsiString); virtual;
266 procedure WriteBinary( const b: TBytes); virtual; abstract;
267
Jens Geyer17c3ad92017-09-05 20:31:27 +0200268 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200269 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200270 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200271 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200272 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200273 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200274 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200275 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200276 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200277 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200278 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200279 procedure ReadSetEnd(); virtual; abstract;
280 function ReadBool: Boolean; virtual; abstract;
281 function ReadByte: ShortInt; virtual; abstract;
282 function ReadI16: SmallInt; virtual; abstract;
283 function ReadI32: Integer; virtual; abstract;
284 function ReadI64: Int64; virtual; abstract;
285 function ReadDouble:Double; virtual; abstract;
286 function ReadBinary: TBytes; virtual; abstract;
287 function ReadString: string; virtual;
288 function ReadAnsiString: AnsiString; virtual;
289
290 property Transport: ITransport read GetTransport;
291
292 constructor Create( trans: ITransport );
293 end;
294
295 IBase = interface
296 ['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
297 function ToString: string;
298 procedure Read( const iprot: IProtocol);
299 procedure Write( const iprot: IProtocol);
300 end;
301
Jens Geyerd5436f52014-10-03 19:50:38 +0200302
303 TBinaryProtocolImpl = class( TProtocolImpl )
304 protected
305 const
306 VERSION_MASK : Cardinal = $ffff0000;
307 VERSION_1 : Cardinal = $80010000;
308 protected
309 FStrictRead : Boolean;
310 FStrictWrite : Boolean;
311
312 private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200313 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200314 function ReadStringBody( size: Integer): string;
315
316 public
317
318 type
319 TFactory = class( TInterfacedObject, IProtocolFactory)
320 protected
321 FStrictRead : Boolean;
322 FStrictWrite : Boolean;
323 public
324 function GetProtocol( const trans: ITransport): IProtocol;
325 constructor Create( AStrictRead, AStrictWrite: Boolean ); overload;
326 constructor Create; overload;
327 end;
328
329 constructor Create( const trans: ITransport); overload;
330 constructor Create( const trans: ITransport; strictRead: Boolean; strictWrite: Boolean); overload;
331
Jens Geyer17c3ad92017-09-05 20:31:27 +0200332 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200333 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200334 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200335 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200336 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200337 procedure WriteFieldEnd; override;
338 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200339 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200340 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200341 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200342 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200343 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200344 procedure WriteSetEnd(); override;
345 procedure WriteBool( b: Boolean); override;
346 procedure WriteByte( b: ShortInt); override;
347 procedure WriteI16( i16: SmallInt); override;
348 procedure WriteI32( i32: Integer); override;
349 procedure WriteI64( const i64: Int64); override;
350 procedure WriteDouble( const d: Double); override;
351 procedure WriteBinary( const b: TBytes); override;
352
Jens Geyer17c3ad92017-09-05 20:31:27 +0200353 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200354 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200355 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200356 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200357 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200358 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200359 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200360 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200361 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200362 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200363 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200364 procedure ReadSetEnd(); override;
365 function ReadBool: Boolean; override;
366 function ReadByte: ShortInt; override;
367 function ReadI16: SmallInt; override;
368 function ReadI32: Integer; override;
369 function ReadI64: Int64; override;
370 function ReadDouble:Double; override;
371 function ReadBinary: TBytes; override;
372
373 end;
374
375
376 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
377 providing a way to author concise concrete decorator subclasses. The decorator
378 does not (and should not) modify the behaviour of the enclosed TProtocol
379
380 See p.175 of Design Patterns (by Gamma et al.)
381 }
382 TProtocolDecorator = class( TProtocolImpl)
383 private
384 FWrappedProtocol : IProtocol;
385
386 public
387 // Encloses the specified protocol.
388 // All operations will be forward to the given protocol. Must be non-null.
389 constructor Create( const aProtocol : IProtocol);
390
Jens Geyer17c3ad92017-09-05 20:31:27 +0200391 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200392 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200393 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200394 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200395 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200396 procedure WriteFieldEnd; override;
397 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200398 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200399 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200400 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200401 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200402 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200403 procedure WriteSetEnd(); override;
404 procedure WriteBool( b: Boolean); override;
405 procedure WriteByte( b: ShortInt); override;
406 procedure WriteI16( i16: SmallInt); override;
407 procedure WriteI32( i32: Integer); override;
408 procedure WriteI64( const i64: Int64); override;
409 procedure WriteDouble( const d: Double); override;
410 procedure WriteString( const s: string ); override;
411 procedure WriteAnsiString( const s: AnsiString); override;
412 procedure WriteBinary( const b: TBytes); override;
413
Jens Geyer17c3ad92017-09-05 20:31:27 +0200414 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200415 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200416 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200417 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200418 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200419 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200420 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200421 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200422 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200423 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200424 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200425 procedure ReadSetEnd(); override;
426 function ReadBool: Boolean; override;
427 function ReadByte: ShortInt; override;
428 function ReadI16: SmallInt; override;
429 function ReadI32: Integer; override;
430 function ReadI64: Int64; override;
431 function ReadDouble:Double; override;
432 function ReadBinary: TBytes; override;
433 function ReadString: string; override;
434 function ReadAnsiString: AnsiString; override;
435 end;
436
437
438type
439 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200440 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
441 // Called before reading arguments.
442 procedure PreRead;
443 // Called between reading arguments and calling the handler.
444 procedure PostRead;
445 // Called between calling the handler and writing the response.
446 procedure PreWrite;
447 // Called after writing the response.
448 procedure PostWrite;
449 // Called when an oneway (async) function call completes successfully.
450 procedure OnewayComplete;
451 // Called if the handler throws an undeclared exception.
452 procedure UnhandledError( const e : Exception);
453 // Called when a client has finished request-handling to clean up
454 procedure CleanupContext;
455 end;
456
457
458 IProcessorEvents = interface
459 ['{A8661119-657C-447D-93C5-512E36162A45}']
460 // Called when a client is about to call the processor.
461 procedure Processing( const transport : ITransport);
462 // Called on any service function invocation
463 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
464 // Called when a client has finished request-handling to clean up
465 procedure CleanupContext;
466 end;
467
468
469 IProcessor = interface
470 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200471 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200472 end;
473
Jens Geyerd5436f52014-10-03 19:50:38 +0200474
Jens Geyer17c3ad92017-09-05 20:31:27 +0200475procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
476procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
477procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
478procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
479procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
480procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
481
Jens Geyerd5436f52014-10-03 19:50:38 +0200482
483implementation
484
485function ConvertInt64ToDouble( const n: Int64): Double;
486begin
487 ASSERT( SizeOf(n) = SizeOf(Result));
488 System.Move( n, Result, SizeOf(Result));
489end;
490
491function ConvertDoubleToInt64( const d: Double): Int64;
492begin
493 ASSERT( SizeOf(d) = SizeOf(Result));
494 System.Move( d, Result, SizeOf(Result));
495end;
496
Jens Geyerd5436f52014-10-03 19:50:38 +0200497
Jens Geyerd5436f52014-10-03 19:50:38 +0200498
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200499{ TProtocolRecursionTrackerImpl }
500
501constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
502begin
503 inherited Create;
504
505 // storing the pointer *after* the (successful) increment is important here
506 prot.IncrementRecursionDepth;
507 FProtocol := prot;
508end;
509
510destructor TProtocolRecursionTrackerImpl.Destroy;
511begin
512 try
513 // we have to release the reference iff the pointer has been stored
514 if FProtocol <> nil then begin
515 FProtocol.DecrementRecursionDepth;
516 FProtocol := nil;
517 end;
518 finally
519 inherited Destroy;
520 end;
521end;
522
Jens Geyerd5436f52014-10-03 19:50:38 +0200523{ TProtocolImpl }
524
525constructor TProtocolImpl.Create(trans: ITransport);
526begin
527 inherited Create;
528 FTrans := trans;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200529 FRecursionLimit := DEFAULT_RECURSION_LIMIT;
530 FRecursionDepth := 0;
531end;
532
533procedure TProtocolImpl.SetRecursionLimit( value : Integer);
534begin
535 FRecursionLimit := value;
536end;
537
538function TProtocolImpl.GetRecursionLimit : Integer;
539begin
540 result := FRecursionLimit;
541end;
542
543function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
544begin
545 result := TProtocolRecursionTrackerImpl.Create(Self);
546end;
547
548procedure TProtocolImpl.IncrementRecursionDepth;
549begin
550 if FRecursionDepth < FRecursionLimit
551 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200552 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200553end;
554
555procedure TProtocolImpl.DecrementRecursionDepth;
556begin
557 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200558end;
559
560function TProtocolImpl.GetTransport: ITransport;
561begin
562 Result := FTrans;
563end;
564
565function TProtocolImpl.ReadAnsiString: AnsiString;
566var
567 b : TBytes;
568 len : Integer;
569begin
570 Result := '';
571 b := ReadBinary;
572 len := Length( b );
573 if len > 0 then
574 begin
575 SetLength( Result, len);
576 System.Move( b[0], Pointer(Result)^, len );
577 end;
578end;
579
580function TProtocolImpl.ReadString: string;
581begin
582 Result := TEncoding.UTF8.GetString( ReadBinary );
583end;
584
585procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
586var
587 b : TBytes;
588 len : Integer;
589begin
590 len := Length(s);
591 SetLength( b, len);
592 if len > 0 then
593 begin
594 System.Move( Pointer(s)^, b[0], len );
595 end;
596 WriteBinary( b );
597end;
598
599procedure TProtocolImpl.WriteString(const s: string);
600var
601 b : TBytes;
602begin
603 b := TEncoding.UTF8.GetBytes(s);
604 WriteBinary( b );
605end;
606
607{ TProtocolUtil }
608
609class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200610var field : TThriftField;
611 map : TThriftMap;
612 set_ : TThriftSet;
613 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200614 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200615 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200616begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200617 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200618 case type_ of
619 // simple types
620 TType.Bool_ : prot.ReadBool();
621 TType.Byte_ : prot.ReadByte();
622 TType.I16 : prot.ReadI16();
623 TType.I32 : prot.ReadI32();
624 TType.I64 : prot.ReadI64();
625 TType.Double_ : prot.ReadDouble();
626 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
627
628 // structured types
629 TType.Struct : begin
630 prot.ReadStructBegin();
631 while TRUE do begin
632 field := prot.ReadFieldBegin();
633 if (field.Type_ = TType.Stop) then Break;
634 Skip(prot, field.Type_);
635 prot.ReadFieldEnd();
636 end;
637 prot.ReadStructEnd();
638 end;
639
640 TType.Map : begin
641 map := prot.ReadMapBegin();
642 for i := 0 to map.Count-1 do begin
643 Skip(prot, map.KeyType);
644 Skip(prot, map.ValueType);
645 end;
646 prot.ReadMapEnd();
647 end;
648
649 TType.Set_ : begin
650 set_ := prot.ReadSetBegin();
651 for i := 0 to set_.Count-1
652 do Skip( prot, set_.ElementType);
653 prot.ReadSetEnd();
654 end;
655
656 TType.List : begin
657 list := prot.ReadListBegin();
658 for i := 0 to list.Count-1
659 do Skip( prot, list.ElementType);
660 prot.ReadListEnd();
661 end;
662
663 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100664 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200665 end;
666end;
667
Jens Geyerd5436f52014-10-03 19:50:38 +0200668
669{ TBinaryProtocolImpl }
670
671constructor TBinaryProtocolImpl.Create( const trans: ITransport);
672begin
673 //no inherited
674 Create( trans, False, True);
675end;
676
677constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead,
678 strictWrite: Boolean);
679begin
680 inherited Create( trans );
681 FStrictRead := strictRead;
682 FStrictWrite := strictWrite;
683end;
684
Jens Geyer17c3ad92017-09-05 20:31:27 +0200685function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200686begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200687 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200688end;
689
690function TBinaryProtocolImpl.ReadBinary: TBytes;
691var
692 size : Integer;
693 buf : TBytes;
694begin
695 size := ReadI32;
696 SetLength( buf, size );
697 FTrans.ReadAll( buf, 0, size);
698 Result := buf;
699end;
700
701function TBinaryProtocolImpl.ReadBool: Boolean;
702begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200703 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200704end;
705
706function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200707begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200708 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200709end;
710
711function TBinaryProtocolImpl.ReadDouble: Double;
712begin
713 Result := ConvertInt64ToDouble( ReadI64 )
714end;
715
Jens Geyer17c3ad92017-09-05 20:31:27 +0200716function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200717begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200718 Init( result, '', TType( ReadByte), 0);
719 if ( result.Type_ <> TType.Stop ) then begin
720 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200721 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200722end;
723
724procedure TBinaryProtocolImpl.ReadFieldEnd;
725begin
726
727end;
728
729function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200730var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200731begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200732 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200733 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
734end;
735
736function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200737var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200738begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200739 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200740
741 Result := Integer(
742 ((i32in[0] and $FF) shl 24) or
743 ((i32in[1] and $FF) shl 16) or
744 ((i32in[2] and $FF) shl 8) or
745 (i32in[3] and $FF));
746
747end;
748
749function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200750var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200751begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200752 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200753 Result :=
754 (Int64( i64in[0] and $FF) shl 56) or
755 (Int64( i64in[1] and $FF) shl 48) or
756 (Int64( i64in[2] and $FF) shl 40) or
757 (Int64( i64in[3] and $FF) shl 32) or
758 (Int64( i64in[4] and $FF) shl 24) or
759 (Int64( i64in[5] and $FF) shl 16) or
760 (Int64( i64in[6] and $FF) shl 8) or
761 (Int64( i64in[7] and $FF));
762end;
763
Jens Geyer17c3ad92017-09-05 20:31:27 +0200764function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200765begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200766 result.ElementType := TType(ReadByte);
767 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200768end;
769
770procedure TBinaryProtocolImpl.ReadListEnd;
771begin
772
773end;
774
Jens Geyer17c3ad92017-09-05 20:31:27 +0200775function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200776begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200777 result.KeyType := TType(ReadByte);
778 result.ValueType := TType(ReadByte);
779 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200780end;
781
782procedure TBinaryProtocolImpl.ReadMapEnd;
783begin
784
785end;
786
Jens Geyer17c3ad92017-09-05 20:31:27 +0200787function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200788var
789 size : Integer;
790 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200791begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200792 Init( result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200793 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200794 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200795 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200796 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200797 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +0200798 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200799 result.Type_ := TMessageType( size and $000000ff);
800 result.Name := ReadString;
801 result.SeqID := ReadI32;
802 end
803 else begin
804 if FStrictRead then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200805 raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
Jens Geyerd5436f52014-10-03 19:50:38 +0200806 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200807 result.Name := ReadStringBody( size );
808 result.Type_ := TMessageType( ReadByte );
809 result.SeqID := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200810 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200811end;
812
813procedure TBinaryProtocolImpl.ReadMessageEnd;
814begin
815 inherited;
816
817end;
818
Jens Geyer17c3ad92017-09-05 20:31:27 +0200819function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200820begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200821 result.ElementType := TType(ReadByte);
822 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200823end;
824
825procedure TBinaryProtocolImpl.ReadSetEnd;
826begin
827
828end;
829
830function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
831var
832 buf : TBytes;
833begin
834 SetLength( buf, size );
835 FTrans.ReadAll( buf, 0, size );
836 Result := TEncoding.UTF8.GetString( buf);
837end;
838
Jens Geyer17c3ad92017-09-05 20:31:27 +0200839function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200840begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200841 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200842end;
843
844procedure TBinaryProtocolImpl.ReadStructEnd;
845begin
846 inherited;
847
848end;
849
850procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
851var iLen : Integer;
852begin
853 iLen := Length(b);
854 WriteI32( iLen);
855 if iLen > 0 then FTrans.Write(b, 0, iLen);
856end;
857
858procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
859begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200860 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200861 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +0200862 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200863 WriteByte( 0 );
864 end;
865end;
866
867procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +0200868begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200869 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200870end;
871
872procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
873begin
874 WriteI64(ConvertDoubleToInt64(d));
875end;
876
Jens Geyer17c3ad92017-09-05 20:31:27 +0200877procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200878begin
879 WriteByte(ShortInt(field.Type_));
880 WriteI16(field.ID);
881end;
882
883procedure TBinaryProtocolImpl.WriteFieldEnd;
884begin
885
886end;
887
888procedure TBinaryProtocolImpl.WriteFieldStop;
889begin
890 WriteByte(ShortInt(TType.Stop));
891end;
892
893procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200894var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200895begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200896 i16out[0] := Byte($FF and (i16 shr 8));
897 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200898 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200899end;
900
901procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200902var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200903begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200904 i32out[0] := Byte($FF and (i32 shr 24));
905 i32out[1] := Byte($FF and (i32 shr 16));
906 i32out[2] := Byte($FF and (i32 shr 8));
907 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200908 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200909end;
910
911procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200912var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200913begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200914 i64out[0] := Byte($FF and (i64 shr 56));
915 i64out[1] := Byte($FF and (i64 shr 48));
916 i64out[2] := Byte($FF and (i64 shr 40));
917 i64out[3] := Byte($FF and (i64 shr 32));
918 i64out[4] := Byte($FF and (i64 shr 24));
919 i64out[5] := Byte($FF and (i64 shr 16));
920 i64out[6] := Byte($FF and (i64 shr 8));
921 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200922 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200923end;
924
Jens Geyer17c3ad92017-09-05 20:31:27 +0200925procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200926begin
927 WriteByte(ShortInt(list.ElementType));
928 WriteI32(list.Count);
929end;
930
931procedure TBinaryProtocolImpl.WriteListEnd;
932begin
933
934end;
935
Jens Geyer17c3ad92017-09-05 20:31:27 +0200936procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200937begin
938 WriteByte(ShortInt(map.KeyType));
939 WriteByte(ShortInt(map.ValueType));
940 WriteI32(map.Count);
941end;
942
943procedure TBinaryProtocolImpl.WriteMapEnd;
944begin
945
946end;
947
Jens Geyer17c3ad92017-09-05 20:31:27 +0200948procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200949var
950 version : Cardinal;
951begin
952 if FStrictWrite then
953 begin
954 version := VERSION_1 or Cardinal( msg.Type_);
955 WriteI32( Integer( version) );
956 WriteString( msg.Name);
957 WriteI32( msg.SeqID);
958 end else
959 begin
960 WriteString( msg.Name);
961 WriteByte(ShortInt( msg.Type_));
962 WriteI32( msg.SeqID);
963 end;
964end;
965
966procedure TBinaryProtocolImpl.WriteMessageEnd;
967begin
968
969end;
970
Jens Geyer17c3ad92017-09-05 20:31:27 +0200971procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +0200972begin
973 WriteByte(ShortInt(set_.ElementType));
974 WriteI32(set_.Count);
975end;
976
977procedure TBinaryProtocolImpl.WriteSetEnd;
978begin
979
980end;
981
Jens Geyer17c3ad92017-09-05 20:31:27 +0200982procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200983begin
984
985end;
986
987procedure TBinaryProtocolImpl.WriteStructEnd;
988begin
989
990end;
991
992{ TProtocolException }
993
Jens Geyere0e32402016-04-20 21:50:48 +0200994constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +0200995begin
Jens Geyere0e32402016-04-20 21:50:48 +0200996 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +0200997end;
998
Jens Geyere0e32402016-04-20 21:50:48 +0200999class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001000begin
Jens Geyere0e32402016-04-20 21:50:48 +02001001 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001002end;
1003
Jens Geyere0e32402016-04-20 21:50:48 +02001004class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001005begin
Jens Geyere0e32402016-04-20 21:50:48 +02001006 Result := TProtocolExceptionUnknown.Create('');
1007end;
1008
1009class function TProtocolException.Create(type_: Integer): TProtocolException;
1010begin
1011{$WARN SYMBOL_DEPRECATED OFF}
1012 Result := Create(type_, '');
1013{$WARN SYMBOL_DEPRECATED DEFAULT}
1014end;
1015
1016class function TProtocolException.Create(type_: Integer; const msg: string): TProtocolException;
1017begin
1018 case type_ of
1019 INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1020 NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1021 SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1022 BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1023 NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1024 DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
1025 else
1026 Result := TProtocolExceptionUnknown.Create(msg);
1027 end;
1028end;
1029
1030{ TProtocolExceptionSpecialized }
1031
1032constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1033begin
1034 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001035end;
1036
1037{ TThriftStringBuilder }
1038
1039function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
1040begin
1041 Result := Append( string( RawByteString(Value)) );
1042end;
1043
1044function TThriftStringBuilder.Append(
1045 const Value: IThriftContainer): TStringBuilder;
1046begin
1047 Result := Append( Value.ToString );
1048end;
1049
1050{ TBinaryProtocolImpl.TFactory }
1051
1052constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
1053begin
1054 inherited Create;
1055 FStrictRead := AStrictRead;
1056 FStrictWrite := AStrictWrite;
1057end;
1058
1059constructor TBinaryProtocolImpl.TFactory.Create;
1060begin
1061 //no inherited;
1062 Create( False, True )
1063end;
1064
1065function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1066begin
1067 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1068end;
1069
1070
1071{ TProtocolDecorator }
1072
1073constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1074begin
1075 ASSERT( aProtocol <> nil);
1076 inherited Create( aProtocol.Transport);
1077 FWrappedProtocol := aProtocol;
1078end;
1079
1080
Jens Geyer17c3ad92017-09-05 20:31:27 +02001081procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001082begin
1083 FWrappedProtocol.WriteMessageBegin( msg);
1084end;
1085
1086
1087procedure TProtocolDecorator.WriteMessageEnd;
1088begin
1089 FWrappedProtocol.WriteMessageEnd;
1090end;
1091
1092
Jens Geyer17c3ad92017-09-05 20:31:27 +02001093procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001094begin
1095 FWrappedProtocol.WriteStructBegin( struc);
1096end;
1097
1098
1099procedure TProtocolDecorator.WriteStructEnd;
1100begin
1101 FWrappedProtocol.WriteStructEnd;
1102end;
1103
1104
Jens Geyer17c3ad92017-09-05 20:31:27 +02001105procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001106begin
1107 FWrappedProtocol.WriteFieldBegin( field);
1108end;
1109
1110
1111procedure TProtocolDecorator.WriteFieldEnd;
1112begin
1113 FWrappedProtocol.WriteFieldEnd;
1114end;
1115
1116
1117procedure TProtocolDecorator.WriteFieldStop;
1118begin
1119 FWrappedProtocol.WriteFieldStop;
1120end;
1121
1122
Jens Geyer17c3ad92017-09-05 20:31:27 +02001123procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001124begin
1125 FWrappedProtocol.WriteMapBegin( map);
1126end;
1127
1128
1129procedure TProtocolDecorator.WriteMapEnd;
1130begin
1131 FWrappedProtocol.WriteMapEnd;
1132end;
1133
1134
Jens Geyer17c3ad92017-09-05 20:31:27 +02001135procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001136begin
1137 FWrappedProtocol.WriteListBegin( list);
1138end;
1139
1140
1141procedure TProtocolDecorator.WriteListEnd();
1142begin
1143 FWrappedProtocol.WriteListEnd();
1144end;
1145
1146
Jens Geyer17c3ad92017-09-05 20:31:27 +02001147procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001148begin
1149 FWrappedProtocol.WriteSetBegin( set_);
1150end;
1151
1152
1153procedure TProtocolDecorator.WriteSetEnd();
1154begin
1155 FWrappedProtocol.WriteSetEnd();
1156end;
1157
1158
1159procedure TProtocolDecorator.WriteBool( b: Boolean);
1160begin
1161 FWrappedProtocol.WriteBool( b);
1162end;
1163
1164
1165procedure TProtocolDecorator.WriteByte( b: ShortInt);
1166begin
1167 FWrappedProtocol.WriteByte( b);
1168end;
1169
1170
1171procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1172begin
1173 FWrappedProtocol.WriteI16( i16);
1174end;
1175
1176
1177procedure TProtocolDecorator.WriteI32( i32: Integer);
1178begin
1179 FWrappedProtocol.WriteI32( i32);
1180end;
1181
1182
1183procedure TProtocolDecorator.WriteI64( const i64: Int64);
1184begin
1185 FWrappedProtocol.WriteI64( i64);
1186end;
1187
1188
1189procedure TProtocolDecorator.WriteDouble( const d: Double);
1190begin
1191 FWrappedProtocol.WriteDouble( d);
1192end;
1193
1194
1195procedure TProtocolDecorator.WriteString( const s: string );
1196begin
1197 FWrappedProtocol.WriteString( s);
1198end;
1199
1200
1201procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1202begin
1203 FWrappedProtocol.WriteAnsiString( s);
1204end;
1205
1206
1207procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1208begin
1209 FWrappedProtocol.WriteBinary( b);
1210end;
1211
1212
Jens Geyer17c3ad92017-09-05 20:31:27 +02001213function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001214begin
1215 result := FWrappedProtocol.ReadMessageBegin;
1216end;
1217
1218
1219procedure TProtocolDecorator.ReadMessageEnd();
1220begin
1221 FWrappedProtocol.ReadMessageEnd();
1222end;
1223
1224
Jens Geyer17c3ad92017-09-05 20:31:27 +02001225function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001226begin
1227 result := FWrappedProtocol.ReadStructBegin;
1228end;
1229
1230
1231procedure TProtocolDecorator.ReadStructEnd;
1232begin
1233 FWrappedProtocol.ReadStructEnd;
1234end;
1235
1236
Jens Geyer17c3ad92017-09-05 20:31:27 +02001237function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001238begin
1239 result := FWrappedProtocol.ReadFieldBegin;
1240end;
1241
1242
1243procedure TProtocolDecorator.ReadFieldEnd();
1244begin
1245 FWrappedProtocol.ReadFieldEnd();
1246end;
1247
1248
Jens Geyer17c3ad92017-09-05 20:31:27 +02001249function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001250begin
1251 result := FWrappedProtocol.ReadMapBegin;
1252end;
1253
1254
1255procedure TProtocolDecorator.ReadMapEnd();
1256begin
1257 FWrappedProtocol.ReadMapEnd();
1258end;
1259
1260
Jens Geyer17c3ad92017-09-05 20:31:27 +02001261function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001262begin
1263 result := FWrappedProtocol.ReadListBegin;
1264end;
1265
1266
1267procedure TProtocolDecorator.ReadListEnd();
1268begin
1269 FWrappedProtocol.ReadListEnd();
1270end;
1271
1272
Jens Geyer17c3ad92017-09-05 20:31:27 +02001273function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001274begin
1275 result := FWrappedProtocol.ReadSetBegin;
1276end;
1277
1278
1279procedure TProtocolDecorator.ReadSetEnd();
1280begin
1281 FWrappedProtocol.ReadSetEnd();
1282end;
1283
1284
1285function TProtocolDecorator.ReadBool: Boolean;
1286begin
1287 result := FWrappedProtocol.ReadBool;
1288end;
1289
1290
1291function TProtocolDecorator.ReadByte: ShortInt;
1292begin
1293 result := FWrappedProtocol.ReadByte;
1294end;
1295
1296
1297function TProtocolDecorator.ReadI16: SmallInt;
1298begin
1299 result := FWrappedProtocol.ReadI16;
1300end;
1301
1302
1303function TProtocolDecorator.ReadI32: Integer;
1304begin
1305 result := FWrappedProtocol.ReadI32;
1306end;
1307
1308
1309function TProtocolDecorator.ReadI64: Int64;
1310begin
1311 result := FWrappedProtocol.ReadI64;
1312end;
1313
1314
1315function TProtocolDecorator.ReadDouble:Double;
1316begin
1317 result := FWrappedProtocol.ReadDouble;
1318end;
1319
1320
1321function TProtocolDecorator.ReadBinary: TBytes;
1322begin
1323 result := FWrappedProtocol.ReadBinary;
1324end;
1325
1326
1327function TProtocolDecorator.ReadString: string;
1328begin
1329 result := FWrappedProtocol.ReadString;
1330end;
1331
1332
1333function TProtocolDecorator.ReadAnsiString: AnsiString;
1334begin
1335 result := FWrappedProtocol.ReadAnsiString;
1336end;
1337
1338
Jens Geyer17c3ad92017-09-05 20:31:27 +02001339{ Init helper functions }
1340
1341procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1342begin
1343 rec.Name := AName;
1344 rec.Type_ := AMessageType;
1345 rec.SeqID := ASeqID;
1346end;
1347
1348
1349procedure Init( var rec : TThriftStruct; const AName: string = '');
1350begin
1351 rec.Name := AName;
1352end;
1353
1354
1355procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1356begin
1357 rec.Name := AName;
1358 rec.Type_ := AType;
1359 rec.Id := AId;
1360end;
1361
1362
1363procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1364begin
1365 rec.ValueType := AValueType;
1366 rec.KeyType := AKeyType;
1367 rec.Count := ACount;
1368end;
1369
1370
1371procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1372begin
1373 rec.Count := ACount;
1374 rec.ElementType := AElementType;
1375end;
1376
1377
1378procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1379begin
1380 rec.Count := ACount;
1381 rec.ElementType := AElementType;
1382end;
1383
1384
1385
1386
Jens Geyerd5436f52014-10-03 19:50:38 +02001387
1388end.
1389