blob: 82c58b1abd4ebf5e307c5a80b85920775d1ba9af [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);
559begin
560
561end;
562
563{ TStructImpl }
564
565constructor TStructImpl.Create(const AName: string);
566begin
567 inherited Create;
568 FName := AName;
569end;
570
571function TStructImpl.GetName: string;
572begin
573 Result := FName;
574end;
575
576procedure TStructImpl.SetName(const Value: string);
577begin
578 FName := Value;
579end;
580
581{ TMapImpl }
582
583constructor TMapImpl.Create(AValueType, AKeyType: TType; ACount: Integer);
584begin
585 inherited Create;
586 FValueType := AValueType;
587 FKeyType := AKeyType;
588 FCount := ACount;
589end;
590
591constructor TMapImpl.Create;
592begin
593
594end;
595
596function TMapImpl.GetCount: Integer;
597begin
598 Result := FCount;
599end;
600
601function TMapImpl.GetKeyType: TType;
602begin
603 Result := FKeyType;
604end;
605
606function TMapImpl.GetValueType: TType;
607begin
608 Result := FValueType;
609end;
610
611procedure TMapImpl.SetCount(Value: Integer);
612begin
613 FCount := Value;
614end;
615
616procedure TMapImpl.SetKeyType(Value: TType);
617begin
618 FKeyType := Value;
619end;
620
621procedure TMapImpl.SetValueType(Value: TType);
622begin
623 FValueType := Value;
624end;
625
626{ IMessage }
627
628constructor TMessageImpl.Create(AName: string; AMessageType: TMessageType;
629 ASeqID: Integer);
630begin
631 inherited Create;
632 FName := AName;
633 FMessageType := AMessageType;
634 FSeqID := ASeqID;
635end;
636
637constructor TMessageImpl.Create;
638begin
639 inherited;
640end;
641
642function TMessageImpl.GetName: string;
643begin
644 Result := FName;
645end;
646
647function TMessageImpl.GetSeqID: Integer;
648begin
649 Result := FSeqID;
650end;
651
652function TMessageImpl.GetType: TMessageType;
653begin
654 Result := FMessageType;
655end;
656
657procedure TMessageImpl.SetName(const Value: string);
658begin
659 FName := Value;
660end;
661
662procedure TMessageImpl.SetSeqID(Value: Integer);
663begin
664 FSeqID := Value;
665end;
666
667procedure TMessageImpl.SetType(Value: TMessageType);
668begin
669 FMessageType := Value;
670end;
671
672{ ISet }
673
674constructor TSetImpl.Create( AElementType: TType; ACount: Integer);
675begin
676 inherited Create;
677 FCount := ACount;
678 FElementType := AElementType;
679end;
680
681constructor TSetImpl.Create;
682begin
683
684end;
685
686function TSetImpl.GetCount: Integer;
687begin
688 Result := FCount;
689end;
690
691function TSetImpl.GetElementType: TType;
692begin
693 Result := FElementType;
694end;
695
696procedure TSetImpl.SetCount(Value: Integer);
697begin
698 FCount := Value;
699end;
700
701procedure TSetImpl.SetElementType(Value: TType);
702begin
703 FElementType := Value;
704end;
705
706{ IList }
707
708constructor TListImpl.Create( AElementType: TType; ACount: Integer);
709begin
710 inherited Create;
711 FCount := ACount;
712 FElementType := AElementType;
713end;
714
715constructor TListImpl.Create;
716begin
717
718end;
719
720function TListImpl.GetCount: Integer;
721begin
722 Result := FCount;
723end;
724
725function TListImpl.GetElementType: TType;
726begin
727 Result := FElementType;
728end;
729
730procedure TListImpl.SetCount(Value: Integer);
731begin
732 FCount := Value;
733end;
734
735procedure TListImpl.SetElementType(Value: TType);
736begin
737 FElementType := Value;
738end;
739
740{ TBinaryProtocolImpl }
741
Roger Meier333bbf32012-01-08 21:51:08 +0000742constructor TBinaryProtocolImpl.Create( const trans: ITransport);
Jake Farrell7ae13e12011-10-18 14:35:26 +0000743begin
744 Create( trans, False, True);
745end;
746
747procedure TBinaryProtocolImpl.CheckReadLength(len: Integer);
748begin
749 if FCheckReadLength then
750 begin
751 Dec( FReadLength, len);
752 if FReadLength < 0 then
753 begin
754 raise Exception.Create( 'Message length exceeded: ' + IntToStr( len ) );
755 end;
756 end;
757end;
758
Roger Meier333bbf32012-01-08 21:51:08 +0000759constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead,
Jake Farrell7ae13e12011-10-18 14:35:26 +0000760 strictWrite: Boolean);
761begin
762 inherited Create( trans );
763 FStrictRead := strictRead;
764 FStrictWrite := strictWrite;
765end;
766
767function TBinaryProtocolImpl.ReadAll( var buf: TBytes; off,
768 len: Integer): Integer;
769begin
770 CheckReadLength( len );
771 Result := FTrans.ReadAll( buf, off, len );
772end;
773
774function TBinaryProtocolImpl.ReadBinary: TBytes;
775var
776 size : Integer;
777 buf : TBytes;
778begin
779 size := ReadI32;
780 CheckReadLength( size );
781 SetLength( buf, size );
782 FTrans.ReadAll( buf, 0, size);
783 Result := buf;
784end;
785
786function TBinaryProtocolImpl.ReadBool: Boolean;
787begin
788 Result := ReadByte = 1;
789end;
790
791function TBinaryProtocolImpl.ReadByte: ShortInt;
792var
793 bin : TBytes;
794begin
795 SetLength( bin, 1);
796 ReadAll( bin, 0, 1 );
797 Result := ShortInt( bin[0]);
798end;
799
800function TBinaryProtocolImpl.ReadDouble: Double;
801begin
802 Result := ConvertInt64ToDouble( ReadI64 )
803end;
804
805function TBinaryProtocolImpl.ReadFieldBegin: IField;
806var
807 field : IField;
808begin
809 field := TFieldImpl.Create;
810 field.Type_ := TType( ReadByte);
811 if ( field.Type_ <> TType.Stop ) then
812 begin
813 field.Id := ReadI16;
814 end;
815 Result := field;
816end;
817
818procedure TBinaryProtocolImpl.ReadFieldEnd;
819begin
820
821end;
822
823function TBinaryProtocolImpl.ReadI16: SmallInt;
824var
825 i16in : TBytes;
826begin
827 SetLength( i16in, 2 );
828 ReadAll( i16in, 0, 2);
829 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
830end;
831
832function TBinaryProtocolImpl.ReadI32: Integer;
833var
834 i32in : TBytes;
835begin
836 SetLength( i32in, 4 );
837 ReadAll( i32in, 0, 4);
838
839 Result := Integer(
840 ((i32in[0] and $FF) shl 24) or
841 ((i32in[1] and $FF) shl 16) or
842 ((i32in[2] and $FF) shl 8) or
843 (i32in[3] and $FF));
844
845end;
846
847function TBinaryProtocolImpl.ReadI64: Int64;
848var
849 i64in : TBytes;
850begin
851 SetLength( i64in, 8);
852 ReadAll( i64in, 0, 8);
853 Result :=
854 (Int64( i64in[0] and $FF) shl 56) or
855 (Int64( i64in[1] and $FF) shl 48) or
856 (Int64( i64in[2] and $FF) shl 40) or
857 (Int64( i64in[3] and $FF) shl 32) or
858 (Int64( i64in[4] and $FF) shl 24) or
859 (Int64( i64in[5] and $FF) shl 16) or
860 (Int64( i64in[6] and $FF) shl 8) or
861 (Int64( i64in[7] and $FF));
862end;
863
864function TBinaryProtocolImpl.ReadListBegin: IList;
865var
866 list : IList;
867begin
868 list := TListImpl.Create;
869 list.ElementType := TType( ReadByte );
870 list.Count := ReadI32;
871 Result := list;
872end;
873
874procedure TBinaryProtocolImpl.ReadListEnd;
875begin
876
877end;
878
879function TBinaryProtocolImpl.ReadMapBegin: IMap;
880var
881 map : IMap;
882begin
883 map := TMapImpl.Create;
884 map.KeyType := TType( ReadByte );
885 map.ValueType := TType( ReadByte );
886 map.Count := ReadI32;
887 Result := map;
888end;
889
890procedure TBinaryProtocolImpl.ReadMapEnd;
891begin
892
893end;
894
895function TBinaryProtocolImpl.ReadMessageBegin: IMessage;
896var
897 size : Integer;
898 version : Integer;
899 message : IMessage;
900begin
901 message := TMessageImpl.Create;
902 size := ReadI32;
903 if (size < 0) then
904 begin
905 version := size and Integer( VERSION_MASK);
906 if ( version <> Integer( VERSION_1)) then
907 begin
908 raise TProtocolException.Create(TProtocolException.BAD_VERSION, 'Bad version in ReadMessageBegin: ' + IntToStr(version) );
909 end;
910 message.Type_ := TMessageType( size and $000000ff);
911 message.Name := ReadString;
912 message.SeqID := ReadI32;
913 end else
914 begin
915 if FStrictRead then
916 begin
917 raise TProtocolException.Create( TProtocolException.BAD_VERSION, 'Missing version in readMessageBegin, old client?' );
918 end;
919 message.Name := ReadStringBody( size );
920 message.Type_ := TMessageType( ReadByte );
921 message.SeqID := ReadI32;
922 end;
923 Result := message;
924end;
925
926procedure TBinaryProtocolImpl.ReadMessageEnd;
927begin
928 inherited;
929
930end;
931
932function TBinaryProtocolImpl.ReadSetBegin: ISet;
933var
934 set_ : ISet;
935begin
936 set_ := TSetImpl.Create;
937 set_.ElementType := TType( ReadByte );
938 set_.Count := ReadI32;
939 Result := set_;
940end;
941
942procedure TBinaryProtocolImpl.ReadSetEnd;
943begin
944
945end;
946
947function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
948var
949 buf : TBytes;
950begin
951 CheckReadLength( size );
952 SetLength( buf, size );
953 FTrans.ReadAll( buf, 0, size );
954 Result := TEncoding.UTF8.GetString( buf);
955end;
956
957function TBinaryProtocolImpl.ReadStructBegin: IStruct;
958begin
959 Result := TStructImpl.Create('');
960end;
961
962procedure TBinaryProtocolImpl.ReadStructEnd;
963begin
964 inherited;
965
966end;
967
968procedure TBinaryProtocolImpl.SetReadLength(readLength: Integer);
969begin
970 FReadLength := readLength;
971 FCheckReadLength := True;
972end;
973
974procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
975begin
976 WriteI32( Length(b));
977 FTrans.Write(b, 0, Length( b));
978end;
979
980procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
981begin
982 if b then
983 begin
984 WriteByte( 1 );
985 end else
986 begin
987 WriteByte( 0 );
988 end;
989end;
990
991procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
992var
993 a : TBytes;
994begin
995 SetLength( a, 1);
996 a[0] := Byte( b );
997 FTrans.Write( a, 0, 1 );
998end;
999
Roger Meier333bbf32012-01-08 21:51:08 +00001000procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001001begin
1002 WriteI64(ConvertDoubleToInt64(d));
1003end;
1004
Roger Meier333bbf32012-01-08 21:51:08 +00001005procedure TBinaryProtocolImpl.WriteFieldBegin( const field: IField);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001006begin
1007 WriteByte(ShortInt(field.Type_));
1008 WriteI16(field.ID);
1009end;
1010
1011procedure TBinaryProtocolImpl.WriteFieldEnd;
1012begin
1013
1014end;
1015
1016procedure TBinaryProtocolImpl.WriteFieldStop;
1017begin
1018 WriteByte(ShortInt(TType.Stop));
1019end;
1020
1021procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
1022var
1023 i16out : TBytes;
1024begin
1025 SetLength( i16out, 2);
1026 i16out[0] := Byte($FF and (i16 shr 8));
1027 i16out[1] := Byte($FF and i16);
1028 FTrans.Write( i16out );
1029end;
1030
1031procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
1032var
1033 i32out : TBytes;
1034begin
1035 SetLength( i32out, 4);
1036 i32out[0] := Byte($FF and (i32 shr 24));
1037 i32out[1] := Byte($FF and (i32 shr 16));
1038 i32out[2] := Byte($FF and (i32 shr 8));
1039 i32out[3] := Byte($FF and i32);
1040 FTrans.Write( i32out, 0, 4);
1041end;
1042
Roger Meier333bbf32012-01-08 21:51:08 +00001043procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001044var
1045 i64out : TBytes;
1046begin
1047 SetLength( i64out, 8);
1048 i64out[0] := Byte($FF and (i64 shr 56));
1049 i64out[1] := Byte($FF and (i64 shr 48));
1050 i64out[2] := Byte($FF and (i64 shr 40));
1051 i64out[3] := Byte($FF and (i64 shr 32));
1052 i64out[4] := Byte($FF and (i64 shr 24));
1053 i64out[5] := Byte($FF and (i64 shr 16));
1054 i64out[6] := Byte($FF and (i64 shr 8));
1055 i64out[7] := Byte($FF and i64);
1056 FTrans.Write( i64out, 0, 8);
1057end;
1058
Roger Meier333bbf32012-01-08 21:51:08 +00001059procedure TBinaryProtocolImpl.WriteListBegin( const list: IList);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001060begin
1061 WriteByte(ShortInt(list.ElementType));
1062 WriteI32(list.Count);
1063end;
1064
1065procedure TBinaryProtocolImpl.WriteListEnd;
1066begin
1067
1068end;
1069
Roger Meier333bbf32012-01-08 21:51:08 +00001070procedure TBinaryProtocolImpl.WriteMapBegin( const map: IMap);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001071begin
1072 WriteByte(ShortInt(map.KeyType));
1073 WriteByte(ShortInt(map.ValueType));
1074 WriteI32(map.Count);
1075end;
1076
1077procedure TBinaryProtocolImpl.WriteMapEnd;
1078begin
1079
1080end;
1081
Roger Meier333bbf32012-01-08 21:51:08 +00001082procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: IMessage);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001083var
1084 version : Cardinal;
1085begin
1086 if FStrictWrite then
1087 begin
Roger Meier333bbf32012-01-08 21:51:08 +00001088 version := VERSION_1 or Cardinal( msg.Type_);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001089 WriteI32( Integer( version) );
Roger Meier333bbf32012-01-08 21:51:08 +00001090 WriteString( msg.Name);
1091 WriteI32( msg.SeqID);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001092 end else
1093 begin
Roger Meier333bbf32012-01-08 21:51:08 +00001094 WriteString( msg.Name);
1095 WriteByte(ShortInt( msg.Type_));
1096 WriteI32( msg.SeqID);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001097 end;
1098end;
1099
1100procedure TBinaryProtocolImpl.WriteMessageEnd;
1101begin
1102
1103end;
1104
Roger Meier333bbf32012-01-08 21:51:08 +00001105procedure TBinaryProtocolImpl.WriteSetBegin( const set_: ISet);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001106begin
1107 WriteByte(ShortInt(set_.ElementType));
1108 WriteI32(set_.Count);
1109end;
1110
1111procedure TBinaryProtocolImpl.WriteSetEnd;
1112begin
1113
1114end;
1115
Roger Meier333bbf32012-01-08 21:51:08 +00001116procedure TBinaryProtocolImpl.WriteStructBegin( const struc: IStruct);
Jake Farrell7ae13e12011-10-18 14:35:26 +00001117begin
1118
1119end;
1120
1121procedure TBinaryProtocolImpl.WriteStructEnd;
1122begin
1123
1124end;
1125
1126{ TProtocolException }
1127
1128constructor TProtocolException.Create;
1129begin
1130 inherited Create('');
1131 FType := UNKNOWN;
1132end;
1133
1134constructor TProtocolException.Create(type_: Integer);
1135begin
1136 inherited Create('');
1137 FType := type_;
1138end;
1139
1140constructor TProtocolException.Create(type_: Integer; const msg: string);
1141begin
1142 inherited Create( msg );
1143 FType := type_;
1144end;
1145
1146{ TThriftStringBuilder }
1147
1148function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
1149begin
1150 Result := Append( string( RawByteString(Value)) );
1151end;
1152
1153function TThriftStringBuilder.Append(
1154 const Value: IThriftContainer): TStringBuilder;
1155begin
1156 Result := Append( Value.ToString );
1157end;
1158
1159{ TBinaryProtocolImpl.TFactory }
1160
1161constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
1162begin
1163 FStrictRead := AStrictRead;
1164 FStrictWrite := AStrictWrite;
1165end;
1166
1167constructor TBinaryProtocolImpl.TFactory.Create;
1168begin
1169 Create( False, True )
1170end;
1171
Roger Meier333bbf32012-01-08 21:51:08 +00001172function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
Jake Farrell7ae13e12011-10-18 14:35:26 +00001173begin
1174 Result := TBinaryProtocolImpl.Create( trans );
1175end;
1176
1177end.
1178