blob: f5cb454d4c108d06421471b85c5d377804ebe306 [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 Geyer606f1ef2018-04-09 23:09:41 +020031 Thrift.Exception,
Jens Geyerd5436f52014-10-03 19:50:38 +020032 Thrift.Stream,
Jens Geyer8f7487e2019-05-09 22:21:32 +020033 Thrift.Utils,
Jens Geyerd5436f52014-10-03 19:50:38 +020034 Thrift.Collections,
Jens Geyera019cda2019-11-09 23:24:52 +010035 Thrift.Configuration,
Jens Geyerd5436f52014-10-03 19:50:38 +020036 Thrift.Transport;
37
38type
39
40 TType = (
41 Stop = 0,
42 Void = 1,
43 Bool_ = 2,
44 Byte_ = 3,
45 Double_ = 4,
46 I16 = 6,
47 I32 = 8,
48 I64 = 10,
49 String_ = 11,
50 Struct = 12,
51 Map = 13,
52 Set_ = 14,
Jens Geyer62445c12022-06-29 00:00:00 +020053 List = 15,
54 Uuid = 16
Jens Geyerd5436f52014-10-03 19:50:38 +020055 );
56
57 TMessageType = (
58 Call = 1,
59 Reply = 2,
60 Exception = 3,
61 Oneway = 4
62 );
63
Jens Geyerf0e63312015-03-01 18:47:49 +010064const
65 VALID_TTYPES = [
66 TType.Stop, TType.Void,
Jens Geyer62445c12022-06-29 00:00:00 +020067 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid,
Jens Geyerf0e63312015-03-01 18:47:49 +010068 TType.Struct, TType.Map, TType.Set_, TType.List
69 ];
70
71 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
72
73type
Jens Geyerd5436f52014-10-03 19:50:38 +020074 IProtocol = interface;
Jens Geyer17c3ad92017-09-05 20:31:27 +020075
76 TThriftMessage = record
77 Name: string;
78 Type_: TMessageType;
79 SeqID: Integer;
80 end;
81
82 TThriftStruct = record
83 Name: string;
84 end;
85
86 TThriftField = record
87 Name: string;
88 Type_: TType;
89 Id: SmallInt;
90 end;
91
92 TThriftList = record
93 ElementType: TType;
94 Count: Integer;
95 end;
96
97 TThriftMap = record
98 KeyType: TType;
99 ValueType: TType;
100 Count: Integer;
101 end;
102
103 TThriftSet = record
104 ElementType: TType;
105 Count: Integer;
106 end;
107
108
Jens Geyerd5436f52014-10-03 19:50:38 +0200109 IProtocolFactory = interface
110 ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
111 function GetProtocol( const trans: ITransport): IProtocol;
112 end;
113
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100114 TProtocolException = class abstract( TException)
Jens Geyerd5436f52014-10-03 19:50:38 +0200115 public
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100116 type TExceptionType = (
117 UNKNOWN = 0,
118 INVALID_DATA = 1,
119 NEGATIVE_SIZE = 2,
120 SIZE_LIMIT = 3,
121 BAD_VERSION = 4,
122 NOT_IMPLEMENTED = 5,
123 DEPTH_LIMIT = 6
124 );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100125 strict protected
Jens Geyere0e32402016-04-20 21:50:48 +0200126 constructor HiddenCreate(const Msg: string);
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100127 class function GetType: TExceptionType; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200128 public
Jens Geyere0e32402016-04-20 21:50:48 +0200129 // purposefully hide inherited constructor
130 class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
131 class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100132 class function Create( aType: TExceptionType): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
133 class function Create( aType: TExceptionType; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
134 property Type_: TExceptionType read GetType;
Jens Geyerd5436f52014-10-03 19:50:38 +0200135 end;
136
Jens Geyere0e32402016-04-20 21:50:48 +0200137 // Needed to remove deprecation warning
138 TProtocolExceptionSpecialized = class abstract (TProtocolException)
139 public
140 constructor Create(const Msg: string);
141 end;
142
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100143 TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100144 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100145 class function GetType: TProtocolException.TExceptionType; override;
146 end;
147
148 TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100149 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100150 class function GetType: TProtocolException.TExceptionType; override;
151 end;
152
153 TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100154 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100155 class function GetType: TProtocolException.TExceptionType; override;
156 end;
157
158 TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100159 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100160 class function GetType: TProtocolException.TExceptionType; override;
161 end;
162
163 TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100164 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100165 class function GetType: TProtocolException.TExceptionType; override;
166 end;
167
168 TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100169 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100170 class function GetType: TProtocolException.TExceptionType; override;
171 end;
172
173 TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100174 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100175 class function GetType: TProtocolException.TExceptionType; override;
176 end;
177
Jens Geyere0e32402016-04-20 21:50:48 +0200178
Jens Geyerd5436f52014-10-03 19:50:38 +0200179
180 TProtocolUtil = class
181 public
182 class procedure Skip( prot: IProtocol; type_: TType);
183 end;
184
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200185 IProtocolRecursionTracker = interface
186 ['{29CA033F-BB56-49B1-9EE3-31B1E82FC7A5}']
187 // no members yet
188 end;
189
190 TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRecursionTracker)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100191 strict protected
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200192 FProtocol : IProtocol;
193 public
194 constructor Create( prot : IProtocol);
195 destructor Destroy; override;
196 end;
197
Jens Geyer07f4bb52022-09-03 14:50:06 +0200198 IThriftBytes = interface; // forward
199
Jens Geyer5cf71b22023-12-18 11:44:55 +0100200 {$TYPEINFO ON}
201 TThriftBytes = packed record // can't use SysUtils.TBytes because it has no typinfo -> E2134
202 data : System.TArray<System.Byte>;
203
204 class operator Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
205 class operator Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
206 function Length : Integer;
207 end;
208 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
209
210
Jens Geyerd5436f52014-10-03 19:50:38 +0200211 IProtocol = interface
Jens Geyer07f4bb52022-09-03 14:50:06 +0200212 ['{6067A28E-15BF-4C9D-9A6F-D991BB3DCB85}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200213 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200214 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200215 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200216 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200217 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200218 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200219 procedure WriteFieldEnd;
220 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200221 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200222 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200223 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200224 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200225 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200226 procedure WriteSetEnd();
227 procedure WriteBool( b: Boolean);
228 procedure WriteByte( b: ShortInt);
229 procedure WriteI16( i16: SmallInt);
230 procedure WriteI32( i32: Integer);
231 procedure WriteI64( const i64: Int64);
232 procedure WriteDouble( const d: Double);
233 procedure WriteString( const s: string );
234 procedure WriteAnsiString( const s: AnsiString);
Jens Geyer07f4bb52022-09-03 14:50:06 +0200235 procedure WriteBinary( const b: TBytes); overload;
236 procedure WriteBinary( const b: IThriftBytes); overload;
Jens Geyer62445c12022-06-29 00:00:00 +0200237 procedure WriteUuid( const uuid: TGuid);
Jens Geyerd5436f52014-10-03 19:50:38 +0200238
Jens Geyer17c3ad92017-09-05 20:31:27 +0200239 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200240 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200241 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200242 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200243 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200244 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200245 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200246 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200247 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200248 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200249 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200250 procedure ReadSetEnd();
251 function ReadBool: Boolean;
252 function ReadByte: ShortInt;
253 function ReadI16: SmallInt;
254 function ReadI32: Integer;
255 function ReadI64: Int64;
256 function ReadDouble:Double;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200257 function ReadBinary: TBytes; // IMPORTANT: this is NOT safe across module boundaries
258 function ReadBinaryCOM : IThriftBytes;
Jens Geyer62445c12022-06-29 00:00:00 +0200259 function ReadUuid: TGuid;
Jens Geyerd5436f52014-10-03 19:50:38 +0200260 function ReadString: string;
261 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200262
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200263 function NextRecursionLevel : IProtocolRecursionTracker;
264 procedure IncrementRecursionDepth;
265 procedure DecrementRecursionDepth;
Jens Geyer41f47af2019-11-09 23:24:52 +0100266 function GetMinSerializedSize( const aType : TType) : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200267
Jens Geyerd5436f52014-10-03 19:50:38 +0200268 property Transport: ITransport read GetTransport;
Jens Geyera019cda2019-11-09 23:24:52 +0100269 function Configuration : IThriftConfiguration;
Jens Geyerd5436f52014-10-03 19:50:38 +0200270 end;
271
Jens Geyer3b686532021-07-01 23:04:08 +0200272 TProtocolImplClass = class of TProtocolImpl;
273
Jens Geyerd5436f52014-10-03 19:50:38 +0200274 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100275 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200276 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200277 FRecursionLimit : Integer;
278 FRecursionDepth : Integer;
279
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200280 function NextRecursionLevel : IProtocolRecursionTracker;
281 procedure IncrementRecursionDepth;
282 procedure DecrementRecursionDepth;
283
Jens Geyer41f47af2019-11-09 23:24:52 +0100284 function GetMinSerializedSize( const aType : TType) : Integer; virtual; abstract;
285 procedure CheckReadBytesAvailable( const value : TThriftList); overload; inline;
286 procedure CheckReadBytesAvailable( const value : TThriftSet); overload; inline;
287 procedure CheckReadBytesAvailable( const value : TThriftMap); overload; inline;
288
289 procedure Reset; virtual;
Jens Geyera019cda2019-11-09 23:24:52 +0100290 function GetTransport: ITransport;
291 function Configuration : IThriftConfiguration;
292
Jens Geyer17c3ad92017-09-05 20:31:27 +0200293 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200294 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200295 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200296 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200297 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200298 procedure WriteFieldEnd; virtual; abstract;
299 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200300 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200301 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200302 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200303 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200304 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200305 procedure WriteSetEnd(); virtual; abstract;
306 procedure WriteBool( b: Boolean); virtual; abstract;
307 procedure WriteByte( b: ShortInt); virtual; abstract;
308 procedure WriteI16( i16: SmallInt); virtual; abstract;
309 procedure WriteI32( i32: Integer); virtual; abstract;
310 procedure WriteI64( const i64: Int64); virtual; abstract;
311 procedure WriteDouble( const d: Double); virtual; abstract;
312 procedure WriteString( const s: string ); virtual;
313 procedure WriteAnsiString( const s: AnsiString); virtual;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200314 procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200315 procedure WriteUuid( const b: TGuid); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200316
Jens Geyer17c3ad92017-09-05 20:31:27 +0200317 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200318 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200319 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200320 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200321 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200322 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200323 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200324 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200325 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200326 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200327 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200328 procedure ReadSetEnd(); virtual; abstract;
329 function ReadBool: Boolean; virtual; abstract;
330 function ReadByte: ShortInt; virtual; abstract;
331 function ReadI16: SmallInt; virtual; abstract;
332 function ReadI32: Integer; virtual; abstract;
333 function ReadI64: Int64; virtual; abstract;
334 function ReadDouble:Double; virtual; abstract;
335 function ReadBinary: TBytes; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200336 function ReadUuid: TGuid; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200337 function ReadString: string; virtual;
338 function ReadAnsiString: AnsiString; virtual;
339
Jens Geyer07f4bb52022-09-03 14:50:06 +0200340 // provide generic implementation for all derived classes
341 procedure WriteBinary( const bytes : IThriftBytes); overload; virtual;
342 function ReadBinaryCOM : IThriftBytes; virtual;
343
Jens Geyera019cda2019-11-09 23:24:52 +0100344 property Transport: ITransport read GetTransport;
Jens Geyerd5436f52014-10-03 19:50:38 +0200345
Jens Geyera019cda2019-11-09 23:24:52 +0100346 public
Jens Geyer3b686532021-07-01 23:04:08 +0200347 constructor Create( const aTransport : ITransport); virtual;
Jens Geyerd5436f52014-10-03 19:50:38 +0200348 end;
349
Jens Geyer5cf71b22023-12-18 11:44:55 +0100350 {.$TYPEINFO ON} // big NO -> may cause E2134 due to Delphis stupidity on enums vs TypeInfo
Jens Geyer93222f62023-12-15 16:03:48 +0100351 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
Jens Geyer8f7487e2019-05-09 22:21:32 +0200352 IBase = interface( ISupportsToString)
353 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyer07f4bb52022-09-03 14:50:06 +0200354 procedure Read( const prot: IProtocol);
355 procedure Write( const prot: IProtocol);
356 end;
Jens Geyer5cf71b22023-12-18 11:44:55 +0100357
358 {$TYPEINFO ON}
359 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
360 IBaseWithTypeInfo = interface( IBase) end;
361
Jens Geyer93222f62023-12-15 16:03:48 +0100362 {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
363 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
Jens Geyer07f4bb52022-09-03 14:50:06 +0200364
365
366 IThriftBytes = interface( ISupportsToString)
367 ['{CDBEF7E8-BEF2-4A0A-983A-F334E3FF0016}']
368 function GetCount : Integer;
369 procedure SetCount(const value : Integer);
370
371 // WARNING: This returns a direct pointer to the underlying data structure
372 function QueryRawDataPtr : Pointer;
373
374 property Count : Integer read GetCount write SetCount;
375 end;
376
377
378 TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString)
379 strict private
380 FData : TBytes;
381
382 strict protected
383 function GetCount : Integer;
384 procedure SetCount(const value : Integer);
385 function QueryRawDataPtr : Pointer;
386
387 public
388 constructor Create; overload;
389 constructor Create( const bytes : TBytes); overload;
390 constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload;
391
392 function ToString : string; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200393 end;
394
Jens Geyerd5436f52014-10-03 19:50:38 +0200395
396 TBinaryProtocolImpl = class( TProtocolImpl )
Jens Geyerfad7fd32019-11-09 23:24:52 +0100397 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200398 const
399 VERSION_MASK : Cardinal = $ffff0000;
400 VERSION_1 : Cardinal = $80010000;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100401 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200402 FStrictRead : Boolean;
403 FStrictWrite : Boolean;
Jens Geyer41f47af2019-11-09 23:24:52 +0100404 function GetMinSerializedSize( const aType : TType) : Integer; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200405
Jens Geyerfad7fd32019-11-09 23:24:52 +0100406 strict private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200407 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200408 function ReadStringBody( size: Integer): string;
409
410 public
Jens Geyerd5436f52014-10-03 19:50:38 +0200411 type
412 TFactory = class( TInterfacedObject, IProtocolFactory)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100413 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200414 FStrictRead : Boolean;
415 FStrictWrite : Boolean;
Jens Geyerd5436f52014-10-03 19:50:38 +0200416 function GetProtocol( const trans: ITransport): IProtocol;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100417 public
418 constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200419 end;
420
Jens Geyer3b686532021-07-01 23:04:08 +0200421 constructor Create( const trans: ITransport); overload; override;
422 constructor Create( const trans: ITransport; strictRead, strictWrite: Boolean); reintroduce; overload;
Jens Geyerd5436f52014-10-03 19:50:38 +0200423
Jens Geyer17c3ad92017-09-05 20:31:27 +0200424 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200425 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200426 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200427 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200428 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200429 procedure WriteFieldEnd; override;
430 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200431 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200432 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200433 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200434 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200435 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200436 procedure WriteSetEnd(); override;
437 procedure WriteBool( b: Boolean); override;
438 procedure WriteByte( b: ShortInt); override;
439 procedure WriteI16( i16: SmallInt); override;
440 procedure WriteI32( i32: Integer); override;
441 procedure WriteI64( const i64: Int64); override;
442 procedure WriteDouble( const d: Double); override;
443 procedure WriteBinary( const b: TBytes); override;
Jens Geyer62445c12022-06-29 00:00:00 +0200444 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200445
Jens Geyer17c3ad92017-09-05 20:31:27 +0200446 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200447 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200448 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200449 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200450 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200451 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200452 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200453 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200454 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200455 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200456 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200457 procedure ReadSetEnd(); override;
458 function ReadBool: Boolean; override;
459 function ReadByte: ShortInt; override;
460 function ReadI16: SmallInt; override;
461 function ReadI32: Integer; override;
462 function ReadI64: Int64; override;
463 function ReadDouble:Double; override;
464 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200465 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200466
467 end;
468
469
470 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
471 providing a way to author concise concrete decorator subclasses. The decorator
472 does not (and should not) modify the behaviour of the enclosed TProtocol
473
474 See p.175 of Design Patterns (by Gamma et al.)
475 }
476 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100477 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200478 FWrappedProtocol : IProtocol;
479
Jens Geyer41f47af2019-11-09 23:24:52 +0100480 strict protected
481 function GetMinSerializedSize( const aType : TType) : Integer; override;
482
Jens Geyerd5436f52014-10-03 19:50:38 +0200483 public
484 // Encloses the specified protocol.
485 // All operations will be forward to the given protocol. Must be non-null.
Jens Geyer3b686532021-07-01 23:04:08 +0200486 constructor Create( const aProtocol : IProtocol); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200487
Jens Geyer17c3ad92017-09-05 20:31:27 +0200488 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200489 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200490 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200491 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200492 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200493 procedure WriteFieldEnd; override;
494 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200495 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200496 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200497 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200498 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200499 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200500 procedure WriteSetEnd(); override;
501 procedure WriteBool( b: Boolean); override;
502 procedure WriteByte( b: ShortInt); override;
503 procedure WriteI16( i16: SmallInt); override;
504 procedure WriteI32( i32: Integer); override;
505 procedure WriteI64( const i64: Int64); override;
506 procedure WriteDouble( const d: Double); override;
507 procedure WriteString( const s: string ); override;
508 procedure WriteAnsiString( const s: AnsiString); override;
509 procedure WriteBinary( const b: TBytes); override;
Jens Geyer62445c12022-06-29 00:00:00 +0200510 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200511
Jens Geyer17c3ad92017-09-05 20:31:27 +0200512 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200513 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200514 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200515 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200516 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200517 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200518 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200519 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200520 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200521 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200522 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200523 procedure ReadSetEnd(); override;
524 function ReadBool: Boolean; override;
525 function ReadByte: ShortInt; override;
526 function ReadI16: SmallInt; override;
527 function ReadI32: Integer; override;
528 function ReadI64: Int64; override;
529 function ReadDouble:Double; override;
530 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200531 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200532 function ReadString: string; override;
533 function ReadAnsiString: AnsiString; override;
534 end;
535
536
537type
538 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200539 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
540 // Called before reading arguments.
541 procedure PreRead;
542 // Called between reading arguments and calling the handler.
543 procedure PostRead;
544 // Called between calling the handler and writing the response.
545 procedure PreWrite;
546 // Called after writing the response.
547 procedure PostWrite;
548 // Called when an oneway (async) function call completes successfully.
549 procedure OnewayComplete;
550 // Called if the handler throws an undeclared exception.
551 procedure UnhandledError( const e : Exception);
552 // Called when a client has finished request-handling to clean up
553 procedure CleanupContext;
554 end;
555
556
557 IProcessorEvents = interface
558 ['{A8661119-657C-447D-93C5-512E36162A45}']
559 // Called when a client is about to call the processor.
560 procedure Processing( const transport : ITransport);
561 // Called on any service function invocation
562 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
563 // Called when a client has finished request-handling to clean up
564 procedure CleanupContext;
565 end;
566
567
568 IProcessor = interface
569 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200570 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200571 end;
572
Jens Geyerd5436f52014-10-03 19:50:38 +0200573
Jens Geyer17c3ad92017-09-05 20:31:27 +0200574procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
575procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
576procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
577procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
578procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
579procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
580
Jens Geyerd5436f52014-10-03 19:50:38 +0200581
582implementation
583
Jens Geyerfad7fd32019-11-09 23:24:52 +0100584function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200585begin
586 ASSERT( SizeOf(n) = SizeOf(Result));
587 System.Move( n, Result, SizeOf(Result));
588end;
589
Jens Geyerfad7fd32019-11-09 23:24:52 +0100590function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200591begin
592 ASSERT( SizeOf(d) = SizeOf(Result));
593 System.Move( d, Result, SizeOf(Result));
594end;
595
Jens Geyerd5436f52014-10-03 19:50:38 +0200596
Jens Geyer5cf71b22023-12-18 11:44:55 +0100597//--- TThriftBytes ----------------------------------------------------------------------
598
599
600class operator TThriftBytes.Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
601begin
602 ASSERT( @result.data = @result); // must be first field
603 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
604 result := TThriftBytes(aRec);
605end;
606
607
608class operator TThriftBytes.Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
609begin
610 ASSERT( @aRec.data = @aRec); // must be first field
611 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
612 result := SysUtils.TBytes(aRec.data);
613end;
614
615
616function TThriftBytes.Length : Integer;
617begin
618 result := System.Length(data);
619end;
620
Jens Geyerd5436f52014-10-03 19:50:38 +0200621
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200622{ TProtocolRecursionTrackerImpl }
623
624constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
625begin
626 inherited Create;
627
628 // storing the pointer *after* the (successful) increment is important here
629 prot.IncrementRecursionDepth;
630 FProtocol := prot;
631end;
632
633destructor TProtocolRecursionTrackerImpl.Destroy;
634begin
635 try
636 // we have to release the reference iff the pointer has been stored
637 if FProtocol <> nil then begin
638 FProtocol.DecrementRecursionDepth;
639 FProtocol := nil;
640 end;
641 finally
642 inherited Destroy;
643 end;
644end;
645
Jens Geyerd5436f52014-10-03 19:50:38 +0200646{ TProtocolImpl }
647
Jens Geyera019cda2019-11-09 23:24:52 +0100648constructor TProtocolImpl.Create( const aTransport : ITransport);
Jens Geyerd5436f52014-10-03 19:50:38 +0200649begin
650 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100651 FTrans := aTransport;
652 FRecursionLimit := aTransport.Configuration.RecursionLimit;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200653 FRecursionDepth := 0;
654end;
655
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200656function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
657begin
658 result := TProtocolRecursionTrackerImpl.Create(Self);
659end;
660
661procedure TProtocolImpl.IncrementRecursionDepth;
662begin
663 if FRecursionDepth < FRecursionLimit
664 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200665 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200666end;
667
668procedure TProtocolImpl.DecrementRecursionDepth;
669begin
670 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200671end;
672
673function TProtocolImpl.GetTransport: ITransport;
674begin
675 Result := FTrans;
676end;
677
Jens Geyera019cda2019-11-09 23:24:52 +0100678function TProtocolImpl.Configuration : IThriftConfiguration;
679begin
680 Result := FTrans.Configuration;
681end;
682
Jens Geyer41f47af2019-11-09 23:24:52 +0100683procedure TProtocolImpl.Reset;
684begin
Jens Geyera019cda2019-11-09 23:24:52 +0100685 FTrans.ResetConsumedMessageSize;
Jens Geyer41f47af2019-11-09 23:24:52 +0100686end;
687
Jens Geyerd5436f52014-10-03 19:50:38 +0200688function TProtocolImpl.ReadAnsiString: AnsiString;
689var
690 b : TBytes;
691 len : Integer;
692begin
693 Result := '';
694 b := ReadBinary;
695 len := Length( b );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100696 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200697 SetLength( Result, len);
698 System.Move( b[0], Pointer(Result)^, len );
699 end;
700end;
701
702function TProtocolImpl.ReadString: string;
703begin
704 Result := TEncoding.UTF8.GetString( ReadBinary );
705end;
706
707procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
708var
709 b : TBytes;
710 len : Integer;
711begin
712 len := Length(s);
713 SetLength( b, len);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100714 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200715 System.Move( Pointer(s)^, b[0], len );
716 end;
717 WriteBinary( b );
718end;
719
720procedure TProtocolImpl.WriteString(const s: string);
721var
722 b : TBytes;
723begin
724 b := TEncoding.UTF8.GetBytes(s);
725 WriteBinary( b );
726end;
727
Jens Geyer41f47af2019-11-09 23:24:52 +0100728
729procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList);
730begin
731 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
732end;
733
734
735procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet);
736begin
737 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
738end;
739
740
741procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap);
Jens Geyera019cda2019-11-09 23:24:52 +0100742var nPairSize : Integer;
Jens Geyer41f47af2019-11-09 23:24:52 +0100743begin
744 nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType);
745 FTrans.CheckReadBytesAvailable( value.Count * nPairSize);
746end;
747
Jens Geyer07f4bb52022-09-03 14:50:06 +0200748
749procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
750var tmp : TBytes;
751begin
752 SetLength( tmp, bytes.Count);
753 if Length(tmp) > 0
754 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp));
755 WriteBinary( tmp);
756end;
757
758
759function TProtocolImpl.ReadBinaryCOM : IThriftBytes;
760var bytes : TBytes;
761begin
762 bytes := ReadBinary;
763 result := TThriftBytesImpl.Create(bytes,TRUE);
764end;
765
766
767{ TThriftBytesImpl }
768
769constructor TThriftBytesImpl.Create;
770begin
771 inherited Create;
772 ASSERT( Length(FData) = 0);
773end;
774
775
776constructor TThriftBytesImpl.Create( const bytes : TBytes);
777begin
778 FData := bytes; // copies the data
779end;
780
781
782constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean);
783
784 procedure SwapPointer( var one, two);
785 var
786 pOne : Pointer absolute one;
787 pTwo : Pointer absolute two;
788 pTmp : Pointer;
789 begin
790 pTmp := pOne;
791 pOne := pTwo;
792 pTwo := pTmp;
793 end;
794
795begin
796 inherited Create;
797 ASSERT( Length(FData) = 0);
798
799 if aTakeOwnership
800 then SwapPointer( FData, bytes)
801 else FData := bytes; // copies the data
802end;
803
804
805function TThriftBytesImpl.ToString : string;
806var sb : TThriftStringBuilder;
807begin
808 sb := TThriftStringBuilder.Create();
809 try
810 sb.Append('Bin: ');
811 sb.Append( FData);
812
813 result := sb.ToString;
814 finally
815 sb.Free;
816 end;
817end;
818
819
820function TThriftBytesImpl.GetCount : Integer;
821begin
822 result := Length(FData);
823end;
824
825
826procedure TThriftBytesImpl.SetCount(const value : Integer);
827begin
828 SetLength( FData, value);
829end;
830
831
832function TThriftBytesImpl.QueryRawDataPtr : Pointer;
833begin
834 result := FData;
835end;
836
Jens Geyerd5436f52014-10-03 19:50:38 +0200837{ TProtocolUtil }
838
839class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200840var field : TThriftField;
841 map : TThriftMap;
842 set_ : TThriftSet;
843 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200844 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200845 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200846begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200847 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200848 case type_ of
849 // simple types
850 TType.Bool_ : prot.ReadBool();
851 TType.Byte_ : prot.ReadByte();
852 TType.I16 : prot.ReadI16();
853 TType.I32 : prot.ReadI32();
854 TType.I64 : prot.ReadI64();
855 TType.Double_ : prot.ReadDouble();
856 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jens Geyer62445c12022-06-29 00:00:00 +0200857 TType.Uuid : prot.ReadUuid();
Jens Geyerd5436f52014-10-03 19:50:38 +0200858
859 // structured types
860 TType.Struct : begin
861 prot.ReadStructBegin();
862 while TRUE do begin
863 field := prot.ReadFieldBegin();
864 if (field.Type_ = TType.Stop) then Break;
865 Skip(prot, field.Type_);
866 prot.ReadFieldEnd();
867 end;
868 prot.ReadStructEnd();
869 end;
870
871 TType.Map : begin
872 map := prot.ReadMapBegin();
873 for i := 0 to map.Count-1 do begin
874 Skip(prot, map.KeyType);
875 Skip(prot, map.ValueType);
876 end;
877 prot.ReadMapEnd();
878 end;
879
880 TType.Set_ : begin
881 set_ := prot.ReadSetBegin();
882 for i := 0 to set_.Count-1
883 do Skip( prot, set_.ElementType);
884 prot.ReadSetEnd();
885 end;
886
887 TType.List : begin
888 list := prot.ReadListBegin();
889 for i := 0 to list.Count-1
890 do Skip( prot, list.ElementType);
891 prot.ReadListEnd();
892 end;
893
894 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100895 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200896 end;
897end;
898
Jens Geyerd5436f52014-10-03 19:50:38 +0200899
900{ TBinaryProtocolImpl }
901
Jens Geyer3b686532021-07-01 23:04:08 +0200902constructor TBinaryProtocolImpl.Create( const trans: ITransport);
903begin
904 // call the real CTOR
905 Self.Create( trans, FALSE, TRUE);
906end;
907
Jens Geyerfad7fd32019-11-09 23:24:52 +0100908constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200909begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100910 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200911 FStrictRead := strictRead;
912 FStrictWrite := strictWrite;
913end;
914
Jens Geyer17c3ad92017-09-05 20:31:27 +0200915function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200916begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200917 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200918end;
919
920function TBinaryProtocolImpl.ReadBinary: TBytes;
921var
922 size : Integer;
923 buf : TBytes;
924begin
925 size := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100926 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100927 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200928 FTrans.ReadAll( buf, 0, size);
929 Result := buf;
930end;
931
Jens Geyer62445c12022-06-29 00:00:00 +0200932function TBinaryProtocolImpl.ReadUuid : TGuid;
933var network : TGuid; // in network order (Big Endian)
934begin
935 ASSERT( SizeOf(result) = 16);
936 FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
Jens Geyerf8f62782022-09-10 00:55:02 +0200937 result := GuidUtils.SwapByteOrder(network);
Jens Geyer62445c12022-06-29 00:00:00 +0200938end;
939
Jens Geyerd5436f52014-10-03 19:50:38 +0200940function TBinaryProtocolImpl.ReadBool: Boolean;
941begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200942 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200943end;
944
945function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200946begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200947 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200948end;
949
950function TBinaryProtocolImpl.ReadDouble: Double;
951begin
952 Result := ConvertInt64ToDouble( ReadI64 )
953end;
954
Jens Geyer17c3ad92017-09-05 20:31:27 +0200955function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200956begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200957 Init( result, '', TType( ReadByte), 0);
958 if ( result.Type_ <> TType.Stop ) then begin
959 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200960 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200961end;
962
963procedure TBinaryProtocolImpl.ReadFieldEnd;
964begin
965
966end;
967
968function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200969var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200970begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200971 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200972 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
973end;
974
975function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200976var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200977begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200978 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200979
980 Result := Integer(
981 ((i32in[0] and $FF) shl 24) or
982 ((i32in[1] and $FF) shl 16) or
983 ((i32in[2] and $FF) shl 8) or
984 (i32in[3] and $FF));
985
986end;
987
988function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200989var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200990begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200991 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200992 Result :=
993 (Int64( i64in[0] and $FF) shl 56) or
994 (Int64( i64in[1] and $FF) shl 48) or
995 (Int64( i64in[2] and $FF) shl 40) or
996 (Int64( i64in[3] and $FF) shl 32) or
997 (Int64( i64in[4] and $FF) shl 24) or
998 (Int64( i64in[5] and $FF) shl 16) or
999 (Int64( i64in[6] and $FF) shl 8) or
1000 (Int64( i64in[7] and $FF));
1001end;
1002
Jens Geyer17c3ad92017-09-05 20:31:27 +02001003function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001004begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001005 result.ElementType := TType(ReadByte);
1006 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001007 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001008end;
1009
1010procedure TBinaryProtocolImpl.ReadListEnd;
1011begin
1012
1013end;
1014
Jens Geyer17c3ad92017-09-05 20:31:27 +02001015function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001016begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001017 result.KeyType := TType(ReadByte);
1018 result.ValueType := 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.ReadMapEnd;
1024begin
1025
1026end;
1027
Jens Geyer17c3ad92017-09-05 20:31:27 +02001028function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001029var
1030 size : Integer;
1031 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +02001032begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001033 Reset;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001034 Init( result);
Jens Geyer589ee5b2021-03-29 21:40:55 +02001035
Jens Geyerd5436f52014-10-03 19:50:38 +02001036 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001037 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001038 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001039 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +02001040 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +02001041 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001042 result.Type_ := TMessageType( size and $000000ff);
1043 result.Name := ReadString;
1044 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001045 Exit;
1046 end;
1047
1048 try
1049 if FStrictRead
1050 then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
1051
Jens Geyer17c3ad92017-09-05 20:31:27 +02001052 result.Name := ReadStringBody( size );
1053 result.Type_ := TMessageType( ReadByte );
1054 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001055 except
1056 if CharUtils.IsHtmlDoctype(size)
1057 then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
1058 else raise; // something else
Jens Geyerd5436f52014-10-03 19:50:38 +02001059 end;
Jens Geyerd5436f52014-10-03 19:50:38 +02001060end;
1061
1062procedure TBinaryProtocolImpl.ReadMessageEnd;
1063begin
1064 inherited;
1065
1066end;
1067
Jens Geyer17c3ad92017-09-05 20:31:27 +02001068function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001069begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001070 result.ElementType := TType(ReadByte);
1071 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001072 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001073end;
1074
1075procedure TBinaryProtocolImpl.ReadSetEnd;
1076begin
1077
1078end;
1079
1080function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001081var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +02001082begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001083 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001084 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +02001085 FTrans.ReadAll( buf, 0, size );
1086 Result := TEncoding.UTF8.GetString( buf);
1087end;
1088
Jens Geyer17c3ad92017-09-05 20:31:27 +02001089function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001090begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001091 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001092end;
1093
1094procedure TBinaryProtocolImpl.ReadStructEnd;
1095begin
1096 inherited;
1097
1098end;
1099
1100procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1101var iLen : Integer;
1102begin
1103 iLen := Length(b);
1104 WriteI32( iLen);
1105 if iLen > 0 then FTrans.Write(b, 0, iLen);
1106end;
1107
Jens Geyer62445c12022-06-29 00:00:00 +02001108procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
1109var network : TGuid; // in network order (Big Endian)
1110begin
1111 ASSERT( SizeOf(uuid) = 16);
Jens Geyerf8f62782022-09-10 00:55:02 +02001112 network := GuidUtils.SwapByteOrder(uuid);
Jens Geyer62445c12022-06-29 00:00:00 +02001113 Transport.Write( @network, 0, SizeOf(network));
1114end;
1115
Jens Geyerd5436f52014-10-03 19:50:38 +02001116procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1117begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001118 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001119 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +02001120 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001121 WriteByte( 0 );
1122 end;
1123end;
1124
1125procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +02001126begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001127 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +02001128end;
1129
1130procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1131begin
1132 WriteI64(ConvertDoubleToInt64(d));
1133end;
1134
Jens Geyer17c3ad92017-09-05 20:31:27 +02001135procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001136begin
1137 WriteByte(ShortInt(field.Type_));
1138 WriteI16(field.ID);
1139end;
1140
1141procedure TBinaryProtocolImpl.WriteFieldEnd;
1142begin
1143
1144end;
1145
1146procedure TBinaryProtocolImpl.WriteFieldStop;
1147begin
1148 WriteByte(ShortInt(TType.Stop));
1149end;
1150
1151procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001152var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001153begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001154 i16out[0] := Byte($FF and (i16 shr 8));
1155 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001156 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +02001157end;
1158
1159procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001160var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001161begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001162 i32out[0] := Byte($FF and (i32 shr 24));
1163 i32out[1] := Byte($FF and (i32 shr 16));
1164 i32out[2] := Byte($FF and (i32 shr 8));
1165 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001166 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001167end;
1168
1169procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001170var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001171begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001172 i64out[0] := Byte($FF and (i64 shr 56));
1173 i64out[1] := Byte($FF and (i64 shr 48));
1174 i64out[2] := Byte($FF and (i64 shr 40));
1175 i64out[3] := Byte($FF and (i64 shr 32));
1176 i64out[4] := Byte($FF and (i64 shr 24));
1177 i64out[5] := Byte($FF and (i64 shr 16));
1178 i64out[6] := Byte($FF and (i64 shr 8));
1179 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001180 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001181end;
1182
Jens Geyer17c3ad92017-09-05 20:31:27 +02001183procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001184begin
1185 WriteByte(ShortInt(list.ElementType));
1186 WriteI32(list.Count);
1187end;
1188
1189procedure TBinaryProtocolImpl.WriteListEnd;
1190begin
1191
1192end;
1193
Jens Geyer17c3ad92017-09-05 20:31:27 +02001194procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001195begin
1196 WriteByte(ShortInt(map.KeyType));
1197 WriteByte(ShortInt(map.ValueType));
1198 WriteI32(map.Count);
1199end;
1200
1201procedure TBinaryProtocolImpl.WriteMapEnd;
1202begin
1203
1204end;
1205
Jens Geyer17c3ad92017-09-05 20:31:27 +02001206procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001207var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +02001208begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001209 Reset;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001210 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001211 version := VERSION_1 or Cardinal( msg.Type_);
1212 WriteI32( Integer( version) );
1213 WriteString( msg.Name);
1214 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001215 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001216 WriteString( msg.Name);
1217 WriteByte(ShortInt( msg.Type_));
1218 WriteI32( msg.SeqID);
1219 end;
1220end;
1221
1222procedure TBinaryProtocolImpl.WriteMessageEnd;
1223begin
1224
1225end;
1226
Jens Geyer17c3ad92017-09-05 20:31:27 +02001227procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +02001228begin
1229 WriteByte(ShortInt(set_.ElementType));
1230 WriteI32(set_.Count);
1231end;
1232
1233procedure TBinaryProtocolImpl.WriteSetEnd;
1234begin
1235
1236end;
1237
Jens Geyer17c3ad92017-09-05 20:31:27 +02001238procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001239begin
1240
1241end;
1242
1243procedure TBinaryProtocolImpl.WriteStructEnd;
1244begin
1245
1246end;
1247
Jens Geyer41f47af2019-11-09 23:24:52 +01001248function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
1249// Return the minimum number of bytes a type will consume on the wire
1250begin
1251 case aType of
1252 TType.Stop: result := 0;
1253 TType.Void: result := 0;
1254 TType.Bool_: result := SizeOf(Byte);
1255 TType.Byte_: result := SizeOf(Byte);
1256 TType.Double_: result := SizeOf(Double);
1257 TType.I16: result := SizeOf(Int16);
1258 TType.I32: result := SizeOf(Int32);
1259 TType.I64: result := SizeOf(Int64);
1260 TType.String_: result := SizeOf(Int32); // string length
1261 TType.Struct: result := 0; // empty struct
1262 TType.Map: result := SizeOf(Int32); // element count
1263 TType.Set_: result := SizeOf(Int32); // element count
1264 TType.List: result := SizeOf(Int32); // element count
Jens Geyer62445c12022-06-29 00:00:00 +02001265 TType.Uuid: result := SizeOf(TGuid);
Jens Geyer41f47af2019-11-09 23:24:52 +01001266 else
1267 raise TTransportExceptionBadArgs.Create('Unhandled type code');
1268 end;
1269end;
1270
1271
Jens Geyerd5436f52014-10-03 19:50:38 +02001272{ TProtocolException }
1273
Jens Geyere0e32402016-04-20 21:50:48 +02001274constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001275begin
Jens Geyere0e32402016-04-20 21:50:48 +02001276 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001277end;
1278
Jens Geyere0e32402016-04-20 21:50:48 +02001279class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001280begin
Jens Geyere0e32402016-04-20 21:50:48 +02001281 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001282end;
1283
Jens Geyere0e32402016-04-20 21:50:48 +02001284class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001285begin
Jens Geyere0e32402016-04-20 21:50:48 +02001286 Result := TProtocolExceptionUnknown.Create('');
1287end;
1288
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001289class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001290begin
1291{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001292 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001293{$WARN SYMBOL_DEPRECATED DEFAULT}
1294end;
1295
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001296class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001297begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001298 case aType of
1299 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1300 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1301 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1302 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1303 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1304 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001305 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001306 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001307 Result := TProtocolExceptionUnknown.Create(msg);
1308 end;
1309end;
1310
1311{ TProtocolExceptionSpecialized }
1312
1313constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1314begin
1315 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001316end;
1317
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001318{ specialized TProtocolExceptions }
1319
1320class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1321begin
1322 result := TExceptionType.UNKNOWN;
1323end;
1324
1325class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1326begin
1327 result := TExceptionType.INVALID_DATA;
1328end;
1329
1330class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1331begin
1332 result := TExceptionType.NEGATIVE_SIZE;
1333end;
1334
1335class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1336begin
1337 result := TExceptionType.SIZE_LIMIT;
1338end;
1339
1340class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1341begin
1342 result := TExceptionType.BAD_VERSION;
1343end;
1344
1345class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1346begin
1347 result := TExceptionType.NOT_IMPLEMENTED;
1348end;
1349
1350class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1351begin
1352 result := TExceptionType.DEPTH_LIMIT;
1353end;
1354
Jens Geyerd5436f52014-10-03 19:50:38 +02001355{ TBinaryProtocolImpl.TFactory }
1356
Jens Geyerfad7fd32019-11-09 23:24:52 +01001357constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001358begin
1359 inherited Create;
1360 FStrictRead := AStrictRead;
1361 FStrictWrite := AStrictWrite;
1362end;
1363
Jens Geyerd5436f52014-10-03 19:50:38 +02001364function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1365begin
1366 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1367end;
1368
1369
1370{ TProtocolDecorator }
1371
1372constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1373begin
1374 ASSERT( aProtocol <> nil);
1375 inherited Create( aProtocol.Transport);
1376 FWrappedProtocol := aProtocol;
1377end;
1378
1379
Jens Geyer17c3ad92017-09-05 20:31:27 +02001380procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001381begin
1382 FWrappedProtocol.WriteMessageBegin( msg);
1383end;
1384
1385
1386procedure TProtocolDecorator.WriteMessageEnd;
1387begin
1388 FWrappedProtocol.WriteMessageEnd;
1389end;
1390
1391
Jens Geyer17c3ad92017-09-05 20:31:27 +02001392procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001393begin
1394 FWrappedProtocol.WriteStructBegin( struc);
1395end;
1396
1397
1398procedure TProtocolDecorator.WriteStructEnd;
1399begin
1400 FWrappedProtocol.WriteStructEnd;
1401end;
1402
1403
Jens Geyer17c3ad92017-09-05 20:31:27 +02001404procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001405begin
1406 FWrappedProtocol.WriteFieldBegin( field);
1407end;
1408
1409
1410procedure TProtocolDecorator.WriteFieldEnd;
1411begin
1412 FWrappedProtocol.WriteFieldEnd;
1413end;
1414
1415
1416procedure TProtocolDecorator.WriteFieldStop;
1417begin
1418 FWrappedProtocol.WriteFieldStop;
1419end;
1420
1421
Jens Geyer17c3ad92017-09-05 20:31:27 +02001422procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001423begin
1424 FWrappedProtocol.WriteMapBegin( map);
1425end;
1426
1427
1428procedure TProtocolDecorator.WriteMapEnd;
1429begin
1430 FWrappedProtocol.WriteMapEnd;
1431end;
1432
1433
Jens Geyer17c3ad92017-09-05 20:31:27 +02001434procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001435begin
1436 FWrappedProtocol.WriteListBegin( list);
1437end;
1438
1439
1440procedure TProtocolDecorator.WriteListEnd();
1441begin
1442 FWrappedProtocol.WriteListEnd();
1443end;
1444
1445
Jens Geyer17c3ad92017-09-05 20:31:27 +02001446procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001447begin
1448 FWrappedProtocol.WriteSetBegin( set_);
1449end;
1450
1451
1452procedure TProtocolDecorator.WriteSetEnd();
1453begin
1454 FWrappedProtocol.WriteSetEnd();
1455end;
1456
1457
1458procedure TProtocolDecorator.WriteBool( b: Boolean);
1459begin
1460 FWrappedProtocol.WriteBool( b);
1461end;
1462
1463
1464procedure TProtocolDecorator.WriteByte( b: ShortInt);
1465begin
1466 FWrappedProtocol.WriteByte( b);
1467end;
1468
1469
1470procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1471begin
1472 FWrappedProtocol.WriteI16( i16);
1473end;
1474
1475
1476procedure TProtocolDecorator.WriteI32( i32: Integer);
1477begin
1478 FWrappedProtocol.WriteI32( i32);
1479end;
1480
1481
1482procedure TProtocolDecorator.WriteI64( const i64: Int64);
1483begin
1484 FWrappedProtocol.WriteI64( i64);
1485end;
1486
1487
1488procedure TProtocolDecorator.WriteDouble( const d: Double);
1489begin
1490 FWrappedProtocol.WriteDouble( d);
1491end;
1492
1493
1494procedure TProtocolDecorator.WriteString( const s: string );
1495begin
1496 FWrappedProtocol.WriteString( s);
1497end;
1498
1499
1500procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1501begin
1502 FWrappedProtocol.WriteAnsiString( s);
1503end;
1504
1505
1506procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1507begin
1508 FWrappedProtocol.WriteBinary( b);
1509end;
1510
1511
Jens Geyer62445c12022-06-29 00:00:00 +02001512procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
1513begin
1514 FWrappedProtocol.WriteUuid( uuid);
1515end;
1516
1517
Jens Geyer17c3ad92017-09-05 20:31:27 +02001518function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001519begin
1520 result := FWrappedProtocol.ReadMessageBegin;
1521end;
1522
1523
1524procedure TProtocolDecorator.ReadMessageEnd();
1525begin
1526 FWrappedProtocol.ReadMessageEnd();
1527end;
1528
1529
Jens Geyer17c3ad92017-09-05 20:31:27 +02001530function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001531begin
1532 result := FWrappedProtocol.ReadStructBegin;
1533end;
1534
1535
1536procedure TProtocolDecorator.ReadStructEnd;
1537begin
1538 FWrappedProtocol.ReadStructEnd;
1539end;
1540
1541
Jens Geyer17c3ad92017-09-05 20:31:27 +02001542function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001543begin
1544 result := FWrappedProtocol.ReadFieldBegin;
1545end;
1546
1547
1548procedure TProtocolDecorator.ReadFieldEnd();
1549begin
1550 FWrappedProtocol.ReadFieldEnd();
1551end;
1552
1553
Jens Geyer17c3ad92017-09-05 20:31:27 +02001554function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001555begin
1556 result := FWrappedProtocol.ReadMapBegin;
1557end;
1558
1559
1560procedure TProtocolDecorator.ReadMapEnd();
1561begin
1562 FWrappedProtocol.ReadMapEnd();
1563end;
1564
1565
Jens Geyer17c3ad92017-09-05 20:31:27 +02001566function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001567begin
1568 result := FWrappedProtocol.ReadListBegin;
1569end;
1570
1571
1572procedure TProtocolDecorator.ReadListEnd();
1573begin
1574 FWrappedProtocol.ReadListEnd();
1575end;
1576
1577
Jens Geyer17c3ad92017-09-05 20:31:27 +02001578function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001579begin
1580 result := FWrappedProtocol.ReadSetBegin;
1581end;
1582
1583
1584procedure TProtocolDecorator.ReadSetEnd();
1585begin
1586 FWrappedProtocol.ReadSetEnd();
1587end;
1588
1589
1590function TProtocolDecorator.ReadBool: Boolean;
1591begin
1592 result := FWrappedProtocol.ReadBool;
1593end;
1594
1595
1596function TProtocolDecorator.ReadByte: ShortInt;
1597begin
1598 result := FWrappedProtocol.ReadByte;
1599end;
1600
1601
1602function TProtocolDecorator.ReadI16: SmallInt;
1603begin
1604 result := FWrappedProtocol.ReadI16;
1605end;
1606
1607
1608function TProtocolDecorator.ReadI32: Integer;
1609begin
1610 result := FWrappedProtocol.ReadI32;
1611end;
1612
1613
1614function TProtocolDecorator.ReadI64: Int64;
1615begin
1616 result := FWrappedProtocol.ReadI64;
1617end;
1618
1619
1620function TProtocolDecorator.ReadDouble:Double;
1621begin
1622 result := FWrappedProtocol.ReadDouble;
1623end;
1624
1625
1626function TProtocolDecorator.ReadBinary: TBytes;
1627begin
1628 result := FWrappedProtocol.ReadBinary;
1629end;
1630
1631
Jens Geyer62445c12022-06-29 00:00:00 +02001632function TProtocolDecorator.ReadUuid: TGuid;
1633begin
1634 result := FWrappedProtocol.ReadUuid;
1635end;
1636
1637
Jens Geyerd5436f52014-10-03 19:50:38 +02001638function TProtocolDecorator.ReadString: string;
1639begin
1640 result := FWrappedProtocol.ReadString;
1641end;
1642
1643
1644function TProtocolDecorator.ReadAnsiString: AnsiString;
1645begin
1646 result := FWrappedProtocol.ReadAnsiString;
1647end;
1648
1649
Jens Geyer41f47af2019-11-09 23:24:52 +01001650function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer;
1651begin
1652 result := FWrappedProtocol.GetMinSerializedSize(aType);
1653end;
1654
1655
Jens Geyer17c3ad92017-09-05 20:31:27 +02001656{ Init helper functions }
1657
1658procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1659begin
1660 rec.Name := AName;
1661 rec.Type_ := AMessageType;
1662 rec.SeqID := ASeqID;
1663end;
1664
1665
1666procedure Init( var rec : TThriftStruct; const AName: string = '');
1667begin
1668 rec.Name := AName;
1669end;
1670
1671
1672procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1673begin
1674 rec.Name := AName;
1675 rec.Type_ := AType;
1676 rec.Id := AId;
1677end;
1678
1679
1680procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1681begin
1682 rec.ValueType := AValueType;
1683 rec.KeyType := AKeyType;
1684 rec.Count := ACount;
1685end;
1686
1687
1688procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1689begin
1690 rec.Count := ACount;
1691 rec.ElementType := AElementType;
1692end;
1693
1694
1695procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1696begin
1697 rec.Count := ACount;
1698 rec.ElementType := AElementType;
1699end;
1700
1701
1702
Jens Geyerd5436f52014-10-03 19:50:38 +02001703end.
1704