blob: 7c802214d919d1a91c089c59e691c72e16a5de93 [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}
21
22unit Thrift.Protocol;
23
24interface
25
26uses
27 Classes,
28 SysUtils,
29 Contnrs,
Jens Geyer606f1ef2018-04-09 23:09:41 +020030 Thrift.Exception,
Jens Geyerd5436f52014-10-03 19:50:38 +020031 Thrift.Stream,
Jens Geyer8f7487e2019-05-09 22:21:32 +020032 Thrift.Utils,
Jens Geyerd5436f52014-10-03 19:50:38 +020033 Thrift.Collections,
34 Thrift.Transport;
35
36type
37
38 TType = (
39 Stop = 0,
40 Void = 1,
41 Bool_ = 2,
42 Byte_ = 3,
43 Double_ = 4,
44 I16 = 6,
45 I32 = 8,
46 I64 = 10,
47 String_ = 11,
48 Struct = 12,
49 Map = 13,
50 Set_ = 14,
51 List = 15
52 );
53
54 TMessageType = (
55 Call = 1,
56 Reply = 2,
57 Exception = 3,
58 Oneway = 4
59 );
60
Jens Geyerf0e63312015-03-01 18:47:49 +010061const
62 VALID_TTYPES = [
63 TType.Stop, TType.Void,
64 TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
65 TType.Struct, TType.Map, TType.Set_, TType.List
66 ];
67
68 VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)];
69
Jens Geyerd47fcdd2015-07-09 22:05:18 +020070const
71 DEFAULT_RECURSION_LIMIT = 64;
72
Jens Geyerf0e63312015-03-01 18:47:49 +010073type
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 Geyerd5436f52014-10-03 19:50:38 +0200198 IProtocol = interface
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200199 ['{602A7FFB-0D9E-4CD8-8D7F-E5076660588A}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200200 function GetTransport: ITransport;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200201 procedure WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +0200202 procedure WriteMessageEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200203 procedure WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200204 procedure WriteStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200205 procedure WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200206 procedure WriteFieldEnd;
207 procedure WriteFieldStop;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200208 procedure WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200209 procedure WriteMapEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200210 procedure WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200211 procedure WriteListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200212 procedure WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +0200213 procedure WriteSetEnd();
214 procedure WriteBool( b: Boolean);
215 procedure WriteByte( b: ShortInt);
216 procedure WriteI16( i16: SmallInt);
217 procedure WriteI32( i32: Integer);
218 procedure WriteI64( const i64: Int64);
219 procedure WriteDouble( const d: Double);
220 procedure WriteString( const s: string );
221 procedure WriteAnsiString( const s: AnsiString);
222 procedure WriteBinary( const b: TBytes);
223
Jens Geyer17c3ad92017-09-05 20:31:27 +0200224 function ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200225 procedure ReadMessageEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200226 function ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200227 procedure ReadStructEnd;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200228 function ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200229 procedure ReadFieldEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200230 function ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200231 procedure ReadMapEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200232 function ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200233 procedure ReadListEnd();
Jens Geyer17c3ad92017-09-05 20:31:27 +0200234 function ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200235 procedure ReadSetEnd();
236 function ReadBool: Boolean;
237 function ReadByte: ShortInt;
238 function ReadI16: SmallInt;
239 function ReadI32: Integer;
240 function ReadI64: Int64;
241 function ReadDouble:Double;
242 function ReadBinary: TBytes;
243 function ReadString: string;
244 function ReadAnsiString: AnsiString;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200245
246 procedure SetRecursionLimit( value : Integer);
247 function GetRecursionLimit : Integer;
248 function NextRecursionLevel : IProtocolRecursionTracker;
249 procedure IncrementRecursionDepth;
250 procedure DecrementRecursionDepth;
251
Jens Geyerd5436f52014-10-03 19:50:38 +0200252 property Transport: ITransport read GetTransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200253 property RecursionLimit : Integer read GetRecursionLimit write SetRecursionLimit;
Jens Geyerd5436f52014-10-03 19:50:38 +0200254 end;
255
256 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100257 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200258 FTrans : ITransport;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200259 FRecursionLimit : Integer;
260 FRecursionDepth : Integer;
261
262 procedure SetRecursionLimit( value : Integer);
263 function GetRecursionLimit : Integer;
264 function NextRecursionLevel : IProtocolRecursionTracker;
265 procedure IncrementRecursionDepth;
266 procedure DecrementRecursionDepth;
267
Jens Geyerd5436f52014-10-03 19:50:38 +0200268 function GetTransport: ITransport;
269 public
Jens Geyer17c3ad92017-09-05 20:31:27 +0200270 procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200271 procedure WriteMessageEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200272 procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200273 procedure WriteStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200274 procedure WriteFieldBegin( const field: TThriftField); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200275 procedure WriteFieldEnd; virtual; abstract;
276 procedure WriteFieldStop; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200277 procedure WriteMapBegin( const map: TThriftMap); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200278 procedure WriteMapEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200279 procedure WriteListBegin( const list: TThriftList); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200280 procedure WriteListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200281 procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200282 procedure WriteSetEnd(); virtual; abstract;
283 procedure WriteBool( b: Boolean); virtual; abstract;
284 procedure WriteByte( b: ShortInt); virtual; abstract;
285 procedure WriteI16( i16: SmallInt); virtual; abstract;
286 procedure WriteI32( i32: Integer); virtual; abstract;
287 procedure WriteI64( const i64: Int64); virtual; abstract;
288 procedure WriteDouble( const d: Double); virtual; abstract;
289 procedure WriteString( const s: string ); virtual;
290 procedure WriteAnsiString( const s: AnsiString); virtual;
291 procedure WriteBinary( const b: TBytes); virtual; abstract;
292
Jens Geyer17c3ad92017-09-05 20:31:27 +0200293 function ReadMessageBegin: TThriftMessage; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200294 procedure ReadMessageEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200295 function ReadStructBegin: TThriftStruct; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200296 procedure ReadStructEnd; virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200297 function ReadFieldBegin: TThriftField; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200298 procedure ReadFieldEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200299 function ReadMapBegin: TThriftMap; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200300 procedure ReadMapEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200301 function ReadListBegin: TThriftList; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200302 procedure ReadListEnd(); virtual; abstract;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200303 function ReadSetBegin: TThriftSet; virtual; abstract;
Jens Geyerd5436f52014-10-03 19:50:38 +0200304 procedure ReadSetEnd(); virtual; abstract;
305 function ReadBool: Boolean; virtual; abstract;
306 function ReadByte: ShortInt; virtual; abstract;
307 function ReadI16: SmallInt; virtual; abstract;
308 function ReadI32: Integer; virtual; abstract;
309 function ReadI64: Int64; virtual; abstract;
310 function ReadDouble:Double; virtual; abstract;
311 function ReadBinary: TBytes; virtual; abstract;
312 function ReadString: string; virtual;
313 function ReadAnsiString: AnsiString; virtual;
314
315 property Transport: ITransport read GetTransport;
316
317 constructor Create( trans: ITransport );
318 end;
319
Jens Geyer8f7487e2019-05-09 22:21:32 +0200320 IBase = interface( ISupportsToString)
321 ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
Jens Geyerd5436f52014-10-03 19:50:38 +0200322 procedure Read( const iprot: IProtocol);
323 procedure Write( const iprot: IProtocol);
324 end;
325
Jens Geyerd5436f52014-10-03 19:50:38 +0200326
327 TBinaryProtocolImpl = class( TProtocolImpl )
Jens Geyerfad7fd32019-11-09 23:24:52 +0100328 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200329 const
330 VERSION_MASK : Cardinal = $ffff0000;
331 VERSION_1 : Cardinal = $80010000;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100332 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200333 FStrictRead : Boolean;
334 FStrictWrite : Boolean;
335
Jens Geyerfad7fd32019-11-09 23:24:52 +0100336 strict private
Jens Geyer17c3ad92017-09-05 20:31:27 +0200337 function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200338 function ReadStringBody( size: Integer): string;
339
340 public
Jens Geyerd5436f52014-10-03 19:50:38 +0200341 type
342 TFactory = class( TInterfacedObject, IProtocolFactory)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100343 strict protected
Jens Geyerd5436f52014-10-03 19:50:38 +0200344 FStrictRead : Boolean;
345 FStrictWrite : Boolean;
Jens Geyerd5436f52014-10-03 19:50:38 +0200346 function GetProtocol( const trans: ITransport): IProtocol;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100347 public
348 constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200349 end;
350
Jens Geyerfad7fd32019-11-09 23:24:52 +0100351 constructor Create( const trans: ITransport; strictRead: Boolean = FALSE; strictWrite: Boolean = TRUE); reintroduce;
Jens Geyerd5436f52014-10-03 19:50:38 +0200352
Jens Geyer17c3ad92017-09-05 20:31:27 +0200353 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200354 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200355 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200356 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200357 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200358 procedure WriteFieldEnd; override;
359 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200360 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200361 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200362 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200363 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200364 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200365 procedure WriteSetEnd(); override;
366 procedure WriteBool( b: Boolean); override;
367 procedure WriteByte( b: ShortInt); override;
368 procedure WriteI16( i16: SmallInt); override;
369 procedure WriteI32( i32: Integer); override;
370 procedure WriteI64( const i64: Int64); override;
371 procedure WriteDouble( const d: Double); override;
372 procedure WriteBinary( const b: TBytes); override;
373
Jens Geyer17c3ad92017-09-05 20:31:27 +0200374 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200375 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200376 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200377 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200378 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200379 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200380 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200381 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200382 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200383 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200384 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200385 procedure ReadSetEnd(); override;
386 function ReadBool: Boolean; override;
387 function ReadByte: ShortInt; override;
388 function ReadI16: SmallInt; override;
389 function ReadI32: Integer; override;
390 function ReadI64: Int64; override;
391 function ReadDouble:Double; override;
392 function ReadBinary: TBytes; override;
393
394 end;
395
396
397 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
398 providing a way to author concise concrete decorator subclasses. The decorator
399 does not (and should not) modify the behaviour of the enclosed TProtocol
400
401 See p.175 of Design Patterns (by Gamma et al.)
402 }
403 TProtocolDecorator = class( TProtocolImpl)
Jens Geyerfad7fd32019-11-09 23:24:52 +0100404 strict private
Jens Geyerd5436f52014-10-03 19:50:38 +0200405 FWrappedProtocol : IProtocol;
406
407 public
408 // Encloses the specified protocol.
409 // All operations will be forward to the given protocol. Must be non-null.
410 constructor Create( const aProtocol : IProtocol);
411
Jens Geyer17c3ad92017-09-05 20:31:27 +0200412 procedure WriteMessageBegin( const msg: TThriftMessage); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200413 procedure WriteMessageEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200414 procedure WriteStructBegin( const struc: TThriftStruct); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200415 procedure WriteStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200416 procedure WriteFieldBegin( const field: TThriftField); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200417 procedure WriteFieldEnd; override;
418 procedure WriteFieldStop; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200419 procedure WriteMapBegin( const map: TThriftMap); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200420 procedure WriteMapEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200421 procedure WriteListBegin( const list: TThriftList); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200422 procedure WriteListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200423 procedure WriteSetBegin( const set_: TThriftSet ); override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200424 procedure WriteSetEnd(); override;
425 procedure WriteBool( b: Boolean); override;
426 procedure WriteByte( b: ShortInt); override;
427 procedure WriteI16( i16: SmallInt); override;
428 procedure WriteI32( i32: Integer); override;
429 procedure WriteI64( const i64: Int64); override;
430 procedure WriteDouble( const d: Double); override;
431 procedure WriteString( const s: string ); override;
432 procedure WriteAnsiString( const s: AnsiString); override;
433 procedure WriteBinary( const b: TBytes); override;
434
Jens Geyer17c3ad92017-09-05 20:31:27 +0200435 function ReadMessageBegin: TThriftMessage; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200436 procedure ReadMessageEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200437 function ReadStructBegin: TThriftStruct; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200438 procedure ReadStructEnd; override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200439 function ReadFieldBegin: TThriftField; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200440 procedure ReadFieldEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200441 function ReadMapBegin: TThriftMap; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200442 procedure ReadMapEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200443 function ReadListBegin: TThriftList; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200444 procedure ReadListEnd(); override;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200445 function ReadSetBegin: TThriftSet; override;
Jens Geyerd5436f52014-10-03 19:50:38 +0200446 procedure ReadSetEnd(); override;
447 function ReadBool: Boolean; override;
448 function ReadByte: ShortInt; override;
449 function ReadI16: SmallInt; override;
450 function ReadI32: Integer; override;
451 function ReadI64: Int64; override;
452 function ReadDouble:Double; override;
453 function ReadBinary: TBytes; override;
454 function ReadString: string; override;
455 function ReadAnsiString: AnsiString; override;
456 end;
457
458
459type
460 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200461 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
462 // Called before reading arguments.
463 procedure PreRead;
464 // Called between reading arguments and calling the handler.
465 procedure PostRead;
466 // Called between calling the handler and writing the response.
467 procedure PreWrite;
468 // Called after writing the response.
469 procedure PostWrite;
470 // Called when an oneway (async) function call completes successfully.
471 procedure OnewayComplete;
472 // Called if the handler throws an undeclared exception.
473 procedure UnhandledError( const e : Exception);
474 // Called when a client has finished request-handling to clean up
475 procedure CleanupContext;
476 end;
477
478
479 IProcessorEvents = interface
480 ['{A8661119-657C-447D-93C5-512E36162A45}']
481 // Called when a client is about to call the processor.
482 procedure Processing( const transport : ITransport);
483 // Called on any service function invocation
484 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
485 // Called when a client has finished request-handling to clean up
486 procedure CleanupContext;
487 end;
488
489
490 IProcessor = interface
491 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200492 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200493 end;
494
Jens Geyerd5436f52014-10-03 19:50:38 +0200495
Jens Geyer17c3ad92017-09-05 20:31:27 +0200496procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline;
497procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline;
498procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline;
499procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
500procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
501procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline;
502
Jens Geyerd5436f52014-10-03 19:50:38 +0200503
504implementation
505
Jens Geyerfad7fd32019-11-09 23:24:52 +0100506function ConvertInt64ToDouble( const n: Int64): Double; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200507begin
508 ASSERT( SizeOf(n) = SizeOf(Result));
509 System.Move( n, Result, SizeOf(Result));
510end;
511
Jens Geyerfad7fd32019-11-09 23:24:52 +0100512function ConvertDoubleToInt64( const d: Double): Int64; inline;
Jens Geyerd5436f52014-10-03 19:50:38 +0200513begin
514 ASSERT( SizeOf(d) = SizeOf(Result));
515 System.Move( d, Result, SizeOf(Result));
516end;
517
Jens Geyerd5436f52014-10-03 19:50:38 +0200518
Jens Geyerd5436f52014-10-03 19:50:38 +0200519
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200520{ TProtocolRecursionTrackerImpl }
521
522constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol);
523begin
524 inherited Create;
525
526 // storing the pointer *after* the (successful) increment is important here
527 prot.IncrementRecursionDepth;
528 FProtocol := prot;
529end;
530
531destructor TProtocolRecursionTrackerImpl.Destroy;
532begin
533 try
534 // we have to release the reference iff the pointer has been stored
535 if FProtocol <> nil then begin
536 FProtocol.DecrementRecursionDepth;
537 FProtocol := nil;
538 end;
539 finally
540 inherited Destroy;
541 end;
542end;
543
Jens Geyerd5436f52014-10-03 19:50:38 +0200544{ TProtocolImpl }
545
546constructor TProtocolImpl.Create(trans: ITransport);
547begin
548 inherited Create;
549 FTrans := trans;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200550 FRecursionLimit := DEFAULT_RECURSION_LIMIT;
551 FRecursionDepth := 0;
552end;
553
554procedure TProtocolImpl.SetRecursionLimit( value : Integer);
555begin
556 FRecursionLimit := value;
557end;
558
559function TProtocolImpl.GetRecursionLimit : Integer;
560begin
561 result := FRecursionLimit;
562end;
563
564function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker;
565begin
566 result := TProtocolRecursionTrackerImpl.Create(Self);
567end;
568
569procedure TProtocolImpl.IncrementRecursionDepth;
570begin
571 if FRecursionDepth < FRecursionLimit
572 then Inc(FRecursionDepth)
Jens Geyere0e32402016-04-20 21:50:48 +0200573 else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200574end;
575
576procedure TProtocolImpl.DecrementRecursionDepth;
577begin
578 Dec(FRecursionDepth)
Jens Geyerd5436f52014-10-03 19:50:38 +0200579end;
580
581function TProtocolImpl.GetTransport: ITransport;
582begin
583 Result := FTrans;
584end;
585
586function TProtocolImpl.ReadAnsiString: AnsiString;
587var
588 b : TBytes;
589 len : Integer;
590begin
591 Result := '';
592 b := ReadBinary;
593 len := Length( b );
Jens Geyerfad7fd32019-11-09 23:24:52 +0100594 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200595 SetLength( Result, len);
596 System.Move( b[0], Pointer(Result)^, len );
597 end;
598end;
599
600function TProtocolImpl.ReadString: string;
601begin
602 Result := TEncoding.UTF8.GetString( ReadBinary );
603end;
604
605procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
606var
607 b : TBytes;
608 len : Integer;
609begin
610 len := Length(s);
611 SetLength( b, len);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100612 if len > 0 then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200613 System.Move( Pointer(s)^, b[0], len );
614 end;
615 WriteBinary( b );
616end;
617
618procedure TProtocolImpl.WriteString(const s: string);
619var
620 b : TBytes;
621begin
622 b := TEncoding.UTF8.GetBytes(s);
623 WriteBinary( b );
624end;
625
626{ TProtocolUtil }
627
628class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200629var field : TThriftField;
630 map : TThriftMap;
631 set_ : TThriftSet;
632 list : TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200633 i : Integer;
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200634 tracker : IProtocolRecursionTracker;
Jens Geyerd5436f52014-10-03 19:50:38 +0200635begin
Jens Geyerd47fcdd2015-07-09 22:05:18 +0200636 tracker := prot.NextRecursionLevel;
Jens Geyerd5436f52014-10-03 19:50:38 +0200637 case type_ of
638 // simple types
639 TType.Bool_ : prot.ReadBool();
640 TType.Byte_ : prot.ReadByte();
641 TType.I16 : prot.ReadI16();
642 TType.I32 : prot.ReadI32();
643 TType.I64 : prot.ReadI64();
644 TType.Double_ : prot.ReadDouble();
645 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
646
647 // structured types
648 TType.Struct : begin
649 prot.ReadStructBegin();
650 while TRUE do begin
651 field := prot.ReadFieldBegin();
652 if (field.Type_ = TType.Stop) then Break;
653 Skip(prot, field.Type_);
654 prot.ReadFieldEnd();
655 end;
656 prot.ReadStructEnd();
657 end;
658
659 TType.Map : begin
660 map := prot.ReadMapBegin();
661 for i := 0 to map.Count-1 do begin
662 Skip(prot, map.KeyType);
663 Skip(prot, map.ValueType);
664 end;
665 prot.ReadMapEnd();
666 end;
667
668 TType.Set_ : begin
669 set_ := prot.ReadSetBegin();
670 for i := 0 to set_.Count-1
671 do Skip( prot, set_.ElementType);
672 prot.ReadSetEnd();
673 end;
674
675 TType.List : begin
676 list := prot.ReadListBegin();
677 for i := 0 to list.Count-1
678 do Skip( prot, list.ElementType);
679 prot.ReadListEnd();
680 end;
681
682 else
Jens Geyer5f723cd2017-01-10 21:57:48 +0100683 raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_)));
Jens Geyerd5436f52014-10-03 19:50:38 +0200684 end;
685end;
686
Jens Geyerd5436f52014-10-03 19:50:38 +0200687
688{ TBinaryProtocolImpl }
689
Jens Geyerfad7fd32019-11-09 23:24:52 +0100690constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +0200691begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100692 inherited Create( trans);
Jens Geyerd5436f52014-10-03 19:50:38 +0200693 FStrictRead := strictRead;
694 FStrictWrite := strictWrite;
695end;
696
Jens Geyer17c3ad92017-09-05 20:31:27 +0200697function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200698begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200699 Result := FTrans.ReadAll( pBuf, buflen, off, len );
Jens Geyerd5436f52014-10-03 19:50:38 +0200700end;
701
702function TBinaryProtocolImpl.ReadBinary: TBytes;
703var
704 size : Integer;
705 buf : TBytes;
706begin
707 size := ReadI32;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100708 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200709 FTrans.ReadAll( buf, 0, size);
710 Result := buf;
711end;
712
713function TBinaryProtocolImpl.ReadBool: Boolean;
714begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200715 Result := (ReadByte = 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200716end;
717
718function TBinaryProtocolImpl.ReadByte: ShortInt;
Jens Geyerd5436f52014-10-03 19:50:38 +0200719begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200720 ReadAll( @result, SizeOf(result), 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200721end;
722
723function TBinaryProtocolImpl.ReadDouble: Double;
724begin
725 Result := ConvertInt64ToDouble( ReadI64 )
726end;
727
Jens Geyer17c3ad92017-09-05 20:31:27 +0200728function TBinaryProtocolImpl.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +0200729begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200730 Init( result, '', TType( ReadByte), 0);
731 if ( result.Type_ <> TType.Stop ) then begin
732 result.Id := ReadI16;
Jens Geyerd5436f52014-10-03 19:50:38 +0200733 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200734end;
735
736procedure TBinaryProtocolImpl.ReadFieldEnd;
737begin
738
739end;
740
741function TBinaryProtocolImpl.ReadI16: SmallInt;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200742var i16in : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200743begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200744 ReadAll( @i16in, Sizeof(i16in), 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200745 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
746end;
747
748function TBinaryProtocolImpl.ReadI32: Integer;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200749var i32in : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200750begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200751 ReadAll( @i32in, SizeOf(i32in), 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200752
753 Result := Integer(
754 ((i32in[0] and $FF) shl 24) or
755 ((i32in[1] and $FF) shl 16) or
756 ((i32in[2] and $FF) shl 8) or
757 (i32in[3] and $FF));
758
759end;
760
761function TBinaryProtocolImpl.ReadI64: Int64;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200762var i64in : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200763begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200764 ReadAll( @i64in, SizeOf(i64in), 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200765 Result :=
766 (Int64( i64in[0] and $FF) shl 56) or
767 (Int64( i64in[1] and $FF) shl 48) or
768 (Int64( i64in[2] and $FF) shl 40) or
769 (Int64( i64in[3] and $FF) shl 32) or
770 (Int64( i64in[4] and $FF) shl 24) or
771 (Int64( i64in[5] and $FF) shl 16) or
772 (Int64( i64in[6] and $FF) shl 8) or
773 (Int64( i64in[7] and $FF));
774end;
775
Jens Geyer17c3ad92017-09-05 20:31:27 +0200776function TBinaryProtocolImpl.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +0200777begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200778 result.ElementType := TType(ReadByte);
779 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200780end;
781
782procedure TBinaryProtocolImpl.ReadListEnd;
783begin
784
785end;
786
Jens Geyer17c3ad92017-09-05 20:31:27 +0200787function TBinaryProtocolImpl.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +0200788begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200789 result.KeyType := TType(ReadByte);
790 result.ValueType := TType(ReadByte);
791 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200792end;
793
794procedure TBinaryProtocolImpl.ReadMapEnd;
795begin
796
797end;
798
Jens Geyer17c3ad92017-09-05 20:31:27 +0200799function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +0200800var
801 size : Integer;
802 version : Integer;
Jens Geyerd5436f52014-10-03 19:50:38 +0200803begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200804 Init( result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200805 size := ReadI32;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200806 if (size < 0) then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200807 version := size and Integer( VERSION_MASK);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200808 if ( version <> Integer( VERSION_1)) then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200809 raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
Jens Geyerd5436f52014-10-03 19:50:38 +0200810 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200811 result.Type_ := TMessageType( size and $000000ff);
812 result.Name := ReadString;
813 result.SeqID := ReadI32;
814 end
815 else begin
816 if FStrictRead then begin
Jens Geyere0e32402016-04-20 21:50:48 +0200817 raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
Jens Geyerd5436f52014-10-03 19:50:38 +0200818 end;
Jens Geyer17c3ad92017-09-05 20:31:27 +0200819 result.Name := ReadStringBody( size );
820 result.Type_ := TMessageType( ReadByte );
821 result.SeqID := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200822 end;
Jens Geyerd5436f52014-10-03 19:50:38 +0200823end;
824
825procedure TBinaryProtocolImpl.ReadMessageEnd;
826begin
827 inherited;
828
829end;
830
Jens Geyer17c3ad92017-09-05 20:31:27 +0200831function TBinaryProtocolImpl.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +0200832begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200833 result.ElementType := TType(ReadByte);
834 result.Count := ReadI32;
Jens Geyerd5436f52014-10-03 19:50:38 +0200835end;
836
837procedure TBinaryProtocolImpl.ReadSetEnd;
838begin
839
840end;
841
842function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
Jens Geyerfad7fd32019-11-09 23:24:52 +0100843var buf : TBytes;
Jens Geyerd5436f52014-10-03 19:50:38 +0200844begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100845 SetLength( buf, size);
Jens Geyerd5436f52014-10-03 19:50:38 +0200846 FTrans.ReadAll( buf, 0, size );
847 Result := TEncoding.UTF8.GetString( buf);
848end;
849
Jens Geyer17c3ad92017-09-05 20:31:27 +0200850function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +0200851begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200852 Init( Result);
Jens Geyerd5436f52014-10-03 19:50:38 +0200853end;
854
855procedure TBinaryProtocolImpl.ReadStructEnd;
856begin
857 inherited;
858
859end;
860
861procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
862var iLen : Integer;
863begin
864 iLen := Length(b);
865 WriteI32( iLen);
866 if iLen > 0 then FTrans.Write(b, 0, iLen);
867end;
868
869procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
870begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200871 if b then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200872 WriteByte( 1 );
Jens Geyer17c3ad92017-09-05 20:31:27 +0200873 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200874 WriteByte( 0 );
875 end;
876end;
877
878procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
Jens Geyerd5436f52014-10-03 19:50:38 +0200879begin
Jens Geyer17c3ad92017-09-05 20:31:27 +0200880 FTrans.Write( @b, 0, 1);
Jens Geyerd5436f52014-10-03 19:50:38 +0200881end;
882
883procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
884begin
885 WriteI64(ConvertDoubleToInt64(d));
886end;
887
Jens Geyer17c3ad92017-09-05 20:31:27 +0200888procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +0200889begin
890 WriteByte(ShortInt(field.Type_));
891 WriteI16(field.ID);
892end;
893
894procedure TBinaryProtocolImpl.WriteFieldEnd;
895begin
896
897end;
898
899procedure TBinaryProtocolImpl.WriteFieldStop;
900begin
901 WriteByte(ShortInt(TType.Stop));
902end;
903
904procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200905var i16out : packed array[0..1] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200906begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200907 i16out[0] := Byte($FF and (i16 shr 8));
908 i16out[1] := Byte($FF and i16);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200909 FTrans.Write( @i16out, 0, 2);
Jens Geyerd5436f52014-10-03 19:50:38 +0200910end;
911
912procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200913var i32out : packed array[0..3] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200914begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200915 i32out[0] := Byte($FF and (i32 shr 24));
916 i32out[1] := Byte($FF and (i32 shr 16));
917 i32out[2] := Byte($FF and (i32 shr 8));
918 i32out[3] := Byte($FF and i32);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200919 FTrans.Write( @i32out, 0, 4);
Jens Geyerd5436f52014-10-03 19:50:38 +0200920end;
921
922procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200923var i64out : packed array[0..7] of Byte;
Jens Geyerd5436f52014-10-03 19:50:38 +0200924begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200925 i64out[0] := Byte($FF and (i64 shr 56));
926 i64out[1] := Byte($FF and (i64 shr 48));
927 i64out[2] := Byte($FF and (i64 shr 40));
928 i64out[3] := Byte($FF and (i64 shr 32));
929 i64out[4] := Byte($FF and (i64 shr 24));
930 i64out[5] := Byte($FF and (i64 shr 16));
931 i64out[6] := Byte($FF and (i64 shr 8));
932 i64out[7] := Byte($FF and i64);
Jens Geyer17c3ad92017-09-05 20:31:27 +0200933 FTrans.Write( @i64out, 0, 8);
Jens Geyerd5436f52014-10-03 19:50:38 +0200934end;
935
Jens Geyer17c3ad92017-09-05 20:31:27 +0200936procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +0200937begin
938 WriteByte(ShortInt(list.ElementType));
939 WriteI32(list.Count);
940end;
941
942procedure TBinaryProtocolImpl.WriteListEnd;
943begin
944
945end;
946
Jens Geyer17c3ad92017-09-05 20:31:27 +0200947procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +0200948begin
949 WriteByte(ShortInt(map.KeyType));
950 WriteByte(ShortInt(map.ValueType));
951 WriteI32(map.Count);
952end;
953
954procedure TBinaryProtocolImpl.WriteMapEnd;
955begin
956
957end;
958
Jens Geyer17c3ad92017-09-05 20:31:27 +0200959procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100960var version : Cardinal;
Jens Geyerd5436f52014-10-03 19:50:38 +0200961begin
Jens Geyerfad7fd32019-11-09 23:24:52 +0100962 if FStrictWrite then begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200963 version := VERSION_1 or Cardinal( msg.Type_);
964 WriteI32( Integer( version) );
965 WriteString( msg.Name);
966 WriteI32( msg.SeqID);
Jens Geyerfad7fd32019-11-09 23:24:52 +0100967 end else begin
Jens Geyerd5436f52014-10-03 19:50:38 +0200968 WriteString( msg.Name);
969 WriteByte(ShortInt( msg.Type_));
970 WriteI32( msg.SeqID);
971 end;
972end;
973
974procedure TBinaryProtocolImpl.WriteMessageEnd;
975begin
976
977end;
978
Jens Geyer17c3ad92017-09-05 20:31:27 +0200979procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet);
Jens Geyerd5436f52014-10-03 19:50:38 +0200980begin
981 WriteByte(ShortInt(set_.ElementType));
982 WriteI32(set_.Count);
983end;
984
985procedure TBinaryProtocolImpl.WriteSetEnd;
986begin
987
988end;
989
Jens Geyer17c3ad92017-09-05 20:31:27 +0200990procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +0200991begin
992
993end;
994
995procedure TBinaryProtocolImpl.WriteStructEnd;
996begin
997
998end;
999
1000{ TProtocolException }
1001
Jens Geyere0e32402016-04-20 21:50:48 +02001002constructor TProtocolException.HiddenCreate(const Msg: string);
Jens Geyerd5436f52014-10-03 19:50:38 +02001003begin
Jens Geyere0e32402016-04-20 21:50:48 +02001004 inherited Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001005end;
1006
Jens Geyere0e32402016-04-20 21:50:48 +02001007class function TProtocolException.Create(const Msg: string): TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001008begin
Jens Geyere0e32402016-04-20 21:50:48 +02001009 Result := TProtocolExceptionUnknown.Create(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001010end;
1011
Jens Geyere0e32402016-04-20 21:50:48 +02001012class function TProtocolException.Create: TProtocolException;
Jens Geyerd5436f52014-10-03 19:50:38 +02001013begin
Jens Geyere0e32402016-04-20 21:50:48 +02001014 Result := TProtocolExceptionUnknown.Create('');
1015end;
1016
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001017class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001018begin
1019{$WARN SYMBOL_DEPRECATED OFF}
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001020 Result := Create(aType, '');
Jens Geyere0e32402016-04-20 21:50:48 +02001021{$WARN SYMBOL_DEPRECATED DEFAULT}
1022end;
1023
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001024class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException;
Jens Geyere0e32402016-04-20 21:50:48 +02001025begin
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001026 case aType of
1027 TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg);
1028 TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg);
1029 TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg);
1030 TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg);
1031 TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
1032 TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg);
Jens Geyere0e32402016-04-20 21:50:48 +02001033 else
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001034 ASSERT( TExceptionType.UNKNOWN = aType);
Jens Geyere0e32402016-04-20 21:50:48 +02001035 Result := TProtocolExceptionUnknown.Create(msg);
1036 end;
1037end;
1038
1039{ TProtocolExceptionSpecialized }
1040
1041constructor TProtocolExceptionSpecialized.Create(const Msg: string);
1042begin
1043 inherited HiddenCreate(Msg);
Jens Geyerd5436f52014-10-03 19:50:38 +02001044end;
1045
Jens Geyer9f11c1e2019-11-09 19:39:20 +01001046{ specialized TProtocolExceptions }
1047
1048class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
1049begin
1050 result := TExceptionType.UNKNOWN;
1051end;
1052
1053class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
1054begin
1055 result := TExceptionType.INVALID_DATA;
1056end;
1057
1058class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
1059begin
1060 result := TExceptionType.NEGATIVE_SIZE;
1061end;
1062
1063class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
1064begin
1065 result := TExceptionType.SIZE_LIMIT;
1066end;
1067
1068class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
1069begin
1070 result := TExceptionType.BAD_VERSION;
1071end;
1072
1073class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
1074begin
1075 result := TExceptionType.NOT_IMPLEMENTED;
1076end;
1077
1078class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
1079begin
1080 result := TExceptionType.DEPTH_LIMIT;
1081end;
1082
Jens Geyerd5436f52014-10-03 19:50:38 +02001083{ TBinaryProtocolImpl.TFactory }
1084
Jens Geyerfad7fd32019-11-09 23:24:52 +01001085constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean);
Jens Geyerd5436f52014-10-03 19:50:38 +02001086begin
1087 inherited Create;
1088 FStrictRead := AStrictRead;
1089 FStrictWrite := AStrictWrite;
1090end;
1091
Jens Geyerd5436f52014-10-03 19:50:38 +02001092function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1093begin
1094 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1095end;
1096
1097
1098{ TProtocolDecorator }
1099
1100constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1101begin
1102 ASSERT( aProtocol <> nil);
1103 inherited Create( aProtocol.Transport);
1104 FWrappedProtocol := aProtocol;
1105end;
1106
1107
Jens Geyer17c3ad92017-09-05 20:31:27 +02001108procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage);
Jens Geyerd5436f52014-10-03 19:50:38 +02001109begin
1110 FWrappedProtocol.WriteMessageBegin( msg);
1111end;
1112
1113
1114procedure TProtocolDecorator.WriteMessageEnd;
1115begin
1116 FWrappedProtocol.WriteMessageEnd;
1117end;
1118
1119
Jens Geyer17c3ad92017-09-05 20:31:27 +02001120procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct);
Jens Geyerd5436f52014-10-03 19:50:38 +02001121begin
1122 FWrappedProtocol.WriteStructBegin( struc);
1123end;
1124
1125
1126procedure TProtocolDecorator.WriteStructEnd;
1127begin
1128 FWrappedProtocol.WriteStructEnd;
1129end;
1130
1131
Jens Geyer17c3ad92017-09-05 20:31:27 +02001132procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField);
Jens Geyerd5436f52014-10-03 19:50:38 +02001133begin
1134 FWrappedProtocol.WriteFieldBegin( field);
1135end;
1136
1137
1138procedure TProtocolDecorator.WriteFieldEnd;
1139begin
1140 FWrappedProtocol.WriteFieldEnd;
1141end;
1142
1143
1144procedure TProtocolDecorator.WriteFieldStop;
1145begin
1146 FWrappedProtocol.WriteFieldStop;
1147end;
1148
1149
Jens Geyer17c3ad92017-09-05 20:31:27 +02001150procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap);
Jens Geyerd5436f52014-10-03 19:50:38 +02001151begin
1152 FWrappedProtocol.WriteMapBegin( map);
1153end;
1154
1155
1156procedure TProtocolDecorator.WriteMapEnd;
1157begin
1158 FWrappedProtocol.WriteMapEnd;
1159end;
1160
1161
Jens Geyer17c3ad92017-09-05 20:31:27 +02001162procedure TProtocolDecorator.WriteListBegin( const list: TThriftList);
Jens Geyerd5436f52014-10-03 19:50:38 +02001163begin
1164 FWrappedProtocol.WriteListBegin( list);
1165end;
1166
1167
1168procedure TProtocolDecorator.WriteListEnd();
1169begin
1170 FWrappedProtocol.WriteListEnd();
1171end;
1172
1173
Jens Geyer17c3ad92017-09-05 20:31:27 +02001174procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet );
Jens Geyerd5436f52014-10-03 19:50:38 +02001175begin
1176 FWrappedProtocol.WriteSetBegin( set_);
1177end;
1178
1179
1180procedure TProtocolDecorator.WriteSetEnd();
1181begin
1182 FWrappedProtocol.WriteSetEnd();
1183end;
1184
1185
1186procedure TProtocolDecorator.WriteBool( b: Boolean);
1187begin
1188 FWrappedProtocol.WriteBool( b);
1189end;
1190
1191
1192procedure TProtocolDecorator.WriteByte( b: ShortInt);
1193begin
1194 FWrappedProtocol.WriteByte( b);
1195end;
1196
1197
1198procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1199begin
1200 FWrappedProtocol.WriteI16( i16);
1201end;
1202
1203
1204procedure TProtocolDecorator.WriteI32( i32: Integer);
1205begin
1206 FWrappedProtocol.WriteI32( i32);
1207end;
1208
1209
1210procedure TProtocolDecorator.WriteI64( const i64: Int64);
1211begin
1212 FWrappedProtocol.WriteI64( i64);
1213end;
1214
1215
1216procedure TProtocolDecorator.WriteDouble( const d: Double);
1217begin
1218 FWrappedProtocol.WriteDouble( d);
1219end;
1220
1221
1222procedure TProtocolDecorator.WriteString( const s: string );
1223begin
1224 FWrappedProtocol.WriteString( s);
1225end;
1226
1227
1228procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1229begin
1230 FWrappedProtocol.WriteAnsiString( s);
1231end;
1232
1233
1234procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1235begin
1236 FWrappedProtocol.WriteBinary( b);
1237end;
1238
1239
Jens Geyer17c3ad92017-09-05 20:31:27 +02001240function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
Jens Geyerd5436f52014-10-03 19:50:38 +02001241begin
1242 result := FWrappedProtocol.ReadMessageBegin;
1243end;
1244
1245
1246procedure TProtocolDecorator.ReadMessageEnd();
1247begin
1248 FWrappedProtocol.ReadMessageEnd();
1249end;
1250
1251
Jens Geyer17c3ad92017-09-05 20:31:27 +02001252function TProtocolDecorator.ReadStructBegin: TThriftStruct;
Jens Geyerd5436f52014-10-03 19:50:38 +02001253begin
1254 result := FWrappedProtocol.ReadStructBegin;
1255end;
1256
1257
1258procedure TProtocolDecorator.ReadStructEnd;
1259begin
1260 FWrappedProtocol.ReadStructEnd;
1261end;
1262
1263
Jens Geyer17c3ad92017-09-05 20:31:27 +02001264function TProtocolDecorator.ReadFieldBegin: TThriftField;
Jens Geyerd5436f52014-10-03 19:50:38 +02001265begin
1266 result := FWrappedProtocol.ReadFieldBegin;
1267end;
1268
1269
1270procedure TProtocolDecorator.ReadFieldEnd();
1271begin
1272 FWrappedProtocol.ReadFieldEnd();
1273end;
1274
1275
Jens Geyer17c3ad92017-09-05 20:31:27 +02001276function TProtocolDecorator.ReadMapBegin: TThriftMap;
Jens Geyerd5436f52014-10-03 19:50:38 +02001277begin
1278 result := FWrappedProtocol.ReadMapBegin;
1279end;
1280
1281
1282procedure TProtocolDecorator.ReadMapEnd();
1283begin
1284 FWrappedProtocol.ReadMapEnd();
1285end;
1286
1287
Jens Geyer17c3ad92017-09-05 20:31:27 +02001288function TProtocolDecorator.ReadListBegin: TThriftList;
Jens Geyerd5436f52014-10-03 19:50:38 +02001289begin
1290 result := FWrappedProtocol.ReadListBegin;
1291end;
1292
1293
1294procedure TProtocolDecorator.ReadListEnd();
1295begin
1296 FWrappedProtocol.ReadListEnd();
1297end;
1298
1299
Jens Geyer17c3ad92017-09-05 20:31:27 +02001300function TProtocolDecorator.ReadSetBegin: TThriftSet;
Jens Geyerd5436f52014-10-03 19:50:38 +02001301begin
1302 result := FWrappedProtocol.ReadSetBegin;
1303end;
1304
1305
1306procedure TProtocolDecorator.ReadSetEnd();
1307begin
1308 FWrappedProtocol.ReadSetEnd();
1309end;
1310
1311
1312function TProtocolDecorator.ReadBool: Boolean;
1313begin
1314 result := FWrappedProtocol.ReadBool;
1315end;
1316
1317
1318function TProtocolDecorator.ReadByte: ShortInt;
1319begin
1320 result := FWrappedProtocol.ReadByte;
1321end;
1322
1323
1324function TProtocolDecorator.ReadI16: SmallInt;
1325begin
1326 result := FWrappedProtocol.ReadI16;
1327end;
1328
1329
1330function TProtocolDecorator.ReadI32: Integer;
1331begin
1332 result := FWrappedProtocol.ReadI32;
1333end;
1334
1335
1336function TProtocolDecorator.ReadI64: Int64;
1337begin
1338 result := FWrappedProtocol.ReadI64;
1339end;
1340
1341
1342function TProtocolDecorator.ReadDouble:Double;
1343begin
1344 result := FWrappedProtocol.ReadDouble;
1345end;
1346
1347
1348function TProtocolDecorator.ReadBinary: TBytes;
1349begin
1350 result := FWrappedProtocol.ReadBinary;
1351end;
1352
1353
1354function TProtocolDecorator.ReadString: string;
1355begin
1356 result := FWrappedProtocol.ReadString;
1357end;
1358
1359
1360function TProtocolDecorator.ReadAnsiString: AnsiString;
1361begin
1362 result := FWrappedProtocol.ReadAnsiString;
1363end;
1364
1365
Jens Geyer17c3ad92017-09-05 20:31:27 +02001366{ Init helper functions }
1367
1368procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer);
1369begin
1370 rec.Name := AName;
1371 rec.Type_ := AMessageType;
1372 rec.SeqID := ASeqID;
1373end;
1374
1375
1376procedure Init( var rec : TThriftStruct; const AName: string = '');
1377begin
1378 rec.Name := AName;
1379end;
1380
1381
1382procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt);
1383begin
1384 rec.Name := AName;
1385 rec.Type_ := AType;
1386 rec.Id := AId;
1387end;
1388
1389
1390procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer);
1391begin
1392 rec.ValueType := AValueType;
1393 rec.KeyType := AKeyType;
1394 rec.Count := ACount;
1395end;
1396
1397
1398procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer);
1399begin
1400 rec.Count := ACount;
1401 rec.ElementType := AElementType;
1402end;
1403
1404
1405procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer);
1406begin
1407 rec.Count := ACount;
1408 rec.ElementType := AElementType;
1409end;
1410
1411
1412
1413
Jens Geyerd5436f52014-10-03 19:50:38 +02001414
1415end.
1416