blob: 0134ddffcc5f58ccf39ffd3a67285b1f9a18ec14 [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 Geyerd5436f52014-10-03 19:50:38 +0200200 IProtocol = interface
Jens Geyer07f4bb52022-09-03 14:50:06 +0200201 ['{6067A28E-15BF-4C9D-9A6F-D991BB3DCB85}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200202 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200203 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200204 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200205 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200206 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200207 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200208 procedure WriteFieldEnd;
209 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200210 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200211 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200212 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200213 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200214 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200215 procedure WriteSetEnd();
216 procedure WriteBool( b: Boolean);
217 procedure WriteByte( b: ShortInt);
218 procedure WriteI16( i16: SmallInt);
219 procedure WriteI32( i32: Integer);
220 procedure WriteI64( const i64: Int64);
221 procedure WriteDouble( const d: Double);
222 procedure WriteString( const s: string );
223 procedure WriteAnsiString( const s: AnsiString);
Jens Geyer07f4bb52022-09-03 14:50:06 +0200224 procedure WriteBinary( const b: TBytes); overload;
225 procedure WriteBinary( const b: IThriftBytes); overload;
Jens Geyer62445c12022-06-29 00:00:00 +0200226 procedure WriteUuid( const uuid: TGuid);
Jens Geyerd5436f52014-10-03 19:50:38 +0200227
Jens Geyer17c3ad92017-09-05 20:31:27 +0200228 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200229 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200230 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200231 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200232 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200233 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200234 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200235 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200236 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200237 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200238 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200239 procedure ReadSetEnd();
240 function ReadBool: Boolean;
241 function ReadByte: ShortInt;
242 function ReadI16: SmallInt;
243 function ReadI32: Integer;
244 function ReadI64: Int64;
245 function ReadDouble:Double;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200246 function ReadBinary: TBytes; // IMPORTANT: this is NOT safe across module boundaries
247 function ReadBinaryCOM : IThriftBytes;
Jens Geyer62445c12022-06-29 00:00:00 +0200248 function ReadUuid: TGuid;
Jens Geyerd5436f52014-10-03 19:50:38 +0200249 function ReadString: string;
250 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200251
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200252 function NextRecursionLevel : IProtocolRecursionTracker;
253 procedure IncrementRecursionDepth;
254 procedure DecrementRecursionDepth;
Jens Geyer41f47af2019-11-09 23:24:52 +0100255 function GetMinSerializedSize( const aType : TType) : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200256
Jens Geyerd5436f52014-10-03 19:50:38 +0200257 property Transport: ITransport read GetTransport;
Jens Geyera019cda2019-11-09 23:24:52 +0100258 function Configuration : IThriftConfiguration;
Jens Geyerd5436f52014-10-03 19:50:38 +0200259 end;
260
Jens Geyer3b686532021-07-01 23:04:08 +0200261 TProtocolImplClass = class of TProtocolImpl;
262
Jens Geyerd5436f52014-10-03 19:50:38 +0200263 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100264 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200265 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200266 FRecursionLimit : Integer;
267 FRecursionDepth : Integer;
268
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200269 function NextRecursionLevel : IProtocolRecursionTracker;
270 procedure IncrementRecursionDepth;
271 procedure DecrementRecursionDepth;
272
Jens Geyer41f47af2019-11-09 23:24:52 +0100273 function GetMinSerializedSize( const aType : TType) : Integer; virtual; abstract;
274 procedure CheckReadBytesAvailable( const value : TThriftList); overload; inline;
275 procedure CheckReadBytesAvailable( const value : TThriftSet); overload; inline;
276 procedure CheckReadBytesAvailable( const value : TThriftMap); overload; inline;
277
278 procedure Reset; virtual;
Jens Geyera019cda2019-11-09 23:24:52 +0100279 function GetTransport: ITransport;
280 function Configuration : IThriftConfiguration;
281
Jens Geyer17c3ad92017-09-05 20:31:27 +0200282 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200283 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200284 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200285 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200286 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200287 procedure WriteFieldEnd; virtual; abstract;
288 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200289 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200290 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200291 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200292 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200293 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200294 procedure WriteSetEnd(); virtual; abstract;
295 procedure WriteBool( b: Boolean); virtual; abstract;
296 procedure WriteByte( b: ShortInt); virtual; abstract;
297 procedure WriteI16( i16: SmallInt); virtual; abstract;
298 procedure WriteI32( i32: Integer); virtual; abstract;
299 procedure WriteI64( const i64: Int64); virtual; abstract;
300 procedure WriteDouble( const d: Double); virtual; abstract;
301 procedure WriteString( const s: string ); virtual;
302 procedure WriteAnsiString( const s: AnsiString); virtual;
Jens Geyer07f4bb52022-09-03 14:50:06 +0200303 procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200304 procedure WriteUuid( const b: TGuid); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200305
Jens Geyer17c3ad92017-09-05 20:31:27 +0200306 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200307 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200308 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200309 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200310 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200311 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200312 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200313 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200314 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200315 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200316 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200317 procedure ReadSetEnd(); virtual; abstract;
318 function ReadBool: Boolean; virtual; abstract;
319 function ReadByte: ShortInt; virtual; abstract;
320 function ReadI16: SmallInt; virtual; abstract;
321 function ReadI32: Integer; virtual; abstract;
322 function ReadI64: Int64; virtual; abstract;
323 function ReadDouble:Double; virtual; abstract;
324 function ReadBinary: TBytes; virtual; abstract;
Jens Geyer62445c12022-06-29 00:00:00 +0200325 function ReadUuid: TGuid; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200326 function ReadString: string; virtual;
327 function ReadAnsiString: AnsiString; virtual;
328
Jens Geyer07f4bb52022-09-03 14:50:06 +0200329 // provide generic implementation for all derived classes
330 procedure WriteBinary( const bytes : IThriftBytes); overload; virtual;
331 function ReadBinaryCOM : IThriftBytes; virtual;
332
Jens Geyera019cda2019-11-09 23:24:52 +0100333 property Transport: ITransport read GetTransport;
Jens Geyerd5436f52014-10-03 19:50:38 +0200334
Jens Geyera019cda2019-11-09 23:24:52 +0100335 public
Jens Geyer3b686532021-07-01 23:04:08 +0200336 constructor Create( const aTransport : ITransport); virtual;
Jens Geyerd5436f52014-10-03 19:50:38 +0200337 end;
338
Jens Geyer93222f62023-12-15 16:03:48 +0100339 {$TYPEINFO ON}
340 {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
Jens Geyer8f7487e2019-05-09 22:21:32 +0200341 IBase = interface( ISupportsToString)
342 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyer07f4bb52022-09-03 14:50:06 +0200343 procedure Read( const prot: IProtocol);
344 procedure Write( const prot: IProtocol);
345 end;
Jens Geyer93222f62023-12-15 16:03:48 +0100346 {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
347 {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
Jens Geyer07f4bb52022-09-03 14:50:06 +0200348
349
350 IThriftBytes = interface( ISupportsToString)
351 ['{CDBEF7E8-BEF2-4A0A-983A-F334E3FF0016}']
352 function GetCount : Integer;
353 procedure SetCount(const value : Integer);
354
355 // WARNING: This returns a direct pointer to the underlying data structure
356 function QueryRawDataPtr : Pointer;
357
358 property Count : Integer read GetCount write SetCount;
359 end;
360
361
362 TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString)
363 strict private
364 FData : TBytes;
365
366 strict protected
367 function GetCount : Integer;
368 procedure SetCount(const value : Integer);
369 function QueryRawDataPtr : Pointer;
370
371 public
372 constructor Create; overload;
373 constructor Create( const bytes : TBytes); overload;
374 constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload;
375
376 function ToString : string; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200377 end;
378
Jens Geyerd5436f52014-10-03 19:50:38 +0200379
380 TBinaryProtocolImpl = class( TProtocolImpl )
Jens Geyerfad7fd32019-11-09 23:24:52 +0100381 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200382 const
383 VERSION_MASK : Cardinal = $ffff0000;
384 VERSION_1 : Cardinal = $80010000;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100385 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200386 FStrictRead : Boolean;
387 FStrictWrite : Boolean;
Jens Geyer41f47af2019-11-09 23:24:52 +0100388 function GetMinSerializedSize( const aType : TType) : Integer; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200389
Jens Geyerfad7fd32019-11-09 23:24:52 +0100390 strict private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200391 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200392 function ReadStringBody( size: Integer): string;
393
394 public
Jens Geyerd5436f52014-10-03 19:50:38 +0200395 type
396 TFactory = class( TInterfacedObject, IProtocolFactory)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100397 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200398 FStrictRead : Boolean;
399 FStrictWrite : Boolean;
Jens Geyerd5436f52014-10-03 19:50:38 +0200400 function GetProtocol( const trans: ITransport): IProtocol;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100401 public
402 constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200403 end;
404
Jens Geyer3b686532021-07-01 23:04:08 +0200405 constructor Create( const trans: ITransport); overload; override;
406 constructor Create( const trans: ITransport; strictRead, strictWrite: Boolean); reintroduce; overload;
Jens Geyerd5436f52014-10-03 19:50:38 +0200407
Jens Geyer17c3ad92017-09-05 20:31:27 +0200408 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200409 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200410 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200411 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200412 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200413 procedure WriteFieldEnd; override;
414 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200415 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200416 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200417 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200418 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200419 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200420 procedure WriteSetEnd(); override;
421 procedure WriteBool( b: Boolean); override;
422 procedure WriteByte( b: ShortInt); override;
423 procedure WriteI16( i16: SmallInt); override;
424 procedure WriteI32( i32: Integer); override;
425 procedure WriteI64( const i64: Int64); override;
426 procedure WriteDouble( const d: Double); override;
427 procedure WriteBinary( const b: TBytes); override;
Jens Geyer62445c12022-06-29 00:00:00 +0200428 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200429
Jens Geyer17c3ad92017-09-05 20:31:27 +0200430 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200431 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200432 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200433 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200434 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200435 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200436 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200437 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200438 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200439 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200440 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200441 procedure ReadSetEnd(); override;
442 function ReadBool: Boolean; override;
443 function ReadByte: ShortInt; override;
444 function ReadI16: SmallInt; override;
445 function ReadI32: Integer; override;
446 function ReadI64: Int64; override;
447 function ReadDouble:Double; override;
448 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200449 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200450
451 end;
452
453
454 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
455 providing a way to author concise concrete decorator subclasses. The decorator
456 does not (and should not) modify the behaviour of the enclosed TProtocol
457
458 See p.175 of Design Patterns (by Gamma et al.)
459 }
460 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100461 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200462 FWrappedProtocol : IProtocol;
463
Jens Geyer41f47af2019-11-09 23:24:52 +0100464 strict protected
465 function GetMinSerializedSize( const aType : TType) : Integer; override;
466
Jens Geyerd5436f52014-10-03 19:50:38 +0200467 public
468 // Encloses the specified protocol.
469 // All operations will be forward to the given protocol. Must be non-null.
Jens Geyer3b686532021-07-01 23:04:08 +0200470 constructor Create( const aProtocol : IProtocol); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200471
Jens Geyer17c3ad92017-09-05 20:31:27 +0200472 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200473 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200474 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200475 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200476 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200477 procedure WriteFieldEnd; override;
478 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200479 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200480 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200481 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200482 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200483 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200484 procedure WriteSetEnd(); override;
485 procedure WriteBool( b: Boolean); override;
486 procedure WriteByte( b: ShortInt); override;
487 procedure WriteI16( i16: SmallInt); override;
488 procedure WriteI32( i32: Integer); override;
489 procedure WriteI64( const i64: Int64); override;
490 procedure WriteDouble( const d: Double); override;
491 procedure WriteString( const s: string ); override;
492 procedure WriteAnsiString( const s: AnsiString); override;
493 procedure WriteBinary( const b: TBytes); override;
Jens Geyer62445c12022-06-29 00:00:00 +0200494 procedure WriteUuid( const uuid: TGuid); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200495
Jens Geyer17c3ad92017-09-05 20:31:27 +0200496 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200497 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200498 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200499 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200500 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200501 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200502 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200503 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200504 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200505 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200506 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200507 procedure ReadSetEnd(); override;
508 function ReadBool: Boolean; override;
509 function ReadByte: ShortInt; override;
510 function ReadI16: SmallInt; override;
511 function ReadI32: Integer; override;
512 function ReadI64: Int64; override;
513 function ReadDouble:Double; override;
514 function ReadBinary: TBytes; override;
Jens Geyer62445c12022-06-29 00:00:00 +0200515 function ReadUuid: TGuid; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200516 function ReadString: string; override;
517 function ReadAnsiString: AnsiString; override;
518 end;
519
520
521type
522 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200523 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
524 // Called before reading arguments.
525 procedure PreRead;
526 // Called between reading arguments and calling the handler.
527 procedure PostRead;
528 // Called between calling the handler and writing the response.
529 procedure PreWrite;
530 // Called after writing the response.
531 procedure PostWrite;
532 // Called when an oneway (async) function call completes successfully.
533 procedure OnewayComplete;
534 // Called if the handler throws an undeclared exception.
535 procedure UnhandledError( const e : Exception);
536 // Called when a client has finished request-handling to clean up
537 procedure CleanupContext;
538 end;
539
540
541 IProcessorEvents = interface
542 ['{A8661119-657C-447D-93C5-512E36162A45}']
543 // Called when a client is about to call the processor.
544 procedure Processing( const transport : ITransport);
545 // Called on any service function invocation
546 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
547 // Called when a client has finished request-handling to clean up
548 procedure CleanupContext;
549 end;
550
551
552 IProcessor = interface
553 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200554 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200555 end;
556
Jens Geyerd5436f52014-10-03 19:50:38 +0200557
Jens Geyer17c3ad92017-09-05 20:31:27 +0200558procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
559procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
560procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
561procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
562procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
563procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
564
Jens Geyerd5436f52014-10-03 19:50:38 +0200565
566implementation
567
Jens Geyerfad7fd32019-11-09 23:24:52 +0100568function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200569begin
570 ASSERT( SizeOf(n) = SizeOf(Result));
571 System.Move( n, Result, SizeOf(Result));
572end;
573
Jens Geyerfad7fd32019-11-09 23:24:52 +0100574function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200575begin
576 ASSERT( SizeOf(d) = SizeOf(Result));
577 System.Move( d, Result, SizeOf(Result));
578end;
579
Jens Geyerd5436f52014-10-03 19:50:38 +0200580
Jens Geyerd5436f52014-10-03 19:50:38 +0200581
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200582{ TProtocolRecursionTrackerImpl }
583
584constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
585begin
586 inherited Create;
587
588 // storing the pointer *after* the (successful) increment is important here
589 prot.IncrementRecursionDepth;
590 FProtocol := prot;
591end;
592
593destructor TProtocolRecursionTrackerImpl.Destroy;
594begin
595 try
596 // we have to release the reference iff the pointer has been stored
597 if FProtocol <> nil then begin
598 FProtocol.DecrementRecursionDepth;
599 FProtocol := nil;
600 end;
601 finally
602 inherited Destroy;
603 end;
604end;
605
Jens Geyerd5436f52014-10-03 19:50:38 +0200606{ TProtocolImpl }
607
Jens Geyera019cda2019-11-09 23:24:52 +0100608constructor TProtocolImpl.Create( const aTransport : ITransport);
Jens Geyerd5436f52014-10-03 19:50:38 +0200609begin
610 inherited Create;
Jens Geyera019cda2019-11-09 23:24:52 +0100611 FTrans := aTransport;
612 FRecursionLimit := aTransport.Configuration.RecursionLimit;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200613 FRecursionDepth := 0;
614end;
615
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200616function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
617begin
618 result := TProtocolRecursionTrackerImpl.Create(Self);
619end;
620
621procedure TProtocolImpl.IncrementRecursionDepth;
622begin
623 if FRecursionDepth < FRecursionLimit
624 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200625 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200626end;
627
628procedure TProtocolImpl.DecrementRecursionDepth;
629begin
630 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200631end;
632
633function TProtocolImpl.GetTransport: ITransport;
634begin
635 Result := FTrans;
636end;
637
Jens Geyera019cda2019-11-09 23:24:52 +0100638function TProtocolImpl.Configuration : IThriftConfiguration;
639begin
640 Result := FTrans.Configuration;
641end;
642
Jens Geyer41f47af2019-11-09 23:24:52 +0100643procedure TProtocolImpl.Reset;
644begin
Jens Geyera019cda2019-11-09 23:24:52 +0100645 FTrans.ResetConsumedMessageSize;
Jens Geyer41f47af2019-11-09 23:24:52 +0100646end;
647
Jens Geyerd5436f52014-10-03 19:50:38 +0200648function TProtocolImpl.ReadAnsiString: AnsiString;
649var
650 b : TBytes;
651 len : Integer;
652begin
653 Result := '';
654 b := ReadBinary;
655 len := Length( b );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100656 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200657 SetLength( Result, len);
658 System.Move( b[0], Pointer(Result)^, len );
659 end;
660end;
661
662function TProtocolImpl.ReadString: string;
663begin
664 Result := TEncoding.UTF8.GetString( ReadBinary );
665end;
666
667procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
668var
669 b : TBytes;
670 len : Integer;
671begin
672 len := Length(s);
673 SetLength( b, len);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100674 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200675 System.Move( Pointer(s)^, b[0], len );
676 end;
677 WriteBinary( b );
678end;
679
680procedure TProtocolImpl.WriteString(const s: string);
681var
682 b : TBytes;
683begin
684 b := TEncoding.UTF8.GetBytes(s);
685 WriteBinary( b );
686end;
687
Jens Geyer41f47af2019-11-09 23:24:52 +0100688
689procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList);
690begin
691 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
692end;
693
694
695procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet);
696begin
697 FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType));
698end;
699
700
701procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap);
Jens Geyera019cda2019-11-09 23:24:52 +0100702var nPairSize : Integer;
Jens Geyer41f47af2019-11-09 23:24:52 +0100703begin
704 nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType);
705 FTrans.CheckReadBytesAvailable( value.Count * nPairSize);
706end;
707
Jens Geyer07f4bb52022-09-03 14:50:06 +0200708
709procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes);
710var tmp : TBytes;
711begin
712 SetLength( tmp, bytes.Count);
713 if Length(tmp) > 0
714 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp));
715 WriteBinary( tmp);
716end;
717
718
719function TProtocolImpl.ReadBinaryCOM : IThriftBytes;
720var bytes : TBytes;
721begin
722 bytes := ReadBinary;
723 result := TThriftBytesImpl.Create(bytes,TRUE);
724end;
725
726
727{ TThriftBytesImpl }
728
729constructor TThriftBytesImpl.Create;
730begin
731 inherited Create;
732 ASSERT( Length(FData) = 0);
733end;
734
735
736constructor TThriftBytesImpl.Create( const bytes : TBytes);
737begin
738 FData := bytes; // copies the data
739end;
740
741
742constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean);
743
744 procedure SwapPointer( var one, two);
745 var
746 pOne : Pointer absolute one;
747 pTwo : Pointer absolute two;
748 pTmp : Pointer;
749 begin
750 pTmp := pOne;
751 pOne := pTwo;
752 pTwo := pTmp;
753 end;
754
755begin
756 inherited Create;
757 ASSERT( Length(FData) = 0);
758
759 if aTakeOwnership
760 then SwapPointer( FData, bytes)
761 else FData := bytes; // copies the data
762end;
763
764
765function TThriftBytesImpl.ToString : string;
766var sb : TThriftStringBuilder;
767begin
768 sb := TThriftStringBuilder.Create();
769 try
770 sb.Append('Bin: ');
771 sb.Append( FData);
772
773 result := sb.ToString;
774 finally
775 sb.Free;
776 end;
777end;
778
779
780function TThriftBytesImpl.GetCount : Integer;
781begin
782 result := Length(FData);
783end;
784
785
786procedure TThriftBytesImpl.SetCount(const value : Integer);
787begin
788 SetLength( FData, value);
789end;
790
791
792function TThriftBytesImpl.QueryRawDataPtr : Pointer;
793begin
794 result := FData;
795end;
796
Jens Geyerd5436f52014-10-03 19:50:38 +0200797{ TProtocolUtil }
798
799class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200800var field : TThriftField;
801 map : TThriftMap;
802 set_ : TThriftSet;
803 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200804 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200805 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200806begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200807 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200808 case type_ of
809 // simple types
810 TType.Bool_ : prot.ReadBool();
811 TType.Byte_ : prot.ReadByte();
812 TType.I16 : prot.ReadI16();
813 TType.I32 : prot.ReadI32();
814 TType.I64 : prot.ReadI64();
815 TType.Double_ : prot.ReadDouble();
816 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jens Geyer62445c12022-06-29 00:00:00 +0200817 TType.Uuid : prot.ReadUuid();
Jens Geyerd5436f52014-10-03 19:50:38 +0200818
819 // structured types
820 TType.Struct : begin
821 prot.ReadStructBegin();
822 while TRUE do begin
823 field := prot.ReadFieldBegin();
824 if (field.Type_ = TType.Stop) then Break;
825 Skip(prot, field.Type_);
826 prot.ReadFieldEnd();
827 end;
828 prot.ReadStructEnd();
829 end;
830
831 TType.Map : begin
832 map := prot.ReadMapBegin();
833 for i := 0 to map.Count-1 do begin
834 Skip(prot, map.KeyType);
835 Skip(prot, map.ValueType);
836 end;
837 prot.ReadMapEnd();
838 end;
839
840 TType.Set_ : begin
841 set_ := prot.ReadSetBegin();
842 for i := 0 to set_.Count-1
843 do Skip( prot, set_.ElementType);
844 prot.ReadSetEnd();
845 end;
846
847 TType.List : begin
848 list := prot.ReadListBegin();
849 for i := 0 to list.Count-1
850 do Skip( prot, list.ElementType);
851 prot.ReadListEnd();
852 end;
853
854 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100855 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200856 end;
857end;
858
Jens Geyerd5436f52014-10-03 19:50:38 +0200859
860{ TBinaryProtocolImpl }
861
Jens Geyer3b686532021-07-01 23:04:08 +0200862constructor TBinaryProtocolImpl.Create( const trans: ITransport);
863begin
864 // call the real CTOR
865 Self.Create( trans, FALSE, TRUE);
866end;
867
Jens Geyerfad7fd32019-11-09 23:24:52 +0100868constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200869begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100870 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200871 FStrictRead := strictRead;
872 FStrictWrite := strictWrite;
873end;
874
Jens Geyer17c3ad92017-09-05 20:31:27 +0200875function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200876begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200877 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200878end;
879
880function TBinaryProtocolImpl.ReadBinary: TBytes;
881var
882 size : Integer;
883 buf : TBytes;
884begin
885 size := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100886 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100887 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200888 FTrans.ReadAll( buf, 0, size);
889 Result := buf;
890end;
891
Jens Geyer62445c12022-06-29 00:00:00 +0200892function TBinaryProtocolImpl.ReadUuid : TGuid;
893var network : TGuid; // in network order (Big Endian)
894begin
895 ASSERT( SizeOf(result) = 16);
896 FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
Jens Geyerf8f62782022-09-10 00:55:02 +0200897 result := GuidUtils.SwapByteOrder(network);
Jens Geyer62445c12022-06-29 00:00:00 +0200898end;
899
Jens Geyerd5436f52014-10-03 19:50:38 +0200900function TBinaryProtocolImpl.ReadBool: Boolean;
901begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200902 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200903end;
904
905function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200906begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200907 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200908end;
909
910function TBinaryProtocolImpl.ReadDouble: Double;
911begin
912 Result := ConvertInt64ToDouble( ReadI64 )
913end;
914
Jens Geyer17c3ad92017-09-05 20:31:27 +0200915function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200916begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200917 Init( result, '', TType( ReadByte), 0);
918 if ( result.Type_ <> TType.Stop ) then begin
919 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200920 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200921end;
922
923procedure TBinaryProtocolImpl.ReadFieldEnd;
924begin
925
926end;
927
928function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200929var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200930begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200931 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200932 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
933end;
934
935function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200936var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200937begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200938 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200939
940 Result := Integer(
941 ((i32in[0] and $FF) shl 24) or
942 ((i32in[1] and $FF) shl 16) or
943 ((i32in[2] and $FF) shl 8) or
944 (i32in[3] and $FF));
945
946end;
947
948function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200949var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200950begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200951 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200952 Result :=
953 (Int64( i64in[0] and $FF) shl 56) or
954 (Int64( i64in[1] and $FF) shl 48) or
955 (Int64( i64in[2] and $FF) shl 40) or
956 (Int64( i64in[3] and $FF) shl 32) or
957 (Int64( i64in[4] and $FF) shl 24) or
958 (Int64( i64in[5] and $FF) shl 16) or
959 (Int64( i64in[6] and $FF) shl 8) or
960 (Int64( i64in[7] and $FF));
961end;
962
Jens Geyer17c3ad92017-09-05 20:31:27 +0200963function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200964begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200965 result.ElementType := TType(ReadByte);
966 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100967 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200968end;
969
970procedure TBinaryProtocolImpl.ReadListEnd;
971begin
972
973end;
974
Jens Geyer17c3ad92017-09-05 20:31:27 +0200975function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200976begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200977 result.KeyType := TType(ReadByte);
978 result.ValueType := TType(ReadByte);
979 result.Count := ReadI32;
Jens Geyer41f47af2019-11-09 23:24:52 +0100980 CheckReadBytesAvailable(result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200981end;
982
983procedure TBinaryProtocolImpl.ReadMapEnd;
984begin
985
986end;
987
Jens Geyer17c3ad92017-09-05 20:31:27 +0200988function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200989var
990 size : Integer;
991 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200992begin
Jens Geyer41f47af2019-11-09 23:24:52 +0100993 Reset;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200994 Init( result);
Jens Geyer589ee5b2021-03-29 21:40:55 +0200995
Jens Geyerd5436f52014-10-03 19:50:38 +0200996 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200997 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200998 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200999 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +02001000 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +02001001 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +02001002 result.Type_ := TMessageType( size and $000000ff);
1003 result.Name := ReadString;
1004 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001005 Exit;
1006 end;
1007
1008 try
1009 if FStrictRead
1010 then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
1011
Jens Geyer17c3ad92017-09-05 20:31:27 +02001012 result.Name := ReadStringBody( size );
1013 result.Type_ := TMessageType( ReadByte );
1014 result.SeqID := ReadI32;
Jens Geyer589ee5b2021-03-29 21:40:55 +02001015 except
1016 if CharUtils.IsHtmlDoctype(size)
1017 then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
1018 else raise; // something else
Jens Geyerd5436f52014-10-03 19:50:38 +02001019 end;
Jens Geyerd5436f52014-10-03 19:50:38 +02001020end;
1021
1022procedure TBinaryProtocolImpl.ReadMessageEnd;
1023begin
1024 inherited;
1025
1026end;
1027
Jens Geyer17c3ad92017-09-05 20:31:27 +02001028function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
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.ReadSetEnd;
1036begin
1037
1038end;
1039
1040function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001041var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +02001042begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001043 FTrans.CheckReadBytesAvailable( size);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001044 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +02001045 FTrans.ReadAll( buf, 0, size );
1046 Result := TEncoding.UTF8.GetString( buf);
1047end;
1048
Jens Geyer17c3ad92017-09-05 20:31:27 +02001049function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001050begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001051 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +02001052end;
1053
1054procedure TBinaryProtocolImpl.ReadStructEnd;
1055begin
1056 inherited;
1057
1058end;
1059
1060procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1061var iLen : Integer;
1062begin
1063 iLen := Length(b);
1064 WriteI32( iLen);
1065 if iLen > 0 then FTrans.Write(b, 0, iLen);
1066end;
1067
Jens Geyer62445c12022-06-29 00:00:00 +02001068procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
1069var network : TGuid; // in network order (Big Endian)
1070begin
1071 ASSERT( SizeOf(uuid) = 16);
Jens Geyerf8f62782022-09-10 00:55:02 +02001072 network := GuidUtils.SwapByteOrder(uuid);
Jens Geyer62445c12022-06-29 00:00:00 +02001073 Transport.Write( @network, 0, SizeOf(network));
1074end;
1075
Jens Geyerd5436f52014-10-03 19:50:38 +02001076procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1077begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001078 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001079 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +02001080 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001081 WriteByte( 0 );
1082 end;
1083end;
1084
1085procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +02001086begin
Jens Geyer17c3ad92017-09-05 20:31:27 +02001087 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +02001088end;
1089
1090procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1091begin
1092 WriteI64(ConvertDoubleToInt64(d));
1093end;
1094
Jens Geyer17c3ad92017-09-05 20:31:27 +02001095procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001096begin
1097 WriteByte(ShortInt(field.Type_));
1098 WriteI16(field.ID);
1099end;
1100
1101procedure TBinaryProtocolImpl.WriteFieldEnd;
1102begin
1103
1104end;
1105
1106procedure TBinaryProtocolImpl.WriteFieldStop;
1107begin
1108 WriteByte(ShortInt(TType.Stop));
1109end;
1110
1111procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001112var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001113begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001114 i16out[0] := Byte($FF and (i16 shr 8));
1115 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001116 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +02001117end;
1118
1119procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001120var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001121begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001122 i32out[0] := Byte($FF and (i32 shr 24));
1123 i32out[1] := Byte($FF and (i32 shr 16));
1124 i32out[2] := Byte($FF and (i32 shr 8));
1125 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001126 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +02001127end;
1128
1129procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001130var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +02001131begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001132 i64out[0] := Byte($FF and (i64 shr 56));
1133 i64out[1] := Byte($FF and (i64 shr 48));
1134 i64out[2] := Byte($FF and (i64 shr 40));
1135 i64out[3] := Byte($FF and (i64 shr 32));
1136 i64out[4] := Byte($FF and (i64 shr 24));
1137 i64out[5] := Byte($FF and (i64 shr 16));
1138 i64out[6] := Byte($FF and (i64 shr 8));
1139 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +02001140 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +02001141end;
1142
Jens Geyer17c3ad92017-09-05 20:31:27 +02001143procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001144begin
1145 WriteByte(ShortInt(list.ElementType));
1146 WriteI32(list.Count);
1147end;
1148
1149procedure TBinaryProtocolImpl.WriteListEnd;
1150begin
1151
1152end;
1153
Jens Geyer17c3ad92017-09-05 20:31:27 +02001154procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001155begin
1156 WriteByte(ShortInt(map.KeyType));
1157 WriteByte(ShortInt(map.ValueType));
1158 WriteI32(map.Count);
1159end;
1160
1161procedure TBinaryProtocolImpl.WriteMapEnd;
1162begin
1163
1164end;
1165
Jens Geyer17c3ad92017-09-05 20:31:27 +02001166procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001167var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +02001168begin
Jens Geyer41f47af2019-11-09 23:24:52 +01001169 Reset;
Jens Geyerfad7fd32019-11-09 23:24:52 +01001170 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001171 version := VERSION_1 or Cardinal( msg.Type_);
1172 WriteI32( Integer( version) );
1173 WriteString( msg.Name);
1174 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +01001175 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +02001176 WriteString( msg.Name);
1177 WriteByte(ShortInt( msg.Type_));
1178 WriteI32( msg.SeqID);
1179 end;
1180end;
1181
1182procedure TBinaryProtocolImpl.WriteMessageEnd;
1183begin
1184
1185end;
1186
Jens Geyer17c3ad92017-09-05 20:31:27 +02001187procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +02001188begin
1189 WriteByte(ShortInt(set_.ElementType));
1190 WriteI32(set_.Count);
1191end;
1192
1193procedure TBinaryProtocolImpl.WriteSetEnd;
1194begin
1195
1196end;
1197
Jens Geyer17c3ad92017-09-05 20:31:27 +02001198procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001199begin
1200
1201end;
1202
1203procedure TBinaryProtocolImpl.WriteStructEnd;
1204begin
1205
1206end;
1207
Jens Geyer41f47af2019-11-09 23:24:52 +01001208function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
1209// Return the minimum number of bytes a type will consume on the wire
1210begin
1211 case aType of
1212 TType.Stop: result := 0;
1213 TType.Void: result := 0;
1214 TType.Bool_: result := SizeOf(Byte);
1215 TType.Byte_: result := SizeOf(Byte);
1216 TType.Double_: result := SizeOf(Double);
1217 TType.I16: result := SizeOf(Int16);
1218 TType.I32: result := SizeOf(Int32);
1219 TType.I64: result := SizeOf(Int64);
1220 TType.String_: result := SizeOf(Int32); // string length
1221 TType.Struct: result := 0; // empty struct
1222 TType.Map: result := SizeOf(Int32); // element count
1223 TType.Set_: result := SizeOf(Int32); // element count
1224 TType.List: result := SizeOf(Int32); // element count
Jens Geyer62445c12022-06-29 00:00:00 +02001225 TType.Uuid: result := SizeOf(TGuid);
Jens Geyer41f47af2019-11-09 23:24:52 +01001226 else
1227 raise TTransportExceptionBadArgs.Create('Unhandled type code');
1228 end;
1229end;
1230
1231
Jens Geyerd5436f52014-10-03 19:50:38 +02001232{ TProtocolException }
1233
Jens Geyere0e32402016-04-20 21:50:48 +02001234constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001235begin
Jens Geyere0e32402016-04-20 21:50:48 +02001236 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001237end;
1238
Jens Geyere0e32402016-04-20 21:50:48 +02001239class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001240begin
Jens Geyere0e32402016-04-20 21:50:48 +02001241 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001242end;
1243
Jens Geyere0e32402016-04-20 21:50:48 +02001244class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001245begin
Jens Geyere0e32402016-04-20 21:50:48 +02001246 Result := TProtocolExceptionUnknown.Create('');
1247end;
1248
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001249class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001250begin
1251{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001252 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001253{$WARN SYMBOL_DEPRECATED DEFAULT}
1254end;
1255
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001256class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001257begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001258 case aType of
1259 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1260 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1261 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1262 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1263 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1264 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001265 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001266 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001267 Result := TProtocolExceptionUnknown.Create(msg);
1268 end;
1269end;
1270
1271{ TProtocolExceptionSpecialized }
1272
1273constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1274begin
1275 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001276end;
1277
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001278{ specialized TProtocolExceptions }
1279
1280class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1281begin
1282 result := TExceptionType.UNKNOWN;
1283end;
1284
1285class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1286begin
1287 result := TExceptionType.INVALID_DATA;
1288end;
1289
1290class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1291begin
1292 result := TExceptionType.NEGATIVE_SIZE;
1293end;
1294
1295class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1296begin
1297 result := TExceptionType.SIZE_LIMIT;
1298end;
1299
1300class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1301begin
1302 result := TExceptionType.BAD_VERSION;
1303end;
1304
1305class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1306begin
1307 result := TExceptionType.NOT_IMPLEMENTED;
1308end;
1309
1310class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1311begin
1312 result := TExceptionType.DEPTH_LIMIT;
1313end;
1314
Jens Geyerd5436f52014-10-03 19:50:38 +02001315{ TBinaryProtocolImpl.TFactory }
1316
Jens Geyerfad7fd32019-11-09 23:24:52 +01001317constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001318begin
1319 inherited Create;
1320 FStrictRead := AStrictRead;
1321 FStrictWrite := AStrictWrite;
1322end;
1323
Jens Geyerd5436f52014-10-03 19:50:38 +02001324function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1325begin
1326 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1327end;
1328
1329
1330{ TProtocolDecorator }
1331
1332constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1333begin
1334 ASSERT( aProtocol <> nil);
1335 inherited Create( aProtocol.Transport);
1336 FWrappedProtocol := aProtocol;
1337end;
1338
1339
Jens Geyer17c3ad92017-09-05 20:31:27 +02001340procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001341begin
1342 FWrappedProtocol.WriteMessageBegin( msg);
1343end;
1344
1345
1346procedure TProtocolDecorator.WriteMessageEnd;
1347begin
1348 FWrappedProtocol.WriteMessageEnd;
1349end;
1350
1351
Jens Geyer17c3ad92017-09-05 20:31:27 +02001352procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001353begin
1354 FWrappedProtocol.WriteStructBegin( struc);
1355end;
1356
1357
1358procedure TProtocolDecorator.WriteStructEnd;
1359begin
1360 FWrappedProtocol.WriteStructEnd;
1361end;
1362
1363
Jens Geyer17c3ad92017-09-05 20:31:27 +02001364procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001365begin
1366 FWrappedProtocol.WriteFieldBegin( field);
1367end;
1368
1369
1370procedure TProtocolDecorator.WriteFieldEnd;
1371begin
1372 FWrappedProtocol.WriteFieldEnd;
1373end;
1374
1375
1376procedure TProtocolDecorator.WriteFieldStop;
1377begin
1378 FWrappedProtocol.WriteFieldStop;
1379end;
1380
1381
Jens Geyer17c3ad92017-09-05 20:31:27 +02001382procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001383begin
1384 FWrappedProtocol.WriteMapBegin( map);
1385end;
1386
1387
1388procedure TProtocolDecorator.WriteMapEnd;
1389begin
1390 FWrappedProtocol.WriteMapEnd;
1391end;
1392
1393
Jens Geyer17c3ad92017-09-05 20:31:27 +02001394procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001395begin
1396 FWrappedProtocol.WriteListBegin( list);
1397end;
1398
1399
1400procedure TProtocolDecorator.WriteListEnd();
1401begin
1402 FWrappedProtocol.WriteListEnd();
1403end;
1404
1405
Jens Geyer17c3ad92017-09-05 20:31:27 +02001406procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001407begin
1408 FWrappedProtocol.WriteSetBegin( set_);
1409end;
1410
1411
1412procedure TProtocolDecorator.WriteSetEnd();
1413begin
1414 FWrappedProtocol.WriteSetEnd();
1415end;
1416
1417
1418procedure TProtocolDecorator.WriteBool( b: Boolean);
1419begin
1420 FWrappedProtocol.WriteBool( b);
1421end;
1422
1423
1424procedure TProtocolDecorator.WriteByte( b: ShortInt);
1425begin
1426 FWrappedProtocol.WriteByte( b);
1427end;
1428
1429
1430procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1431begin
1432 FWrappedProtocol.WriteI16( i16);
1433end;
1434
1435
1436procedure TProtocolDecorator.WriteI32( i32: Integer);
1437begin
1438 FWrappedProtocol.WriteI32( i32);
1439end;
1440
1441
1442procedure TProtocolDecorator.WriteI64( const i64: Int64);
1443begin
1444 FWrappedProtocol.WriteI64( i64);
1445end;
1446
1447
1448procedure TProtocolDecorator.WriteDouble( const d: Double);
1449begin
1450 FWrappedProtocol.WriteDouble( d);
1451end;
1452
1453
1454procedure TProtocolDecorator.WriteString( const s: string );
1455begin
1456 FWrappedProtocol.WriteString( s);
1457end;
1458
1459
1460procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1461begin
1462 FWrappedProtocol.WriteAnsiString( s);
1463end;
1464
1465
1466procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1467begin
1468 FWrappedProtocol.WriteBinary( b);
1469end;
1470
1471
Jens Geyer62445c12022-06-29 00:00:00 +02001472procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
1473begin
1474 FWrappedProtocol.WriteUuid( uuid);
1475end;
1476
1477
Jens Geyer17c3ad92017-09-05 20:31:27 +02001478function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001479begin
1480 result := FWrappedProtocol.ReadMessageBegin;
1481end;
1482
1483
1484procedure TProtocolDecorator.ReadMessageEnd();
1485begin
1486 FWrappedProtocol.ReadMessageEnd();
1487end;
1488
1489
Jens Geyer17c3ad92017-09-05 20:31:27 +02001490function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001491begin
1492 result := FWrappedProtocol.ReadStructBegin;
1493end;
1494
1495
1496procedure TProtocolDecorator.ReadStructEnd;
1497begin
1498 FWrappedProtocol.ReadStructEnd;
1499end;
1500
1501
Jens Geyer17c3ad92017-09-05 20:31:27 +02001502function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001503begin
1504 result := FWrappedProtocol.ReadFieldBegin;
1505end;
1506
1507
1508procedure TProtocolDecorator.ReadFieldEnd();
1509begin
1510 FWrappedProtocol.ReadFieldEnd();
1511end;
1512
1513
Jens Geyer17c3ad92017-09-05 20:31:27 +02001514function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001515begin
1516 result := FWrappedProtocol.ReadMapBegin;
1517end;
1518
1519
1520procedure TProtocolDecorator.ReadMapEnd();
1521begin
1522 FWrappedProtocol.ReadMapEnd();
1523end;
1524
1525
Jens Geyer17c3ad92017-09-05 20:31:27 +02001526function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001527begin
1528 result := FWrappedProtocol.ReadListBegin;
1529end;
1530
1531
1532procedure TProtocolDecorator.ReadListEnd();
1533begin
1534 FWrappedProtocol.ReadListEnd();
1535end;
1536
1537
Jens Geyer17c3ad92017-09-05 20:31:27 +02001538function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001539begin
1540 result := FWrappedProtocol.ReadSetBegin;
1541end;
1542
1543
1544procedure TProtocolDecorator.ReadSetEnd();
1545begin
1546 FWrappedProtocol.ReadSetEnd();
1547end;
1548
1549
1550function TProtocolDecorator.ReadBool: Boolean;
1551begin
1552 result := FWrappedProtocol.ReadBool;
1553end;
1554
1555
1556function TProtocolDecorator.ReadByte: ShortInt;
1557begin
1558 result := FWrappedProtocol.ReadByte;
1559end;
1560
1561
1562function TProtocolDecorator.ReadI16: SmallInt;
1563begin
1564 result := FWrappedProtocol.ReadI16;
1565end;
1566
1567
1568function TProtocolDecorator.ReadI32: Integer;
1569begin
1570 result := FWrappedProtocol.ReadI32;
1571end;
1572
1573
1574function TProtocolDecorator.ReadI64: Int64;
1575begin
1576 result := FWrappedProtocol.ReadI64;
1577end;
1578
1579
1580function TProtocolDecorator.ReadDouble:Double;
1581begin
1582 result := FWrappedProtocol.ReadDouble;
1583end;
1584
1585
1586function TProtocolDecorator.ReadBinary: TBytes;
1587begin
1588 result := FWrappedProtocol.ReadBinary;
1589end;
1590
1591
Jens Geyer62445c12022-06-29 00:00:00 +02001592function TProtocolDecorator.ReadUuid: TGuid;
1593begin
1594 result := FWrappedProtocol.ReadUuid;
1595end;
1596
1597
Jens Geyerd5436f52014-10-03 19:50:38 +02001598function TProtocolDecorator.ReadString: string;
1599begin
1600 result := FWrappedProtocol.ReadString;
1601end;
1602
1603
1604function TProtocolDecorator.ReadAnsiString: AnsiString;
1605begin
1606 result := FWrappedProtocol.ReadAnsiString;
1607end;
1608
1609
Jens Geyer41f47af2019-11-09 23:24:52 +01001610function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer;
1611begin
1612 result := FWrappedProtocol.GetMinSerializedSize(aType);
1613end;
1614
1615
Jens Geyer17c3ad92017-09-05 20:31:27 +02001616{ Init helper functions }
1617
1618procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1619begin
1620 rec.Name := AName;
1621 rec.Type_ := AMessageType;
1622 rec.SeqID := ASeqID;
1623end;
1624
1625
1626procedure Init( var rec : TThriftStruct; const AName: string = '');
1627begin
1628 rec.Name := AName;
1629end;
1630
1631
1632procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1633begin
1634 rec.Name := AName;
1635 rec.Type_ := AType;
1636 rec.Id := AId;
1637end;
1638
1639
1640procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1641begin
1642 rec.ValueType := AValueType;
1643 rec.KeyType := AKeyType;
1644 rec.Count := ACount;
1645end;
1646
1647
1648procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1649begin
1650 rec.Count := ACount;
1651 rec.ElementType := AElementType;
1652end;
1653
1654
1655procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1656begin
1657 rec.Count := ACount;
1658 rec.ElementType := AElementType;
1659end;
1660
1661
1662
Jens Geyerd5436f52014-10-03 19:50:38 +02001663end.
1664