blob: fd92da9b73bb1615a6ba458a718ae47ca4333d5d [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 Geyerb53fa8e2024-03-08 00:33:22 +0100446 procedure WriteBinary( const bytes : IThriftBytes); overload; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200447 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200448
Jens Geyer17c3ad92017-09-05 20:31:27 +0200449 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200450 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200451 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200452 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200453 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200454 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200455 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200456 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200457 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200458 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200459 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200460 procedure ReadSetEnd(); override;
461 function ReadBool: Boolean; override;
462 function ReadByte: ShortInt; override;
463 function ReadI16: SmallInt; override;
464 function ReadI32: Integer; override;
465 function ReadI64: Int64; override;
466 function ReadDouble:Double; override;
467 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200468 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200469
470 end;
471
472
473 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
474 providing a way to author concise concrete decorator subclasses. The decorator
475 does not (and should not) modify the behaviour of the enclosed TProtocol
476
477 See p.175 of Design Patterns (by Gamma et al.)
478 }
479 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100480 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200481 FWrappedProtocol : IProtocol;
482
Jens Geyer41f47af2019-11-09 23:24:52 +0100483 strict protected
484 function GetMinSerializedSize( const aType : TType) : Integer; override;
485
Jens Geyerd5436f52014-10-03 19:50:38 +0200486 public
487 // Encloses the specified protocol.
488 // All operations will be forward to the given protocol. Must be non-null.
Jens Geyer3b686532021-07-01 23:04:08 +0200489 constructor Create( const aProtocol : IProtocol); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200490
Jens Geyer17c3ad92017-09-05 20:31:27 +0200491 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200492 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200493 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200494 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200495 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200496 procedure WriteFieldEnd; override;
497 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200498 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200499 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200500 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200501 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200502 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200503 procedure WriteSetEnd(); override;
504 procedure WriteBool( b: Boolean); override;
505 procedure WriteByte( b: ShortInt); override;
506 procedure WriteI16( i16: SmallInt); override;
507 procedure WriteI32( i32: Integer); override;
508 procedure WriteI64( const i64: Int64); override;
509 procedure WriteDouble( const d: Double); override;
510 procedure WriteString( const s: string ); override;
511 procedure WriteAnsiString( const s: AnsiString); override;
512 procedure WriteBinary( const b: TBytes); override;
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100513 procedure WriteBinary( const bytes : IThriftBytes); overload; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200514 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200515
Jens Geyer17c3ad92017-09-05 20:31:27 +0200516 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200517 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200518 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200519 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200520 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200521 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200522 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200523 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200524 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200525 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200526 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200527 procedure ReadSetEnd(); override;
528 function ReadBool: Boolean; override;
529 function ReadByte: ShortInt; override;
530 function ReadI16: SmallInt; override;
531 function ReadI32: Integer; override;
532 function ReadI64: Int64; override;
533 function ReadDouble:Double; override;
534 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200535 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200536 function ReadString: string; override;
537 function ReadAnsiString: AnsiString; override;
538 end;
539
540
541type
542 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200543 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
544 // Called before reading arguments.
545 procedure PreRead;
546 // Called between reading arguments and calling the handler.
547 procedure PostRead;
548 // Called between calling the handler and writing the response.
549 procedure PreWrite;
550 // Called after writing the response.
551 procedure PostWrite;
552 // Called when an oneway (async) function call completes successfully.
553 procedure OnewayComplete;
554 // Called if the handler throws an undeclared exception.
555 procedure UnhandledError( const e : Exception);
556 // Called when a client has finished request-handling to clean up
557 procedure CleanupContext;
558 end;
559
560
561 IProcessorEvents = interface
562 ['{A8661119-657C-447D-93C5-512E36162A45}']
563 // Called when a client is about to call the processor.
564 procedure Processing( const transport : ITransport);
565 // Called on any service function invocation
566 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
567 // Called when a client has finished request-handling to clean up
568 procedure CleanupContext;
569 end;
570
571
572 IProcessor = interface
573 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200574 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200575 end;
576
Jens Geyerd5436f52014-10-03 19:50:38 +0200577
Jens Geyer17c3ad92017-09-05 20:31:27 +0200578procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
579procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
580procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
581procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
582procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
583procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
584
Jens Geyerd5436f52014-10-03 19:50:38 +0200585
586implementation
587
Jens Geyerfad7fd32019-11-09 23:24:52 +0100588function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200589begin
590 ASSERT( SizeOf(n) = SizeOf(Result));
591 System.Move( n, Result, SizeOf(Result));
592end;
593
Jens Geyerfad7fd32019-11-09 23:24:52 +0100594function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200595begin
596 ASSERT( SizeOf(d) = SizeOf(Result));
597 System.Move( d, Result, SizeOf(Result));
598end;
599
Jens Geyerd5436f52014-10-03 19:50:38 +0200600
Jens Geyer5cf71b22023-12-18 11:44:55 +0100601//--- TThriftBytes ----------------------------------------------------------------------
602
603
604class operator TThriftBytes.Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
605begin
606 ASSERT( @result.data = @result); // must be first field
607 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
608 result := TThriftBytes(aRec);
609end;
610
611
612class operator TThriftBytes.Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
613begin
614 ASSERT( @aRec.data = @aRec); // must be first field
615 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
616 result := SysUtils.TBytes(aRec.data);
617end;
618
619
620function TThriftBytes.Length : Integer;
621begin
622 result := System.Length(data);
623end;
624
Jens Geyerd5436f52014-10-03 19:50:38 +0200625
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200626{ TProtocolRecursionTrackerImpl }
627
628constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
629begin
630 inherited Create;
631
632 // storing the pointer *after* the (successful) increment is important here
633 prot.IncrementRecursionDepth;
634 FProtocol := prot;
635end;
636
637destructor TProtocolRecursionTrackerImpl.Destroy;
638begin
639 try
640 // we have to release the reference iff the pointer has been stored
641 if FProtocol <> nil then begin
642 FProtocol.DecrementRecursionDepth;
643 FProtocol := nil;
644 end;
645 finally
646 inherited Destroy;
647 end;
648end;
649
Jens Geyerd5436f52014-10-03 19:50:38 +0200650{ TProtocolImpl }
651
Jens Geyera019cda2019-11-09 23:24:52 +0100652constructor TProtocolImpl.Create( const aTransport : ITransport);
Jens Geyerd5436f52014-10-03 19:50:38 +0200653begin
654 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100655 FTrans := aTransport;
656 FRecursionLimit := aTransport.Configuration.RecursionLimit;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200657 FRecursionDepth := 0;
658end;
659
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200660function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
661begin
662 result := TProtocolRecursionTrackerImpl.Create(Self);
663end;
664
665procedure TProtocolImpl.IncrementRecursionDepth;
666begin
667 if FRecursionDepth < FRecursionLimit
668 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200669 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200670end;
671
672procedure TProtocolImpl.DecrementRecursionDepth;
673begin
674 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200675end;
676
677function TProtocolImpl.GetTransport: ITransport;
678begin
679 Result := FTrans;
680end;
681
Jens Geyera019cda2019-11-09 23:24:52 +0100682function TProtocolImpl.Configuration : IThriftConfiguration;
683begin
684 Result := FTrans.Configuration;
685end;
686
Jens Geyer41f47af2019-11-09 23:24:52 +0100687procedure TProtocolImpl.Reset;
688begin
Jens Geyera019cda2019-11-09 23:24:52 +0100689 FTrans.ResetConsumedMessageSize;
Jens Geyer41f47af2019-11-09 23:24:52 +0100690end;
691
Jens Geyerd5436f52014-10-03 19:50:38 +0200692function TProtocolImpl.ReadAnsiString: AnsiString;
693var
694 b : TBytes;
695 len : Integer;
696begin
697 Result := '';
698 b := ReadBinary;
699 len := Length( b );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100700 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200701 SetLength( Result, len);
702 System.Move( b[0], Pointer(Result)^, len );
703 end;
704end;
705
706function TProtocolImpl.ReadString: string;
707begin
708 Result := TEncoding.UTF8.GetString( ReadBinary );
709end;
710
711procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
712var
713 b : TBytes;
714 len : Integer;
715begin
716 len := Length(s);
717 SetLength( b, len);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100718 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200719 System.Move( Pointer(s)^, b[0], len );
720 end;
721 WriteBinary( b );
722end;
723
724procedure TProtocolImpl.WriteString(const s: string);
725var
726 b : TBytes;
727begin
728 b := TEncoding.UTF8.GetBytes(s);
729 WriteBinary( b );
730end;
731
Jens Geyer41f47af2019-11-09 23:24:52 +0100732
733procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList);
734begin
735 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
736end;
737
738
739procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet);
740begin
741 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
742end;
743
744
745procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap);
Jens Geyera019cda2019-11-09 23:24:52 +0100746var nPairSize : Integer;
Jens Geyer41f47af2019-11-09 23:24:52 +0100747begin
748 nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType);
749 FTrans.CheckReadBytesAvailable( value.Count * nPairSize);
750end;
751
Jens Geyer07f4bb52022-09-03 14:50:06 +0200752
753procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100754// This implementation works, but is rather inefficient due to the extra memory allocation
755// Consider overwriting this for your transport implementation
Jens Geyer07f4bb52022-09-03 14:50:06 +0200756var tmp : TBytes;
757begin
758 SetLength( tmp, bytes.Count);
759 if Length(tmp) > 0
760 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp));
761 WriteBinary( tmp);
762end;
763
764
765function TProtocolImpl.ReadBinaryCOM : IThriftBytes;
766var bytes : TBytes;
767begin
768 bytes := ReadBinary;
769 result := TThriftBytesImpl.Create(bytes,TRUE);
770end;
771
772
773{ TThriftBytesImpl }
774
775constructor TThriftBytesImpl.Create;
776begin
777 inherited Create;
778 ASSERT( Length(FData) = 0);
779end;
780
781
782constructor TThriftBytesImpl.Create( const bytes : TBytes);
783begin
784 FData := bytes; // copies the data
785end;
786
787
788constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean);
789
790 procedure SwapPointer( var one, two);
791 var
792 pOne : Pointer absolute one;
793 pTwo : Pointer absolute two;
794 pTmp : Pointer;
795 begin
796 pTmp := pOne;
797 pOne := pTwo;
798 pTwo := pTmp;
799 end;
800
801begin
802 inherited Create;
803 ASSERT( Length(FData) = 0);
804
805 if aTakeOwnership
806 then SwapPointer( FData, bytes)
807 else FData := bytes; // copies the data
808end;
809
810
Jens Geyer16819262024-03-07 23:01:20 +0100811constructor TThriftBytesImpl.Create( const pData : Pointer; const nCount : Integer);
812begin
813 SetLength(FData, Max(nCount,0));
814 if Length(FData) > 0 then Move( pData^, FData[0], Length(FData));
815end;
816
817
Jens Geyer07f4bb52022-09-03 14:50:06 +0200818function TThriftBytesImpl.ToString : string;
819var sb : TThriftStringBuilder;
820begin
821 sb := TThriftStringBuilder.Create();
822 try
823 sb.Append('Bin: ');
824 sb.Append( FData);
825
826 result := sb.ToString;
827 finally
828 sb.Free;
829 end;
830end;
831
832
833function TThriftBytesImpl.GetCount : Integer;
834begin
835 result := Length(FData);
836end;
837
838
839procedure TThriftBytesImpl.SetCount(const value : Integer);
840begin
841 SetLength( FData, value);
842end;
843
844
845function TThriftBytesImpl.QueryRawDataPtr : Pointer;
846begin
847 result := FData;
848end;
849
Jens Geyerd5436f52014-10-03 19:50:38 +0200850{ TProtocolUtil }
851
852class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200853var field : TThriftField;
854 map : TThriftMap;
855 set_ : TThriftSet;
856 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200857 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200858 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200859begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200860 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200861 case type_ of
862 // simple types
863 TType.Bool_ : prot.ReadBool();
864 TType.Byte_ : prot.ReadByte();
865 TType.I16 : prot.ReadI16();
866 TType.I32 : prot.ReadI32();
867 TType.I64 : prot.ReadI64();
868 TType.Double_ : prot.ReadDouble();
869 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jens Geyer62445c12022-06-29 00:00:00 +0200870 TType.Uuid : prot.ReadUuid();
Jens Geyerd5436f52014-10-03 19:50:38 +0200871
872 // structured types
873 TType.Struct : begin
874 prot.ReadStructBegin();
875 while TRUE do begin
876 field := prot.ReadFieldBegin();
877 if (field.Type_ = TType.Stop) then Break;
878 Skip(prot, field.Type_);
879 prot.ReadFieldEnd();
880 end;
881 prot.ReadStructEnd();
882 end;
883
884 TType.Map : begin
885 map := prot.ReadMapBegin();
886 for i := 0 to map.Count-1 do begin
887 Skip(prot, map.KeyType);
888 Skip(prot, map.ValueType);
889 end;
890 prot.ReadMapEnd();
891 end;
892
893 TType.Set_ : begin
894 set_ := prot.ReadSetBegin();
895 for i := 0 to set_.Count-1
896 do Skip( prot, set_.ElementType);
897 prot.ReadSetEnd();
898 end;
899
900 TType.List : begin
901 list := prot.ReadListBegin();
902 for i := 0 to list.Count-1
903 do Skip( prot, list.ElementType);
904 prot.ReadListEnd();
905 end;
906
907 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100908 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200909 end;
910end;
911
Jens Geyerd5436f52014-10-03 19:50:38 +0200912
913{ TBinaryProtocolImpl }
914
Jens Geyer3b686532021-07-01 23:04:08 +0200915constructor TBinaryProtocolImpl.Create( const trans: ITransport);
916begin
917 // call the real CTOR
918 Self.Create( trans, FALSE, TRUE);
919end;
920
Jens Geyerfad7fd32019-11-09 23:24:52 +0100921constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200922begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100923 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200924 FStrictRead := strictRead;
925 FStrictWrite := strictWrite;
926end;
927
Jens Geyer17c3ad92017-09-05 20:31:27 +0200928function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200929begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200930 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200931end;
932
933function TBinaryProtocolImpl.ReadBinary: TBytes;
934var
935 size : Integer;
936 buf : TBytes;
937begin
938 size := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100939 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100940 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200941 FTrans.ReadAll( buf, 0, size);
942 Result := buf;
943end;
944
Jens Geyer62445c12022-06-29 00:00:00 +0200945function TBinaryProtocolImpl.ReadUuid : TGuid;
946var network : TGuid; // in network order (Big Endian)
947begin
948 ASSERT( SizeOf(result) = 16);
949 FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
Jens Geyerf8f62782022-09-10 00:55:02 +0200950 result := GuidUtils.SwapByteOrder(network);
Jens Geyer62445c12022-06-29 00:00:00 +0200951end;
952
Jens Geyerd5436f52014-10-03 19:50:38 +0200953function TBinaryProtocolImpl.ReadBool: Boolean;
954begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200955 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200956end;
957
958function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200959begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200960 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200961end;
962
963function TBinaryProtocolImpl.ReadDouble: Double;
964begin
965 Result := ConvertInt64ToDouble( ReadI64 )
966end;
967
Jens Geyer17c3ad92017-09-05 20:31:27 +0200968function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200969begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200970 Init( result, '', TType( ReadByte), 0);
971 if ( result.Type_ <> TType.Stop ) then begin
972 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200973 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200974end;
975
976procedure TBinaryProtocolImpl.ReadFieldEnd;
977begin
978
979end;
980
981function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200982var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200983begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200984 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200985 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
986end;
987
988function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200989var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200990begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200991 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200992
993 Result := Integer(
994 ((i32in[0] and $FF) shl 24) or
995 ((i32in[1] and $FF) shl 16) or
996 ((i32in[2] and $FF) shl 8) or
997 (i32in[3] and $FF));
998
999end;
1000
1001function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001002var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001003begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001004 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001005 Result :=
1006 (Int64( i64in[0] and $FF) shl 56) or
1007 (Int64( i64in[1] and $FF) shl 48) or
1008 (Int64( i64in[2] and $FF) shl 40) or
1009 (Int64( i64in[3] and $FF) shl 32) or
1010 (Int64( i64in[4] and $FF) shl 24) or
1011 (Int64( i64in[5] and $FF) shl 16) or
1012 (Int64( i64in[6] and $FF) shl 8) or
1013 (Int64( i64in[7] and $FF));
1014end;
1015
Jens Geyer17c3ad92017-09-05 20:31:27 +02001016function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001017begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001018 result.ElementType := TType(ReadByte);
1019 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001020 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001021end;
1022
1023procedure TBinaryProtocolImpl.ReadListEnd;
1024begin
1025
1026end;
1027
Jens Geyer17c3ad92017-09-05 20:31:27 +02001028function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001029begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001030 result.KeyType := TType(ReadByte);
1031 result.ValueType := TType(ReadByte);
1032 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001033 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001034end;
1035
1036procedure TBinaryProtocolImpl.ReadMapEnd;
1037begin
1038
1039end;
1040
Jens Geyer17c3ad92017-09-05 20:31:27 +02001041function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001042var
1043 size : Integer;
1044 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +02001045begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001046 Reset;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001047 Init( result);
Jens Geyer589ee5b2021-03-29 21:40:55 +02001048
Jens Geyerd5436f52014-10-03 19:50:38 +02001049 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001050 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001051 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001052 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +02001053 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +02001054 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001055 result.Type_ := TMessageType( size and $000000ff);
1056 result.Name := ReadString;
1057 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001058 Exit;
1059 end;
1060
1061 try
1062 if FStrictRead
1063 then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
1064
Jens Geyer17c3ad92017-09-05 20:31:27 +02001065 result.Name := ReadStringBody( size );
1066 result.Type_ := TMessageType( ReadByte );
1067 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001068 except
1069 if CharUtils.IsHtmlDoctype(size)
1070 then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
1071 else raise; // something else
Jens Geyerd5436f52014-10-03 19:50:38 +02001072 end;
Jens Geyerd5436f52014-10-03 19:50:38 +02001073end;
1074
1075procedure TBinaryProtocolImpl.ReadMessageEnd;
1076begin
1077 inherited;
1078
1079end;
1080
Jens Geyer17c3ad92017-09-05 20:31:27 +02001081function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001082begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001083 result.ElementType := TType(ReadByte);
1084 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001085 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001086end;
1087
1088procedure TBinaryProtocolImpl.ReadSetEnd;
1089begin
1090
1091end;
1092
1093function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001094var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +02001095begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001096 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001097 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +02001098 FTrans.ReadAll( buf, 0, size );
1099 Result := TEncoding.UTF8.GetString( buf);
1100end;
1101
Jens Geyer17c3ad92017-09-05 20:31:27 +02001102function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001103begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001104 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001105end;
1106
1107procedure TBinaryProtocolImpl.ReadStructEnd;
1108begin
1109 inherited;
1110
1111end;
1112
1113procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1114var iLen : Integer;
1115begin
1116 iLen := Length(b);
1117 WriteI32( iLen);
1118 if iLen > 0 then FTrans.Write(b, 0, iLen);
1119end;
1120
Jens Geyerb53fa8e2024-03-08 00:33:22 +01001121procedure TBinaryProtocolImpl.WriteBinary( const bytes : IThriftBytes);
1122var iLen : Integer;
1123begin
1124 iLen := bytes.Count;
1125 WriteI32( iLen);
1126 if iLen > 0 then FTrans.Write( bytes.QueryRawDataPtr, 0, iLen);
1127end;
1128
Jens Geyer62445c12022-06-29 00:00:00 +02001129procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
1130var network : TGuid; // in network order (Big Endian)
1131begin
1132 ASSERT( SizeOf(uuid) = 16);
Jens Geyerf8f62782022-09-10 00:55:02 +02001133 network := GuidUtils.SwapByteOrder(uuid);
Jens Geyer62445c12022-06-29 00:00:00 +02001134 Transport.Write( @network, 0, SizeOf(network));
1135end;
1136
Jens Geyerd5436f52014-10-03 19:50:38 +02001137procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1138begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001139 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001140 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +02001141 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001142 WriteByte( 0 );
1143 end;
1144end;
1145
1146procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +02001147begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001148 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +02001149end;
1150
1151procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1152begin
1153 WriteI64(ConvertDoubleToInt64(d));
1154end;
1155
Jens Geyer17c3ad92017-09-05 20:31:27 +02001156procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001157begin
1158 WriteByte(ShortInt(field.Type_));
1159 WriteI16(field.ID);
1160end;
1161
1162procedure TBinaryProtocolImpl.WriteFieldEnd;
1163begin
1164
1165end;
1166
1167procedure TBinaryProtocolImpl.WriteFieldStop;
1168begin
1169 WriteByte(ShortInt(TType.Stop));
1170end;
1171
1172procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001173var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001174begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001175 i16out[0] := Byte($FF and (i16 shr 8));
1176 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001177 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +02001178end;
1179
1180procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001181var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001182begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001183 i32out[0] := Byte($FF and (i32 shr 24));
1184 i32out[1] := Byte($FF and (i32 shr 16));
1185 i32out[2] := Byte($FF and (i32 shr 8));
1186 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001187 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001188end;
1189
1190procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001191var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001192begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001193 i64out[0] := Byte($FF and (i64 shr 56));
1194 i64out[1] := Byte($FF and (i64 shr 48));
1195 i64out[2] := Byte($FF and (i64 shr 40));
1196 i64out[3] := Byte($FF and (i64 shr 32));
1197 i64out[4] := Byte($FF and (i64 shr 24));
1198 i64out[5] := Byte($FF and (i64 shr 16));
1199 i64out[6] := Byte($FF and (i64 shr 8));
1200 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001201 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001202end;
1203
Jens Geyer17c3ad92017-09-05 20:31:27 +02001204procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001205begin
1206 WriteByte(ShortInt(list.ElementType));
1207 WriteI32(list.Count);
1208end;
1209
1210procedure TBinaryProtocolImpl.WriteListEnd;
1211begin
1212
1213end;
1214
Jens Geyer17c3ad92017-09-05 20:31:27 +02001215procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001216begin
1217 WriteByte(ShortInt(map.KeyType));
1218 WriteByte(ShortInt(map.ValueType));
1219 WriteI32(map.Count);
1220end;
1221
1222procedure TBinaryProtocolImpl.WriteMapEnd;
1223begin
1224
1225end;
1226
Jens Geyer17c3ad92017-09-05 20:31:27 +02001227procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001228var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +02001229begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001230 Reset;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001231 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001232 version := VERSION_1 or Cardinal( msg.Type_);
1233 WriteI32( Integer( version) );
1234 WriteString( msg.Name);
1235 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001236 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001237 WriteString( msg.Name);
1238 WriteByte(ShortInt( msg.Type_));
1239 WriteI32( msg.SeqID);
1240 end;
1241end;
1242
1243procedure TBinaryProtocolImpl.WriteMessageEnd;
1244begin
1245
1246end;
1247
Jens Geyer17c3ad92017-09-05 20:31:27 +02001248procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +02001249begin
1250 WriteByte(ShortInt(set_.ElementType));
1251 WriteI32(set_.Count);
1252end;
1253
1254procedure TBinaryProtocolImpl.WriteSetEnd;
1255begin
1256
1257end;
1258
Jens Geyer17c3ad92017-09-05 20:31:27 +02001259procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001260begin
1261
1262end;
1263
1264procedure TBinaryProtocolImpl.WriteStructEnd;
1265begin
1266
1267end;
1268
Jens Geyer41f47af2019-11-09 23:24:52 +01001269function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
1270// Return the minimum number of bytes a type will consume on the wire
1271begin
1272 case aType of
1273 TType.Stop: result := 0;
1274 TType.Void: result := 0;
1275 TType.Bool_: result := SizeOf(Byte);
1276 TType.Byte_: result := SizeOf(Byte);
1277 TType.Double_: result := SizeOf(Double);
1278 TType.I16: result := SizeOf(Int16);
1279 TType.I32: result := SizeOf(Int32);
1280 TType.I64: result := SizeOf(Int64);
1281 TType.String_: result := SizeOf(Int32); // string length
1282 TType.Struct: result := 0; // empty struct
1283 TType.Map: result := SizeOf(Int32); // element count
1284 TType.Set_: result := SizeOf(Int32); // element count
1285 TType.List: result := SizeOf(Int32); // element count
Jens Geyer62445c12022-06-29 00:00:00 +02001286 TType.Uuid: result := SizeOf(TGuid);
Jens Geyer41f47af2019-11-09 23:24:52 +01001287 else
1288 raise TTransportExceptionBadArgs.Create('Unhandled type code');
1289 end;
1290end;
1291
1292
Jens Geyerd5436f52014-10-03 19:50:38 +02001293{ TProtocolException }
1294
Jens Geyere0e32402016-04-20 21:50:48 +02001295constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001296begin
Jens Geyere0e32402016-04-20 21:50:48 +02001297 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001298end;
1299
Jens Geyere0e32402016-04-20 21:50:48 +02001300class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001301begin
Jens Geyere0e32402016-04-20 21:50:48 +02001302 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001303end;
1304
Jens Geyere0e32402016-04-20 21:50:48 +02001305class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001306begin
Jens Geyere0e32402016-04-20 21:50:48 +02001307 Result := TProtocolExceptionUnknown.Create('');
1308end;
1309
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001310class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001311begin
1312{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001313 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001314{$WARN SYMBOL_DEPRECATED DEFAULT}
1315end;
1316
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001317class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001318begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001319 case aType of
1320 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1321 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1322 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1323 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1324 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1325 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001326 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001327 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001328 Result := TProtocolExceptionUnknown.Create(msg);
1329 end;
1330end;
1331
1332{ TProtocolExceptionSpecialized }
1333
1334constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1335begin
1336 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001337end;
1338
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001339{ specialized TProtocolExceptions }
1340
1341class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1342begin
1343 result := TExceptionType.UNKNOWN;
1344end;
1345
1346class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1347begin
1348 result := TExceptionType.INVALID_DATA;
1349end;
1350
1351class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1352begin
1353 result := TExceptionType.NEGATIVE_SIZE;
1354end;
1355
1356class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1357begin
1358 result := TExceptionType.SIZE_LIMIT;
1359end;
1360
1361class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1362begin
1363 result := TExceptionType.BAD_VERSION;
1364end;
1365
1366class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1367begin
1368 result := TExceptionType.NOT_IMPLEMENTED;
1369end;
1370
1371class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1372begin
1373 result := TExceptionType.DEPTH_LIMIT;
1374end;
1375
Jens Geyerd5436f52014-10-03 19:50:38 +02001376{ TBinaryProtocolImpl.TFactory }
1377
Jens Geyerfad7fd32019-11-09 23:24:52 +01001378constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001379begin
1380 inherited Create;
1381 FStrictRead := AStrictRead;
1382 FStrictWrite := AStrictWrite;
1383end;
1384
Jens Geyerd5436f52014-10-03 19:50:38 +02001385function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1386begin
1387 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1388end;
1389
1390
1391{ TProtocolDecorator }
1392
1393constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1394begin
1395 ASSERT( aProtocol <> nil);
1396 inherited Create( aProtocol.Transport);
1397 FWrappedProtocol := aProtocol;
1398end;
1399
1400
Jens Geyer17c3ad92017-09-05 20:31:27 +02001401procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001402begin
1403 FWrappedProtocol.WriteMessageBegin( msg);
1404end;
1405
1406
1407procedure TProtocolDecorator.WriteMessageEnd;
1408begin
1409 FWrappedProtocol.WriteMessageEnd;
1410end;
1411
1412
Jens Geyer17c3ad92017-09-05 20:31:27 +02001413procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001414begin
1415 FWrappedProtocol.WriteStructBegin( struc);
1416end;
1417
1418
1419procedure TProtocolDecorator.WriteStructEnd;
1420begin
1421 FWrappedProtocol.WriteStructEnd;
1422end;
1423
1424
Jens Geyer17c3ad92017-09-05 20:31:27 +02001425procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001426begin
1427 FWrappedProtocol.WriteFieldBegin( field);
1428end;
1429
1430
1431procedure TProtocolDecorator.WriteFieldEnd;
1432begin
1433 FWrappedProtocol.WriteFieldEnd;
1434end;
1435
1436
1437procedure TProtocolDecorator.WriteFieldStop;
1438begin
1439 FWrappedProtocol.WriteFieldStop;
1440end;
1441
1442
Jens Geyer17c3ad92017-09-05 20:31:27 +02001443procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001444begin
1445 FWrappedProtocol.WriteMapBegin( map);
1446end;
1447
1448
1449procedure TProtocolDecorator.WriteMapEnd;
1450begin
1451 FWrappedProtocol.WriteMapEnd;
1452end;
1453
1454
Jens Geyer17c3ad92017-09-05 20:31:27 +02001455procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001456begin
1457 FWrappedProtocol.WriteListBegin( list);
1458end;
1459
1460
1461procedure TProtocolDecorator.WriteListEnd();
1462begin
1463 FWrappedProtocol.WriteListEnd();
1464end;
1465
1466
Jens Geyer17c3ad92017-09-05 20:31:27 +02001467procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001468begin
1469 FWrappedProtocol.WriteSetBegin( set_);
1470end;
1471
1472
1473procedure TProtocolDecorator.WriteSetEnd();
1474begin
1475 FWrappedProtocol.WriteSetEnd();
1476end;
1477
1478
1479procedure TProtocolDecorator.WriteBool( b: Boolean);
1480begin
1481 FWrappedProtocol.WriteBool( b);
1482end;
1483
1484
1485procedure TProtocolDecorator.WriteByte( b: ShortInt);
1486begin
1487 FWrappedProtocol.WriteByte( b);
1488end;
1489
1490
1491procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1492begin
1493 FWrappedProtocol.WriteI16( i16);
1494end;
1495
1496
1497procedure TProtocolDecorator.WriteI32( i32: Integer);
1498begin
1499 FWrappedProtocol.WriteI32( i32);
1500end;
1501
1502
1503procedure TProtocolDecorator.WriteI64( const i64: Int64);
1504begin
1505 FWrappedProtocol.WriteI64( i64);
1506end;
1507
1508
1509procedure TProtocolDecorator.WriteDouble( const d: Double);
1510begin
1511 FWrappedProtocol.WriteDouble( d);
1512end;
1513
1514
1515procedure TProtocolDecorator.WriteString( const s: string );
1516begin
1517 FWrappedProtocol.WriteString( s);
1518end;
1519
1520
1521procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1522begin
1523 FWrappedProtocol.WriteAnsiString( s);
1524end;
1525
1526
1527procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1528begin
1529 FWrappedProtocol.WriteBinary( b);
1530end;
1531
1532
Jens Geyerb53fa8e2024-03-08 00:33:22 +01001533procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes);
1534begin
1535 FWrappedProtocol.WriteBinary( bytes);
1536end;
1537
1538
Jens Geyer62445c12022-06-29 00:00:00 +02001539procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
1540begin
1541 FWrappedProtocol.WriteUuid( uuid);
1542end;
1543
1544
Jens Geyer17c3ad92017-09-05 20:31:27 +02001545function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001546begin
1547 result := FWrappedProtocol.ReadMessageBegin;
1548end;
1549
1550
1551procedure TProtocolDecorator.ReadMessageEnd();
1552begin
1553 FWrappedProtocol.ReadMessageEnd();
1554end;
1555
1556
Jens Geyer17c3ad92017-09-05 20:31:27 +02001557function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001558begin
1559 result := FWrappedProtocol.ReadStructBegin;
1560end;
1561
1562
1563procedure TProtocolDecorator.ReadStructEnd;
1564begin
1565 FWrappedProtocol.ReadStructEnd;
1566end;
1567
1568
Jens Geyer17c3ad92017-09-05 20:31:27 +02001569function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001570begin
1571 result := FWrappedProtocol.ReadFieldBegin;
1572end;
1573
1574
1575procedure TProtocolDecorator.ReadFieldEnd();
1576begin
1577 FWrappedProtocol.ReadFieldEnd();
1578end;
1579
1580
Jens Geyer17c3ad92017-09-05 20:31:27 +02001581function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001582begin
1583 result := FWrappedProtocol.ReadMapBegin;
1584end;
1585
1586
1587procedure TProtocolDecorator.ReadMapEnd();
1588begin
1589 FWrappedProtocol.ReadMapEnd();
1590end;
1591
1592
Jens Geyer17c3ad92017-09-05 20:31:27 +02001593function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001594begin
1595 result := FWrappedProtocol.ReadListBegin;
1596end;
1597
1598
1599procedure TProtocolDecorator.ReadListEnd();
1600begin
1601 FWrappedProtocol.ReadListEnd();
1602end;
1603
1604
Jens Geyer17c3ad92017-09-05 20:31:27 +02001605function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001606begin
1607 result := FWrappedProtocol.ReadSetBegin;
1608end;
1609
1610
1611procedure TProtocolDecorator.ReadSetEnd();
1612begin
1613 FWrappedProtocol.ReadSetEnd();
1614end;
1615
1616
1617function TProtocolDecorator.ReadBool: Boolean;
1618begin
1619 result := FWrappedProtocol.ReadBool;
1620end;
1621
1622
1623function TProtocolDecorator.ReadByte: ShortInt;
1624begin
1625 result := FWrappedProtocol.ReadByte;
1626end;
1627
1628
1629function TProtocolDecorator.ReadI16: SmallInt;
1630begin
1631 result := FWrappedProtocol.ReadI16;
1632end;
1633
1634
1635function TProtocolDecorator.ReadI32: Integer;
1636begin
1637 result := FWrappedProtocol.ReadI32;
1638end;
1639
1640
1641function TProtocolDecorator.ReadI64: Int64;
1642begin
1643 result := FWrappedProtocol.ReadI64;
1644end;
1645
1646
1647function TProtocolDecorator.ReadDouble:Double;
1648begin
1649 result := FWrappedProtocol.ReadDouble;
1650end;
1651
1652
1653function TProtocolDecorator.ReadBinary: TBytes;
1654begin
1655 result := FWrappedProtocol.ReadBinary;
1656end;
1657
1658
Jens Geyer62445c12022-06-29 00:00:00 +02001659function TProtocolDecorator.ReadUuid: TGuid;
1660begin
1661 result := FWrappedProtocol.ReadUuid;
1662end;
1663
1664
Jens Geyerd5436f52014-10-03 19:50:38 +02001665function TProtocolDecorator.ReadString: string;
1666begin
1667 result := FWrappedProtocol.ReadString;
1668end;
1669
1670
1671function TProtocolDecorator.ReadAnsiString: AnsiString;
1672begin
1673 result := FWrappedProtocol.ReadAnsiString;
1674end;
1675
1676
Jens Geyer41f47af2019-11-09 23:24:52 +01001677function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer;
1678begin
1679 result := FWrappedProtocol.GetMinSerializedSize(aType);
1680end;
1681
1682
Jens Geyer17c3ad92017-09-05 20:31:27 +02001683{ Init helper functions }
1684
1685procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1686begin
1687 rec.Name := AName;
1688 rec.Type_ := AMessageType;
1689 rec.SeqID := ASeqID;
1690end;
1691
1692
1693procedure Init( var rec : TThriftStruct; const AName: string = '');
1694begin
1695 rec.Name := AName;
1696end;
1697
1698
1699procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1700begin
1701 rec.Name := AName;
1702 rec.Type_ := AType;
1703 rec.Id := AId;
1704end;
1705
1706
1707procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1708begin
1709 rec.ValueType := AValueType;
1710 rec.KeyType := AKeyType;
1711 rec.Count := ACount;
1712end;
1713
1714
1715procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1716begin
1717 rec.Count := ACount;
1718 rec.ElementType := AElementType;
1719end;
1720
1721
1722procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1723begin
1724 rec.Count := ACount;
1725 rec.ElementType := AElementType;
1726end;
1727
1728
1729
Jens Geyerd5436f52014-10-03 19:50:38 +02001730end.
1731