blob: 7cfc2ae651bea00f9cdb3f296ade86cda89284de [file] [log] [blame]
Jens Geyerd5436f52014-10-03 19:50:38 +02001(*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19
20{$SCOPEDENUMS ON}
Jens Geyer93222f62023-12-15 16:03:48 +010021{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}
Jens Geyerd5436f52014-10-03 19:50:38 +020022
23unit Thrift.Protocol;
24
25interface
26
27uses
28 Classes,
29 SysUtils,
30 Contnrs,
Jens Geyer16819262024-03-07 23:01:20 +010031 Math,
Jens Geyer606f1ef2018-04-09 23:09:41 +020032 Thrift.Exception,
Jens Geyerd5436f52014-10-03 19:50:38 +020033 Thrift.Stream,
Jens Geyer8f7487e2019-05-09 22:21:32 +020034 Thrift.Utils,
Jens Geyerd5436f52014-10-03 19:50:38 +020035 Thrift.Collections,
Jens Geyera019cda2019-11-09 23:24:52 +010036 Thrift.Configuration,
Jens Geyerd5436f52014-10-03 19:50:38 +020037 Thrift.Transport;
38
39type
40
41 TType = (
42 Stop = 0,
43 Void = 1,
44 Bool_ = 2,
45 Byte_ = 3,
46 Double_ = 4,
47 I16 = 6,
48 I32 = 8,
49 I64 = 10,
50 String_ = 11,
51 Struct = 12,
52 Map = 13,
53 Set_ = 14,
Jens Geyer62445c12022-06-29 00:00:00 +020054 List = 15,
55 Uuid = 16
Jens Geyerd5436f52014-10-03 19:50:38 +020056 );
57
58 TMessageType = (
59 Call = 1,
60 Reply = 2,
61 Exception = 3,
62 Oneway = 4
63 );
64
Jens Geyerf0e63312015-03-01 18:47:49 +010065const
66 VALID_TTYPES = [
67 TType.Stop, TType.Void,
Jens Geyer62445c12022-06-29 00:00:00 +020068 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid,
Jens Geyerf0e63312015-03-01 18:47:49 +010069 TType.Struct, TType.Map, TType.Set_, TType.List
70 ];
71
72 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
73
74type
Jens Geyerd5436f52014-10-03 19:50:38 +020075 IProtocol = interface;
Jens Geyer17c3ad92017-09-05 20:31:27 +020076
77 TThriftMessage = record
78 Name: string;
79 Type_: TMessageType;
80 SeqID: Integer;
81 end;
82
83 TThriftStruct = record
84 Name: string;
85 end;
86
87 TThriftField = record
88 Name: string;
89 Type_: TType;
90 Id: SmallInt;
91 end;
92
93 TThriftList = record
94 ElementType: TType;
95 Count: Integer;
96 end;
97
98 TThriftMap = record
99 KeyType: TType;
100 ValueType: TType;
101 Count: Integer;
102 end;
103
104 TThriftSet = record
105 ElementType: TType;
106 Count: Integer;
107 end;
108
109
Jens Geyerd5436f52014-10-03 19:50:38 +0200110 IProtocolFactory = interface
111 ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
112 function GetProtocol( const trans: ITransport): IProtocol;
113 end;
114
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100115 TProtocolException = class abstract( TException)
Jens Geyerd5436f52014-10-03 19:50:38 +0200116 public
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100117 type TExceptionType = (
118 UNKNOWN = 0,
119 INVALID_DATA = 1,
120 NEGATIVE_SIZE = 2,
121 SIZE_LIMIT = 3,
122 BAD_VERSION = 4,
123 NOT_IMPLEMENTED = 5,
124 DEPTH_LIMIT = 6
125 );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100126 strict protected
Jens Geyere0e32402016-04-20 21:50:48 +0200127 constructor HiddenCreate(const Msg: string);
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100128 class function GetType: TExceptionType; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200129 public
Jens Geyere0e32402016-04-20 21:50:48 +0200130 // purposefully hide inherited constructor
131 class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
132 class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100133 class function Create( aType: TExceptionType): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
134 class function Create( aType: TExceptionType; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
135 property Type_: TExceptionType read GetType;
Jens Geyerd5436f52014-10-03 19:50:38 +0200136 end;
137
Jens Geyere0e32402016-04-20 21:50:48 +0200138 // Needed to remove deprecation warning
139 TProtocolExceptionSpecialized = class abstract (TProtocolException)
140 public
141 constructor Create(const Msg: string);
142 end;
143
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100144 TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100145 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100146 class function GetType: TProtocolException.TExceptionType; override;
147 end;
148
149 TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100150 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100151 class function GetType: TProtocolException.TExceptionType; override;
152 end;
153
154 TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100155 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100156 class function GetType: TProtocolException.TExceptionType; override;
157 end;
158
159 TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100160 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100161 class function GetType: TProtocolException.TExceptionType; override;
162 end;
163
164 TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100165 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100166 class function GetType: TProtocolException.TExceptionType; override;
167 end;
168
169 TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100170 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100171 class function GetType: TProtocolException.TExceptionType; override;
172 end;
173
174 TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100175 strict protected
Jens Geyer9f11c1e2019-11-09 19:39:20 +0100176 class function GetType: TProtocolException.TExceptionType; override;
177 end;
178
Jens Geyere0e32402016-04-20 21:50:48 +0200179
Jens Geyerd5436f52014-10-03 19:50:38 +0200180
181 TProtocolUtil = class
182 public
183 class procedure Skip( prot: IProtocol; type_: TType);
184 end;
185
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200186 IProtocolRecursionTracker = interface
187 ['{29CA033F-BB56-49B1-9EE3-31B1E82FC7A5}']
188 // no members yet
189 end;
190
191 TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRecursionTracker)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100192 strict protected
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200193 FProtocol : IProtocol;
194 public
195 constructor Create( prot : IProtocol);
196 destructor Destroy; override;
197 end;
198
Jens Geyer07f4bb52022-09-03 14:50:06 +0200199 IThriftBytes = interface; // forward
200
Jens Geyer5cf71b22023-12-18 11:44:55 +0100201 {$TYPEINFO ON}
202 TThriftBytes = packed record // can't use SysUtils.TBytes because it has no typinfo -> E2134
203 data : System.TArray<System.Byte>;
204
205 class operator Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
206 class operator Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
207 function Length : Integer;
208 end;
209 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
210
211
Jens Geyerd5436f52014-10-03 19:50:38 +0200212 IProtocol = interface
Jens Geyer07f4bb52022-09-03 14:50:06 +0200213 ['{6067A28E-15BF-4C9D-9A6F-D991BB3DCB85}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200214 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200215 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200216 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200217 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200218 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200219 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200220 procedure WriteFieldEnd;
221 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200222 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200223 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200224 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200225 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200226 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200227 procedure WriteSetEnd();
228 procedure WriteBool( b: Boolean);
229 procedure WriteByte( b: ShortInt);
230 procedure WriteI16( i16: SmallInt);
231 procedure WriteI32( i32: Integer);
232 procedure WriteI64( const i64: Int64);
233 procedure WriteDouble( const d: Double);
234 procedure WriteString( const s: string );
Jens Geyer2adfd142024-04-01 22:44:14 +0200235 procedure WriteAnsiString( const s: AnsiString); deprecated 'AnsiString routines are deprecated, see THRIFT-5750';
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;
Jens Geyer2adfd142024-04-01 22:44:14 +0200262 function ReadAnsiString: AnsiString; deprecated 'AnsiString routines are deprecated, see THRIFT-5750';
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;
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;
Jens Geyerd5436f52014-10-03 19:50:38 +0200338
Jens Geyer07f4bb52022-09-03 14:50:06 +0200339 // provide generic implementation for all derived classes
340 procedure WriteBinary( const bytes : IThriftBytes); overload; virtual;
341 function ReadBinaryCOM : IThriftBytes; virtual;
342
Jens Geyera019cda2019-11-09 23:24:52 +0100343 property Transport: ITransport read GetTransport;
Jens Geyerd5436f52014-10-03 19:50:38 +0200344
Jens Geyer2adfd142024-04-01 22:44:14 +0200345 private
346 // THRIFT-5750 unit visible, but no longer protected - awaiting final removal
347 // - Note that you can implement whavetever you want in your derived class, but no longer inherit
348 // - The function can still be called via IProtocol until final removal
349 function ReadAnsiString: AnsiString; virtual; //deprecated;
350 procedure WriteAnsiString( const s: AnsiString); virtual; //deprecated;
351
Jens Geyera019cda2019-11-09 23:24:52 +0100352 public
Jens Geyer3b686532021-07-01 23:04:08 +0200353 constructor Create( const aTransport : ITransport); virtual;
Jens Geyerd5436f52014-10-03 19:50:38 +0200354 end;
355
Jens Geyer5cf71b22023-12-18 11:44:55 +0100356 {.$TYPEINFO ON} // big NO -> may cause E2134 due to Delphis stupidity on enums vs TypeInfo
Jens Geyer93222f62023-12-15 16:03:48 +0100357 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
Jens Geyer8f7487e2019-05-09 22:21:32 +0200358 IBase = interface( ISupportsToString)
359 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyer07f4bb52022-09-03 14:50:06 +0200360 procedure Read( const prot: IProtocol);
361 procedure Write( const prot: IProtocol);
362 end;
Jens Geyer5cf71b22023-12-18 11:44:55 +0100363
364 {$TYPEINFO ON}
365 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
366 IBaseWithTypeInfo = interface( IBase) end;
367
Jens Geyer93222f62023-12-15 16:03:48 +0100368 {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
369 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
Jens Geyer07f4bb52022-09-03 14:50:06 +0200370
371
372 IThriftBytes = interface( ISupportsToString)
373 ['{CDBEF7E8-BEF2-4A0A-983A-F334E3FF0016}']
374 function GetCount : Integer;
375 procedure SetCount(const value : Integer);
376
377 // WARNING: This returns a direct pointer to the underlying data structure
378 function QueryRawDataPtr : Pointer;
379
380 property Count : Integer read GetCount write SetCount;
381 end;
382
383
384 TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString)
385 strict private
386 FData : TBytes;
387
388 strict protected
389 function GetCount : Integer;
390 procedure SetCount(const value : Integer);
391 function QueryRawDataPtr : Pointer;
392
393 public
394 constructor Create; overload;
395 constructor Create( const bytes : TBytes); overload;
396 constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload;
Jens Geyer16819262024-03-07 23:01:20 +0100397 constructor Create( const pData : Pointer; const nCount : Integer); overload;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200398
399 function ToString : string; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200400 end;
401
Jens Geyerd5436f52014-10-03 19:50:38 +0200402
403 TBinaryProtocolImpl = class( TProtocolImpl )
Jens Geyerfad7fd32019-11-09 23:24:52 +0100404 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200405 const
406 VERSION_MASK : Cardinal = $ffff0000;
407 VERSION_1 : Cardinal = $80010000;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100408 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200409 FStrictRead : Boolean;
410 FStrictWrite : Boolean;
Jens Geyer41f47af2019-11-09 23:24:52 +0100411 function GetMinSerializedSize( const aType : TType) : Integer; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200412
Jens Geyerfad7fd32019-11-09 23:24:52 +0100413 strict private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200414 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200415 function ReadStringBody( size: Integer): string;
416
417 public
Jens Geyerd5436f52014-10-03 19:50:38 +0200418 type
419 TFactory = class( TInterfacedObject, IProtocolFactory)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100420 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200421 FStrictRead : Boolean;
422 FStrictWrite : Boolean;
Jens Geyerd5436f52014-10-03 19:50:38 +0200423 function GetProtocol( const trans: ITransport): IProtocol;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100424 public
425 constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200426 end;
427
Jens Geyer3b686532021-07-01 23:04:08 +0200428 constructor Create( const trans: ITransport); overload; override;
429 constructor Create( const trans: ITransport; strictRead, strictWrite: Boolean); reintroduce; overload;
Jens Geyerd5436f52014-10-03 19:50:38 +0200430
Jens Geyer17c3ad92017-09-05 20:31:27 +0200431 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200432 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200433 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200434 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200435 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200436 procedure WriteFieldEnd; override;
437 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200438 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200439 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200440 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200441 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200442 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200443 procedure WriteSetEnd(); override;
444 procedure WriteBool( b: Boolean); override;
445 procedure WriteByte( b: ShortInt); override;
446 procedure WriteI16( i16: SmallInt); override;
447 procedure WriteI32( i32: Integer); override;
448 procedure WriteI64( const i64: Int64); override;
449 procedure WriteDouble( const d: Double); override;
450 procedure WriteBinary( const b: TBytes); override;
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100451 procedure WriteBinary( const bytes : IThriftBytes); overload; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200452 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200453
Jens Geyer17c3ad92017-09-05 20:31:27 +0200454 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200455 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200456 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200457 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200458 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200459 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200460 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200461 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200462 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200463 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200464 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200465 procedure ReadSetEnd(); override;
466 function ReadBool: Boolean; override;
467 function ReadByte: ShortInt; override;
468 function ReadI16: SmallInt; override;
469 function ReadI32: Integer; override;
470 function ReadI64: Int64; override;
471 function ReadDouble:Double; override;
472 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200473 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200474
475 end;
476
477
478 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
479 providing a way to author concise concrete decorator subclasses. The decorator
480 does not (and should not) modify the behaviour of the enclosed TProtocol
481
482 See p.175 of Design Patterns (by Gamma et al.)
483 }
484 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100485 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200486 FWrappedProtocol : IProtocol;
487
Jens Geyer41f47af2019-11-09 23:24:52 +0100488 strict protected
489 function GetMinSerializedSize( const aType : TType) : Integer; override;
490
Jens Geyerd5436f52014-10-03 19:50:38 +0200491 public
492 // Encloses the specified protocol.
493 // All operations will be forward to the given protocol. Must be non-null.
Jens Geyer3b686532021-07-01 23:04:08 +0200494 constructor Create( const aProtocol : IProtocol); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200495
Jens Geyer17c3ad92017-09-05 20:31:27 +0200496 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200497 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200498 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200499 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200500 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200501 procedure WriteFieldEnd; override;
502 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200503 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200504 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200505 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200506 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200507 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200508 procedure WriteSetEnd(); override;
509 procedure WriteBool( b: Boolean); override;
510 procedure WriteByte( b: ShortInt); override;
511 procedure WriteI16( i16: SmallInt); override;
512 procedure WriteI32( i32: Integer); override;
513 procedure WriteI64( const i64: Int64); override;
514 procedure WriteDouble( const d: Double); override;
515 procedure WriteString( const s: string ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200516 procedure WriteBinary( const b: TBytes); override;
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100517 procedure WriteBinary( const bytes : IThriftBytes); overload; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200518 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200519
Jens Geyer17c3ad92017-09-05 20:31:27 +0200520 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200521 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200522 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200523 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200524 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200525 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200526 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200527 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200528 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200529 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200530 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200531 procedure ReadSetEnd(); override;
532 function ReadBool: Boolean; override;
533 function ReadByte: ShortInt; override;
534 function ReadI16: SmallInt; override;
535 function ReadI32: Integer; override;
536 function ReadI64: Int64; override;
537 function ReadDouble:Double; override;
538 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200539 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200540 function ReadString: string; override;
Jens Geyer2adfd142024-04-01 22:44:14 +0200541
542 private
543 // THRIFT-5750 unit visible, but no longer protected - awaiting final removal
544 // - Note that you can implement whavetever you want in your derived class, but no longer inherit
545 // - The function can still be called via IProtocol until final removal
546 {$WARN SYMBOL_DEPRECATED OFF}
547 function ReadAnsiString: AnsiString; override; deprecated;
548 procedure WriteAnsiString( const s: AnsiString); override; deprecated;
549 {$WARN SYMBOL_DEPRECATED DEFAULT}
Jens Geyerd5436f52014-10-03 19:50:38 +0200550 end;
551
552
553type
554 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200555 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
556 // Called before reading arguments.
557 procedure PreRead;
558 // Called between reading arguments and calling the handler.
559 procedure PostRead;
560 // Called between calling the handler and writing the response.
561 procedure PreWrite;
562 // Called after writing the response.
563 procedure PostWrite;
564 // Called when an oneway (async) function call completes successfully.
565 procedure OnewayComplete;
566 // Called if the handler throws an undeclared exception.
567 procedure UnhandledError( const e : Exception);
568 // Called when a client has finished request-handling to clean up
569 procedure CleanupContext;
570 end;
571
572
573 IProcessorEvents = interface
574 ['{A8661119-657C-447D-93C5-512E36162A45}']
575 // Called when a client is about to call the processor.
576 procedure Processing( const transport : ITransport);
577 // Called on any service function invocation
578 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
579 // Called when a client has finished request-handling to clean up
580 procedure CleanupContext;
581 end;
582
583
584 IProcessor = interface
585 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200586 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200587 end;
588
Jens Geyerd5436f52014-10-03 19:50:38 +0200589
Jens Geyer17c3ad92017-09-05 20:31:27 +0200590procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
591procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
592procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
593procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
594procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
595procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
596
Jens Geyerd5436f52014-10-03 19:50:38 +0200597
598implementation
599
Jens Geyerfad7fd32019-11-09 23:24:52 +0100600function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200601begin
602 ASSERT( SizeOf(n) = SizeOf(Result));
603 System.Move( n, Result, SizeOf(Result));
604end;
605
Jens Geyerfad7fd32019-11-09 23:24:52 +0100606function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200607begin
608 ASSERT( SizeOf(d) = SizeOf(Result));
609 System.Move( d, Result, SizeOf(Result));
610end;
611
Jens Geyerd5436f52014-10-03 19:50:38 +0200612
Jens Geyer5cf71b22023-12-18 11:44:55 +0100613//--- TThriftBytes ----------------------------------------------------------------------
614
615
616class operator TThriftBytes.Implicit(aRec : SysUtils.TBytes) : TThriftBytes;
617begin
618 ASSERT( @result.data = @result); // must be first field
619 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
620 result := TThriftBytes(aRec);
621end;
622
623
624class operator TThriftBytes.Implicit(aRec : TThriftBytes) : SysUtils.TBytes;
625begin
626 ASSERT( @aRec.data = @aRec); // must be first field
627 ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field
628 result := SysUtils.TBytes(aRec.data);
629end;
630
631
632function TThriftBytes.Length : Integer;
633begin
634 result := System.Length(data);
635end;
636
Jens Geyerd5436f52014-10-03 19:50:38 +0200637
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200638{ TProtocolRecursionTrackerImpl }
639
640constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
641begin
642 inherited Create;
643
644 // storing the pointer *after* the (successful) increment is important here
645 prot.IncrementRecursionDepth;
646 FProtocol := prot;
647end;
648
649destructor TProtocolRecursionTrackerImpl.Destroy;
650begin
651 try
652 // we have to release the reference iff the pointer has been stored
653 if FProtocol <> nil then begin
654 FProtocol.DecrementRecursionDepth;
655 FProtocol := nil;
656 end;
657 finally
658 inherited Destroy;
659 end;
660end;
661
Jens Geyerd5436f52014-10-03 19:50:38 +0200662{ TProtocolImpl }
663
Jens Geyera019cda2019-11-09 23:24:52 +0100664constructor TProtocolImpl.Create( const aTransport : ITransport);
Jens Geyerd5436f52014-10-03 19:50:38 +0200665begin
666 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100667 FTrans := aTransport;
668 FRecursionLimit := aTransport.Configuration.RecursionLimit;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200669 FRecursionDepth := 0;
670end;
671
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200672function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
673begin
674 result := TProtocolRecursionTrackerImpl.Create(Self);
675end;
676
677procedure TProtocolImpl.IncrementRecursionDepth;
678begin
679 if FRecursionDepth < FRecursionLimit
680 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200681 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200682end;
683
684procedure TProtocolImpl.DecrementRecursionDepth;
685begin
686 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200687end;
688
689function TProtocolImpl.GetTransport: ITransport;
690begin
691 Result := FTrans;
692end;
693
Jens Geyera019cda2019-11-09 23:24:52 +0100694function TProtocolImpl.Configuration : IThriftConfiguration;
695begin
696 Result := FTrans.Configuration;
697end;
698
Jens Geyer41f47af2019-11-09 23:24:52 +0100699procedure TProtocolImpl.Reset;
700begin
Jens Geyera019cda2019-11-09 23:24:52 +0100701 FTrans.ResetConsumedMessageSize;
Jens Geyer41f47af2019-11-09 23:24:52 +0100702end;
703
Jens Geyerd5436f52014-10-03 19:50:38 +0200704function TProtocolImpl.ReadAnsiString: AnsiString;
705var
706 b : TBytes;
707 len : Integer;
708begin
709 Result := '';
710 b := ReadBinary;
711 len := Length( b );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100712 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200713 SetLength( Result, len);
714 System.Move( b[0], Pointer(Result)^, len );
715 end;
716end;
717
718function TProtocolImpl.ReadString: string;
719begin
720 Result := TEncoding.UTF8.GetString( ReadBinary );
721end;
722
723procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
724var
725 b : TBytes;
726 len : Integer;
727begin
728 len := Length(s);
729 SetLength( b, len);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100730 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200731 System.Move( Pointer(s)^, b[0], len );
732 end;
733 WriteBinary( b );
734end;
735
736procedure TProtocolImpl.WriteString(const s: string);
737var
738 b : TBytes;
739begin
740 b := TEncoding.UTF8.GetBytes(s);
741 WriteBinary( b );
742end;
743
Jens Geyer41f47af2019-11-09 23:24:52 +0100744
745procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList);
746begin
747 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
748end;
749
750
751procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet);
752begin
753 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
754end;
755
756
757procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap);
Jens Geyera019cda2019-11-09 23:24:52 +0100758var nPairSize : Integer;
Jens Geyer41f47af2019-11-09 23:24:52 +0100759begin
760 nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType);
761 FTrans.CheckReadBytesAvailable( value.Count * nPairSize);
762end;
763
Jens Geyer07f4bb52022-09-03 14:50:06 +0200764
765procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
Jens Geyerb53fa8e2024-03-08 00:33:22 +0100766// This implementation works, but is rather inefficient due to the extra memory allocation
767// Consider overwriting this for your transport implementation
Jens Geyer07f4bb52022-09-03 14:50:06 +0200768var tmp : TBytes;
769begin
770 SetLength( tmp, bytes.Count);
771 if Length(tmp) > 0
772 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp));
773 WriteBinary( tmp);
774end;
775
776
777function TProtocolImpl.ReadBinaryCOM : IThriftBytes;
778var bytes : TBytes;
779begin
780 bytes := ReadBinary;
781 result := TThriftBytesImpl.Create(bytes,TRUE);
782end;
783
784
785{ TThriftBytesImpl }
786
787constructor TThriftBytesImpl.Create;
788begin
789 inherited Create;
790 ASSERT( Length(FData) = 0);
791end;
792
793
794constructor TThriftBytesImpl.Create( const bytes : TBytes);
795begin
796 FData := bytes; // copies the data
797end;
798
799
800constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean);
801
802 procedure SwapPointer( var one, two);
803 var
804 pOne : Pointer absolute one;
805 pTwo : Pointer absolute two;
806 pTmp : Pointer;
807 begin
808 pTmp := pOne;
809 pOne := pTwo;
810 pTwo := pTmp;
811 end;
812
813begin
814 inherited Create;
815 ASSERT( Length(FData) = 0);
816
817 if aTakeOwnership
818 then SwapPointer( FData, bytes)
819 else FData := bytes; // copies the data
820end;
821
822
Jens Geyer16819262024-03-07 23:01:20 +0100823constructor TThriftBytesImpl.Create( const pData : Pointer; const nCount : Integer);
824begin
825 SetLength(FData, Max(nCount,0));
826 if Length(FData) > 0 then Move( pData^, FData[0], Length(FData));
827end;
828
829
Jens Geyer07f4bb52022-09-03 14:50:06 +0200830function TThriftBytesImpl.ToString : string;
831var sb : TThriftStringBuilder;
832begin
833 sb := TThriftStringBuilder.Create();
834 try
835 sb.Append('Bin: ');
836 sb.Append( FData);
837
838 result := sb.ToString;
839 finally
840 sb.Free;
841 end;
842end;
843
844
845function TThriftBytesImpl.GetCount : Integer;
846begin
847 result := Length(FData);
848end;
849
850
851procedure TThriftBytesImpl.SetCount(const value : Integer);
852begin
853 SetLength( FData, value);
854end;
855
856
857function TThriftBytesImpl.QueryRawDataPtr : Pointer;
858begin
859 result := FData;
860end;
861
Jens Geyerd5436f52014-10-03 19:50:38 +0200862{ TProtocolUtil }
863
864class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200865var field : TThriftField;
866 map : TThriftMap;
867 set_ : TThriftSet;
868 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200869 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200870 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200871begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200872 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200873 case type_ of
874 // simple types
875 TType.Bool_ : prot.ReadBool();
876 TType.Byte_ : prot.ReadByte();
877 TType.I16 : prot.ReadI16();
878 TType.I32 : prot.ReadI32();
879 TType.I64 : prot.ReadI64();
880 TType.Double_ : prot.ReadDouble();
881 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jens Geyer62445c12022-06-29 00:00:00 +0200882 TType.Uuid : prot.ReadUuid();
Jens Geyerd5436f52014-10-03 19:50:38 +0200883
884 // structured types
885 TType.Struct : begin
886 prot.ReadStructBegin();
887 while TRUE do begin
888 field := prot.ReadFieldBegin();
889 if (field.Type_ = TType.Stop) then Break;
890 Skip(prot, field.Type_);
891 prot.ReadFieldEnd();
892 end;
893 prot.ReadStructEnd();
894 end;
895
896 TType.Map : begin
897 map := prot.ReadMapBegin();
898 for i := 0 to map.Count-1 do begin
899 Skip(prot, map.KeyType);
900 Skip(prot, map.ValueType);
901 end;
902 prot.ReadMapEnd();
903 end;
904
905 TType.Set_ : begin
906 set_ := prot.ReadSetBegin();
907 for i := 0 to set_.Count-1
908 do Skip( prot, set_.ElementType);
909 prot.ReadSetEnd();
910 end;
911
912 TType.List : begin
913 list := prot.ReadListBegin();
914 for i := 0 to list.Count-1
915 do Skip( prot, list.ElementType);
916 prot.ReadListEnd();
917 end;
918
919 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100920 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200921 end;
922end;
923
Jens Geyerd5436f52014-10-03 19:50:38 +0200924
925{ TBinaryProtocolImpl }
926
Jens Geyer3b686532021-07-01 23:04:08 +0200927constructor TBinaryProtocolImpl.Create( const trans: ITransport);
928begin
929 // call the real CTOR
930 Self.Create( trans, FALSE, TRUE);
931end;
932
Jens Geyerfad7fd32019-11-09 23:24:52 +0100933constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200934begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100935 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200936 FStrictRead := strictRead;
937 FStrictWrite := strictWrite;
938end;
939
Jens Geyer17c3ad92017-09-05 20:31:27 +0200940function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200941begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200942 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200943end;
944
945function TBinaryProtocolImpl.ReadBinary: TBytes;
946var
947 size : Integer;
948 buf : TBytes;
949begin
950 size := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100951 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100952 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200953 FTrans.ReadAll( buf, 0, size);
954 Result := buf;
955end;
956
Jens Geyer62445c12022-06-29 00:00:00 +0200957function TBinaryProtocolImpl.ReadUuid : TGuid;
958var network : TGuid; // in network order (Big Endian)
959begin
960 ASSERT( SizeOf(result) = 16);
961 FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
Jens Geyerf8f62782022-09-10 00:55:02 +0200962 result := GuidUtils.SwapByteOrder(network);
Jens Geyer62445c12022-06-29 00:00:00 +0200963end;
964
Jens Geyerd5436f52014-10-03 19:50:38 +0200965function TBinaryProtocolImpl.ReadBool: Boolean;
966begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200967 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200968end;
969
970function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200971begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200972 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200973end;
974
975function TBinaryProtocolImpl.ReadDouble: Double;
976begin
977 Result := ConvertInt64ToDouble( ReadI64 )
978end;
979
Jens Geyer17c3ad92017-09-05 20:31:27 +0200980function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200981begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200982 Init( result, '', TType( ReadByte), 0);
983 if ( result.Type_ <> TType.Stop ) then begin
984 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200985 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200986end;
987
988procedure TBinaryProtocolImpl.ReadFieldEnd;
989begin
990
991end;
992
993function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200994var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200995begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200996 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200997 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
998end;
999
1000function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001001var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001002begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001003 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001004
1005 Result := Integer(
1006 ((i32in[0] and $FF) shl 24) or
1007 ((i32in[1] and $FF) shl 16) or
1008 ((i32in[2] and $FF) shl 8) or
1009 (i32in[3] and $FF));
1010
1011end;
1012
1013function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001014var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001015begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001016 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001017 Result :=
1018 (Int64( i64in[0] and $FF) shl 56) or
1019 (Int64( i64in[1] and $FF) shl 48) or
1020 (Int64( i64in[2] and $FF) shl 40) or
1021 (Int64( i64in[3] and $FF) shl 32) or
1022 (Int64( i64in[4] and $FF) shl 24) or
1023 (Int64( i64in[5] and $FF) shl 16) or
1024 (Int64( i64in[6] and $FF) shl 8) or
1025 (Int64( i64in[7] and $FF));
1026end;
1027
Jens Geyer17c3ad92017-09-05 20:31:27 +02001028function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001029begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001030 result.ElementType := TType(ReadByte);
1031 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001032 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001033end;
1034
1035procedure TBinaryProtocolImpl.ReadListEnd;
1036begin
1037
1038end;
1039
Jens Geyer17c3ad92017-09-05 20:31:27 +02001040function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001041begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001042 result.KeyType := TType(ReadByte);
1043 result.ValueType := TType(ReadByte);
1044 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001045 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001046end;
1047
1048procedure TBinaryProtocolImpl.ReadMapEnd;
1049begin
1050
1051end;
1052
Jens Geyer17c3ad92017-09-05 20:31:27 +02001053function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001054var
1055 size : Integer;
1056 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +02001057begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001058 Reset;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001059 Init( result);
Jens Geyer589ee5b2021-03-29 21:40:55 +02001060
Jens Geyerd5436f52014-10-03 19:50:38 +02001061 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001062 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001063 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001064 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +02001065 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +02001066 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001067 result.Type_ := TMessageType( size and $000000ff);
1068 result.Name := ReadString;
1069 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001070 Exit;
1071 end;
1072
1073 try
1074 if FStrictRead
1075 then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
1076
Jens Geyer17c3ad92017-09-05 20:31:27 +02001077 result.Name := ReadStringBody( size );
1078 result.Type_ := TMessageType( ReadByte );
1079 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001080 except
1081 if CharUtils.IsHtmlDoctype(size)
1082 then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
1083 else raise; // something else
Jens Geyerd5436f52014-10-03 19:50:38 +02001084 end;
Jens Geyerd5436f52014-10-03 19:50:38 +02001085end;
1086
1087procedure TBinaryProtocolImpl.ReadMessageEnd;
1088begin
1089 inherited;
1090
1091end;
1092
Jens Geyer17c3ad92017-09-05 20:31:27 +02001093function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001094begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001095 result.ElementType := TType(ReadByte);
1096 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +01001097 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001098end;
1099
1100procedure TBinaryProtocolImpl.ReadSetEnd;
1101begin
1102
1103end;
1104
1105function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001106var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +02001107begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001108 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001109 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +02001110 FTrans.ReadAll( buf, 0, size );
1111 Result := TEncoding.UTF8.GetString( buf);
1112end;
1113
Jens Geyer17c3ad92017-09-05 20:31:27 +02001114function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001115begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001116 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001117end;
1118
1119procedure TBinaryProtocolImpl.ReadStructEnd;
1120begin
1121 inherited;
1122
1123end;
1124
1125procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1126var iLen : Integer;
1127begin
1128 iLen := Length(b);
1129 WriteI32( iLen);
1130 if iLen > 0 then FTrans.Write(b, 0, iLen);
1131end;
1132
Jens Geyerb53fa8e2024-03-08 00:33:22 +01001133procedure TBinaryProtocolImpl.WriteBinary( const bytes : IThriftBytes);
1134var iLen : Integer;
1135begin
1136 iLen := bytes.Count;
1137 WriteI32( iLen);
1138 if iLen > 0 then FTrans.Write( bytes.QueryRawDataPtr, 0, iLen);
1139end;
1140
Jens Geyer62445c12022-06-29 00:00:00 +02001141procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
1142var network : TGuid; // in network order (Big Endian)
1143begin
1144 ASSERT( SizeOf(uuid) = 16);
Jens Geyerf8f62782022-09-10 00:55:02 +02001145 network := GuidUtils.SwapByteOrder(uuid);
Jens Geyer62445c12022-06-29 00:00:00 +02001146 Transport.Write( @network, 0, SizeOf(network));
1147end;
1148
Jens Geyerd5436f52014-10-03 19:50:38 +02001149procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1150begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001151 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001152 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +02001153 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001154 WriteByte( 0 );
1155 end;
1156end;
1157
1158procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +02001159begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001160 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +02001161end;
1162
1163procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1164begin
1165 WriteI64(ConvertDoubleToInt64(d));
1166end;
1167
Jens Geyer17c3ad92017-09-05 20:31:27 +02001168procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001169begin
1170 WriteByte(ShortInt(field.Type_));
1171 WriteI16(field.ID);
1172end;
1173
1174procedure TBinaryProtocolImpl.WriteFieldEnd;
1175begin
1176
1177end;
1178
1179procedure TBinaryProtocolImpl.WriteFieldStop;
1180begin
1181 WriteByte(ShortInt(TType.Stop));
1182end;
1183
1184procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001185var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001186begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001187 i16out[0] := Byte($FF and (i16 shr 8));
1188 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001189 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +02001190end;
1191
1192procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001193var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001194begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001195 i32out[0] := Byte($FF and (i32 shr 24));
1196 i32out[1] := Byte($FF and (i32 shr 16));
1197 i32out[2] := Byte($FF and (i32 shr 8));
1198 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001199 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001200end;
1201
1202procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001203var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001204begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001205 i64out[0] := Byte($FF and (i64 shr 56));
1206 i64out[1] := Byte($FF and (i64 shr 48));
1207 i64out[2] := Byte($FF and (i64 shr 40));
1208 i64out[3] := Byte($FF and (i64 shr 32));
1209 i64out[4] := Byte($FF and (i64 shr 24));
1210 i64out[5] := Byte($FF and (i64 shr 16));
1211 i64out[6] := Byte($FF and (i64 shr 8));
1212 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001213 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001214end;
1215
Jens Geyer17c3ad92017-09-05 20:31:27 +02001216procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001217begin
1218 WriteByte(ShortInt(list.ElementType));
1219 WriteI32(list.Count);
1220end;
1221
1222procedure TBinaryProtocolImpl.WriteListEnd;
1223begin
1224
1225end;
1226
Jens Geyer17c3ad92017-09-05 20:31:27 +02001227procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001228begin
1229 WriteByte(ShortInt(map.KeyType));
1230 WriteByte(ShortInt(map.ValueType));
1231 WriteI32(map.Count);
1232end;
1233
1234procedure TBinaryProtocolImpl.WriteMapEnd;
1235begin
1236
1237end;
1238
Jens Geyer17c3ad92017-09-05 20:31:27 +02001239procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001240var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +02001241begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001242 Reset;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001243 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001244 version := VERSION_1 or Cardinal( msg.Type_);
1245 WriteI32( Integer( version) );
1246 WriteString( msg.Name);
1247 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001248 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001249 WriteString( msg.Name);
1250 WriteByte(ShortInt( msg.Type_));
1251 WriteI32( msg.SeqID);
1252 end;
1253end;
1254
1255procedure TBinaryProtocolImpl.WriteMessageEnd;
1256begin
1257
1258end;
1259
Jens Geyer17c3ad92017-09-05 20:31:27 +02001260procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +02001261begin
1262 WriteByte(ShortInt(set_.ElementType));
1263 WriteI32(set_.Count);
1264end;
1265
1266procedure TBinaryProtocolImpl.WriteSetEnd;
1267begin
1268
1269end;
1270
Jens Geyer17c3ad92017-09-05 20:31:27 +02001271procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001272begin
1273
1274end;
1275
1276procedure TBinaryProtocolImpl.WriteStructEnd;
1277begin
1278
1279end;
1280
Jens Geyer41f47af2019-11-09 23:24:52 +01001281function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
1282// Return the minimum number of bytes a type will consume on the wire
1283begin
1284 case aType of
1285 TType.Stop: result := 0;
1286 TType.Void: result := 0;
1287 TType.Bool_: result := SizeOf(Byte);
1288 TType.Byte_: result := SizeOf(Byte);
1289 TType.Double_: result := SizeOf(Double);
1290 TType.I16: result := SizeOf(Int16);
1291 TType.I32: result := SizeOf(Int32);
1292 TType.I64: result := SizeOf(Int64);
1293 TType.String_: result := SizeOf(Int32); // string length
1294 TType.Struct: result := 0; // empty struct
1295 TType.Map: result := SizeOf(Int32); // element count
1296 TType.Set_: result := SizeOf(Int32); // element count
1297 TType.List: result := SizeOf(Int32); // element count
Jens Geyer62445c12022-06-29 00:00:00 +02001298 TType.Uuid: result := SizeOf(TGuid);
Jens Geyer41f47af2019-11-09 23:24:52 +01001299 else
1300 raise TTransportExceptionBadArgs.Create('Unhandled type code');
1301 end;
1302end;
1303
1304
Jens Geyerd5436f52014-10-03 19:50:38 +02001305{ TProtocolException }
1306
Jens Geyere0e32402016-04-20 21:50:48 +02001307constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001308begin
Jens Geyere0e32402016-04-20 21:50:48 +02001309 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001310end;
1311
Jens Geyere0e32402016-04-20 21:50:48 +02001312class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001313begin
Jens Geyere0e32402016-04-20 21:50:48 +02001314 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001315end;
1316
Jens Geyere0e32402016-04-20 21:50:48 +02001317class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001318begin
Jens Geyere0e32402016-04-20 21:50:48 +02001319 Result := TProtocolExceptionUnknown.Create('');
1320end;
1321
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001322class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001323begin
1324{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001325 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001326{$WARN SYMBOL_DEPRECATED DEFAULT}
1327end;
1328
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001329class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001330begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001331 case aType of
1332 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1333 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1334 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1335 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1336 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1337 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001338 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001339 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001340 Result := TProtocolExceptionUnknown.Create(msg);
1341 end;
1342end;
1343
1344{ TProtocolExceptionSpecialized }
1345
1346constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1347begin
1348 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001349end;
1350
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001351{ specialized TProtocolExceptions }
1352
1353class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1354begin
1355 result := TExceptionType.UNKNOWN;
1356end;
1357
1358class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1359begin
1360 result := TExceptionType.INVALID_DATA;
1361end;
1362
1363class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1364begin
1365 result := TExceptionType.NEGATIVE_SIZE;
1366end;
1367
1368class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1369begin
1370 result := TExceptionType.SIZE_LIMIT;
1371end;
1372
1373class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1374begin
1375 result := TExceptionType.BAD_VERSION;
1376end;
1377
1378class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1379begin
1380 result := TExceptionType.NOT_IMPLEMENTED;
1381end;
1382
1383class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1384begin
1385 result := TExceptionType.DEPTH_LIMIT;
1386end;
1387
Jens Geyerd5436f52014-10-03 19:50:38 +02001388{ TBinaryProtocolImpl.TFactory }
1389
Jens Geyerfad7fd32019-11-09 23:24:52 +01001390constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001391begin
1392 inherited Create;
1393 FStrictRead := AStrictRead;
1394 FStrictWrite := AStrictWrite;
1395end;
1396
Jens Geyerd5436f52014-10-03 19:50:38 +02001397function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1398begin
1399 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1400end;
1401
1402
1403{ TProtocolDecorator }
1404
1405constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1406begin
1407 ASSERT( aProtocol <> nil);
1408 inherited Create( aProtocol.Transport);
1409 FWrappedProtocol := aProtocol;
1410end;
1411
1412
Jens Geyer17c3ad92017-09-05 20:31:27 +02001413procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001414begin
1415 FWrappedProtocol.WriteMessageBegin( msg);
1416end;
1417
1418
1419procedure TProtocolDecorator.WriteMessageEnd;
1420begin
1421 FWrappedProtocol.WriteMessageEnd;
1422end;
1423
1424
Jens Geyer17c3ad92017-09-05 20:31:27 +02001425procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001426begin
1427 FWrappedProtocol.WriteStructBegin( struc);
1428end;
1429
1430
1431procedure TProtocolDecorator.WriteStructEnd;
1432begin
1433 FWrappedProtocol.WriteStructEnd;
1434end;
1435
1436
Jens Geyer17c3ad92017-09-05 20:31:27 +02001437procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001438begin
1439 FWrappedProtocol.WriteFieldBegin( field);
1440end;
1441
1442
1443procedure TProtocolDecorator.WriteFieldEnd;
1444begin
1445 FWrappedProtocol.WriteFieldEnd;
1446end;
1447
1448
1449procedure TProtocolDecorator.WriteFieldStop;
1450begin
1451 FWrappedProtocol.WriteFieldStop;
1452end;
1453
1454
Jens Geyer17c3ad92017-09-05 20:31:27 +02001455procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001456begin
1457 FWrappedProtocol.WriteMapBegin( map);
1458end;
1459
1460
1461procedure TProtocolDecorator.WriteMapEnd;
1462begin
1463 FWrappedProtocol.WriteMapEnd;
1464end;
1465
1466
Jens Geyer17c3ad92017-09-05 20:31:27 +02001467procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001468begin
1469 FWrappedProtocol.WriteListBegin( list);
1470end;
1471
1472
1473procedure TProtocolDecorator.WriteListEnd();
1474begin
1475 FWrappedProtocol.WriteListEnd();
1476end;
1477
1478
Jens Geyer17c3ad92017-09-05 20:31:27 +02001479procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001480begin
1481 FWrappedProtocol.WriteSetBegin( set_);
1482end;
1483
1484
1485procedure TProtocolDecorator.WriteSetEnd();
1486begin
1487 FWrappedProtocol.WriteSetEnd();
1488end;
1489
1490
1491procedure TProtocolDecorator.WriteBool( b: Boolean);
1492begin
1493 FWrappedProtocol.WriteBool( b);
1494end;
1495
1496
1497procedure TProtocolDecorator.WriteByte( b: ShortInt);
1498begin
1499 FWrappedProtocol.WriteByte( b);
1500end;
1501
1502
1503procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1504begin
1505 FWrappedProtocol.WriteI16( i16);
1506end;
1507
1508
1509procedure TProtocolDecorator.WriteI32( i32: Integer);
1510begin
1511 FWrappedProtocol.WriteI32( i32);
1512end;
1513
1514
1515procedure TProtocolDecorator.WriteI64( const i64: Int64);
1516begin
1517 FWrappedProtocol.WriteI64( i64);
1518end;
1519
1520
1521procedure TProtocolDecorator.WriteDouble( const d: Double);
1522begin
1523 FWrappedProtocol.WriteDouble( d);
1524end;
1525
1526
1527procedure TProtocolDecorator.WriteString( const s: string );
1528begin
1529 FWrappedProtocol.WriteString( s);
1530end;
1531
1532
1533procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1534begin
Jens Geyer2adfd142024-04-01 22:44:14 +02001535 {$WARN SYMBOL_DEPRECATED OFF}
Jens Geyerd5436f52014-10-03 19:50:38 +02001536 FWrappedProtocol.WriteAnsiString( s);
Jens Geyer2adfd142024-04-01 22:44:14 +02001537 {$WARN SYMBOL_DEPRECATED DEFAULT}
Jens Geyerd5436f52014-10-03 19:50:38 +02001538end;
1539
1540
1541procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1542begin
1543 FWrappedProtocol.WriteBinary( b);
1544end;
1545
1546
Jens Geyerb53fa8e2024-03-08 00:33:22 +01001547procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes);
1548begin
1549 FWrappedProtocol.WriteBinary( bytes);
1550end;
1551
1552
Jens Geyer62445c12022-06-29 00:00:00 +02001553procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
1554begin
1555 FWrappedProtocol.WriteUuid( uuid);
1556end;
1557
1558
Jens Geyer17c3ad92017-09-05 20:31:27 +02001559function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001560begin
1561 result := FWrappedProtocol.ReadMessageBegin;
1562end;
1563
1564
1565procedure TProtocolDecorator.ReadMessageEnd();
1566begin
1567 FWrappedProtocol.ReadMessageEnd();
1568end;
1569
1570
Jens Geyer17c3ad92017-09-05 20:31:27 +02001571function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001572begin
1573 result := FWrappedProtocol.ReadStructBegin;
1574end;
1575
1576
1577procedure TProtocolDecorator.ReadStructEnd;
1578begin
1579 FWrappedProtocol.ReadStructEnd;
1580end;
1581
1582
Jens Geyer17c3ad92017-09-05 20:31:27 +02001583function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001584begin
1585 result := FWrappedProtocol.ReadFieldBegin;
1586end;
1587
1588
1589procedure TProtocolDecorator.ReadFieldEnd();
1590begin
1591 FWrappedProtocol.ReadFieldEnd();
1592end;
1593
1594
Jens Geyer17c3ad92017-09-05 20:31:27 +02001595function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001596begin
1597 result := FWrappedProtocol.ReadMapBegin;
1598end;
1599
1600
1601procedure TProtocolDecorator.ReadMapEnd();
1602begin
1603 FWrappedProtocol.ReadMapEnd();
1604end;
1605
1606
Jens Geyer17c3ad92017-09-05 20:31:27 +02001607function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001608begin
1609 result := FWrappedProtocol.ReadListBegin;
1610end;
1611
1612
1613procedure TProtocolDecorator.ReadListEnd();
1614begin
1615 FWrappedProtocol.ReadListEnd();
1616end;
1617
1618
Jens Geyer17c3ad92017-09-05 20:31:27 +02001619function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001620begin
1621 result := FWrappedProtocol.ReadSetBegin;
1622end;
1623
1624
1625procedure TProtocolDecorator.ReadSetEnd();
1626begin
1627 FWrappedProtocol.ReadSetEnd();
1628end;
1629
1630
1631function TProtocolDecorator.ReadBool: Boolean;
1632begin
1633 result := FWrappedProtocol.ReadBool;
1634end;
1635
1636
1637function TProtocolDecorator.ReadByte: ShortInt;
1638begin
1639 result := FWrappedProtocol.ReadByte;
1640end;
1641
1642
1643function TProtocolDecorator.ReadI16: SmallInt;
1644begin
1645 result := FWrappedProtocol.ReadI16;
1646end;
1647
1648
1649function TProtocolDecorator.ReadI32: Integer;
1650begin
1651 result := FWrappedProtocol.ReadI32;
1652end;
1653
1654
1655function TProtocolDecorator.ReadI64: Int64;
1656begin
1657 result := FWrappedProtocol.ReadI64;
1658end;
1659
1660
1661function TProtocolDecorator.ReadDouble:Double;
1662begin
1663 result := FWrappedProtocol.ReadDouble;
1664end;
1665
1666
1667function TProtocolDecorator.ReadBinary: TBytes;
1668begin
1669 result := FWrappedProtocol.ReadBinary;
1670end;
1671
1672
Jens Geyer62445c12022-06-29 00:00:00 +02001673function TProtocolDecorator.ReadUuid: TGuid;
1674begin
1675 result := FWrappedProtocol.ReadUuid;
1676end;
1677
1678
Jens Geyerd5436f52014-10-03 19:50:38 +02001679function TProtocolDecorator.ReadString: string;
1680begin
1681 result := FWrappedProtocol.ReadString;
1682end;
1683
1684
1685function TProtocolDecorator.ReadAnsiString: AnsiString;
1686begin
Jens Geyer2adfd142024-04-01 22:44:14 +02001687 {$WARN SYMBOL_DEPRECATED OFF}
Jens Geyerd5436f52014-10-03 19:50:38 +02001688 result := FWrappedProtocol.ReadAnsiString;
Jens Geyer2adfd142024-04-01 22:44:14 +02001689 {$WARN SYMBOL_DEPRECATED DEFAULT}
Jens Geyerd5436f52014-10-03 19:50:38 +02001690end;
1691
1692
Jens Geyer41f47af2019-11-09 23:24:52 +01001693function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer;
1694begin
1695 result := FWrappedProtocol.GetMinSerializedSize(aType);
1696end;
1697
1698
Jens Geyer17c3ad92017-09-05 20:31:27 +02001699{ Init helper functions }
1700
1701procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1702begin
1703 rec.Name := AName;
1704 rec.Type_ := AMessageType;
1705 rec.SeqID := ASeqID;
1706end;
1707
1708
1709procedure Init( var rec : TThriftStruct; const AName: string = '');
1710begin
1711 rec.Name := AName;
1712end;
1713
1714
1715procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1716begin
1717 rec.Name := AName;
1718 rec.Type_ := AType;
1719 rec.Id := AId;
1720end;
1721
1722
1723procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1724begin
1725 rec.ValueType := AValueType;
1726 rec.KeyType := AKeyType;
1727 rec.Count := ACount;
1728end;
1729
1730
1731procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1732begin
1733 rec.Count := ACount;
1734 rec.ElementType := AElementType;
1735end;
1736
1737
1738procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1739begin
1740 rec.Count := ACount;
1741 rec.ElementType := AElementType;
1742end;
1743
1744
1745
Jens Geyerd5436f52014-10-03 19:50:38 +02001746end.
1747