blob: 33e17d78fad9b20d33232caf535e9214bf4a2a7e [file] [log] [blame]
Jake Farrell7ae13e12011-10-18 14:35:26 +00001(*
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,
30 Thrift.Stream,
31 Thrift.Collections,
32 Thrift.Transport;
33
34type
35
36 TType = (
37 Stop = 0,
38 Void = 1,
39 Bool_ = 2,
40 Byte_ = 3,
41 Double_ = 4,
42 I16 = 6,
43 I32 = 8,
44 I64 = 10,
45 String_ = 11,
46 Struct = 12,
47 Map = 13,
48 Set_ = 14,
49 List = 15
50 );
51
52 TMessageType = (
53 Call = 1,
54 Reply = 2,
55 Exception = 3,
56 Oneway = 4
57 );
58
59 IProtocol = interface;
60 IStruct = interface;
61
62 IProtocolFactory = interface
63 ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}']
Roger Meier333bbf32012-01-08 21:51:08 +000064 function GetProtocol( const trans: ITransport): IProtocol;
Jake Farrell7ae13e12011-10-18 14:35:26 +000065 end;
66
67 TThriftStringBuilder = class( TStringBuilder)
68 public
69 function Append(const Value: TBytes): TStringBuilder; overload;
70 function Append(const Value: IThriftContainer): TStringBuilder; overload;
71 end;
72
73 TProtocolException = class( Exception )
74 public
75 const
76 UNKNOWN : Integer = 0;
77 INVALID_DATA : Integer = 1;
78 NEGATIVE_SIZE : Integer = 2;
79 SIZE_LIMIT : Integer = 3;
80 BAD_VERSION : Integer = 4;
81 NOT_IMPLEMENTED : Integer = 5;
82 protected
83 FType : Integer;
84 public
85 constructor Create; overload;
86 constructor Create( type_: Integer ); overload;
87 constructor Create( type_: Integer; const msg: string); overload;
88 end;
89
90 IMap = interface
91 ['{30531D97-7E06-4233-B800-C3F53CCD23E7}']
92 function GetKeyType: TType;
93 procedure SetKeyType( Value: TType);
94 function GetValueType: TType;
95 procedure SetValueType( Value: TType);
96 function GetCount: Integer;
97 procedure SetCount( Value: Integer);
98 property KeyType: TType read GetKeyType write SetKeyType;
99 property ValueType: TType read GetValueType write SetValueType;
100 property Count: Integer read GetCount write SetCount;
101 end;
102
103 TMapImpl = class( TInterfacedObject, IMap)
104 private
105 FValueType: TType;
106 FKeyType: TType;
107 FCount: Integer;
108 protected
109 function GetKeyType: TType;
110 procedure SetKeyType( Value: TType);
111 function GetValueType: TType;
112 procedure SetValueType( Value: TType);
113 function GetCount: Integer;
114 procedure SetCount( Value: Integer);
115 public
116 constructor Create( AValueType: TType; AKeyType: TType; ACount: Integer); overload;
117 constructor Create; overload;
118 end;
119
120 IList = interface
121 ['{6763E1EA-A934-4472-904F-0083980B9B87}']
122 function GetElementType: TType;
123 procedure SetElementType( Value: TType);
124 function GetCount: Integer;
125 procedure SetCount( Value: Integer);
126 property ElementType: TType read GetElementType write SetElementType;
127 property Count: Integer read GetCount write SetCount;
128 end;
129
130 TListImpl = class( TInterfacedObject, IList)
131 private
132 FElementType: TType;
133 FCount : Integer;
134 protected
135 function GetElementType: TType;
136 procedure SetElementType( Value: TType);
137 function GetCount: Integer;
138 procedure SetCount( Value: Integer);
139 public
140 constructor Create( AElementType: TType; ACount: Integer); overload;
141 constructor Create; overload;
142 end;
143
144 ISet = interface
145 ['{A8671700-7514-4C1E-8A05-62786872005F}']
146 function GetElementType: TType;
147 procedure SetElementType( Value: TType);
148 function GetCount: Integer;
149 procedure SetCount( Value: Integer);
150 property ElementType: TType read GetElementType write SetElementType;
151 property Count: Integer read GetCount write SetCount;
152 end;
153
154 TSetImpl = class( TInterfacedObject, ISet)
155 private
156 FCount: Integer;
157 FElementType: TType;
158 protected
159 function GetElementType: TType;
160 procedure SetElementType( Value: TType);
161 function GetCount: Integer;
162 procedure SetCount( Value: Integer);
163 public
164 constructor Create( AElementType: TType; ACount: Integer); overload;
165 constructor Create; overload;
166 end;
167
168 IMessage = interface
169 ['{9E368B4A-B1FA-43E7-8CF5-56C66D256CA7}']
170 function GetName: string;
171 procedure SetName( const Value: string);
172 function GetType: TMessageType;
173 procedure SetType( Value: TMessageType);
174 function GetSeqID: Integer;
175 procedure SetSeqID( Value: Integer);
176 property Name: string read GetName write SetName;
177 property Type_: TMessageType read GetType write SetType;
178 property SeqID: Integer read GetSeqID write SetSeqID;
179 end;
180
181 TMessageImpl = class( TInterfacedObject, IMessage )
182 private
183 FName: string;
184 FMessageType: TMessageType;
185 FSeqID: Integer;
186 protected
187 function GetName: string;
188 procedure SetName( const Value: string);
189 function GetType: TMessageType;
190 procedure SetType( Value: TMessageType);
191 function GetSeqID: Integer;
192 procedure SetSeqID( Value: Integer);
193 public
194 property Name: string read FName write FName;
195 property Type_: TMessageType read FMessageType write FMessageType;
196 property SeqID: Integer read FSeqID write FSeqID;
197 constructor Create( AName: string; AMessageType: TMessageType; ASeqID: Integer); overload;
198 constructor Create; overload;
199 end;
200
201 IField = interface
202 ['{F0D43BE5-7883-442E-83FF-0580CC632B72}']
203 function GetName: string;
204 procedure SetName( const Value: string);
205 function GetType: TType;
206 procedure SetType( Value: TType);
207 function GetId: SmallInt;
208 procedure SetId( Value: SmallInt);
209 property Name: string read GetName write SetName;
210 property Type_: TType read GetType write SetType;
211 property Id: SmallInt read GetId write SetId;
212 end;
213
214 TFieldImpl = class( TInterfacedObject, IField)
215 private
216 FName : string;
217 FType : TType;
218 FId : SmallInt;
219 protected
220 function GetName: string;
221 procedure SetName( const Value: string);
222 function GetType: TType;
223 procedure SetType( Value: TType);
224 function GetId: SmallInt;
225 procedure SetId( Value: SmallInt);
226 public
227 constructor Create( const AName: string; const AType: TType; AId: SmallInt); overload;
228 constructor Create; overload;
229 end;
230
231 TProtocolUtil = class
232 public
233 class procedure Skip( prot: IProtocol; type_: TType);
234 end;
235
236 IProtocol = interface
237 ['{FD95C151-1527-4C96-8134-B902BFC4B4FC}']
238 function GetTransport: ITransport;
Roger Meier333bbf32012-01-08 21:51:08 +0000239 procedure WriteMessageBegin( const msg: IMessage);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000240 procedure WriteMessageEnd;
Roger Meier333bbf32012-01-08 21:51:08 +0000241 procedure WriteStructBegin( const struc: IStruct);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000242 procedure WriteStructEnd;
Roger Meier333bbf32012-01-08 21:51:08 +0000243 procedure WriteFieldBegin( const field: IField);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000244 procedure WriteFieldEnd;
245 procedure WriteFieldStop;
Roger Meier333bbf32012-01-08 21:51:08 +0000246 procedure WriteMapBegin( const map: IMap);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000247 procedure WriteMapEnd;
Roger Meier333bbf32012-01-08 21:51:08 +0000248 procedure WriteListBegin( const list: IList);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000249 procedure WriteListEnd();
Roger Meier333bbf32012-01-08 21:51:08 +0000250 procedure WriteSetBegin( const set_: ISet );
Jake Farrell7ae13e12011-10-18 14:35:26 +0000251 procedure WriteSetEnd();
252 procedure WriteBool( b: Boolean);
253 procedure WriteByte( b: ShortInt);
254 procedure WriteI16( i16: SmallInt);
255 procedure WriteI32( i32: Integer);
Roger Meier333bbf32012-01-08 21:51:08 +0000256 procedure WriteI64( const i64: Int64);
257 procedure WriteDouble( const d: Double);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000258 procedure WriteString( const s: string );
259 procedure WriteAnsiString( const s: AnsiString);
260 procedure WriteBinary( const b: TBytes);
261
262 function ReadMessageBegin: IMessage;
263 procedure ReadMessageEnd();
264 function ReadStructBegin: IStruct;
265 procedure ReadStructEnd;
266 function ReadFieldBegin: IField;
267 procedure ReadFieldEnd();
268 function ReadMapBegin: IMap;
269 procedure ReadMapEnd();
270 function ReadListBegin: IList;
271 procedure ReadListEnd();
272 function ReadSetBegin: ISet;
273 procedure ReadSetEnd();
274 function ReadBool: Boolean;
275 function ReadByte: ShortInt;
276 function ReadI16: SmallInt;
277 function ReadI32: Integer;
278 function ReadI64: Int64;
279 function ReadDouble:Double;
280 function ReadBinary: TBytes;
281 function ReadString: string;
282 function ReadAnsiString: AnsiString;
283 property Transport: ITransport read GetTransport;
284 end;
285
286 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
287 protected
288 FTrans : ITransport;
289 function GetTransport: ITransport;
290 public
Roger Meier333bbf32012-01-08 21:51:08 +0000291 procedure WriteMessageBegin( const msg: IMessage); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000292 procedure WriteMessageEnd; virtual; abstract;
Roger Meier333bbf32012-01-08 21:51:08 +0000293 procedure WriteStructBegin( const struc: IStruct); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000294 procedure WriteStructEnd; virtual; abstract;
Roger Meier333bbf32012-01-08 21:51:08 +0000295 procedure WriteFieldBegin( const field: IField); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000296 procedure WriteFieldEnd; virtual; abstract;
297 procedure WriteFieldStop; virtual; abstract;
Roger Meier333bbf32012-01-08 21:51:08 +0000298 procedure WriteMapBegin( const map: IMap); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000299 procedure WriteMapEnd; virtual; abstract;
Roger Meier333bbf32012-01-08 21:51:08 +0000300 procedure WriteListBegin( const list: IList); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000301 procedure WriteListEnd(); virtual; abstract;
Roger Meier333bbf32012-01-08 21:51:08 +0000302 procedure WriteSetBegin( const set_: ISet ); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000303 procedure WriteSetEnd(); virtual; abstract;
304 procedure WriteBool( b: Boolean); virtual; abstract;
305 procedure WriteByte( b: ShortInt); virtual; abstract;
306 procedure WriteI16( i16: SmallInt); virtual; abstract;
307 procedure WriteI32( i32: Integer); virtual; abstract;
Roger Meier333bbf32012-01-08 21:51:08 +0000308 procedure WriteI64( const i64: Int64); virtual; abstract;
309 procedure WriteDouble( const d: Double); virtual; abstract;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000310 procedure WriteString( const s: string ); virtual;
311 procedure WriteAnsiString( const s: AnsiString); virtual;
312 procedure WriteBinary( const b: TBytes); virtual; abstract;
313
314 function ReadMessageBegin: IMessage; virtual; abstract;
315 procedure ReadMessageEnd(); virtual; abstract;
316 function ReadStructBegin: IStruct; virtual; abstract;
317 procedure ReadStructEnd; virtual; abstract;
318 function ReadFieldBegin: IField; virtual; abstract;
319 procedure ReadFieldEnd(); virtual; abstract;
320 function ReadMapBegin: IMap; virtual; abstract;
321 procedure ReadMapEnd(); virtual; abstract;
322 function ReadListBegin: IList; virtual; abstract;
323 procedure ReadListEnd(); virtual; abstract;
324 function ReadSetBegin: ISet; virtual; abstract;
325 procedure ReadSetEnd(); virtual; abstract;
326 function ReadBool: Boolean; virtual; abstract;
327 function ReadByte: ShortInt; virtual; abstract;
328 function ReadI16: SmallInt; virtual; abstract;
329 function ReadI32: Integer; virtual; abstract;
330 function ReadI64: Int64; virtual; abstract;
331 function ReadDouble:Double; virtual; abstract;
332 function ReadBinary: TBytes; virtual; abstract;
333 function ReadString: string; virtual;
334 function ReadAnsiString: AnsiString; virtual;
335
336 property Transport: ITransport read GetTransport;
337
338 constructor Create( trans: ITransport );
339 end;
340
341 IBase = interface
342 ['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
343 function ToString: string;
Roger Meier333bbf32012-01-08 21:51:08 +0000344 procedure Read( const iprot: IProtocol);
345 procedure Write( const iprot: IProtocol);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000346 end;
347
348 IStruct = interface
349 ['{5DCE39AA-C916-4BC7-A79B-96A0C36B2220}']
350 procedure SetName(const Value: string);
351 function GetName: string;
352 property Name: string read GetName write SetName;
353 end;
354
355 TStructImpl = class( TInterfacedObject, IStruct )
356 private
357 FName: string;
358 protected
359 function GetName: string;
360 procedure SetName(const Value: string);
361 public
362 constructor Create( const AName: string);
363 end;
364
365 TBinaryProtocolImpl = class( TProtocolImpl )
366 protected
367 const
368 VERSION_MASK : Cardinal = $ffff0000;
369 VERSION_1 : Cardinal = $80010000;
370 protected
371 FStrictRead : Boolean;
372 FStrictWrite : Boolean;
373 FReadLength : Integer;
374 FCheckReadLength : Boolean;
375
376 private
377 function ReadAll( var buf: TBytes; off: Integer; len: Integer ): Integer;
378 function ReadStringBody( size: Integer): string;
379 procedure CheckReadLength( len: Integer );
380 public
381
382 type
383 TFactory = class( TInterfacedObject, IProtocolFactory)
384 protected
385 FStrictRead : Boolean;
386 FStrictWrite : Boolean;
387 public
Roger Meier333bbf32012-01-08 21:51:08 +0000388 function GetProtocol( const trans: ITransport): IProtocol;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000389 constructor Create( AStrictRead, AStrictWrite: Boolean ); overload;
390 constructor Create; overload;
391 end;
392
Roger Meier333bbf32012-01-08 21:51:08 +0000393 constructor Create( const trans: ITransport); overload;
394 constructor Create( const trans: ITransport; strictRead: Boolean; strictWrite: Boolean); overload;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000395
Roger Meier333bbf32012-01-08 21:51:08 +0000396 procedure WriteMessageBegin( const msg: IMessage); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000397 procedure WriteMessageEnd; override;
Roger Meier333bbf32012-01-08 21:51:08 +0000398 procedure WriteStructBegin( const struc: IStruct); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000399 procedure WriteStructEnd; override;
Roger Meier333bbf32012-01-08 21:51:08 +0000400 procedure WriteFieldBegin( const field: IField); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000401 procedure WriteFieldEnd; override;
402 procedure WriteFieldStop; override;
Roger Meier333bbf32012-01-08 21:51:08 +0000403 procedure WriteMapBegin( const map: IMap); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000404 procedure WriteMapEnd; override;
Roger Meier333bbf32012-01-08 21:51:08 +0000405 procedure WriteListBegin( const list: IList); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000406 procedure WriteListEnd(); override;
Roger Meier333bbf32012-01-08 21:51:08 +0000407 procedure WriteSetBegin( const set_: ISet ); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000408 procedure WriteSetEnd(); override;
409 procedure WriteBool( b: Boolean); override;
410 procedure WriteByte( b: ShortInt); override;
411 procedure WriteI16( i16: SmallInt); override;
412 procedure WriteI32( i32: Integer); override;
Roger Meier333bbf32012-01-08 21:51:08 +0000413 procedure WriteI64( const i64: Int64); override;
414 procedure WriteDouble( const d: Double); override;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000415 procedure WriteBinary( const b: TBytes); override;
416
417 function ReadMessageBegin: IMessage; override;
418 procedure ReadMessageEnd(); override;
419 function ReadStructBegin: IStruct; override;
420 procedure ReadStructEnd; override;
421 function ReadFieldBegin: IField; override;
422 procedure ReadFieldEnd(); override;
423 function ReadMapBegin: IMap; override;
424 procedure ReadMapEnd(); override;
425 function ReadListBegin: IList; override;
426 procedure ReadListEnd(); override;
427 function ReadSetBegin: ISet; override;
428 procedure ReadSetEnd(); override;
429 function ReadBool: Boolean; override;
430 function ReadByte: ShortInt; override;
431 function ReadI16: SmallInt; override;
432 function ReadI32: Integer; override;
433 function ReadI64: Int64; override;
434 function ReadDouble:Double; override;
435 function ReadBinary: TBytes; override;
436
437 procedure SetReadLength( readLength: Integer );
438 end;
439
440implementation
441
Roger Meier333bbf32012-01-08 21:51:08 +0000442function ConvertInt64ToDouble( const n: Int64): Double;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000443begin
444 ASSERT( SizeOf(n) = SizeOf(Result));
445 System.Move( n, Result, SizeOf(Result));
446end;
447
Roger Meier333bbf32012-01-08 21:51:08 +0000448function ConvertDoubleToInt64( const d: Double): Int64;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000449begin
450 ASSERT( SizeOf(d) = SizeOf(Result));
451 System.Move( d, Result, SizeOf(Result));
452end;
453
454{ TFieldImpl }
455
456constructor TFieldImpl.Create(const AName: string; const AType: TType;
457 AId: SmallInt);
458begin
459 FName := AName;
460 FType := AType;
461 FId := AId;
462end;
463
464constructor TFieldImpl.Create;
465begin
466 FName := '';
467 FType := Low(TType);
468 FId := 0;
469end;
470
471function TFieldImpl.GetId: SmallInt;
472begin
473 Result := FId;
474end;
475
476function TFieldImpl.GetName: string;
477begin
478 Result := FName;
479end;
480
481function TFieldImpl.GetType: TType;
482begin
483 Result := FType;
484end;
485
486procedure TFieldImpl.SetId(Value: SmallInt);
487begin
488 FId := Value;
489end;
490
491procedure TFieldImpl.SetName(const Value: string);
492begin
493 FName := Value;
494end;
495
496procedure TFieldImpl.SetType(Value: TType);
497begin
498 FType := Value;
499end;
500
501{ TProtocolImpl }
502
503constructor TProtocolImpl.Create(trans: ITransport);
504begin
505 inherited Create;
506 FTrans := trans;
507end;
508
509function TProtocolImpl.GetTransport: ITransport;
510begin
511 Result := FTrans;
512end;
513
514function TProtocolImpl.ReadAnsiString: AnsiString;
515var
516 b : TBytes;
517 len : Integer;
518begin
519 Result := '';
520 b := ReadBinary;
521 len := Length( b );
522 if len > 0 then
523 begin
524 SetLength( Result, len);
525 System.Move( b[0], Pointer(Result)^, len );
526 end;
527end;
528
529function TProtocolImpl.ReadString: string;
530begin
531 Result := TEncoding.UTF8.GetString( ReadBinary );
532end;
533
534procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
535var
536 b : TBytes;
537 len : Integer;
538begin
539 len := Length(s);
540 SetLength( b, len);
541 if len > 0 then
542 begin
543 System.Move( Pointer(s)^, b[0], len );
544 end;
545 WriteBinary( b );
546end;
547
548procedure TProtocolImpl.WriteString(const s: string);
549var
550 b : TBytes;
551begin
552 b := TEncoding.UTF8.GetBytes(s);
553 WriteBinary( b );
554end;
555
556{ TProtocolUtil }
557
558class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
Jake Farrell6cd63ec2012-08-29 02:04:35 +0000559var field : IField;
560 map : IMap;
561 set_ : ISet;
562 list : IList;
563 i : Integer;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000564begin
Jake Farrell6cd63ec2012-08-29 02:04:35 +0000565 case type_ of
566 // simple types
567 TType.Bool_ : prot.ReadBool();
568 TType.Byte_ : prot.ReadByte();
569 TType.I16 : prot.ReadI16();
570 TType.I32 : prot.ReadI32();
571 TType.I64 : prot.ReadI64();
572 TType.Double_ : prot.ReadDouble();
573 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
Jake Farrell7ae13e12011-10-18 14:35:26 +0000574
Jake Farrell6cd63ec2012-08-29 02:04:35 +0000575 // structured types
576 TType.Struct : begin
577 prot.ReadStructBegin();
578 while TRUE do begin
579 field := prot.ReadFieldBegin();
580 if (field.Type_ = TType.Stop) then Break;
581 Skip(prot, field.Type_);
582 prot.ReadFieldEnd();
583 end;
584 prot.ReadStructEnd();
585 end;
586
587 TType.Map : begin
588 map := prot.ReadMapBegin();
589 for i := 0 to map.Count-1 do begin
590 Skip(prot, map.KeyType);
591 Skip(prot, map.ValueType);
592 end;
593 prot.ReadMapEnd();
594 end;
595
596 TType.Set_ : begin
597 set_ := prot.ReadSetBegin();
598 for i := 0 to set_.Count-1
599 do Skip( prot, set_.ElementType);
600 prot.ReadSetEnd();
601 end;
602
603 TType.List : begin
604 list := prot.ReadListBegin();
605 for i := 0 to list.Count-1
606 do Skip( prot, list.ElementType);
607 prot.ReadListEnd();
608 end;
609
610 else
611 ASSERT( FALSE); // any new types?
612 end;
Jake Farrell7ae13e12011-10-18 14:35:26 +0000613end;
614
615{ TStructImpl }
616
617constructor TStructImpl.Create(const AName: string);
618begin
619 inherited Create;
620 FName := AName;
621end;
622
623function TStructImpl.GetName: string;
624begin
625 Result := FName;
626end;
627
628procedure TStructImpl.SetName(const Value: string);
629begin
630 FName := Value;
631end;
632
633{ TMapImpl }
634
635constructor TMapImpl.Create(AValueType, AKeyType: TType; ACount: Integer);
636begin
637 inherited Create;
638 FValueType := AValueType;
639 FKeyType := AKeyType;
640 FCount := ACount;
641end;
642
643constructor TMapImpl.Create;
644begin
645
646end;
647
648function TMapImpl.GetCount: Integer;
649begin
650 Result := FCount;
651end;
652
653function TMapImpl.GetKeyType: TType;
654begin
655 Result := FKeyType;
656end;
657
658function TMapImpl.GetValueType: TType;
659begin
660 Result := FValueType;
661end;
662
663procedure TMapImpl.SetCount(Value: Integer);
664begin
665 FCount := Value;
666end;
667
668procedure TMapImpl.SetKeyType(Value: TType);
669begin
670 FKeyType := Value;
671end;
672
673procedure TMapImpl.SetValueType(Value: TType);
674begin
675 FValueType := Value;
676end;
677
678{ IMessage }
679
680constructor TMessageImpl.Create(AName: string; AMessageType: TMessageType;
681 ASeqID: Integer);
682begin
683 inherited Create;
684 FName := AName;
685 FMessageType := AMessageType;
686 FSeqID := ASeqID;
687end;
688
689constructor TMessageImpl.Create;
690begin
691 inherited;
692end;
693
694function TMessageImpl.GetName: string;
695begin
696 Result := FName;
697end;
698
699function TMessageImpl.GetSeqID: Integer;
700begin
701 Result := FSeqID;
702end;
703
704function TMessageImpl.GetType: TMessageType;
705begin
706 Result := FMessageType;
707end;
708
709procedure TMessageImpl.SetName(const Value: string);
710begin
711 FName := Value;
712end;
713
714procedure TMessageImpl.SetSeqID(Value: Integer);
715begin
716 FSeqID := Value;
717end;
718
719procedure TMessageImpl.SetType(Value: TMessageType);
720begin
721 FMessageType := Value;
722end;
723
724{ ISet }
725
726constructor TSetImpl.Create( AElementType: TType; ACount: Integer);
727begin
728 inherited Create;
729 FCount := ACount;
730 FElementType := AElementType;
731end;
732
733constructor TSetImpl.Create;
734begin
735
736end;
737
738function TSetImpl.GetCount: Integer;
739begin
740 Result := FCount;
741end;
742
743function TSetImpl.GetElementType: TType;
744begin
745 Result := FElementType;
746end;
747
748procedure TSetImpl.SetCount(Value: Integer);
749begin
750 FCount := Value;
751end;
752
753procedure TSetImpl.SetElementType(Value: TType);
754begin
755 FElementType := Value;
756end;
757
758{ IList }
759
760constructor TListImpl.Create( AElementType: TType; ACount: Integer);
761begin
762 inherited Create;
763 FCount := ACount;
764 FElementType := AElementType;
765end;
766
767constructor TListImpl.Create;
768begin
769
770end;
771
772function TListImpl.GetCount: Integer;
773begin
774 Result := FCount;
775end;
776
777function TListImpl.GetElementType: TType;
778begin
779 Result := FElementType;
780end;
781
782procedure TListImpl.SetCount(Value: Integer);
783begin
784 FCount := Value;
785end;
786
787procedure TListImpl.SetElementType(Value: TType);
788begin
789 FElementType := Value;
790end;
791
792{ TBinaryProtocolImpl }
793
Roger Meier333bbf32012-01-08 21:51:08 +0000794constructor TBinaryProtocolImpl.Create( const trans: ITransport);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000795begin
796 Create( trans, False, True);
797end;
798
799procedure TBinaryProtocolImpl.CheckReadLength(len: Integer);
800begin
801 if FCheckReadLength then
802 begin
803 Dec( FReadLength, len);
804 if FReadLength < 0 then
805 begin
806 raise Exception.Create( 'Message length exceeded: ' + IntToStr( len ) );
807 end;
808 end;
809end;
810
Roger Meier333bbf32012-01-08 21:51:08 +0000811constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead,
Jake Farrell7ae13e12011-10-18 14:35:26 +0000812 strictWrite: Boolean);
813begin
814 inherited Create( trans );
815 FStrictRead := strictRead;
816 FStrictWrite := strictWrite;
817end;
818
819function TBinaryProtocolImpl.ReadAll( var buf: TBytes; off,
820 len: Integer): Integer;
821begin
822 CheckReadLength( len );
823 Result := FTrans.ReadAll( buf, off, len );
824end;
825
826function TBinaryProtocolImpl.ReadBinary: TBytes;
827var
828 size : Integer;
829 buf : TBytes;
830begin
831 size := ReadI32;
832 CheckReadLength( size );
833 SetLength( buf, size );
834 FTrans.ReadAll( buf, 0, size);
835 Result := buf;
836end;
837
838function TBinaryProtocolImpl.ReadBool: Boolean;
839begin
840 Result := ReadByte = 1;
841end;
842
843function TBinaryProtocolImpl.ReadByte: ShortInt;
844var
845 bin : TBytes;
846begin
847 SetLength( bin, 1);
848 ReadAll( bin, 0, 1 );
849 Result := ShortInt( bin[0]);
850end;
851
852function TBinaryProtocolImpl.ReadDouble: Double;
853begin
854 Result := ConvertInt64ToDouble( ReadI64 )
855end;
856
857function TBinaryProtocolImpl.ReadFieldBegin: IField;
858var
859 field : IField;
860begin
861 field := TFieldImpl.Create;
862 field.Type_ := TType( ReadByte);
863 if ( field.Type_ <> TType.Stop ) then
864 begin
865 field.Id := ReadI16;
866 end;
867 Result := field;
868end;
869
870procedure TBinaryProtocolImpl.ReadFieldEnd;
871begin
872
873end;
874
875function TBinaryProtocolImpl.ReadI16: SmallInt;
876var
877 i16in : TBytes;
878begin
879 SetLength( i16in, 2 );
880 ReadAll( i16in, 0, 2);
881 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
882end;
883
884function TBinaryProtocolImpl.ReadI32: Integer;
885var
886 i32in : TBytes;
887begin
888 SetLength( i32in, 4 );
889 ReadAll( i32in, 0, 4);
890
891 Result := Integer(
892 ((i32in[0] and $FF) shl 24) or
893 ((i32in[1] and $FF) shl 16) or
894 ((i32in[2] and $FF) shl 8) or
895 (i32in[3] and $FF));
896
897end;
898
899function TBinaryProtocolImpl.ReadI64: Int64;
900var
901 i64in : TBytes;
902begin
903 SetLength( i64in, 8);
904 ReadAll( i64in, 0, 8);
905 Result :=
906 (Int64( i64in[0] and $FF) shl 56) or
907 (Int64( i64in[1] and $FF) shl 48) or
908 (Int64( i64in[2] and $FF) shl 40) or
909 (Int64( i64in[3] and $FF) shl 32) or
910 (Int64( i64in[4] and $FF) shl 24) or
911 (Int64( i64in[5] and $FF) shl 16) or
912 (Int64( i64in[6] and $FF) shl 8) or
913 (Int64( i64in[7] and $FF));
914end;
915
916function TBinaryProtocolImpl.ReadListBegin: IList;
917var
918 list : IList;
919begin
920 list := TListImpl.Create;
921 list.ElementType := TType( ReadByte );
922 list.Count := ReadI32;
923 Result := list;
924end;
925
926procedure TBinaryProtocolImpl.ReadListEnd;
927begin
928
929end;
930
931function TBinaryProtocolImpl.ReadMapBegin: IMap;
932var
933 map : IMap;
934begin
935 map := TMapImpl.Create;
936 map.KeyType := TType( ReadByte );
937 map.ValueType := TType( ReadByte );
938 map.Count := ReadI32;
939 Result := map;
940end;
941
942procedure TBinaryProtocolImpl.ReadMapEnd;
943begin
944
945end;
946
947function TBinaryProtocolImpl.ReadMessageBegin: IMessage;
948var
949 size : Integer;
950 version : Integer;
951 message : IMessage;
952begin
953 message := TMessageImpl.Create;
954 size := ReadI32;
955 if (size < 0) then
956 begin
957 version := size and Integer( VERSION_MASK);
958 if ( version <> Integer( VERSION_1)) then
959 begin
960 raise TProtocolException.Create(TProtocolException.BAD_VERSION, 'Bad version in ReadMessageBegin: ' + IntToStr(version) );
961 end;
962 message.Type_ := TMessageType( size and $000000ff);
963 message.Name := ReadString;
964 message.SeqID := ReadI32;
965 end else
966 begin
967 if FStrictRead then
968 begin
969 raise TProtocolException.Create( TProtocolException.BAD_VERSION, 'Missing version in readMessageBegin, old client?' );
970 end;
971 message.Name := ReadStringBody( size );
972 message.Type_ := TMessageType( ReadByte );
973 message.SeqID := ReadI32;
974 end;
975 Result := message;
976end;
977
978procedure TBinaryProtocolImpl.ReadMessageEnd;
979begin
980 inherited;
981
982end;
983
984function TBinaryProtocolImpl.ReadSetBegin: ISet;
985var
986 set_ : ISet;
987begin
988 set_ := TSetImpl.Create;
989 set_.ElementType := TType( ReadByte );
990 set_.Count := ReadI32;
991 Result := set_;
992end;
993
994procedure TBinaryProtocolImpl.ReadSetEnd;
995begin
996
997end;
998
999function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
1000var
1001 buf : TBytes;
1002begin
1003 CheckReadLength( size );
1004 SetLength( buf, size );
1005 FTrans.ReadAll( buf, 0, size );
1006 Result := TEncoding.UTF8.GetString( buf);
1007end;
1008
1009function TBinaryProtocolImpl.ReadStructBegin: IStruct;
1010begin
1011 Result := TStructImpl.Create('');
1012end;
1013
1014procedure TBinaryProtocolImpl.ReadStructEnd;
1015begin
1016 inherited;
1017
1018end;
1019
1020procedure TBinaryProtocolImpl.SetReadLength(readLength: Integer);
1021begin
1022 FReadLength := readLength;
1023 FCheckReadLength := True;
1024end;
1025
1026procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
Jake Farrell9c6773a2012-03-22 02:40:45 +00001027var iLen : Integer;
Jake Farrell7ae13e12011-10-18 14:35:26 +00001028begin
Jake Farrell9c6773a2012-03-22 02:40:45 +00001029 iLen := Length(b);
1030 WriteI32( iLen);
1031 if iLen > 0 then FTrans.Write(b, 0, iLen);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001032end;
1033
1034procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1035begin
1036 if b then
1037 begin
1038 WriteByte( 1 );
1039 end else
1040 begin
1041 WriteByte( 0 );
1042 end;
1043end;
1044
1045procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
1046var
1047 a : TBytes;
1048begin
1049 SetLength( a, 1);
1050 a[0] := Byte( b );
1051 FTrans.Write( a, 0, 1 );
1052end;
1053
Roger Meier333bbf32012-01-08 21:51:08 +00001054procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001055begin
1056 WriteI64(ConvertDoubleToInt64(d));
1057end;
1058
Roger Meier333bbf32012-01-08 21:51:08 +00001059procedure TBinaryProtocolImpl.WriteFieldBegin( const field: IField);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001060begin
1061 WriteByte(ShortInt(field.Type_));
1062 WriteI16(field.ID);
1063end;
1064
1065procedure TBinaryProtocolImpl.WriteFieldEnd;
1066begin
1067
1068end;
1069
1070procedure TBinaryProtocolImpl.WriteFieldStop;
1071begin
1072 WriteByte(ShortInt(TType.Stop));
1073end;
1074
1075procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
1076var
1077 i16out : TBytes;
1078begin
1079 SetLength( i16out, 2);
1080 i16out[0] := Byte($FF and (i16 shr 8));
1081 i16out[1] := Byte($FF and i16);
1082 FTrans.Write( i16out );
1083end;
1084
1085procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
1086var
1087 i32out : TBytes;
1088begin
1089 SetLength( i32out, 4);
1090 i32out[0] := Byte($FF and (i32 shr 24));
1091 i32out[1] := Byte($FF and (i32 shr 16));
1092 i32out[2] := Byte($FF and (i32 shr 8));
1093 i32out[3] := Byte($FF and i32);
1094 FTrans.Write( i32out, 0, 4);
1095end;
1096
Roger Meier333bbf32012-01-08 21:51:08 +00001097procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001098var
1099 i64out : TBytes;
1100begin
1101 SetLength( i64out, 8);
1102 i64out[0] := Byte($FF and (i64 shr 56));
1103 i64out[1] := Byte($FF and (i64 shr 48));
1104 i64out[2] := Byte($FF and (i64 shr 40));
1105 i64out[3] := Byte($FF and (i64 shr 32));
1106 i64out[4] := Byte($FF and (i64 shr 24));
1107 i64out[5] := Byte($FF and (i64 shr 16));
1108 i64out[6] := Byte($FF and (i64 shr 8));
1109 i64out[7] := Byte($FF and i64);
1110 FTrans.Write( i64out, 0, 8);
1111end;
1112
Roger Meier333bbf32012-01-08 21:51:08 +00001113procedure TBinaryProtocolImpl.WriteListBegin( const list: IList);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001114begin
1115 WriteByte(ShortInt(list.ElementType));
1116 WriteI32(list.Count);
1117end;
1118
1119procedure TBinaryProtocolImpl.WriteListEnd;
1120begin
1121
1122end;
1123
Roger Meier333bbf32012-01-08 21:51:08 +00001124procedure TBinaryProtocolImpl.WriteMapBegin( const map: IMap);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001125begin
1126 WriteByte(ShortInt(map.KeyType));
1127 WriteByte(ShortInt(map.ValueType));
1128 WriteI32(map.Count);
1129end;
1130
1131procedure TBinaryProtocolImpl.WriteMapEnd;
1132begin
1133
1134end;
1135
Roger Meier333bbf32012-01-08 21:51:08 +00001136procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: IMessage);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001137var
1138 version : Cardinal;
1139begin
1140 if FStrictWrite then
1141 begin
Roger Meier333bbf32012-01-08 21:51:08 +00001142 version := VERSION_1 or Cardinal( msg.Type_);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001143 WriteI32( Integer( version) );
Roger Meier333bbf32012-01-08 21:51:08 +00001144 WriteString( msg.Name);
Jake Farrell6cd63ec2012-08-29 02:04:35 +00001145 WriteI32( msg.SeqID);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001146 end else
1147 begin
Roger Meier333bbf32012-01-08 21:51:08 +00001148 WriteString( msg.Name);
1149 WriteByte(ShortInt( msg.Type_));
1150 WriteI32( msg.SeqID);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001151 end;
1152end;
1153
1154procedure TBinaryProtocolImpl.WriteMessageEnd;
1155begin
1156
1157end;
1158
Roger Meier333bbf32012-01-08 21:51:08 +00001159procedure TBinaryProtocolImpl.WriteSetBegin( const set_: ISet);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001160begin
1161 WriteByte(ShortInt(set_.ElementType));
1162 WriteI32(set_.Count);
1163end;
1164
1165procedure TBinaryProtocolImpl.WriteSetEnd;
1166begin
1167
1168end;
1169
Roger Meier333bbf32012-01-08 21:51:08 +00001170procedure TBinaryProtocolImpl.WriteStructBegin( const struc: IStruct);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001171begin
1172
1173end;
1174
1175procedure TBinaryProtocolImpl.WriteStructEnd;
1176begin
1177
1178end;
1179
1180{ TProtocolException }
1181
1182constructor TProtocolException.Create;
1183begin
1184 inherited Create('');
1185 FType := UNKNOWN;
1186end;
1187
1188constructor TProtocolException.Create(type_: Integer);
1189begin
1190 inherited Create('');
1191 FType := type_;
1192end;
1193
1194constructor TProtocolException.Create(type_: Integer; const msg: string);
1195begin
1196 inherited Create( msg );
1197 FType := type_;
1198end;
1199
1200{ TThriftStringBuilder }
1201
1202function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
1203begin
1204 Result := Append( string( RawByteString(Value)) );
1205end;
1206
1207function TThriftStringBuilder.Append(
1208 const Value: IThriftContainer): TStringBuilder;
1209begin
1210 Result := Append( Value.ToString );
1211end;
1212
1213{ TBinaryProtocolImpl.TFactory }
1214
1215constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
1216begin
1217 FStrictRead := AStrictRead;
1218 FStrictWrite := AStrictWrite;
1219end;
1220
1221constructor TBinaryProtocolImpl.TFactory.Create;
1222begin
1223 Create( False, True )
1224end;
1225
Roger Meier333bbf32012-01-08 21:51:08 +00001226function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
Jake Farrell7ae13e12011-10-18 14:35:26 +00001227begin
1228 Result := TBinaryProtocolImpl.Create( trans );
1229end;
1230
1231end.
1232