blob: 4c02d3ff317dca17e9bb0b25bea19d37c06a9667 [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 );
235 procedure WriteAnsiString( const s: AnsiString);
Jens Geyer07f4bb52022-09-03 14:50:06 +0200236 procedure WriteBinary( const b: TBytes); overload;
237 procedure WriteBinary( const b: IThriftBytes); overload;
Jens Geyer62445c12022-06-29 00:00:00 +0200238 procedure WriteUuid( const uuid: TGuid);
Jens Geyerd5436f52014-10-03 19:50:38 +0200239
Jens Geyer17c3ad92017-09-05 20:31:27 +0200240 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200241 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200242 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200243 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200244 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200245 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200246 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200247 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200248 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200249 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200250 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200251 procedure ReadSetEnd();
252 function ReadBool: Boolean;
253 function ReadByte: ShortInt;
254 function ReadI16: SmallInt;
255 function ReadI32: Integer;
256 function ReadI64: Int64;
257 function ReadDouble:Double;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200258 function ReadBinary: TBytes; // IMPORTANT: this is NOT safe across module boundaries
259 function ReadBinaryCOM : IThriftBytes;
Jens Geyer62445c12022-06-29 00:00:00 +0200260 function ReadUuid: TGuid;
Jens Geyerd5436f52014-10-03 19:50:38 +0200261 function ReadString: string;
262 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200263
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200264 function NextRecursionLevel : IProtocolRecursionTracker;
265 procedure IncrementRecursionDepth;
266 procedure DecrementRecursionDepth;
Jens Geyer41f47af2019-11-09 23:24:52 +0100267 function GetMinSerializedSize( const aType : TType) : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200268
Jens Geyerd5436f52014-10-03 19:50:38 +0200269 property Transport: ITransport read GetTransport;
Jens Geyera019cda2019-11-09 23:24:52 +0100270 function Configuration : IThriftConfiguration;
Jens Geyerd5436f52014-10-03 19:50:38 +0200271 end;
272
Jens Geyer3b686532021-07-01 23:04:08 +0200273 TProtocolImplClass = class of TProtocolImpl;
274
Jens Geyerd5436f52014-10-03 19:50:38 +0200275 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100276 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200277 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200278 FRecursionLimit : Integer;
279 FRecursionDepth : Integer;
280
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200281 function NextRecursionLevel : IProtocolRecursionTracker;
282 procedure IncrementRecursionDepth;
283 procedure DecrementRecursionDepth;
284
Jens Geyer41f47af2019-11-09 23:24:52 +0100285 function GetMinSerializedSize( const aType : TType) : Integer; virtual; abstract;
286 procedure CheckReadBytesAvailable( const value : TThriftList); overload; inline;
287 procedure CheckReadBytesAvailable( const value : TThriftSet); overload; inline;
288 procedure CheckReadBytesAvailable( const value : TThriftMap); overload; inline;
289
290 procedure Reset; virtual;
Jens Geyera019cda2019-11-09 23:24:52 +0100291 function GetTransport: ITransport;
292 function Configuration : IThriftConfiguration;
293
Jens Geyer17c3ad92017-09-05 20:31:27 +0200294 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200295 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200296 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200297 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200298 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200299 procedure WriteFieldEnd; virtual; abstract;
300 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200301 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200302 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200303 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200304 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200305 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200306 procedure WriteSetEnd(); virtual; abstract;
307 procedure WriteBool( b: Boolean); virtual; abstract;
308 procedure WriteByte( b: ShortInt); virtual; abstract;
309 procedure WriteI16( i16: SmallInt); virtual; abstract;
310 procedure WriteI32( i32: Integer); virtual; abstract;
311 procedure WriteI64( const i64: Int64); virtual; abstract;
312 procedure WriteDouble( const d: Double); virtual; abstract;
313 procedure WriteString( const s: string ); virtual;
314 procedure WriteAnsiString( const s: AnsiString); virtual;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200315 procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200316 procedure WriteUuid( const b: TGuid); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200317
Jens Geyer17c3ad92017-09-05 20:31:27 +0200318 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200319 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200320 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200321 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200322 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200323 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200324 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200325 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200326 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200327 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200328 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200329 procedure ReadSetEnd(); virtual; abstract;
330 function ReadBool: Boolean; virtual; abstract;
331 function ReadByte: ShortInt; virtual; abstract;
332 function ReadI16: SmallInt; virtual; abstract;
333 function ReadI32: Integer; virtual; abstract;
334 function ReadI64: Int64; virtual; abstract;
335 function ReadDouble:Double; virtual; abstract;
336 function ReadBinary: TBytes; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200337 function ReadUuid: TGuid; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200338 function ReadString: string; virtual;
339 function ReadAnsiString: AnsiString; virtual;
340
Jens Geyer07f4bb52022-09-03 14:50:06 +0200341 // provide generic implementation for all derived classes
342 procedure WriteBinary( const bytes : IThriftBytes); overload; virtual;
343 function ReadBinaryCOM : IThriftBytes; virtual;
344
Jens Geyera019cda2019-11-09 23:24:52 +0100345 property Transport: ITransport read GetTransport;
Jens Geyerd5436f52014-10-03 19:50:38 +0200346
Jens Geyera019cda2019-11-09 23:24:52 +0100347 public
Jens Geyer3b686532021-07-01 23:04:08 +0200348 constructor Create( const aTransport : ITransport); virtual;
Jens Geyerd5436f52014-10-03 19:50:38 +0200349 end;
350
Jens Geyer5cf71b22023-12-18 11:44:55 +0100351 {.$TYPEINFO ON} // big NO -> may cause E2134 due to Delphis stupidity on enums vs TypeInfo
Jens Geyer93222f62023-12-15 16:03:48 +0100352 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
Jens Geyer8f7487e2019-05-09 22:21:32 +0200353 IBase = interface( ISupportsToString)
354 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyer07f4bb52022-09-03 14:50:06 +0200355 procedure Read( const prot: IProtocol);
356 procedure Write( const prot: IProtocol);
357 end;
Jens Geyer5cf71b22023-12-18 11:44:55 +0100358
359 {$TYPEINFO ON}
360 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
361 IBaseWithTypeInfo = interface( IBase) end;
362
Jens Geyer93222f62023-12-15 16:03:48 +0100363 {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
364 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
Jens Geyer07f4bb52022-09-03 14:50:06 +0200365
366
367 IThriftBytes = interface( ISupportsToString)
368 ['{CDBEF7E8-BEF2-4A0A-983A-F334E3FF0016}']
369 function GetCount : Integer;
370 procedure SetCount(const value : Integer);
371
372 // WARNING: This returns a direct pointer to the underlying data structure
373 function QueryRawDataPtr : Pointer;
374
375 property Count : Integer read GetCount write SetCount;
376 end;
377
378
379 TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString)
380 strict private
381 FData : TBytes;
382
383 strict protected
384 function GetCount : Integer;
385 procedure SetCount(const value : Integer);
386 function QueryRawDataPtr : Pointer;
387
388 public
389 constructor Create; overload;
390 constructor Create( const bytes : TBytes); overload;
391 constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload;
Jens Geyer16819262024-03-07 23:01:20 +0100392 constructor Create( const pData : Pointer; const nCount : Integer); overload;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200393
394 function ToString : string; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200395 end;
396
Jens Geyerd5436f52014-10-03 19:50:38 +0200397
398 TBinaryProtocolImpl = class( TProtocolImpl )
Jens Geyerfad7fd32019-11-09 23:24:52 +0100399 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200400 const
401 VERSION_MASK : Cardinal = $ffff0000;
402 VERSION_1 : Cardinal = $80010000;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100403 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200404 FStrictRead : Boolean;
405 FStrictWrite : Boolean;
Jens Geyer41f47af2019-11-09 23:24:52 +0100406 function GetMinSerializedSize( const aType : TType) : Integer; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200407
Jens Geyerfad7fd32019-11-09 23:24:52 +0100408 strict private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200409 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200410 function ReadStringBody( size: Integer): string;
411
412 public
Jens Geyerd5436f52014-10-03 19:50:38 +0200413 type
414 TFactory = class( TInterfacedObject, IProtocolFactory)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100415 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200416 FStrictRead : Boolean;
417 FStrictWrite : Boolean;
Jens Geyerd5436f52014-10-03 19:50:38 +0200418 function GetProtocol( const trans: ITransport): IProtocol;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100419 public
420 constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200421 end;
422
Jens Geyer3b686532021-07-01 23:04:08 +0200423 constructor Create( const trans: ITransport); overload; override;
424 constructor Create( const trans: ITransport; strictRead, strictWrite: Boolean); reintroduce; overload;
Jens Geyerd5436f52014-10-03 19:50:38 +0200425
Jens Geyer17c3ad92017-09-05 20:31:27 +0200426 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200427 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200428 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200429 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200430 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200431 procedure WriteFieldEnd; override;
432 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200433 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200434 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200435 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200436 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200437 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200438 procedure WriteSetEnd(); override;
439 procedure WriteBool( b: Boolean); override;
440 procedure WriteByte( b: ShortInt); override;
441 procedure WriteI16( i16: SmallInt); override;
442 procedure WriteI32( i32: Integer); override;
443 procedure WriteI64( const i64: Int64); override;
444 procedure WriteDouble( const d: Double); override;
445 procedure WriteBinary( const b: TBytes); override;
Jens Geyer62445c12022-06-29 00:00:00 +0200446 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200447
Jens Geyer17c3ad92017-09-05 20:31:27 +0200448 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200449 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200450 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200451 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200452 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200453 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200454 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200455 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200456 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200457 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200458 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200459 procedure ReadSetEnd(); override;
460 function ReadBool: Boolean; override;
461 function ReadByte: ShortInt; override;
462 function ReadI16: SmallInt; override;
463 function ReadI32: Integer; override;
464 function ReadI64: Int64; override;
465 function ReadDouble:Double; override;
466 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200467 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200468
469 end;
470
471
472 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
473 providing a way to author concise concrete decorator subclasses. The decorator
474 does not (and should not) modify the behaviour of the enclosed TProtocol
475
476 See p.175 of Design Patterns (by Gamma et al.)
477 }
478 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100479 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200480 FWrappedProtocol : IProtocol;
481
Jens Geyer41f47af2019-11-09 23:24:52 +0100482 strict protected
483 function GetMinSerializedSize( const aType : TType) : Integer; override;
484
Jens Geyerd5436f52014-10-03 19:50:38 +0200485 public
486 // Encloses the specified protocol.
487 // All operations will be forward to the given protocol. Must be non-null.
Jens Geyer3b686532021-07-01 23:04:08 +0200488 constructor Create( const aProtocol : IProtocol); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200489
Jens Geyer17c3ad92017-09-05 20:31:27 +0200490 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200491 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200492 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200493 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200494 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200495 procedure WriteFieldEnd; override;
496 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200497 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200498 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200499 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200500 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200501 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200502 procedure WriteSetEnd(); override;
503 procedure WriteBool( b: Boolean); override;
504 procedure WriteByte( b: ShortInt); override;
505 procedure WriteI16( i16: SmallInt); override;
506 procedure WriteI32( i32: Integer); override;
507 procedure WriteI64( const i64: Int64); override;
508 procedure WriteDouble( const d: Double); override;
509 procedure WriteString( const s: string ); override;
510 procedure WriteAnsiString( const s: AnsiString); override;
511 procedure WriteBinary( const b: TBytes); override;
Jens Geyer62445c12022-06-29 00:00:00 +0200512 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200513
Jens Geyer17c3ad92017-09-05 20:31:27 +0200514 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200515 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200516 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200517 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200518 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200519 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200520 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200521 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200522 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200523 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200524 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200525 procedure ReadSetEnd(); override;
526 function ReadBool: Boolean; override;
527 function ReadByte: ShortInt; override;
528 function ReadI16: SmallInt; override;
529 function ReadI32: Integer; override;
530 function ReadI64: Int64; override;
531 function ReadDouble:Double; override;
532 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200533 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200534 function ReadString: string; override;
535 function ReadAnsiString: AnsiString; override;
536 end;
537
538
539type
540 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200541 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
542 // Called before reading arguments.
543 procedure PreRead;
544 // Called between reading arguments and calling the handler.
545 procedure PostRead;
546 // Called between calling the handler and writing the response.
547 procedure PreWrite;
548 // Called after writing the response.
549 procedure PostWrite;
550 // Called when an oneway (async) function call completes successfully.
551 procedure OnewayComplete;
552 // Called if the handler throws an undeclared exception.
553 procedure UnhandledError( const e : Exception);
554 // Called when a client has finished request-handling to clean up
555 procedure CleanupContext;
556 end;
557
558
559 IProcessorEvents = interface
560 ['{A8661119-657C-447D-93C5-512E36162A45}']
561 // Called when a client is about to call the processor.
562 procedure Processing( const transport : ITransport);
563 // Called on any service function invocation
564 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
565 // Called when a client has finished request-handling to clean up
566 procedure CleanupContext;
567 end;
568
569
570 IProcessor = interface
571 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200572 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200573 end;
574
Jens Geyerd5436f52014-10-03 19:50:38 +0200575
Jens Geyer17c3ad92017-09-05 20:31:27 +0200576procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
577procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
578procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
579procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
580procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
581procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
582
Jens Geyerd5436f52014-10-03 19:50:38 +0200583
584implementation
585
Jens Geyerfad7fd32019-11-09 23:24:52 +0100586function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200587begin
588 ASSERT( SizeOf(n) = SizeOf(Result));
589 System.Move( n, Result, SizeOf(Result));
590end;
591
Jens Geyerfad7fd32019-11-09 23:24:52 +0100592function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200593begin
594 ASSERT( SizeOf(d) = SizeOf(Result));
595 System.Move( d, Result, SizeOf(Result));
596end;
597
Jens Geyerd5436f52014-10-03 19:50:38 +0200598
Jens Geyer5cf71b22023-12-18 11:44:55 +0100599//--- TThriftBytes ----------------------------------------------------------------------
600
601
602class operator TThriftBytes.Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
603begin
604 ASSERT( @result.data = @result); // must be first field
605 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
606 result := TThriftBytes(aRec);
607end;
608
609
610class operator TThriftBytes.Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
611begin
612 ASSERT( @aRec.data = @aRec); // must be first field
613 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
614 result := SysUtils.TBytes(aRec.data);
615end;
616
617
618function TThriftBytes.Length : Integer;
619begin
620 result := System.Length(data);
621end;
622
Jens Geyerd5436f52014-10-03 19:50:38 +0200623
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200624{ TProtocolRecursionTrackerImpl }
625
626constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
627begin
628 inherited Create;
629
630 // storing the pointer *after* the (successful) increment is important here
631 prot.IncrementRecursionDepth;
632 FProtocol := prot;
633end;
634
635destructor TProtocolRecursionTrackerImpl.Destroy;
636begin
637 try
638 // we have to release the reference iff the pointer has been stored
639 if FProtocol <> nil then begin
640 FProtocol.DecrementRecursionDepth;
641 FProtocol := nil;
642 end;
643 finally
644 inherited Destroy;
645 end;
646end;
647
Jens Geyerd5436f52014-10-03 19:50:38 +0200648{ TProtocolImpl }
649
Jens Geyera019cda2019-11-09 23:24:52 +0100650constructor TProtocolImpl.Create( const aTransport : ITransport);
Jens Geyerd5436f52014-10-03 19:50:38 +0200651begin
652 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100653 FTrans := aTransport;
654 FRecursionLimit := aTransport.Configuration.RecursionLimit;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200655 FRecursionDepth := 0;
656end;
657
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200658function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
659begin
660 result := TProtocolRecursionTrackerImpl.Create(Self);
661end;
662
663procedure TProtocolImpl.IncrementRecursionDepth;
664begin
665 if FRecursionDepth < FRecursionLimit
666 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200667 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200668end;
669
670procedure TProtocolImpl.DecrementRecursionDepth;
671begin
672 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200673end;
674
675function TProtocolImpl.GetTransport: ITransport;
676begin
677 Result := FTrans;
678end;
679
Jens Geyera019cda2019-11-09 23:24:52 +0100680function TProtocolImpl.Configuration : IThriftConfiguration;
681begin
682 Result := FTrans.Configuration;
683end;
684
Jens Geyer41f47af2019-11-09 23:24:52 +0100685procedure TProtocolImpl.Reset;
686begin
Jens Geyera019cda2019-11-09 23:24:52 +0100687 FTrans.ResetConsumedMessageSize;
Jens Geyer41f47af2019-11-09 23:24:52 +0100688end;
689
Jens Geyerd5436f52014-10-03 19:50:38 +0200690function TProtocolImpl.ReadAnsiString: AnsiString;
691var
692 b : TBytes;
693 len : Integer;
694begin
695 Result := '';
696 b := ReadBinary;
697 len := Length( b );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100698 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200699 SetLength( Result, len);
700 System.Move( b[0], Pointer(Result)^, len );
701 end;
702end;
703
704function TProtocolImpl.ReadString: string;
705begin
706 Result := TEncoding.UTF8.GetString( ReadBinary );
707end;
708
709procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
710var
711 b : TBytes;
712 len : Integer;
713begin
714 len := Length(s);
715 SetLength( b, len);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100716 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200717 System.Move( Pointer(s)^, b[0], len );
718 end;
719 WriteBinary( b );
720end;
721
722procedure TProtocolImpl.WriteString(const s: string);
723var
724 b : TBytes;
725begin
726 b := TEncoding.UTF8.GetBytes(s);
727 WriteBinary( b );
728end;
729
Jens Geyer41f47af2019-11-09 23:24:52 +0100730
731procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList);
732begin
733 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
734end;
735
736
737procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet);
738begin
739 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
740end;
741
742
743procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap);
Jens Geyera019cda2019-11-09 23:24:52 +0100744var nPairSize : Integer;
Jens Geyer41f47af2019-11-09 23:24:52 +0100745begin
746 nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType);
747 FTrans.CheckReadBytesAvailable( value.Count * nPairSize);
748end;
749
Jens Geyer07f4bb52022-09-03 14:50:06 +0200750
751procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
752var tmp : TBytes;
753begin
754 SetLength( tmp, bytes.Count);
755 if Length(tmp) > 0
756 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp));
757 WriteBinary( tmp);
758end;
759
760
761function TProtocolImpl.ReadBinaryCOM : IThriftBytes;
762var bytes : TBytes;
763begin
764 bytes := ReadBinary;
765 result := TThriftBytesImpl.Create(bytes,TRUE);
766end;
767
768
769{ TThriftBytesImpl }
770
771constructor TThriftBytesImpl.Create;
772begin
773 inherited Create;
774 ASSERT( Length(FData) = 0);
775end;
776
777
778constructor TThriftBytesImpl.Create( const bytes : TBytes);
779begin
780 FData := bytes; // copies the data
781end;
782
783
784constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean);
785
786 procedure SwapPointer( var one, two);
787 var
788 pOne : Pointer absolute one;
789 pTwo : Pointer absolute two;
790 pTmp : Pointer;
791 begin
792 pTmp := pOne;
793 pOne := pTwo;
794 pTwo := pTmp;
795 end;
796
797begin
798 inherited Create;
799 ASSERT( Length(FData) = 0);
800
801 if aTakeOwnership
802 then SwapPointer( FData, bytes)
803 else FData := bytes; // copies the data
804end;
805
806
Jens Geyer16819262024-03-07 23:01:20 +0100807constructor TThriftBytesImpl.Create( const pData : Pointer; const nCount : Integer);
808begin
809 SetLength(FData, Max(nCount,0));
810 if Length(FData) > 0 then Move( pData^, FData[0], Length(FData));
811end;
812
813
Jens Geyer07f4bb52022-09-03 14:50:06 +0200814function TThriftBytesImpl.ToString : string;
815var sb : TThriftStringBuilder;
816begin
817 sb := TThriftStringBuilder.Create();
818 try
819 sb.Append('Bin: ');
820 sb.Append( FData);
821
822 result := sb.ToString;
823 finally
824 sb.Free;
825 end;
826end;
827
828
829function TThriftBytesImpl.GetCount : Integer;
830begin
831 result := Length(FData);
832end;
833
834
835procedure TThriftBytesImpl.SetCount(const value : Integer);
836begin
837 SetLength( FData, value);
838end;
839
840
841function TThriftBytesImpl.QueryRawDataPtr : Pointer;
842begin
843 result := FData;
844end;
845
Jens Geyerd5436f52014-10-03 19:50:38 +0200846{ TProtocolUtil }
847
848class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200849var field : TThriftField;
850 map : TThriftMap;
851 set_ : TThriftSet;
852 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200853 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200854 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200855begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200856 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200857 case type_ of
858 // simple types
859 TType.Bool_ : prot.ReadBool();
860 TType.Byte_ : prot.ReadByte();
861 TType.I16 : prot.ReadI16();
862 TType.I32 : prot.ReadI32();
863 TType.I64 : prot.ReadI64();
864 TType.Double_ : prot.ReadDouble();
865 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jens Geyer62445c12022-06-29 00:00:00 +0200866 TType.Uuid : prot.ReadUuid();
Jens Geyerd5436f52014-10-03 19:50:38 +0200867
868 // structured types
869 TType.Struct : begin
870 prot.ReadStructBegin();
871 while TRUE do begin
872 field := prot.ReadFieldBegin();
873 if (field.Type_ = TType.Stop) then Break;
874 Skip(prot, field.Type_);
875 prot.ReadFieldEnd();
876 end;
877 prot.ReadStructEnd();
878 end;
879
880 TType.Map : begin
881 map := prot.ReadMapBegin();
882 for i := 0 to map.Count-1 do begin
883 Skip(prot, map.KeyType);
884 Skip(prot, map.ValueType);
885 end;
886 prot.ReadMapEnd();
887 end;
888
889 TType.Set_ : begin
890 set_ := prot.ReadSetBegin();
891 for i := 0 to set_.Count-1
892 do Skip( prot, set_.ElementType);
893 prot.ReadSetEnd();
894 end;
895
896 TType.List : begin
897 list := prot.ReadListBegin();
898 for i := 0 to list.Count-1
899 do Skip( prot, list.ElementType);
900 prot.ReadListEnd();
901 end;
902
903 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100904 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200905 end;
906end;
907
Jens Geyerd5436f52014-10-03 19:50:38 +0200908
909{ TBinaryProtocolImpl }
910
Jens Geyer3b686532021-07-01 23:04:08 +0200911constructor TBinaryProtocolImpl.Create( const trans: ITransport);
912begin
913 // call the real CTOR
914 Self.Create( trans, FALSE, TRUE);
915end;
916
Jens Geyerfad7fd32019-11-09 23:24:52 +0100917constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200918begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100919 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200920 FStrictRead := strictRead;
921 FStrictWrite := strictWrite;
922end;
923
Jens Geyer17c3ad92017-09-05 20:31:27 +0200924function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200925begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200926 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200927end;
928
929function TBinaryProtocolImpl.ReadBinary: TBytes;
930var
931 size : Integer;
932 buf : TBytes;
933begin
934 size := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100935 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100936 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200937 FTrans.ReadAll( buf, 0, size);
938 Result := buf;
939end;
940
Jens Geyer62445c12022-06-29 00:00:00 +0200941function TBinaryProtocolImpl.ReadUuid : TGuid;
942var network : TGuid; // in network order (Big Endian)
943begin
944 ASSERT( SizeOf(result) = 16);
945 FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
Jens Geyerf8f62782022-09-10 00:55:02 +0200946 result := GuidUtils.SwapByteOrder(network);
Jens Geyer62445c12022-06-29 00:00:00 +0200947end;
948
Jens Geyerd5436f52014-10-03 19:50:38 +0200949function TBinaryProtocolImpl.ReadBool: Boolean;
950begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200951 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200952end;
953
954function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200955begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200956 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200957end;
958
959function TBinaryProtocolImpl.ReadDouble: Double;
960begin
961 Result := ConvertInt64ToDouble( ReadI64 )
962end;
963
Jens Geyer17c3ad92017-09-05 20:31:27 +0200964function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200965begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200966 Init( result, '', TType( ReadByte), 0);
967 if ( result.Type_ <> TType.Stop ) then begin
968 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200969 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200970end;
971
972procedure TBinaryProtocolImpl.ReadFieldEnd;
973begin
974
975end;
976
977function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200978var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200979begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200980 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200981 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
982end;
983
984function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200985var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200986begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200987 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200988
989 Result := Integer(
990 ((i32in[0] and $FF) shl 24) or
991 ((i32in[1] and $FF) shl 16) or
992 ((i32in[2] and $FF) shl 8) or
993 (i32in[3] and $FF));
994
995end;
996
997function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200998var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200999begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001000 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001001 Result :=
1002 (Int64( i64in[0] and $FF) shl 56) or
1003 (Int64( i64in[1] and $FF) shl 48) or
1004 (Int64( i64in[2] and $FF) shl 40) or
1005 (Int64( i64in[3] and $FF) shl 32) or
1006 (Int64( i64in[4] and $FF) shl 24) or
1007 (Int64( i64in[5] and $FF) shl 16) or
1008 (Int64( i64in[6] and $FF) shl 8) or
1009 (Int64( i64in[7] and $FF));
1010end;
1011
Jens Geyer17c3ad92017-09-05 20:31:27 +02001012function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001013begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001014 result.ElementType := TType(ReadByte);
1015 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001016 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001017end;
1018
1019procedure TBinaryProtocolImpl.ReadListEnd;
1020begin
1021
1022end;
1023
Jens Geyer17c3ad92017-09-05 20:31:27 +02001024function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001025begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001026 result.KeyType := TType(ReadByte);
1027 result.ValueType := TType(ReadByte);
1028 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001029 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001030end;
1031
1032procedure TBinaryProtocolImpl.ReadMapEnd;
1033begin
1034
1035end;
1036
Jens Geyer17c3ad92017-09-05 20:31:27 +02001037function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001038var
1039 size : Integer;
1040 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +02001041begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001042 Reset;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001043 Init( result);
Jens Geyer589ee5b2021-03-29 21:40:55 +02001044
Jens Geyerd5436f52014-10-03 19:50:38 +02001045 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001046 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001047 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001048 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +02001049 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +02001050 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001051 result.Type_ := TMessageType( size and $000000ff);
1052 result.Name := ReadString;
1053 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001054 Exit;
1055 end;
1056
1057 try
1058 if FStrictRead
1059 then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
1060
Jens Geyer17c3ad92017-09-05 20:31:27 +02001061 result.Name := ReadStringBody( size );
1062 result.Type_ := TMessageType( ReadByte );
1063 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001064 except
1065 if CharUtils.IsHtmlDoctype(size)
1066 then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
1067 else raise; // something else
Jens Geyerd5436f52014-10-03 19:50:38 +02001068 end;
Jens Geyerd5436f52014-10-03 19:50:38 +02001069end;
1070
1071procedure TBinaryProtocolImpl.ReadMessageEnd;
1072begin
1073 inherited;
1074
1075end;
1076
Jens Geyer17c3ad92017-09-05 20:31:27 +02001077function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001078begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001079 result.ElementType := TType(ReadByte);
1080 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001081 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001082end;
1083
1084procedure TBinaryProtocolImpl.ReadSetEnd;
1085begin
1086
1087end;
1088
1089function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001090var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +02001091begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001092 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001093 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +02001094 FTrans.ReadAll( buf, 0, size );
1095 Result := TEncoding.UTF8.GetString( buf);
1096end;
1097
Jens Geyer17c3ad92017-09-05 20:31:27 +02001098function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001099begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001100 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001101end;
1102
1103procedure TBinaryProtocolImpl.ReadStructEnd;
1104begin
1105 inherited;
1106
1107end;
1108
1109procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1110var iLen : Integer;
1111begin
1112 iLen := Length(b);
1113 WriteI32( iLen);
1114 if iLen > 0 then FTrans.Write(b, 0, iLen);
1115end;
1116
Jens Geyer62445c12022-06-29 00:00:00 +02001117procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
1118var network : TGuid; // in network order (Big Endian)
1119begin
1120 ASSERT( SizeOf(uuid) = 16);
Jens Geyerf8f62782022-09-10 00:55:02 +02001121 network := GuidUtils.SwapByteOrder(uuid);
Jens Geyer62445c12022-06-29 00:00:00 +02001122 Transport.Write( @network, 0, SizeOf(network));
1123end;
1124
Jens Geyerd5436f52014-10-03 19:50:38 +02001125procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1126begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001127 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001128 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +02001129 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001130 WriteByte( 0 );
1131 end;
1132end;
1133
1134procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +02001135begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001136 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +02001137end;
1138
1139procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1140begin
1141 WriteI64(ConvertDoubleToInt64(d));
1142end;
1143
Jens Geyer17c3ad92017-09-05 20:31:27 +02001144procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001145begin
1146 WriteByte(ShortInt(field.Type_));
1147 WriteI16(field.ID);
1148end;
1149
1150procedure TBinaryProtocolImpl.WriteFieldEnd;
1151begin
1152
1153end;
1154
1155procedure TBinaryProtocolImpl.WriteFieldStop;
1156begin
1157 WriteByte(ShortInt(TType.Stop));
1158end;
1159
1160procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001161var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001162begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001163 i16out[0] := Byte($FF and (i16 shr 8));
1164 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001165 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +02001166end;
1167
1168procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001169var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001170begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001171 i32out[0] := Byte($FF and (i32 shr 24));
1172 i32out[1] := Byte($FF and (i32 shr 16));
1173 i32out[2] := Byte($FF and (i32 shr 8));
1174 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001175 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001176end;
1177
1178procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001179var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001180begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001181 i64out[0] := Byte($FF and (i64 shr 56));
1182 i64out[1] := Byte($FF and (i64 shr 48));
1183 i64out[2] := Byte($FF and (i64 shr 40));
1184 i64out[3] := Byte($FF and (i64 shr 32));
1185 i64out[4] := Byte($FF and (i64 shr 24));
1186 i64out[5] := Byte($FF and (i64 shr 16));
1187 i64out[6] := Byte($FF and (i64 shr 8));
1188 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001189 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001190end;
1191
Jens Geyer17c3ad92017-09-05 20:31:27 +02001192procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001193begin
1194 WriteByte(ShortInt(list.ElementType));
1195 WriteI32(list.Count);
1196end;
1197
1198procedure TBinaryProtocolImpl.WriteListEnd;
1199begin
1200
1201end;
1202
Jens Geyer17c3ad92017-09-05 20:31:27 +02001203procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001204begin
1205 WriteByte(ShortInt(map.KeyType));
1206 WriteByte(ShortInt(map.ValueType));
1207 WriteI32(map.Count);
1208end;
1209
1210procedure TBinaryProtocolImpl.WriteMapEnd;
1211begin
1212
1213end;
1214
Jens Geyer17c3ad92017-09-05 20:31:27 +02001215procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001216var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +02001217begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001218 Reset;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001219 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001220 version := VERSION_1 or Cardinal( msg.Type_);
1221 WriteI32( Integer( version) );
1222 WriteString( msg.Name);
1223 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001224 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001225 WriteString( msg.Name);
1226 WriteByte(ShortInt( msg.Type_));
1227 WriteI32( msg.SeqID);
1228 end;
1229end;
1230
1231procedure TBinaryProtocolImpl.WriteMessageEnd;
1232begin
1233
1234end;
1235
Jens Geyer17c3ad92017-09-05 20:31:27 +02001236procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +02001237begin
1238 WriteByte(ShortInt(set_.ElementType));
1239 WriteI32(set_.Count);
1240end;
1241
1242procedure TBinaryProtocolImpl.WriteSetEnd;
1243begin
1244
1245end;
1246
Jens Geyer17c3ad92017-09-05 20:31:27 +02001247procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001248begin
1249
1250end;
1251
1252procedure TBinaryProtocolImpl.WriteStructEnd;
1253begin
1254
1255end;
1256
Jens Geyer41f47af2019-11-09 23:24:52 +01001257function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
1258// Return the minimum number of bytes a type will consume on the wire
1259begin
1260 case aType of
1261 TType.Stop: result := 0;
1262 TType.Void: result := 0;
1263 TType.Bool_: result := SizeOf(Byte);
1264 TType.Byte_: result := SizeOf(Byte);
1265 TType.Double_: result := SizeOf(Double);
1266 TType.I16: result := SizeOf(Int16);
1267 TType.I32: result := SizeOf(Int32);
1268 TType.I64: result := SizeOf(Int64);
1269 TType.String_: result := SizeOf(Int32); // string length
1270 TType.Struct: result := 0; // empty struct
1271 TType.Map: result := SizeOf(Int32); // element count
1272 TType.Set_: result := SizeOf(Int32); // element count
1273 TType.List: result := SizeOf(Int32); // element count
Jens Geyer62445c12022-06-29 00:00:00 +02001274 TType.Uuid: result := SizeOf(TGuid);
Jens Geyer41f47af2019-11-09 23:24:52 +01001275 else
1276 raise TTransportExceptionBadArgs.Create('Unhandled type code');
1277 end;
1278end;
1279
1280
Jens Geyerd5436f52014-10-03 19:50:38 +02001281{ TProtocolException }
1282
Jens Geyere0e32402016-04-20 21:50:48 +02001283constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001284begin
Jens Geyere0e32402016-04-20 21:50:48 +02001285 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001286end;
1287
Jens Geyere0e32402016-04-20 21:50:48 +02001288class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001289begin
Jens Geyere0e32402016-04-20 21:50:48 +02001290 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001291end;
1292
Jens Geyere0e32402016-04-20 21:50:48 +02001293class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001294begin
Jens Geyere0e32402016-04-20 21:50:48 +02001295 Result := TProtocolExceptionUnknown.Create('');
1296end;
1297
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001298class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001299begin
1300{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001301 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001302{$WARN SYMBOL_DEPRECATED DEFAULT}
1303end;
1304
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001305class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001306begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001307 case aType of
1308 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1309 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1310 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1311 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1312 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1313 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001314 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001315 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001316 Result := TProtocolExceptionUnknown.Create(msg);
1317 end;
1318end;
1319
1320{ TProtocolExceptionSpecialized }
1321
1322constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1323begin
1324 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001325end;
1326
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001327{ specialized TProtocolExceptions }
1328
1329class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1330begin
1331 result := TExceptionType.UNKNOWN;
1332end;
1333
1334class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1335begin
1336 result := TExceptionType.INVALID_DATA;
1337end;
1338
1339class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1340begin
1341 result := TExceptionType.NEGATIVE_SIZE;
1342end;
1343
1344class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1345begin
1346 result := TExceptionType.SIZE_LIMIT;
1347end;
1348
1349class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1350begin
1351 result := TExceptionType.BAD_VERSION;
1352end;
1353
1354class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1355begin
1356 result := TExceptionType.NOT_IMPLEMENTED;
1357end;
1358
1359class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1360begin
1361 result := TExceptionType.DEPTH_LIMIT;
1362end;
1363
Jens Geyerd5436f52014-10-03 19:50:38 +02001364{ TBinaryProtocolImpl.TFactory }
1365
Jens Geyerfad7fd32019-11-09 23:24:52 +01001366constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001367begin
1368 inherited Create;
1369 FStrictRead := AStrictRead;
1370 FStrictWrite := AStrictWrite;
1371end;
1372
Jens Geyerd5436f52014-10-03 19:50:38 +02001373function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1374begin
1375 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1376end;
1377
1378
1379{ TProtocolDecorator }
1380
1381constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1382begin
1383 ASSERT( aProtocol <> nil);
1384 inherited Create( aProtocol.Transport);
1385 FWrappedProtocol := aProtocol;
1386end;
1387
1388
Jens Geyer17c3ad92017-09-05 20:31:27 +02001389procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001390begin
1391 FWrappedProtocol.WriteMessageBegin( msg);
1392end;
1393
1394
1395procedure TProtocolDecorator.WriteMessageEnd;
1396begin
1397 FWrappedProtocol.WriteMessageEnd;
1398end;
1399
1400
Jens Geyer17c3ad92017-09-05 20:31:27 +02001401procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001402begin
1403 FWrappedProtocol.WriteStructBegin( struc);
1404end;
1405
1406
1407procedure TProtocolDecorator.WriteStructEnd;
1408begin
1409 FWrappedProtocol.WriteStructEnd;
1410end;
1411
1412
Jens Geyer17c3ad92017-09-05 20:31:27 +02001413procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001414begin
1415 FWrappedProtocol.WriteFieldBegin( field);
1416end;
1417
1418
1419procedure TProtocolDecorator.WriteFieldEnd;
1420begin
1421 FWrappedProtocol.WriteFieldEnd;
1422end;
1423
1424
1425procedure TProtocolDecorator.WriteFieldStop;
1426begin
1427 FWrappedProtocol.WriteFieldStop;
1428end;
1429
1430
Jens Geyer17c3ad92017-09-05 20:31:27 +02001431procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001432begin
1433 FWrappedProtocol.WriteMapBegin( map);
1434end;
1435
1436
1437procedure TProtocolDecorator.WriteMapEnd;
1438begin
1439 FWrappedProtocol.WriteMapEnd;
1440end;
1441
1442
Jens Geyer17c3ad92017-09-05 20:31:27 +02001443procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001444begin
1445 FWrappedProtocol.WriteListBegin( list);
1446end;
1447
1448
1449procedure TProtocolDecorator.WriteListEnd();
1450begin
1451 FWrappedProtocol.WriteListEnd();
1452end;
1453
1454
Jens Geyer17c3ad92017-09-05 20:31:27 +02001455procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001456begin
1457 FWrappedProtocol.WriteSetBegin( set_);
1458end;
1459
1460
1461procedure TProtocolDecorator.WriteSetEnd();
1462begin
1463 FWrappedProtocol.WriteSetEnd();
1464end;
1465
1466
1467procedure TProtocolDecorator.WriteBool( b: Boolean);
1468begin
1469 FWrappedProtocol.WriteBool( b);
1470end;
1471
1472
1473procedure TProtocolDecorator.WriteByte( b: ShortInt);
1474begin
1475 FWrappedProtocol.WriteByte( b);
1476end;
1477
1478
1479procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1480begin
1481 FWrappedProtocol.WriteI16( i16);
1482end;
1483
1484
1485procedure TProtocolDecorator.WriteI32( i32: Integer);
1486begin
1487 FWrappedProtocol.WriteI32( i32);
1488end;
1489
1490
1491procedure TProtocolDecorator.WriteI64( const i64: Int64);
1492begin
1493 FWrappedProtocol.WriteI64( i64);
1494end;
1495
1496
1497procedure TProtocolDecorator.WriteDouble( const d: Double);
1498begin
1499 FWrappedProtocol.WriteDouble( d);
1500end;
1501
1502
1503procedure TProtocolDecorator.WriteString( const s: string );
1504begin
1505 FWrappedProtocol.WriteString( s);
1506end;
1507
1508
1509procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1510begin
1511 FWrappedProtocol.WriteAnsiString( s);
1512end;
1513
1514
1515procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1516begin
1517 FWrappedProtocol.WriteBinary( b);
1518end;
1519
1520
Jens Geyer62445c12022-06-29 00:00:00 +02001521procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
1522begin
1523 FWrappedProtocol.WriteUuid( uuid);
1524end;
1525
1526
Jens Geyer17c3ad92017-09-05 20:31:27 +02001527function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001528begin
1529 result := FWrappedProtocol.ReadMessageBegin;
1530end;
1531
1532
1533procedure TProtocolDecorator.ReadMessageEnd();
1534begin
1535 FWrappedProtocol.ReadMessageEnd();
1536end;
1537
1538
Jens Geyer17c3ad92017-09-05 20:31:27 +02001539function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001540begin
1541 result := FWrappedProtocol.ReadStructBegin;
1542end;
1543
1544
1545procedure TProtocolDecorator.ReadStructEnd;
1546begin
1547 FWrappedProtocol.ReadStructEnd;
1548end;
1549
1550
Jens Geyer17c3ad92017-09-05 20:31:27 +02001551function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001552begin
1553 result := FWrappedProtocol.ReadFieldBegin;
1554end;
1555
1556
1557procedure TProtocolDecorator.ReadFieldEnd();
1558begin
1559 FWrappedProtocol.ReadFieldEnd();
1560end;
1561
1562
Jens Geyer17c3ad92017-09-05 20:31:27 +02001563function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001564begin
1565 result := FWrappedProtocol.ReadMapBegin;
1566end;
1567
1568
1569procedure TProtocolDecorator.ReadMapEnd();
1570begin
1571 FWrappedProtocol.ReadMapEnd();
1572end;
1573
1574
Jens Geyer17c3ad92017-09-05 20:31:27 +02001575function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001576begin
1577 result := FWrappedProtocol.ReadListBegin;
1578end;
1579
1580
1581procedure TProtocolDecorator.ReadListEnd();
1582begin
1583 FWrappedProtocol.ReadListEnd();
1584end;
1585
1586
Jens Geyer17c3ad92017-09-05 20:31:27 +02001587function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001588begin
1589 result := FWrappedProtocol.ReadSetBegin;
1590end;
1591
1592
1593procedure TProtocolDecorator.ReadSetEnd();
1594begin
1595 FWrappedProtocol.ReadSetEnd();
1596end;
1597
1598
1599function TProtocolDecorator.ReadBool: Boolean;
1600begin
1601 result := FWrappedProtocol.ReadBool;
1602end;
1603
1604
1605function TProtocolDecorator.ReadByte: ShortInt;
1606begin
1607 result := FWrappedProtocol.ReadByte;
1608end;
1609
1610
1611function TProtocolDecorator.ReadI16: SmallInt;
1612begin
1613 result := FWrappedProtocol.ReadI16;
1614end;
1615
1616
1617function TProtocolDecorator.ReadI32: Integer;
1618begin
1619 result := FWrappedProtocol.ReadI32;
1620end;
1621
1622
1623function TProtocolDecorator.ReadI64: Int64;
1624begin
1625 result := FWrappedProtocol.ReadI64;
1626end;
1627
1628
1629function TProtocolDecorator.ReadDouble:Double;
1630begin
1631 result := FWrappedProtocol.ReadDouble;
1632end;
1633
1634
1635function TProtocolDecorator.ReadBinary: TBytes;
1636begin
1637 result := FWrappedProtocol.ReadBinary;
1638end;
1639
1640
Jens Geyer62445c12022-06-29 00:00:00 +02001641function TProtocolDecorator.ReadUuid: TGuid;
1642begin
1643 result := FWrappedProtocol.ReadUuid;
1644end;
1645
1646
Jens Geyerd5436f52014-10-03 19:50:38 +02001647function TProtocolDecorator.ReadString: string;
1648begin
1649 result := FWrappedProtocol.ReadString;
1650end;
1651
1652
1653function TProtocolDecorator.ReadAnsiString: AnsiString;
1654begin
1655 result := FWrappedProtocol.ReadAnsiString;
1656end;
1657
1658
Jens Geyer41f47af2019-11-09 23:24:52 +01001659function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer;
1660begin
1661 result := FWrappedProtocol.GetMinSerializedSize(aType);
1662end;
1663
1664
Jens Geyer17c3ad92017-09-05 20:31:27 +02001665{ Init helper functions }
1666
1667procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1668begin
1669 rec.Name := AName;
1670 rec.Type_ := AMessageType;
1671 rec.SeqID := ASeqID;
1672end;
1673
1674
1675procedure Init( var rec : TThriftStruct; const AName: string = '');
1676begin
1677 rec.Name := AName;
1678end;
1679
1680
1681procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1682begin
1683 rec.Name := AName;
1684 rec.Type_ := AType;
1685 rec.Id := AId;
1686end;
1687
1688
1689procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1690begin
1691 rec.ValueType := AValueType;
1692 rec.KeyType := AKeyType;
1693 rec.Count := ACount;
1694end;
1695
1696
1697procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1698begin
1699 rec.Count := ACount;
1700 rec.ElementType := AElementType;
1701end;
1702
1703
1704procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1705begin
1706 rec.Count := ACount;
1707 rec.ElementType := AElementType;
1708end;
1709
1710
1711
Jens Geyerd5436f52014-10-03 19:50:38 +02001712end.
1713