blob: c09728311a86164defa9bd0303d2809c651e0c34 [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}
Jens Geyer93222f62023-12-15 16:03:48 +010021{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}
Jens Geyerd5436f52014-10-03 19:50:38 +020022
23unit Thrift.Protocol;
24
25interface
26
27uses
28 Classes,
29 SysUtils,
30 Contnrs,
Jens Geyer16819262024-03-07 23:01:20 +010031 Math,
Jens Geyer606f1ef2018-04-09 23:09:41 +020032 Thrift.Exception,
Jens Geyerd5436f52014-10-03 19:50:38 +020033 Thrift.Stream,
Jens Geyer8f7487e2019-05-09 22:21:32 +020034 Thrift.Utils,
Jens Geyerd5436f52014-10-03 19:50:38 +020035 Thrift.Collections,
Jens Geyera019cda2019-11-09 23:24:52 +010036 Thrift.Configuration,
Jens Geyerd5436f52014-10-03 19:50:38 +020037 Thrift.Transport;
38
39type
40
41 TType = (
42 Stop = 0,
43 Void = 1,
44 Bool_ = 2,
45 Byte_ = 3,
46 Double_ = 4,
47 I16 = 6,
48 I32 = 8,
49 I64 = 10,
50 String_ = 11,
51 Struct = 12,
52 Map = 13,
53 Set_ = 14,
Jens Geyer62445c12022-06-29 00:00:00 +020054 List = 15,
55 Uuid = 16
Jens Geyerd5436f52014-10-03 19:50:38 +020056 );
57
58 TMessageType = (
59 Call = 1,
60 Reply = 2,
61 Exception = 3,
62 Oneway = 4
63 );
64
Jens Geyerf0e63312015-03-01 18:47:49 +010065const
66 VALID_TTYPES = [
67 TType.Stop, TType.Void,
Jens Geyer62445c12022-06-29 00:00:00 +020068 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid,
Jens Geyerf0e63312015-03-01 18:47:49 +010069 TType.Struct, TType.Map, TType.Set_, TType.List
70 ];
71
72 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
73
74type
Jens Geyerd5436f52014-10-03 19:50:38 +020075 IProtocol = interface;
Jens Geyer17c3ad92017-09-05 20:31:27 +020076
77 TThriftMessage = record
78 Name: string;
79 Type_: TMessageType;
80 SeqID: Integer;
81 end;
82
83 TThriftStruct = record
84 Name: string;
85 end;
86
87 TThriftField = record
88 Name: string;
89 Type_: TType;
90 Id: SmallInt;
91 end;
92
93 TThriftList = record
94 ElementType: TType;
95 Count: Integer;
96 end;
97
98 TThriftMap = record
99 KeyType: TType;
100 ValueType: TType;
101 Count: Integer;
102 end;
103
104 TThriftSet = record
105 ElementType: TType;
106 Count: Integer;
107 end;
108
109
Jens Geyerd5436f52014-10-03 19:50:38 +0200110 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 Geyerfad7fd32019-11-09 23:24:52 +0100126 strict 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)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100145 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100146 class function GetType: TProtocolException.TExceptionType; override;
147 end;
148
149 TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100150 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100151 class function GetType: TProtocolException.TExceptionType; override;
152 end;
153
154 TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100155 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100156 class function GetType: TProtocolException.TExceptionType; override;
157 end;
158
159 TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100160 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100161 class function GetType: TProtocolException.TExceptionType; override;
162 end;
163
164 TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100165 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100166 class function GetType: TProtocolException.TExceptionType; override;
167 end;
168
169 TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100170 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100171 class function GetType: TProtocolException.TExceptionType; override;
172 end;
173
174 TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100175 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100176 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)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100192 strict protected
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200193 FProtocol : IProtocol;
194 public
195 constructor Create( prot : IProtocol);
196 destructor Destroy; override;
197 end;
198
Jens Geyer07f4bb52022-09-03 14:50:06 +0200199 IThriftBytes = interface; // forward
200
Jens Geyer5cf71b22023-12-18 11:44:55 +0100201 {$TYPEINFO ON}
202 TThriftBytes = packed record // can't use SysUtils.TBytes because it has no typinfo -> E2134
203 data : System.TArray<System.Byte>;
204
205 class operator Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
206 class operator Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
207 function Length : Integer;
208 end;
209 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
210
211
Jens Geyerd5436f52014-10-03 19:50:38 +0200212 IProtocol = interface
Jens Geyer07f4bb52022-09-03 14:50:06 +0200213 ['{6067A28E-15BF-4C9D-9A6F-D991BB3DCB85}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200214 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200215 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200216 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200217 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200218 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200219 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200220 procedure WriteFieldEnd;
221 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200222 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200223 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200224 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200225 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200226 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200227 procedure WriteSetEnd();
228 procedure WriteBool( b: Boolean);
229 procedure WriteByte( b: ShortInt);
230 procedure WriteI16( i16: SmallInt);
231 procedure WriteI32( i32: Integer);
232 procedure WriteI64( const i64: Int64);
233 procedure WriteDouble( const d: Double);
234 procedure WriteString( const s: string );
Jens Geyer07f4bb52022-09-03 14:50:06 +0200235 procedure WriteBinary( const b: TBytes); overload;
236 procedure WriteBinary( const b: IThriftBytes); overload;
Jens Geyer62445c12022-06-29 00:00:00 +0200237 procedure WriteUuid( const uuid: TGuid);
Jens Geyerd5436f52014-10-03 19:50:38 +0200238
Jens Geyer17c3ad92017-09-05 20:31:27 +0200239 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200240 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200241 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200242 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200243 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200244 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200245 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200246 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200247 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200248 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200249 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200250 procedure ReadSetEnd();
251 function ReadBool: Boolean;
252 function ReadByte: ShortInt;
253 function ReadI16: SmallInt;
254 function ReadI32: Integer;
255 function ReadI64: Int64;
256 function ReadDouble:Double;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200257 function ReadBinary: TBytes; // IMPORTANT: this is NOT safe across module boundaries
258 function ReadBinaryCOM : IThriftBytes;
Jens Geyer62445c12022-06-29 00:00:00 +0200259 function ReadUuid: TGuid;
Jens Geyerd5436f52014-10-03 19:50:38 +0200260 function ReadString: string;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200261
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200262 function NextRecursionLevel : IProtocolRecursionTracker;
263 procedure IncrementRecursionDepth;
264 procedure DecrementRecursionDepth;
Jens Geyer41f47af2019-11-09 23:24:52 +0100265 function GetMinSerializedSize( const aType : TType) : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200266
Jens Geyerd5436f52014-10-03 19:50:38 +0200267 property Transport: ITransport read GetTransport;
Jens Geyera019cda2019-11-09 23:24:52 +0100268 function Configuration : IThriftConfiguration;
Jens Geyerd5436f52014-10-03 19:50:38 +0200269 end;
270
Jens Geyer3b686532021-07-01 23:04:08 +0200271 TProtocolImplClass = class of TProtocolImpl;
272
Jens Geyerd5436f52014-10-03 19:50:38 +0200273 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100274 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200275 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200276 FRecursionLimit : Integer;
277 FRecursionDepth : Integer;
278
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200279 function NextRecursionLevel : IProtocolRecursionTracker;
280 procedure IncrementRecursionDepth;
281 procedure DecrementRecursionDepth;
282
Jens Geyer41f47af2019-11-09 23:24:52 +0100283 function GetMinSerializedSize( const aType : TType) : Integer; virtual; abstract;
284 procedure CheckReadBytesAvailable( const value : TThriftList); overload; inline;
285 procedure CheckReadBytesAvailable( const value : TThriftSet); overload; inline;
286 procedure CheckReadBytesAvailable( const value : TThriftMap); overload; inline;
287
288 procedure Reset; virtual;
Jens Geyera019cda2019-11-09 23:24:52 +0100289 function GetTransport: ITransport;
290 function Configuration : IThriftConfiguration;
291
Jens Geyer17c3ad92017-09-05 20:31:27 +0200292 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200293 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200294 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200295 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200296 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200297 procedure WriteFieldEnd; virtual; abstract;
298 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200299 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200300 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200301 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200302 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200303 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200304 procedure WriteSetEnd(); virtual; abstract;
305 procedure WriteBool( b: Boolean); virtual; abstract;
306 procedure WriteByte( b: ShortInt); virtual; abstract;
307 procedure WriteI16( i16: SmallInt); virtual; abstract;
308 procedure WriteI32( i32: Integer); virtual; abstract;
309 procedure WriteI64( const i64: Int64); virtual; abstract;
310 procedure WriteDouble( const d: Double); virtual; abstract;
311 procedure WriteString( const s: string ); virtual;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200312 procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200313 procedure WriteUuid( const b: TGuid); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200314
Jens Geyer17c3ad92017-09-05 20:31:27 +0200315 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200316 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200317 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200318 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200319 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200320 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200321 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200322 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200323 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200324 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200325 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200326 procedure ReadSetEnd(); virtual; abstract;
327 function ReadBool: Boolean; virtual; abstract;
328 function ReadByte: ShortInt; virtual; abstract;
329 function ReadI16: SmallInt; virtual; abstract;
330 function ReadI32: Integer; virtual; abstract;
331 function ReadI64: Int64; virtual; abstract;
332 function ReadDouble:Double; virtual; abstract;
333 function ReadBinary: TBytes; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200334 function ReadUuid: TGuid; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200335 function ReadString: string; virtual;
Jens Geyerd5436f52014-10-03 19:50:38 +0200336
Jens Geyer07f4bb52022-09-03 14:50:06 +0200337 // provide generic implementation for all derived classes
338 procedure WriteBinary( const bytes : IThriftBytes); overload; virtual;
339 function ReadBinaryCOM : IThriftBytes; virtual;
340
Jens Geyera019cda2019-11-09 23:24:52 +0100341 property Transport: ITransport read GetTransport;
Jens Geyerd5436f52014-10-03 19:50:38 +0200342
Jens Geyera019cda2019-11-09 23:24:52 +0100343 public
Jens Geyer3b686532021-07-01 23:04:08 +0200344 constructor Create( const aTransport : ITransport); virtual;
Jens Geyerd5436f52014-10-03 19:50:38 +0200345 end;
346
Jens Geyer5cf71b22023-12-18 11:44:55 +0100347 {.$TYPEINFO ON} // big NO -> may cause E2134 due to Delphis stupidity on enums vs TypeInfo
Jens Geyer93222f62023-12-15 16:03:48 +0100348 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
Jens Geyer8f7487e2019-05-09 22:21:32 +0200349 IBase = interface( ISupportsToString)
350 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyer07f4bb52022-09-03 14:50:06 +0200351 procedure Read( const prot: IProtocol);
352 procedure Write( const prot: IProtocol);
353 end;
Jens Geyer5cf71b22023-12-18 11:44:55 +0100354
355 {$TYPEINFO ON}
356 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
357 IBaseWithTypeInfo = interface( IBase) end;
358
Jens Geyer93222f62023-12-15 16:03:48 +0100359 {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
360 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
Jens Geyer07f4bb52022-09-03 14:50:06 +0200361
362
363 IThriftBytes = interface( ISupportsToString)
364 ['{CDBEF7E8-BEF2-4A0A-983A-F334E3FF0016}']
365 function GetCount : Integer;
366 procedure SetCount(const value : Integer);
367
368 // WARNING: This returns a direct pointer to the underlying data structure
369 function QueryRawDataPtr : Pointer;
370
371 property Count : Integer read GetCount write SetCount;
372 end;
373
374
375 TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString)
376 strict private
377 FData : TBytes;
378
379 strict protected
380 function GetCount : Integer;
381 procedure SetCount(const value : Integer);
382 function QueryRawDataPtr : Pointer;
383
384 public
385 constructor Create; overload;
386 constructor Create( const bytes : TBytes); overload;
387 constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload;
Jens Geyer16819262024-03-07 23:01:20 +0100388 constructor Create( const pData : Pointer; const nCount : Integer); overload;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200389
390 function ToString : string; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200391 end;
392
Jens Geyerd5436f52014-10-03 19:50:38 +0200393
394 TBinaryProtocolImpl = class( TProtocolImpl )
Jens Geyerfad7fd32019-11-09 23:24:52 +0100395 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200396 const
397 VERSION_MASK : Cardinal = $ffff0000;
398 VERSION_1 : Cardinal = $80010000;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100399 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200400 FStrictRead : Boolean;
401 FStrictWrite : Boolean;
Jens Geyer41f47af2019-11-09 23:24:52 +0100402 function GetMinSerializedSize( const aType : TType) : Integer; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200403
Jens Geyerfad7fd32019-11-09 23:24:52 +0100404 strict private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200405 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200406 function ReadStringBody( size: Integer): string;
407
408 public
Jens Geyerd5436f52014-10-03 19:50:38 +0200409 type
410 TFactory = class( TInterfacedObject, IProtocolFactory)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100411 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200412 FStrictRead : Boolean;
413 FStrictWrite : Boolean;
Jens Geyerd5436f52014-10-03 19:50:38 +0200414 function GetProtocol( const trans: ITransport): IProtocol;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100415 public
416 constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200417 end;
418
Jens Geyer3b686532021-07-01 23:04:08 +0200419 constructor Create( const trans: ITransport); overload; override;
420 constructor Create( const trans: ITransport; strictRead, strictWrite: Boolean); reintroduce; overload;
Jens Geyerd5436f52014-10-03 19:50:38 +0200421
Jens Geyer17c3ad92017-09-05 20:31:27 +0200422 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200423 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200424 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200425 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200426 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200427 procedure WriteFieldEnd; override;
428 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200429 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200430 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200431 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200432 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200433 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200434 procedure WriteSetEnd(); override;
435 procedure WriteBool( b: Boolean); override;
436 procedure WriteByte( b: ShortInt); override;
437 procedure WriteI16( i16: SmallInt); override;
438 procedure WriteI32( i32: Integer); override;
439 procedure WriteI64( const i64: Int64); override;
440 procedure WriteDouble( const d: Double); override;
441 procedure WriteBinary( const b: TBytes); override;
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100442 procedure WriteBinary( const bytes : IThriftBytes); overload; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200443 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200444
Jens Geyer17c3ad92017-09-05 20:31:27 +0200445 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200446 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200447 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200448 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200449 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200450 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200451 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200452 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200453 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200454 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200455 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200456 procedure ReadSetEnd(); override;
457 function ReadBool: Boolean; override;
458 function ReadByte: ShortInt; override;
459 function ReadI16: SmallInt; override;
460 function ReadI32: Integer; override;
461 function ReadI64: Int64; override;
462 function ReadDouble:Double; override;
463 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200464 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200465
466 end;
467
468
469 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
470 providing a way to author concise concrete decorator subclasses. The decorator
471 does not (and should not) modify the behaviour of the enclosed TProtocol
472
473 See p.175 of Design Patterns (by Gamma et al.)
474 }
475 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100476 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200477 FWrappedProtocol : IProtocol;
478
Jens Geyer41f47af2019-11-09 23:24:52 +0100479 strict protected
480 function GetMinSerializedSize( const aType : TType) : Integer; override;
481
Jens Geyerd5436f52014-10-03 19:50:38 +0200482 public
483 // Encloses the specified protocol.
484 // All operations will be forward to the given protocol. Must be non-null.
Jens Geyer3b686532021-07-01 23:04:08 +0200485 constructor Create( const aProtocol : IProtocol); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200486
Jens Geyer17c3ad92017-09-05 20:31:27 +0200487 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200488 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200489 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200490 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200491 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200492 procedure WriteFieldEnd; override;
493 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200494 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200495 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200496 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200497 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200498 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200499 procedure WriteSetEnd(); override;
500 procedure WriteBool( b: Boolean); override;
501 procedure WriteByte( b: ShortInt); override;
502 procedure WriteI16( i16: SmallInt); override;
503 procedure WriteI32( i32: Integer); override;
504 procedure WriteI64( const i64: Int64); override;
505 procedure WriteDouble( const d: Double); override;
506 procedure WriteString( const s: string ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200507 procedure WriteBinary( const b: TBytes); override;
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100508 procedure WriteBinary( const bytes : IThriftBytes); overload; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200509 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200510
Jens Geyer17c3ad92017-09-05 20:31:27 +0200511 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200512 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200513 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200514 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200515 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200516 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200517 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200518 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200519 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200520 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200521 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200522 procedure ReadSetEnd(); override;
523 function ReadBool: Boolean; override;
524 function ReadByte: ShortInt; override;
525 function ReadI16: SmallInt; override;
526 function ReadI32: Integer; override;
527 function ReadI64: Int64; override;
528 function ReadDouble:Double; override;
529 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200530 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200531 function ReadString: string; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200532 end;
533
534
535type
536 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200537 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
538 // Called before reading arguments.
539 procedure PreRead;
540 // Called between reading arguments and calling the handler.
541 procedure PostRead;
542 // Called between calling the handler and writing the response.
543 procedure PreWrite;
544 // Called after writing the response.
545 procedure PostWrite;
546 // Called when an oneway (async) function call completes successfully.
547 procedure OnewayComplete;
548 // Called if the handler throws an undeclared exception.
549 procedure UnhandledError( const e : Exception);
550 // Called when a client has finished request-handling to clean up
551 procedure CleanupContext;
552 end;
553
554
555 IProcessorEvents = interface
556 ['{A8661119-657C-447D-93C5-512E36162A45}']
557 // Called when a client is about to call the processor.
558 procedure Processing( const transport : ITransport);
559 // Called on any service function invocation
560 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
561 // Called when a client has finished request-handling to clean up
562 procedure CleanupContext;
563 end;
564
565
566 IProcessor = interface
567 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200568 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200569 end;
570
Jens Geyerd5436f52014-10-03 19:50:38 +0200571
Jens Geyer17c3ad92017-09-05 20:31:27 +0200572procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
573procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
574procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
575procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
576procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
577procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
578
Jens Geyerd5436f52014-10-03 19:50:38 +0200579
580implementation
581
Jens Geyerfad7fd32019-11-09 23:24:52 +0100582function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200583begin
584 ASSERT( SizeOf(n) = SizeOf(Result));
585 System.Move( n, Result, SizeOf(Result));
586end;
587
Jens Geyerfad7fd32019-11-09 23:24:52 +0100588function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200589begin
590 ASSERT( SizeOf(d) = SizeOf(Result));
591 System.Move( d, Result, SizeOf(Result));
592end;
593
Jens Geyerd5436f52014-10-03 19:50:38 +0200594
Jens Geyer5cf71b22023-12-18 11:44:55 +0100595//--- TThriftBytes ----------------------------------------------------------------------
596
597
598class operator TThriftBytes.Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
599begin
600 ASSERT( @result.data = @result); // must be first field
601 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
602 result := TThriftBytes(aRec);
603end;
604
605
606class operator TThriftBytes.Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
607begin
608 ASSERT( @aRec.data = @aRec); // must be first field
609 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
610 result := SysUtils.TBytes(aRec.data);
611end;
612
613
614function TThriftBytes.Length : Integer;
615begin
616 result := System.Length(data);
617end;
618
Jens Geyerd5436f52014-10-03 19:50:38 +0200619
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200620{ TProtocolRecursionTrackerImpl }
621
622constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
623begin
624 inherited Create;
625
626 // storing the pointer *after* the (successful) increment is important here
627 prot.IncrementRecursionDepth;
628 FProtocol := prot;
629end;
630
631destructor TProtocolRecursionTrackerImpl.Destroy;
632begin
633 try
634 // we have to release the reference iff the pointer has been stored
635 if FProtocol <> nil then begin
636 FProtocol.DecrementRecursionDepth;
637 FProtocol := nil;
638 end;
639 finally
640 inherited Destroy;
641 end;
642end;
643
Jens Geyerd5436f52014-10-03 19:50:38 +0200644{ TProtocolImpl }
645
Jens Geyera019cda2019-11-09 23:24:52 +0100646constructor TProtocolImpl.Create( const aTransport : ITransport);
Jens Geyerd5436f52014-10-03 19:50:38 +0200647begin
648 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100649 FTrans := aTransport;
650 FRecursionLimit := aTransport.Configuration.RecursionLimit;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200651 FRecursionDepth := 0;
652end;
653
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200654function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
655begin
656 result := TProtocolRecursionTrackerImpl.Create(Self);
657end;
658
659procedure TProtocolImpl.IncrementRecursionDepth;
660begin
661 if FRecursionDepth < FRecursionLimit
662 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200663 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200664end;
665
666procedure TProtocolImpl.DecrementRecursionDepth;
667begin
668 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200669end;
670
671function TProtocolImpl.GetTransport: ITransport;
672begin
673 Result := FTrans;
674end;
675
Jens Geyera019cda2019-11-09 23:24:52 +0100676function TProtocolImpl.Configuration : IThriftConfiguration;
677begin
678 Result := FTrans.Configuration;
679end;
680
Jens Geyer41f47af2019-11-09 23:24:52 +0100681procedure TProtocolImpl.Reset;
682begin
Jens Geyera019cda2019-11-09 23:24:52 +0100683 FTrans.ResetConsumedMessageSize;
Jens Geyer41f47af2019-11-09 23:24:52 +0100684end;
685
Jens Geyerd5436f52014-10-03 19:50:38 +0200686function TProtocolImpl.ReadString: string;
687begin
688 Result := TEncoding.UTF8.GetString( ReadBinary );
689end;
690
Jens Geyerd5436f52014-10-03 19:50:38 +0200691procedure TProtocolImpl.WriteString(const s: string);
692var
693 b : TBytes;
694begin
695 b := TEncoding.UTF8.GetBytes(s);
696 WriteBinary( b );
697end;
698
Jens Geyer41f47af2019-11-09 23:24:52 +0100699
700procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList);
701begin
702 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
703end;
704
705
706procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet);
707begin
708 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
709end;
710
711
712procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap);
Jens Geyera019cda2019-11-09 23:24:52 +0100713var nPairSize : Integer;
Jens Geyer41f47af2019-11-09 23:24:52 +0100714begin
715 nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType);
716 FTrans.CheckReadBytesAvailable( value.Count * nPairSize);
717end;
718
Jens Geyer07f4bb52022-09-03 14:50:06 +0200719
720procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100721// This implementation works, but is rather inefficient due to the extra memory allocation
722// Consider overwriting this for your transport implementation
Jens Geyer07f4bb52022-09-03 14:50:06 +0200723var tmp : TBytes;
724begin
725 SetLength( tmp, bytes.Count);
726 if Length(tmp) > 0
727 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp));
728 WriteBinary( tmp);
729end;
730
731
732function TProtocolImpl.ReadBinaryCOM : IThriftBytes;
733var bytes : TBytes;
734begin
735 bytes := ReadBinary;
736 result := TThriftBytesImpl.Create(bytes,TRUE);
737end;
738
739
740{ TThriftBytesImpl }
741
742constructor TThriftBytesImpl.Create;
743begin
744 inherited Create;
745 ASSERT( Length(FData) = 0);
746end;
747
748
749constructor TThriftBytesImpl.Create( const bytes : TBytes);
750begin
751 FData := bytes; // copies the data
752end;
753
754
755constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean);
756
757 procedure SwapPointer( var one, two);
758 var
759 pOne : Pointer absolute one;
760 pTwo : Pointer absolute two;
761 pTmp : Pointer;
762 begin
763 pTmp := pOne;
764 pOne := pTwo;
765 pTwo := pTmp;
766 end;
767
768begin
769 inherited Create;
770 ASSERT( Length(FData) = 0);
771
772 if aTakeOwnership
773 then SwapPointer( FData, bytes)
774 else FData := bytes; // copies the data
775end;
776
777
Jens Geyer16819262024-03-07 23:01:20 +0100778constructor TThriftBytesImpl.Create( const pData : Pointer; const nCount : Integer);
779begin
780 SetLength(FData, Max(nCount,0));
781 if Length(FData) > 0 then Move( pData^, FData[0], Length(FData));
782end;
783
784
Jens Geyer07f4bb52022-09-03 14:50:06 +0200785function TThriftBytesImpl.ToString : string;
786var sb : TThriftStringBuilder;
787begin
788 sb := TThriftStringBuilder.Create();
789 try
790 sb.Append('Bin: ');
791 sb.Append( FData);
792
793 result := sb.ToString;
794 finally
795 sb.Free;
796 end;
797end;
798
799
800function TThriftBytesImpl.GetCount : Integer;
801begin
802 result := Length(FData);
803end;
804
805
806procedure TThriftBytesImpl.SetCount(const value : Integer);
807begin
808 SetLength( FData, value);
809end;
810
811
812function TThriftBytesImpl.QueryRawDataPtr : Pointer;
813begin
814 result := FData;
815end;
816
Jens Geyerd5436f52014-10-03 19:50:38 +0200817{ TProtocolUtil }
818
819class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200820var field : TThriftField;
821 map : TThriftMap;
822 set_ : TThriftSet;
823 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200824 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200825 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200826begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200827 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200828 case type_ of
829 // simple types
830 TType.Bool_ : prot.ReadBool();
831 TType.Byte_ : prot.ReadByte();
832 TType.I16 : prot.ReadI16();
833 TType.I32 : prot.ReadI32();
834 TType.I64 : prot.ReadI64();
835 TType.Double_ : prot.ReadDouble();
836 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jens Geyer62445c12022-06-29 00:00:00 +0200837 TType.Uuid : prot.ReadUuid();
Jens Geyerd5436f52014-10-03 19:50:38 +0200838
839 // structured types
840 TType.Struct : begin
841 prot.ReadStructBegin();
842 while TRUE do begin
843 field := prot.ReadFieldBegin();
844 if (field.Type_ = TType.Stop) then Break;
845 Skip(prot, field.Type_);
846 prot.ReadFieldEnd();
847 end;
848 prot.ReadStructEnd();
849 end;
850
851 TType.Map : begin
852 map := prot.ReadMapBegin();
853 for i := 0 to map.Count-1 do begin
854 Skip(prot, map.KeyType);
855 Skip(prot, map.ValueType);
856 end;
857 prot.ReadMapEnd();
858 end;
859
860 TType.Set_ : begin
861 set_ := prot.ReadSetBegin();
862 for i := 0 to set_.Count-1
863 do Skip( prot, set_.ElementType);
864 prot.ReadSetEnd();
865 end;
866
867 TType.List : begin
868 list := prot.ReadListBegin();
869 for i := 0 to list.Count-1
870 do Skip( prot, list.ElementType);
871 prot.ReadListEnd();
872 end;
873
874 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100875 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200876 end;
877end;
878
Jens Geyerd5436f52014-10-03 19:50:38 +0200879
880{ TBinaryProtocolImpl }
881
Jens Geyer3b686532021-07-01 23:04:08 +0200882constructor TBinaryProtocolImpl.Create( const trans: ITransport);
883begin
884 // call the real CTOR
885 Self.Create( trans, FALSE, TRUE);
886end;
887
Jens Geyerfad7fd32019-11-09 23:24:52 +0100888constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200889begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100890 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200891 FStrictRead := strictRead;
892 FStrictWrite := strictWrite;
893end;
894
Jens Geyer17c3ad92017-09-05 20:31:27 +0200895function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200896begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200897 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200898end;
899
900function TBinaryProtocolImpl.ReadBinary: TBytes;
901var
902 size : Integer;
903 buf : TBytes;
904begin
905 size := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100906 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100907 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200908 FTrans.ReadAll( buf, 0, size);
909 Result := buf;
910end;
911
Jens Geyer62445c12022-06-29 00:00:00 +0200912function TBinaryProtocolImpl.ReadUuid : TGuid;
913var network : TGuid; // in network order (Big Endian)
914begin
915 ASSERT( SizeOf(result) = 16);
916 FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
Jens Geyerf8f62782022-09-10 00:55:02 +0200917 result := GuidUtils.SwapByteOrder(network);
Jens Geyer62445c12022-06-29 00:00:00 +0200918end;
919
Jens Geyerd5436f52014-10-03 19:50:38 +0200920function TBinaryProtocolImpl.ReadBool: Boolean;
921begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200922 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200923end;
924
925function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200926begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200927 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200928end;
929
930function TBinaryProtocolImpl.ReadDouble: Double;
931begin
932 Result := ConvertInt64ToDouble( ReadI64 )
933end;
934
Jens Geyer17c3ad92017-09-05 20:31:27 +0200935function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200936begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200937 Init( result, '', TType( ReadByte), 0);
938 if ( result.Type_ <> TType.Stop ) then begin
939 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200940 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200941end;
942
943procedure TBinaryProtocolImpl.ReadFieldEnd;
944begin
945
946end;
947
948function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200949var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200950begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200951 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200952 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
953end;
954
955function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200956var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200957begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200958 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200959
960 Result := Integer(
961 ((i32in[0] and $FF) shl 24) or
962 ((i32in[1] and $FF) shl 16) or
963 ((i32in[2] and $FF) shl 8) or
964 (i32in[3] and $FF));
965
966end;
967
968function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200969var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200970begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200971 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200972 Result :=
973 (Int64( i64in[0] and $FF) shl 56) or
974 (Int64( i64in[1] and $FF) shl 48) or
975 (Int64( i64in[2] and $FF) shl 40) or
976 (Int64( i64in[3] and $FF) shl 32) or
977 (Int64( i64in[4] and $FF) shl 24) or
978 (Int64( i64in[5] and $FF) shl 16) or
979 (Int64( i64in[6] and $FF) shl 8) or
980 (Int64( i64in[7] and $FF));
981end;
982
Jens Geyer17c3ad92017-09-05 20:31:27 +0200983function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200984begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200985 result.ElementType := TType(ReadByte);
986 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100987 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200988end;
989
990procedure TBinaryProtocolImpl.ReadListEnd;
991begin
992
993end;
994
Jens Geyer17c3ad92017-09-05 20:31:27 +0200995function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200996begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200997 result.KeyType := TType(ReadByte);
998 result.ValueType := TType(ReadByte);
999 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001000 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001001end;
1002
1003procedure TBinaryProtocolImpl.ReadMapEnd;
1004begin
1005
1006end;
1007
Jens Geyer17c3ad92017-09-05 20:31:27 +02001008function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001009var
1010 size : Integer;
1011 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +02001012begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001013 Reset;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001014 Init( result);
Jens Geyer589ee5b2021-03-29 21:40:55 +02001015
Jens Geyerd5436f52014-10-03 19:50:38 +02001016 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001017 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001018 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001019 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +02001020 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +02001021 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001022 result.Type_ := TMessageType( size and $000000ff);
1023 result.Name := ReadString;
1024 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001025 Exit;
1026 end;
1027
1028 try
1029 if FStrictRead
1030 then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
1031
Jens Geyer17c3ad92017-09-05 20:31:27 +02001032 result.Name := ReadStringBody( size );
1033 result.Type_ := TMessageType( ReadByte );
1034 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001035 except
1036 if CharUtils.IsHtmlDoctype(size)
1037 then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
1038 else raise; // something else
Jens Geyerd5436f52014-10-03 19:50:38 +02001039 end;
Jens Geyerd5436f52014-10-03 19:50:38 +02001040end;
1041
1042procedure TBinaryProtocolImpl.ReadMessageEnd;
1043begin
1044 inherited;
1045
1046end;
1047
Jens Geyer17c3ad92017-09-05 20:31:27 +02001048function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001049begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001050 result.ElementType := TType(ReadByte);
1051 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001052 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001053end;
1054
1055procedure TBinaryProtocolImpl.ReadSetEnd;
1056begin
1057
1058end;
1059
1060function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001061var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +02001062begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001063 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001064 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +02001065 FTrans.ReadAll( buf, 0, size );
1066 Result := TEncoding.UTF8.GetString( buf);
1067end;
1068
Jens Geyer17c3ad92017-09-05 20:31:27 +02001069function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001070begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001071 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001072end;
1073
1074procedure TBinaryProtocolImpl.ReadStructEnd;
1075begin
1076 inherited;
1077
1078end;
1079
1080procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1081var iLen : Integer;
1082begin
1083 iLen := Length(b);
1084 WriteI32( iLen);
1085 if iLen > 0 then FTrans.Write(b, 0, iLen);
1086end;
1087
Jens Geyerb53fa8e2024-03-08 00:33:22 +01001088procedure TBinaryProtocolImpl.WriteBinary( const bytes : IThriftBytes);
1089var iLen : Integer;
1090begin
1091 iLen := bytes.Count;
1092 WriteI32( iLen);
1093 if iLen > 0 then FTrans.Write( bytes.QueryRawDataPtr, 0, iLen);
1094end;
1095
Jens Geyer62445c12022-06-29 00:00:00 +02001096procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
1097var network : TGuid; // in network order (Big Endian)
1098begin
1099 ASSERT( SizeOf(uuid) = 16);
Jens Geyerf8f62782022-09-10 00:55:02 +02001100 network := GuidUtils.SwapByteOrder(uuid);
Jens Geyer62445c12022-06-29 00:00:00 +02001101 Transport.Write( @network, 0, SizeOf(network));
1102end;
1103
Jens Geyerd5436f52014-10-03 19:50:38 +02001104procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1105begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001106 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001107 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +02001108 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001109 WriteByte( 0 );
1110 end;
1111end;
1112
1113procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +02001114begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001115 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +02001116end;
1117
1118procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1119begin
1120 WriteI64(ConvertDoubleToInt64(d));
1121end;
1122
Jens Geyer17c3ad92017-09-05 20:31:27 +02001123procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001124begin
1125 WriteByte(ShortInt(field.Type_));
1126 WriteI16(field.ID);
1127end;
1128
1129procedure TBinaryProtocolImpl.WriteFieldEnd;
1130begin
1131
1132end;
1133
1134procedure TBinaryProtocolImpl.WriteFieldStop;
1135begin
1136 WriteByte(ShortInt(TType.Stop));
1137end;
1138
1139procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001140var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001141begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001142 i16out[0] := Byte($FF and (i16 shr 8));
1143 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001144 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +02001145end;
1146
1147procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001148var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001149begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001150 i32out[0] := Byte($FF and (i32 shr 24));
1151 i32out[1] := Byte($FF and (i32 shr 16));
1152 i32out[2] := Byte($FF and (i32 shr 8));
1153 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001154 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001155end;
1156
1157procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001158var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001159begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001160 i64out[0] := Byte($FF and (i64 shr 56));
1161 i64out[1] := Byte($FF and (i64 shr 48));
1162 i64out[2] := Byte($FF and (i64 shr 40));
1163 i64out[3] := Byte($FF and (i64 shr 32));
1164 i64out[4] := Byte($FF and (i64 shr 24));
1165 i64out[5] := Byte($FF and (i64 shr 16));
1166 i64out[6] := Byte($FF and (i64 shr 8));
1167 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001168 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001169end;
1170
Jens Geyer17c3ad92017-09-05 20:31:27 +02001171procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001172begin
1173 WriteByte(ShortInt(list.ElementType));
1174 WriteI32(list.Count);
1175end;
1176
1177procedure TBinaryProtocolImpl.WriteListEnd;
1178begin
1179
1180end;
1181
Jens Geyer17c3ad92017-09-05 20:31:27 +02001182procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001183begin
1184 WriteByte(ShortInt(map.KeyType));
1185 WriteByte(ShortInt(map.ValueType));
1186 WriteI32(map.Count);
1187end;
1188
1189procedure TBinaryProtocolImpl.WriteMapEnd;
1190begin
1191
1192end;
1193
Jens Geyer17c3ad92017-09-05 20:31:27 +02001194procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001195var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +02001196begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001197 Reset;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001198 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001199 version := VERSION_1 or Cardinal( msg.Type_);
1200 WriteI32( Integer( version) );
1201 WriteString( msg.Name);
1202 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001203 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001204 WriteString( msg.Name);
1205 WriteByte(ShortInt( msg.Type_));
1206 WriteI32( msg.SeqID);
1207 end;
1208end;
1209
1210procedure TBinaryProtocolImpl.WriteMessageEnd;
1211begin
1212
1213end;
1214
Jens Geyer17c3ad92017-09-05 20:31:27 +02001215procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +02001216begin
1217 WriteByte(ShortInt(set_.ElementType));
1218 WriteI32(set_.Count);
1219end;
1220
1221procedure TBinaryProtocolImpl.WriteSetEnd;
1222begin
1223
1224end;
1225
Jens Geyer17c3ad92017-09-05 20:31:27 +02001226procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001227begin
1228
1229end;
1230
1231procedure TBinaryProtocolImpl.WriteStructEnd;
1232begin
1233
1234end;
1235
Jens Geyer41f47af2019-11-09 23:24:52 +01001236function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
1237// Return the minimum number of bytes a type will consume on the wire
1238begin
1239 case aType of
1240 TType.Stop: result := 0;
1241 TType.Void: result := 0;
1242 TType.Bool_: result := SizeOf(Byte);
1243 TType.Byte_: result := SizeOf(Byte);
1244 TType.Double_: result := SizeOf(Double);
1245 TType.I16: result := SizeOf(Int16);
1246 TType.I32: result := SizeOf(Int32);
1247 TType.I64: result := SizeOf(Int64);
1248 TType.String_: result := SizeOf(Int32); // string length
1249 TType.Struct: result := 0; // empty struct
1250 TType.Map: result := SizeOf(Int32); // element count
1251 TType.Set_: result := SizeOf(Int32); // element count
1252 TType.List: result := SizeOf(Int32); // element count
Jens Geyer62445c12022-06-29 00:00:00 +02001253 TType.Uuid: result := SizeOf(TGuid);
Jens Geyer41f47af2019-11-09 23:24:52 +01001254 else
1255 raise TTransportExceptionBadArgs.Create('Unhandled type code');
1256 end;
1257end;
1258
1259
Jens Geyerd5436f52014-10-03 19:50:38 +02001260{ TProtocolException }
1261
Jens Geyere0e32402016-04-20 21:50:48 +02001262constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001263begin
Jens Geyere0e32402016-04-20 21:50:48 +02001264 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001265end;
1266
Jens Geyere0e32402016-04-20 21:50:48 +02001267class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001268begin
Jens Geyere0e32402016-04-20 21:50:48 +02001269 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001270end;
1271
Jens Geyere0e32402016-04-20 21:50:48 +02001272class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001273begin
Jens Geyere0e32402016-04-20 21:50:48 +02001274 Result := TProtocolExceptionUnknown.Create('');
1275end;
1276
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001277class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001278begin
1279{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001280 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001281{$WARN SYMBOL_DEPRECATED DEFAULT}
1282end;
1283
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001284class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001285begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001286 case aType of
1287 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1288 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1289 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1290 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1291 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1292 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001293 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001294 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001295 Result := TProtocolExceptionUnknown.Create(msg);
1296 end;
1297end;
1298
1299{ TProtocolExceptionSpecialized }
1300
1301constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1302begin
1303 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001304end;
1305
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001306{ specialized TProtocolExceptions }
1307
1308class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1309begin
1310 result := TExceptionType.UNKNOWN;
1311end;
1312
1313class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1314begin
1315 result := TExceptionType.INVALID_DATA;
1316end;
1317
1318class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1319begin
1320 result := TExceptionType.NEGATIVE_SIZE;
1321end;
1322
1323class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1324begin
1325 result := TExceptionType.SIZE_LIMIT;
1326end;
1327
1328class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1329begin
1330 result := TExceptionType.BAD_VERSION;
1331end;
1332
1333class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1334begin
1335 result := TExceptionType.NOT_IMPLEMENTED;
1336end;
1337
1338class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1339begin
1340 result := TExceptionType.DEPTH_LIMIT;
1341end;
1342
Jens Geyerd5436f52014-10-03 19:50:38 +02001343{ TBinaryProtocolImpl.TFactory }
1344
Jens Geyerfad7fd32019-11-09 23:24:52 +01001345constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001346begin
1347 inherited Create;
1348 FStrictRead := AStrictRead;
1349 FStrictWrite := AStrictWrite;
1350end;
1351
Jens Geyerd5436f52014-10-03 19:50:38 +02001352function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1353begin
1354 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1355end;
1356
1357
1358{ TProtocolDecorator }
1359
1360constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1361begin
1362 ASSERT( aProtocol <> nil);
1363 inherited Create( aProtocol.Transport);
1364 FWrappedProtocol := aProtocol;
1365end;
1366
1367
Jens Geyer17c3ad92017-09-05 20:31:27 +02001368procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001369begin
1370 FWrappedProtocol.WriteMessageBegin( msg);
1371end;
1372
1373
1374procedure TProtocolDecorator.WriteMessageEnd;
1375begin
1376 FWrappedProtocol.WriteMessageEnd;
1377end;
1378
1379
Jens Geyer17c3ad92017-09-05 20:31:27 +02001380procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001381begin
1382 FWrappedProtocol.WriteStructBegin( struc);
1383end;
1384
1385
1386procedure TProtocolDecorator.WriteStructEnd;
1387begin
1388 FWrappedProtocol.WriteStructEnd;
1389end;
1390
1391
Jens Geyer17c3ad92017-09-05 20:31:27 +02001392procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001393begin
1394 FWrappedProtocol.WriteFieldBegin( field);
1395end;
1396
1397
1398procedure TProtocolDecorator.WriteFieldEnd;
1399begin
1400 FWrappedProtocol.WriteFieldEnd;
1401end;
1402
1403
1404procedure TProtocolDecorator.WriteFieldStop;
1405begin
1406 FWrappedProtocol.WriteFieldStop;
1407end;
1408
1409
Jens Geyer17c3ad92017-09-05 20:31:27 +02001410procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001411begin
1412 FWrappedProtocol.WriteMapBegin( map);
1413end;
1414
1415
1416procedure TProtocolDecorator.WriteMapEnd;
1417begin
1418 FWrappedProtocol.WriteMapEnd;
1419end;
1420
1421
Jens Geyer17c3ad92017-09-05 20:31:27 +02001422procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001423begin
1424 FWrappedProtocol.WriteListBegin( list);
1425end;
1426
1427
1428procedure TProtocolDecorator.WriteListEnd();
1429begin
1430 FWrappedProtocol.WriteListEnd();
1431end;
1432
1433
Jens Geyer17c3ad92017-09-05 20:31:27 +02001434procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001435begin
1436 FWrappedProtocol.WriteSetBegin( set_);
1437end;
1438
1439
1440procedure TProtocolDecorator.WriteSetEnd();
1441begin
1442 FWrappedProtocol.WriteSetEnd();
1443end;
1444
1445
1446procedure TProtocolDecorator.WriteBool( b: Boolean);
1447begin
1448 FWrappedProtocol.WriteBool( b);
1449end;
1450
1451
1452procedure TProtocolDecorator.WriteByte( b: ShortInt);
1453begin
1454 FWrappedProtocol.WriteByte( b);
1455end;
1456
1457
1458procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1459begin
1460 FWrappedProtocol.WriteI16( i16);
1461end;
1462
1463
1464procedure TProtocolDecorator.WriteI32( i32: Integer);
1465begin
1466 FWrappedProtocol.WriteI32( i32);
1467end;
1468
1469
1470procedure TProtocolDecorator.WriteI64( const i64: Int64);
1471begin
1472 FWrappedProtocol.WriteI64( i64);
1473end;
1474
1475
1476procedure TProtocolDecorator.WriteDouble( const d: Double);
1477begin
1478 FWrappedProtocol.WriteDouble( d);
1479end;
1480
1481
1482procedure TProtocolDecorator.WriteString( const s: string );
1483begin
1484 FWrappedProtocol.WriteString( s);
1485end;
1486
1487
Jens Geyerd5436f52014-10-03 19:50:38 +02001488procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1489begin
1490 FWrappedProtocol.WriteBinary( b);
1491end;
1492
1493
Jens Geyerb53fa8e2024-03-08 00:33:22 +01001494procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes);
1495begin
1496 FWrappedProtocol.WriteBinary( bytes);
1497end;
1498
1499
Jens Geyer62445c12022-06-29 00:00:00 +02001500procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
1501begin
1502 FWrappedProtocol.WriteUuid( uuid);
1503end;
1504
1505
Jens Geyer17c3ad92017-09-05 20:31:27 +02001506function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001507begin
1508 result := FWrappedProtocol.ReadMessageBegin;
1509end;
1510
1511
1512procedure TProtocolDecorator.ReadMessageEnd();
1513begin
1514 FWrappedProtocol.ReadMessageEnd();
1515end;
1516
1517
Jens Geyer17c3ad92017-09-05 20:31:27 +02001518function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001519begin
1520 result := FWrappedProtocol.ReadStructBegin;
1521end;
1522
1523
1524procedure TProtocolDecorator.ReadStructEnd;
1525begin
1526 FWrappedProtocol.ReadStructEnd;
1527end;
1528
1529
Jens Geyer17c3ad92017-09-05 20:31:27 +02001530function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001531begin
1532 result := FWrappedProtocol.ReadFieldBegin;
1533end;
1534
1535
1536procedure TProtocolDecorator.ReadFieldEnd();
1537begin
1538 FWrappedProtocol.ReadFieldEnd();
1539end;
1540
1541
Jens Geyer17c3ad92017-09-05 20:31:27 +02001542function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001543begin
1544 result := FWrappedProtocol.ReadMapBegin;
1545end;
1546
1547
1548procedure TProtocolDecorator.ReadMapEnd();
1549begin
1550 FWrappedProtocol.ReadMapEnd();
1551end;
1552
1553
Jens Geyer17c3ad92017-09-05 20:31:27 +02001554function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001555begin
1556 result := FWrappedProtocol.ReadListBegin;
1557end;
1558
1559
1560procedure TProtocolDecorator.ReadListEnd();
1561begin
1562 FWrappedProtocol.ReadListEnd();
1563end;
1564
1565
Jens Geyer17c3ad92017-09-05 20:31:27 +02001566function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001567begin
1568 result := FWrappedProtocol.ReadSetBegin;
1569end;
1570
1571
1572procedure TProtocolDecorator.ReadSetEnd();
1573begin
1574 FWrappedProtocol.ReadSetEnd();
1575end;
1576
1577
1578function TProtocolDecorator.ReadBool: Boolean;
1579begin
1580 result := FWrappedProtocol.ReadBool;
1581end;
1582
1583
1584function TProtocolDecorator.ReadByte: ShortInt;
1585begin
1586 result := FWrappedProtocol.ReadByte;
1587end;
1588
1589
1590function TProtocolDecorator.ReadI16: SmallInt;
1591begin
1592 result := FWrappedProtocol.ReadI16;
1593end;
1594
1595
1596function TProtocolDecorator.ReadI32: Integer;
1597begin
1598 result := FWrappedProtocol.ReadI32;
1599end;
1600
1601
1602function TProtocolDecorator.ReadI64: Int64;
1603begin
1604 result := FWrappedProtocol.ReadI64;
1605end;
1606
1607
1608function TProtocolDecorator.ReadDouble:Double;
1609begin
1610 result := FWrappedProtocol.ReadDouble;
1611end;
1612
1613
1614function TProtocolDecorator.ReadBinary: TBytes;
1615begin
1616 result := FWrappedProtocol.ReadBinary;
1617end;
1618
1619
Jens Geyer62445c12022-06-29 00:00:00 +02001620function TProtocolDecorator.ReadUuid: TGuid;
1621begin
1622 result := FWrappedProtocol.ReadUuid;
1623end;
1624
1625
Jens Geyerd5436f52014-10-03 19:50:38 +02001626function TProtocolDecorator.ReadString: string;
1627begin
1628 result := FWrappedProtocol.ReadString;
1629end;
1630
1631
Jens Geyer41f47af2019-11-09 23:24:52 +01001632function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer;
1633begin
1634 result := FWrappedProtocol.GetMinSerializedSize(aType);
1635end;
1636
1637
Jens Geyer17c3ad92017-09-05 20:31:27 +02001638{ Init helper functions }
1639
1640procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1641begin
1642 rec.Name := AName;
1643 rec.Type_ := AMessageType;
1644 rec.SeqID := ASeqID;
1645end;
1646
1647
1648procedure Init( var rec : TThriftStruct; const AName: string = '');
1649begin
1650 rec.Name := AName;
1651end;
1652
1653
1654procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1655begin
1656 rec.Name := AName;
1657 rec.Type_ := AType;
1658 rec.Id := AId;
1659end;
1660
1661
1662procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1663begin
1664 rec.ValueType := AValueType;
1665 rec.KeyType := AKeyType;
1666 rec.Count := ACount;
1667end;
1668
1669
1670procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1671begin
1672 rec.Count := ACount;
1673 rec.ElementType := AElementType;
1674end;
1675
1676
1677procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1678begin
1679 rec.Count := ACount;
1680 rec.ElementType := AElementType;
1681end;
1682
1683
1684
Jens Geyerd5436f52014-10-03 19:50:38 +02001685end.
1686