blob: 3df3574b205b5cf47ae81871e6a6840d856593b9 [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,
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}']
64 function GetProtocol( const trans: ITransport): IProtocol;
65 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 // TODO(jensg): change into enum
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 DEPTH_LIMIT : Integer = 6;
83 protected
84 FType : Integer;
85 public
86 constructor Create; overload;
87 constructor Create( type_: Integer ); overload;
88 constructor Create( type_: Integer; const msg: string); overload;
89 end;
90
91 IMap = interface
92 ['{30531D97-7E06-4233-B800-C3F53CCD23E7}']
93 function GetKeyType: TType;
94 procedure SetKeyType( Value: TType);
95 function GetValueType: TType;
96 procedure SetValueType( Value: TType);
97 function GetCount: Integer;
98 procedure SetCount( Value: Integer);
99 property KeyType: TType read GetKeyType write SetKeyType;
100 property ValueType: TType read GetValueType write SetValueType;
101 property Count: Integer read GetCount write SetCount;
102 end;
103
104 TMapImpl = class( TInterfacedObject, IMap)
105 private
106 FValueType: TType;
107 FKeyType: TType;
108 FCount: Integer;
109 protected
110 function GetKeyType: TType;
111 procedure SetKeyType( Value: TType);
112 function GetValueType: TType;
113 procedure SetValueType( Value: TType);
114 function GetCount: Integer;
115 procedure SetCount( Value: Integer);
116 public
Jens Geyer96eff172015-03-02 01:30:05 +0100117 constructor Create( AKeyType, AValueType: TType; ACount: Integer); overload;
Jens Geyerd5436f52014-10-03 19:50:38 +0200118 constructor Create; overload;
119 end;
120
121 IList = interface
122 ['{6763E1EA-A934-4472-904F-0083980B9B87}']
123 function GetElementType: TType;
124 procedure SetElementType( Value: TType);
125 function GetCount: Integer;
126 procedure SetCount( Value: Integer);
127 property ElementType: TType read GetElementType write SetElementType;
128 property Count: Integer read GetCount write SetCount;
129 end;
130
131 TListImpl = class( TInterfacedObject, IList)
132 private
133 FElementType: TType;
134 FCount : Integer;
135 protected
136 function GetElementType: TType;
137 procedure SetElementType( Value: TType);
138 function GetCount: Integer;
139 procedure SetCount( Value: Integer);
140 public
141 constructor Create( AElementType: TType; ACount: Integer); overload;
142 constructor Create; overload;
143 end;
144
145 ISet = interface
146 ['{A8671700-7514-4C1E-8A05-62786872005F}']
147 function GetElementType: TType;
148 procedure SetElementType( Value: TType);
149 function GetCount: Integer;
150 procedure SetCount( Value: Integer);
151 property ElementType: TType read GetElementType write SetElementType;
152 property Count: Integer read GetCount write SetCount;
153 end;
154
155 TSetImpl = class( TInterfacedObject, ISet)
156 private
157 FCount: Integer;
158 FElementType: TType;
159 protected
160 function GetElementType: TType;
161 procedure SetElementType( Value: TType);
162 function GetCount: Integer;
163 procedure SetCount( Value: Integer);
164 public
165 constructor Create( AElementType: TType; ACount: Integer); overload;
166 constructor Create; overload;
167 end;
168
169 IMessage = interface
170 ['{9E368B4A-B1FA-43E7-8CF5-56C66D256CA7}']
171 function GetName: string;
172 procedure SetName( const Value: string);
173 function GetType: TMessageType;
174 procedure SetType( Value: TMessageType);
175 function GetSeqID: Integer;
176 procedure SetSeqID( Value: Integer);
177 property Name: string read GetName write SetName;
178 property Type_: TMessageType read GetType write SetType;
179 property SeqID: Integer read GetSeqID write SetSeqID;
180 end;
181
182 TMessageImpl = class( TInterfacedObject, IMessage )
183 private
184 FName: string;
185 FMessageType: TMessageType;
186 FSeqID: Integer;
187 protected
188 function GetName: string;
189 procedure SetName( const Value: string);
190 function GetType: TMessageType;
191 procedure SetType( Value: TMessageType);
192 function GetSeqID: Integer;
193 procedure SetSeqID( Value: Integer);
194 public
195 property Name: string read FName write FName;
196 property Type_: TMessageType read FMessageType write FMessageType;
197 property SeqID: Integer read FSeqID write FSeqID;
198 constructor Create( AName: string; AMessageType: TMessageType; ASeqID: Integer); overload;
199 constructor Create; overload;
200 end;
201
202 IField = interface
203 ['{F0D43BE5-7883-442E-83FF-0580CC632B72}']
204 function GetName: string;
205 procedure SetName( const Value: string);
206 function GetType: TType;
207 procedure SetType( Value: TType);
208 function GetId: SmallInt;
209 procedure SetId( Value: SmallInt);
210 property Name: string read GetName write SetName;
211 property Type_: TType read GetType write SetType;
212 property Id: SmallInt read GetId write SetId;
213 end;
214
215 TFieldImpl = class( TInterfacedObject, IField)
216 private
217 FName : string;
218 FType : TType;
219 FId : SmallInt;
220 protected
221 function GetName: string;
222 procedure SetName( const Value: string);
223 function GetType: TType;
224 procedure SetType( Value: TType);
225 function GetId: SmallInt;
226 procedure SetId( Value: SmallInt);
227 public
228 constructor Create( const AName: string; const AType: TType; AId: SmallInt); overload;
229 constructor Create; overload;
230 end;
231
232 TProtocolUtil = class
233 public
234 class procedure Skip( prot: IProtocol; type_: TType);
235 end;
236
237 IProtocol = interface
238 ['{FD95C151-1527-4C96-8134-B902BFC4B4FC}']
239 function GetTransport: ITransport;
240 procedure WriteMessageBegin( const msg: IMessage);
241 procedure WriteMessageEnd;
242 procedure WriteStructBegin( const struc: IStruct);
243 procedure WriteStructEnd;
244 procedure WriteFieldBegin( const field: IField);
245 procedure WriteFieldEnd;
246 procedure WriteFieldStop;
247 procedure WriteMapBegin( const map: IMap);
248 procedure WriteMapEnd;
249 procedure WriteListBegin( const list: IList);
250 procedure WriteListEnd();
251 procedure WriteSetBegin( const set_: ISet );
252 procedure WriteSetEnd();
253 procedure WriteBool( b: Boolean);
254 procedure WriteByte( b: ShortInt);
255 procedure WriteI16( i16: SmallInt);
256 procedure WriteI32( i32: Integer);
257 procedure WriteI64( const i64: Int64);
258 procedure WriteDouble( const d: Double);
259 procedure WriteString( const s: string );
260 procedure WriteAnsiString( const s: AnsiString);
261 procedure WriteBinary( const b: TBytes);
262
263 function ReadMessageBegin: IMessage;
264 procedure ReadMessageEnd();
265 function ReadStructBegin: IStruct;
266 procedure ReadStructEnd;
267 function ReadFieldBegin: IField;
268 procedure ReadFieldEnd();
269 function ReadMapBegin: IMap;
270 procedure ReadMapEnd();
271 function ReadListBegin: IList;
272 procedure ReadListEnd();
273 function ReadSetBegin: ISet;
274 procedure ReadSetEnd();
275 function ReadBool: Boolean;
276 function ReadByte: ShortInt;
277 function ReadI16: SmallInt;
278 function ReadI32: Integer;
279 function ReadI64: Int64;
280 function ReadDouble:Double;
281 function ReadBinary: TBytes;
282 function ReadString: string;
283 function ReadAnsiString: AnsiString;
284 property Transport: ITransport read GetTransport;
285 end;
286
287 TProtocolImpl = class abstract( TInterfacedObject, IProtocol)
288 protected
289 FTrans : ITransport;
290 function GetTransport: ITransport;
291 public
292 procedure WriteMessageBegin( const msg: IMessage); virtual; abstract;
293 procedure WriteMessageEnd; virtual; abstract;
294 procedure WriteStructBegin( const struc: IStruct); virtual; abstract;
295 procedure WriteStructEnd; virtual; abstract;
296 procedure WriteFieldBegin( const field: IField); virtual; abstract;
297 procedure WriteFieldEnd; virtual; abstract;
298 procedure WriteFieldStop; virtual; abstract;
299 procedure WriteMapBegin( const map: IMap); virtual; abstract;
300 procedure WriteMapEnd; virtual; abstract;
301 procedure WriteListBegin( const list: IList); virtual; abstract;
302 procedure WriteListEnd(); virtual; abstract;
303 procedure WriteSetBegin( const set_: ISet ); virtual; abstract;
304 procedure WriteSetEnd(); virtual; abstract;
305 procedure WriteBool( b: Boolean); virtual; abstract;
306 procedure WriteByte( b: ShortInt); virtual; abstract;
307 procedure WriteI16( i16: SmallInt); virtual; abstract;
308 procedure WriteI32( i32: Integer); virtual; abstract;
309 procedure WriteI64( const i64: Int64); virtual; abstract;
310 procedure WriteDouble( const d: Double); virtual; abstract;
311 procedure WriteString( const s: string ); virtual;
312 procedure WriteAnsiString( const s: AnsiString); virtual;
313 procedure WriteBinary( const b: TBytes); virtual; abstract;
314
315 function ReadMessageBegin: IMessage; virtual; abstract;
316 procedure ReadMessageEnd(); virtual; abstract;
317 function ReadStructBegin: IStruct; virtual; abstract;
318 procedure ReadStructEnd; virtual; abstract;
319 function ReadFieldBegin: IField; virtual; abstract;
320 procedure ReadFieldEnd(); virtual; abstract;
321 function ReadMapBegin: IMap; virtual; abstract;
322 procedure ReadMapEnd(); virtual; abstract;
323 function ReadListBegin: IList; virtual; abstract;
324 procedure ReadListEnd(); virtual; abstract;
325 function ReadSetBegin: ISet; virtual; abstract;
326 procedure ReadSetEnd(); virtual; abstract;
327 function ReadBool: Boolean; virtual; abstract;
328 function ReadByte: ShortInt; virtual; abstract;
329 function ReadI16: SmallInt; virtual; abstract;
330 function ReadI32: Integer; virtual; abstract;
331 function ReadI64: Int64; virtual; abstract;
332 function ReadDouble:Double; virtual; abstract;
333 function ReadBinary: TBytes; virtual; abstract;
334 function ReadString: string; virtual;
335 function ReadAnsiString: AnsiString; virtual;
336
337 property Transport: ITransport read GetTransport;
338
339 constructor Create( trans: ITransport );
340 end;
341
342 IBase = interface
343 ['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
344 function ToString: string;
345 procedure Read( const iprot: IProtocol);
346 procedure Write( const iprot: IProtocol);
347 end;
348
349 IStruct = interface
350 ['{5DCE39AA-C916-4BC7-A79B-96A0C36B2220}']
351 procedure SetName(const Value: string);
352 function GetName: string;
353 property Name: string read GetName write SetName;
354 end;
355
356 TStructImpl = class( TInterfacedObject, IStruct )
357 private
358 FName: string;
359 protected
360 function GetName: string;
361 procedure SetName(const Value: string);
362 public
363 constructor Create( const AName: string);
364 end;
365
366 TBinaryProtocolImpl = class( TProtocolImpl )
367 protected
368 const
369 VERSION_MASK : Cardinal = $ffff0000;
370 VERSION_1 : Cardinal = $80010000;
371 protected
372 FStrictRead : Boolean;
373 FStrictWrite : Boolean;
374
375 private
376 function ReadAll( var buf: TBytes; off: Integer; len: Integer ): Integer;
377 function ReadStringBody( size: Integer): string;
378
379 public
380
381 type
382 TFactory = class( TInterfacedObject, IProtocolFactory)
383 protected
384 FStrictRead : Boolean;
385 FStrictWrite : Boolean;
386 public
387 function GetProtocol( const trans: ITransport): IProtocol;
388 constructor Create( AStrictRead, AStrictWrite: Boolean ); overload;
389 constructor Create; overload;
390 end;
391
392 constructor Create( const trans: ITransport); overload;
393 constructor Create( const trans: ITransport; strictRead: Boolean; strictWrite: Boolean); overload;
394
395 procedure WriteMessageBegin( const msg: IMessage); override;
396 procedure WriteMessageEnd; override;
397 procedure WriteStructBegin( const struc: IStruct); override;
398 procedure WriteStructEnd; override;
399 procedure WriteFieldBegin( const field: IField); override;
400 procedure WriteFieldEnd; override;
401 procedure WriteFieldStop; override;
402 procedure WriteMapBegin( const map: IMap); override;
403 procedure WriteMapEnd; override;
404 procedure WriteListBegin( const list: IList); override;
405 procedure WriteListEnd(); override;
406 procedure WriteSetBegin( const set_: ISet ); override;
407 procedure WriteSetEnd(); override;
408 procedure WriteBool( b: Boolean); override;
409 procedure WriteByte( b: ShortInt); override;
410 procedure WriteI16( i16: SmallInt); override;
411 procedure WriteI32( i32: Integer); override;
412 procedure WriteI64( const i64: Int64); override;
413 procedure WriteDouble( const d: Double); override;
414 procedure WriteBinary( const b: TBytes); override;
415
416 function ReadMessageBegin: IMessage; override;
417 procedure ReadMessageEnd(); override;
418 function ReadStructBegin: IStruct; override;
419 procedure ReadStructEnd; override;
420 function ReadFieldBegin: IField; override;
421 procedure ReadFieldEnd(); override;
422 function ReadMapBegin: IMap; override;
423 procedure ReadMapEnd(); override;
424 function ReadListBegin: IList; override;
425 procedure ReadListEnd(); override;
426 function ReadSetBegin: ISet; override;
427 procedure ReadSetEnd(); override;
428 function ReadBool: Boolean; override;
429 function ReadByte: ShortInt; override;
430 function ReadI16: SmallInt; override;
431 function ReadI32: Integer; override;
432 function ReadI64: Int64; override;
433 function ReadDouble:Double; override;
434 function ReadBinary: TBytes; override;
435
436 end;
437
438
439 { TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
440 providing a way to author concise concrete decorator subclasses. The decorator
441 does not (and should not) modify the behaviour of the enclosed TProtocol
442
443 See p.175 of Design Patterns (by Gamma et al.)
444 }
445 TProtocolDecorator = class( TProtocolImpl)
446 private
447 FWrappedProtocol : IProtocol;
448
449 public
450 // Encloses the specified protocol.
451 // All operations will be forward to the given protocol. Must be non-null.
452 constructor Create( const aProtocol : IProtocol);
453
454 procedure WriteMessageBegin( const msg: IMessage); override;
455 procedure WriteMessageEnd; override;
456 procedure WriteStructBegin( const struc: IStruct); override;
457 procedure WriteStructEnd; override;
458 procedure WriteFieldBegin( const field: IField); override;
459 procedure WriteFieldEnd; override;
460 procedure WriteFieldStop; override;
461 procedure WriteMapBegin( const map: IMap); override;
462 procedure WriteMapEnd; override;
463 procedure WriteListBegin( const list: IList); override;
464 procedure WriteListEnd(); override;
465 procedure WriteSetBegin( const set_: ISet ); override;
466 procedure WriteSetEnd(); override;
467 procedure WriteBool( b: Boolean); override;
468 procedure WriteByte( b: ShortInt); override;
469 procedure WriteI16( i16: SmallInt); override;
470 procedure WriteI32( i32: Integer); override;
471 procedure WriteI64( const i64: Int64); override;
472 procedure WriteDouble( const d: Double); override;
473 procedure WriteString( const s: string ); override;
474 procedure WriteAnsiString( const s: AnsiString); override;
475 procedure WriteBinary( const b: TBytes); override;
476
477 function ReadMessageBegin: IMessage; override;
478 procedure ReadMessageEnd(); override;
479 function ReadStructBegin: IStruct; override;
480 procedure ReadStructEnd; override;
481 function ReadFieldBegin: IField; override;
482 procedure ReadFieldEnd(); override;
483 function ReadMapBegin: IMap; override;
484 procedure ReadMapEnd(); override;
485 function ReadListBegin: IList; override;
486 procedure ReadListEnd(); override;
487 function ReadSetBegin: ISet; override;
488 procedure ReadSetEnd(); override;
489 function ReadBool: Boolean; override;
490 function ReadByte: ShortInt; override;
491 function ReadI16: SmallInt; override;
492 function ReadI32: Integer; override;
493 function ReadI64: Int64; override;
494 function ReadDouble:Double; override;
495 function ReadBinary: TBytes; override;
496 function ReadString: string; override;
497 function ReadAnsiString: AnsiString; override;
498 end;
499
500
501type
502 IRequestEvents = interface
Jens Geyer01640402013-09-25 21:12:21 +0200503 ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}']
504 // Called before reading arguments.
505 procedure PreRead;
506 // Called between reading arguments and calling the handler.
507 procedure PostRead;
508 // Called between calling the handler and writing the response.
509 procedure PreWrite;
510 // Called after writing the response.
511 procedure PostWrite;
512 // Called when an oneway (async) function call completes successfully.
513 procedure OnewayComplete;
514 // Called if the handler throws an undeclared exception.
515 procedure UnhandledError( const e : Exception);
516 // Called when a client has finished request-handling to clean up
517 procedure CleanupContext;
518 end;
519
520
521 IProcessorEvents = interface
522 ['{A8661119-657C-447D-93C5-512E36162A45}']
523 // Called when a client is about to call the processor.
524 procedure Processing( const transport : ITransport);
525 // Called on any service function invocation
526 function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
527 // Called when a client has finished request-handling to clean up
528 procedure CleanupContext;
529 end;
530
531
532 IProcessor = interface
533 ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}']
Jens Geyerd430bbd2013-09-26 23:37:54 +0200534 function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean;
Jens Geyer01640402013-09-25 21:12:21 +0200535 end;
536
Jens Geyerd5436f52014-10-03 19:50:38 +0200537
538
539implementation
540
541function ConvertInt64ToDouble( const n: Int64): Double;
542begin
543 ASSERT( SizeOf(n) = SizeOf(Result));
544 System.Move( n, Result, SizeOf(Result));
545end;
546
547function ConvertDoubleToInt64( const d: Double): Int64;
548begin
549 ASSERT( SizeOf(d) = SizeOf(Result));
550 System.Move( d, Result, SizeOf(Result));
551end;
552
553{ TFieldImpl }
554
555constructor TFieldImpl.Create(const AName: string; const AType: TType;
556 AId: SmallInt);
557begin
558 inherited Create;
559 FName := AName;
560 FType := AType;
561 FId := AId;
562end;
563
564constructor TFieldImpl.Create;
565begin
566 inherited Create;
567 FName := '';
568 FType := Low(TType);
569 FId := 0;
570end;
571
572function TFieldImpl.GetId: SmallInt;
573begin
574 Result := FId;
575end;
576
577function TFieldImpl.GetName: string;
578begin
579 Result := FName;
580end;
581
582function TFieldImpl.GetType: TType;
583begin
584 Result := FType;
585end;
586
587procedure TFieldImpl.SetId(Value: SmallInt);
588begin
589 FId := Value;
590end;
591
592procedure TFieldImpl.SetName(const Value: string);
593begin
594 FName := Value;
595end;
596
597procedure TFieldImpl.SetType(Value: TType);
598begin
599 FType := Value;
600end;
601
602{ TProtocolImpl }
603
604constructor TProtocolImpl.Create(trans: ITransport);
605begin
606 inherited Create;
607 FTrans := trans;
608end;
609
610function TProtocolImpl.GetTransport: ITransport;
611begin
612 Result := FTrans;
613end;
614
615function TProtocolImpl.ReadAnsiString: AnsiString;
616var
617 b : TBytes;
618 len : Integer;
619begin
620 Result := '';
621 b := ReadBinary;
622 len := Length( b );
623 if len > 0 then
624 begin
625 SetLength( Result, len);
626 System.Move( b[0], Pointer(Result)^, len );
627 end;
628end;
629
630function TProtocolImpl.ReadString: string;
631begin
632 Result := TEncoding.UTF8.GetString( ReadBinary );
633end;
634
635procedure TProtocolImpl.WriteAnsiString(const s: AnsiString);
636var
637 b : TBytes;
638 len : Integer;
639begin
640 len := Length(s);
641 SetLength( b, len);
642 if len > 0 then
643 begin
644 System.Move( Pointer(s)^, b[0], len );
645 end;
646 WriteBinary( b );
647end;
648
649procedure TProtocolImpl.WriteString(const s: string);
650var
651 b : TBytes;
652begin
653 b := TEncoding.UTF8.GetBytes(s);
654 WriteBinary( b );
655end;
656
657{ TProtocolUtil }
658
659class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType);
660var field : IField;
661 map : IMap;
662 set_ : ISet;
663 list : IList;
664 i : Integer;
665begin
666 case type_ of
667 // simple types
668 TType.Bool_ : prot.ReadBool();
669 TType.Byte_ : prot.ReadByte();
670 TType.I16 : prot.ReadI16();
671 TType.I32 : prot.ReadI32();
672 TType.I64 : prot.ReadI64();
673 TType.Double_ : prot.ReadDouble();
674 TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it.
675
676 // structured types
677 TType.Struct : begin
678 prot.ReadStructBegin();
679 while TRUE do begin
680 field := prot.ReadFieldBegin();
681 if (field.Type_ = TType.Stop) then Break;
682 Skip(prot, field.Type_);
683 prot.ReadFieldEnd();
684 end;
685 prot.ReadStructEnd();
686 end;
687
688 TType.Map : begin
689 map := prot.ReadMapBegin();
690 for i := 0 to map.Count-1 do begin
691 Skip(prot, map.KeyType);
692 Skip(prot, map.ValueType);
693 end;
694 prot.ReadMapEnd();
695 end;
696
697 TType.Set_ : begin
698 set_ := prot.ReadSetBegin();
699 for i := 0 to set_.Count-1
700 do Skip( prot, set_.ElementType);
701 prot.ReadSetEnd();
702 end;
703
704 TType.List : begin
705 list := prot.ReadListBegin();
706 for i := 0 to list.Count-1
707 do Skip( prot, list.ElementType);
708 prot.ReadListEnd();
709 end;
710
711 else
712 ASSERT( FALSE); // any new types?
713 end;
714end;
715
716{ TStructImpl }
717
718constructor TStructImpl.Create(const AName: string);
719begin
720 inherited Create;
721 FName := AName;
722end;
723
724function TStructImpl.GetName: string;
725begin
726 Result := FName;
727end;
728
729procedure TStructImpl.SetName(const Value: string);
730begin
731 FName := Value;
732end;
733
734{ TMapImpl }
735
Jens Geyer96eff172015-03-02 01:30:05 +0100736constructor TMapImpl.Create( AKeyType, AValueType: TType; ACount: Integer);
Jens Geyerd5436f52014-10-03 19:50:38 +0200737begin
738 inherited Create;
739 FValueType := AValueType;
740 FKeyType := AKeyType;
741 FCount := ACount;
742end;
743
744constructor TMapImpl.Create;
745begin
746 inherited Create;
747end;
748
749function TMapImpl.GetCount: Integer;
750begin
751 Result := FCount;
752end;
753
754function TMapImpl.GetKeyType: TType;
755begin
756 Result := FKeyType;
757end;
758
759function TMapImpl.GetValueType: TType;
760begin
761 Result := FValueType;
762end;
763
764procedure TMapImpl.SetCount(Value: Integer);
765begin
766 FCount := Value;
767end;
768
769procedure TMapImpl.SetKeyType(Value: TType);
770begin
771 FKeyType := Value;
772end;
773
774procedure TMapImpl.SetValueType(Value: TType);
775begin
776 FValueType := Value;
777end;
778
779{ IMessage }
780
781constructor TMessageImpl.Create(AName: string; AMessageType: TMessageType;
782 ASeqID: Integer);
783begin
784 inherited Create;
785 FName := AName;
786 FMessageType := AMessageType;
787 FSeqID := ASeqID;
788end;
789
790constructor TMessageImpl.Create;
791begin
792 inherited;
793end;
794
795function TMessageImpl.GetName: string;
796begin
797 Result := FName;
798end;
799
800function TMessageImpl.GetSeqID: Integer;
801begin
802 Result := FSeqID;
803end;
804
805function TMessageImpl.GetType: TMessageType;
806begin
807 Result := FMessageType;
808end;
809
810procedure TMessageImpl.SetName(const Value: string);
811begin
812 FName := Value;
813end;
814
815procedure TMessageImpl.SetSeqID(Value: Integer);
816begin
817 FSeqID := Value;
818end;
819
820procedure TMessageImpl.SetType(Value: TMessageType);
821begin
822 FMessageType := Value;
823end;
824
825{ ISet }
826
827constructor TSetImpl.Create( AElementType: TType; ACount: Integer);
828begin
829 inherited Create;
830 FCount := ACount;
831 FElementType := AElementType;
832end;
833
834constructor TSetImpl.Create;
835begin
836 inherited Create;
837end;
838
839function TSetImpl.GetCount: Integer;
840begin
841 Result := FCount;
842end;
843
844function TSetImpl.GetElementType: TType;
845begin
846 Result := FElementType;
847end;
848
849procedure TSetImpl.SetCount(Value: Integer);
850begin
851 FCount := Value;
852end;
853
854procedure TSetImpl.SetElementType(Value: TType);
855begin
856 FElementType := Value;
857end;
858
859{ IList }
860
861constructor TListImpl.Create( AElementType: TType; ACount: Integer);
862begin
863 inherited Create;
864 FCount := ACount;
865 FElementType := AElementType;
866end;
867
868constructor TListImpl.Create;
869begin
870 inherited Create;
871end;
872
873function TListImpl.GetCount: Integer;
874begin
875 Result := FCount;
876end;
877
878function TListImpl.GetElementType: TType;
879begin
880 Result := FElementType;
881end;
882
883procedure TListImpl.SetCount(Value: Integer);
884begin
885 FCount := Value;
886end;
887
888procedure TListImpl.SetElementType(Value: TType);
889begin
890 FElementType := Value;
891end;
892
893{ TBinaryProtocolImpl }
894
895constructor TBinaryProtocolImpl.Create( const trans: ITransport);
896begin
897 //no inherited
898 Create( trans, False, True);
899end;
900
901constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead,
902 strictWrite: Boolean);
903begin
904 inherited Create( trans );
905 FStrictRead := strictRead;
906 FStrictWrite := strictWrite;
907end;
908
909function TBinaryProtocolImpl.ReadAll( var buf: TBytes; off,
910 len: Integer): Integer;
911begin
912 Result := FTrans.ReadAll( buf, off, len );
913end;
914
915function TBinaryProtocolImpl.ReadBinary: TBytes;
916var
917 size : Integer;
918 buf : TBytes;
919begin
920 size := ReadI32;
921 SetLength( buf, size );
922 FTrans.ReadAll( buf, 0, size);
923 Result := buf;
924end;
925
926function TBinaryProtocolImpl.ReadBool: Boolean;
927begin
928 Result := ReadByte = 1;
929end;
930
931function TBinaryProtocolImpl.ReadByte: ShortInt;
932var
933 bin : TBytes;
934begin
935 SetLength( bin, 1);
936 ReadAll( bin, 0, 1 );
937 Result := ShortInt( bin[0]);
938end;
939
940function TBinaryProtocolImpl.ReadDouble: Double;
941begin
942 Result := ConvertInt64ToDouble( ReadI64 )
943end;
944
945function TBinaryProtocolImpl.ReadFieldBegin: IField;
946var
947 field : IField;
948begin
949 field := TFieldImpl.Create;
950 field.Type_ := TType( ReadByte);
951 if ( field.Type_ <> TType.Stop ) then
952 begin
953 field.Id := ReadI16;
954 end;
955 Result := field;
956end;
957
958procedure TBinaryProtocolImpl.ReadFieldEnd;
959begin
960
961end;
962
963function TBinaryProtocolImpl.ReadI16: SmallInt;
964var
965 i16in : TBytes;
966begin
967 SetLength( i16in, 2 );
968 ReadAll( i16in, 0, 2);
969 Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF));
970end;
971
972function TBinaryProtocolImpl.ReadI32: Integer;
973var
974 i32in : TBytes;
975begin
976 SetLength( i32in, 4 );
977 ReadAll( i32in, 0, 4);
978
979 Result := Integer(
980 ((i32in[0] and $FF) shl 24) or
981 ((i32in[1] and $FF) shl 16) or
982 ((i32in[2] and $FF) shl 8) or
983 (i32in[3] and $FF));
984
985end;
986
987function TBinaryProtocolImpl.ReadI64: Int64;
988var
989 i64in : TBytes;
990begin
991 SetLength( i64in, 8);
992 ReadAll( i64in, 0, 8);
993 Result :=
994 (Int64( i64in[0] and $FF) shl 56) or
995 (Int64( i64in[1] and $FF) shl 48) or
996 (Int64( i64in[2] and $FF) shl 40) or
997 (Int64( i64in[3] and $FF) shl 32) or
998 (Int64( i64in[4] and $FF) shl 24) or
999 (Int64( i64in[5] and $FF) shl 16) or
1000 (Int64( i64in[6] and $FF) shl 8) or
1001 (Int64( i64in[7] and $FF));
1002end;
1003
1004function TBinaryProtocolImpl.ReadListBegin: IList;
1005var
1006 list : IList;
1007begin
1008 list := TListImpl.Create;
1009 list.ElementType := TType( ReadByte );
1010 list.Count := ReadI32;
1011 Result := list;
1012end;
1013
1014procedure TBinaryProtocolImpl.ReadListEnd;
1015begin
1016
1017end;
1018
1019function TBinaryProtocolImpl.ReadMapBegin: IMap;
1020var
1021 map : IMap;
1022begin
1023 map := TMapImpl.Create;
1024 map.KeyType := TType( ReadByte );
1025 map.ValueType := TType( ReadByte );
1026 map.Count := ReadI32;
1027 Result := map;
1028end;
1029
1030procedure TBinaryProtocolImpl.ReadMapEnd;
1031begin
1032
1033end;
1034
1035function TBinaryProtocolImpl.ReadMessageBegin: IMessage;
1036var
1037 size : Integer;
1038 version : Integer;
1039 message : IMessage;
1040begin
1041 message := TMessageImpl.Create;
1042 size := ReadI32;
1043 if (size < 0) then
1044 begin
1045 version := size and Integer( VERSION_MASK);
1046 if ( version <> Integer( VERSION_1)) then
1047 begin
1048 raise TProtocolException.Create(TProtocolException.BAD_VERSION, 'Bad version in ReadMessageBegin: ' + IntToStr(version) );
1049 end;
1050 message.Type_ := TMessageType( size and $000000ff);
1051 message.Name := ReadString;
1052 message.SeqID := ReadI32;
1053 end else
1054 begin
1055 if FStrictRead then
1056 begin
1057 raise TProtocolException.Create( TProtocolException.BAD_VERSION, 'Missing version in readMessageBegin, old client?' );
1058 end;
1059 message.Name := ReadStringBody( size );
1060 message.Type_ := TMessageType( ReadByte );
1061 message.SeqID := ReadI32;
1062 end;
1063 Result := message;
1064end;
1065
1066procedure TBinaryProtocolImpl.ReadMessageEnd;
1067begin
1068 inherited;
1069
1070end;
1071
1072function TBinaryProtocolImpl.ReadSetBegin: ISet;
1073var
1074 set_ : ISet;
1075begin
1076 set_ := TSetImpl.Create;
1077 set_.ElementType := TType( ReadByte );
1078 set_.Count := ReadI32;
1079 Result := set_;
1080end;
1081
1082procedure TBinaryProtocolImpl.ReadSetEnd;
1083begin
1084
1085end;
1086
1087function TBinaryProtocolImpl.ReadStringBody( size: Integer): string;
1088var
1089 buf : TBytes;
1090begin
1091 SetLength( buf, size );
1092 FTrans.ReadAll( buf, 0, size );
1093 Result := TEncoding.UTF8.GetString( buf);
1094end;
1095
1096function TBinaryProtocolImpl.ReadStructBegin: IStruct;
1097begin
1098 Result := TStructImpl.Create('');
1099end;
1100
1101procedure TBinaryProtocolImpl.ReadStructEnd;
1102begin
1103 inherited;
1104
1105end;
1106
1107procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes);
1108var iLen : Integer;
1109begin
1110 iLen := Length(b);
1111 WriteI32( iLen);
1112 if iLen > 0 then FTrans.Write(b, 0, iLen);
1113end;
1114
1115procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
1116begin
1117 if b then
1118 begin
1119 WriteByte( 1 );
1120 end else
1121 begin
1122 WriteByte( 0 );
1123 end;
1124end;
1125
1126procedure TBinaryProtocolImpl.WriteByte(b: ShortInt);
1127var
1128 a : TBytes;
1129begin
1130 SetLength( a, 1);
1131 a[0] := Byte( b );
1132 FTrans.Write( a, 0, 1 );
1133end;
1134
1135procedure TBinaryProtocolImpl.WriteDouble( const d: Double);
1136begin
1137 WriteI64(ConvertDoubleToInt64(d));
1138end;
1139
1140procedure TBinaryProtocolImpl.WriteFieldBegin( const field: IField);
1141begin
1142 WriteByte(ShortInt(field.Type_));
1143 WriteI16(field.ID);
1144end;
1145
1146procedure TBinaryProtocolImpl.WriteFieldEnd;
1147begin
1148
1149end;
1150
1151procedure TBinaryProtocolImpl.WriteFieldStop;
1152begin
1153 WriteByte(ShortInt(TType.Stop));
1154end;
1155
1156procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt);
1157var
1158 i16out : TBytes;
1159begin
1160 SetLength( i16out, 2);
1161 i16out[0] := Byte($FF and (i16 shr 8));
1162 i16out[1] := Byte($FF and i16);
1163 FTrans.Write( i16out );
1164end;
1165
1166procedure TBinaryProtocolImpl.WriteI32(i32: Integer);
1167var
1168 i32out : TBytes;
1169begin
1170 SetLength( i32out, 4);
1171 i32out[0] := Byte($FF and (i32 shr 24));
1172 i32out[1] := Byte($FF and (i32 shr 16));
1173 i32out[2] := Byte($FF and (i32 shr 8));
1174 i32out[3] := Byte($FF and i32);
1175 FTrans.Write( i32out, 0, 4);
1176end;
1177
1178procedure TBinaryProtocolImpl.WriteI64( const i64: Int64);
1179var
1180 i64out : TBytes;
1181begin
1182 SetLength( i64out, 8);
1183 i64out[0] := Byte($FF and (i64 shr 56));
1184 i64out[1] := Byte($FF and (i64 shr 48));
1185 i64out[2] := Byte($FF and (i64 shr 40));
1186 i64out[3] := Byte($FF and (i64 shr 32));
1187 i64out[4] := Byte($FF and (i64 shr 24));
1188 i64out[5] := Byte($FF and (i64 shr 16));
1189 i64out[6] := Byte($FF and (i64 shr 8));
1190 i64out[7] := Byte($FF and i64);
1191 FTrans.Write( i64out, 0, 8);
1192end;
1193
1194procedure TBinaryProtocolImpl.WriteListBegin( const list: IList);
1195begin
1196 WriteByte(ShortInt(list.ElementType));
1197 WriteI32(list.Count);
1198end;
1199
1200procedure TBinaryProtocolImpl.WriteListEnd;
1201begin
1202
1203end;
1204
1205procedure TBinaryProtocolImpl.WriteMapBegin( const map: IMap);
1206begin
1207 WriteByte(ShortInt(map.KeyType));
1208 WriteByte(ShortInt(map.ValueType));
1209 WriteI32(map.Count);
1210end;
1211
1212procedure TBinaryProtocolImpl.WriteMapEnd;
1213begin
1214
1215end;
1216
1217procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: IMessage);
1218var
1219 version : Cardinal;
1220begin
1221 if FStrictWrite then
1222 begin
1223 version := VERSION_1 or Cardinal( msg.Type_);
1224 WriteI32( Integer( version) );
1225 WriteString( msg.Name);
1226 WriteI32( msg.SeqID);
1227 end else
1228 begin
1229 WriteString( msg.Name);
1230 WriteByte(ShortInt( msg.Type_));
1231 WriteI32( msg.SeqID);
1232 end;
1233end;
1234
1235procedure TBinaryProtocolImpl.WriteMessageEnd;
1236begin
1237
1238end;
1239
1240procedure TBinaryProtocolImpl.WriteSetBegin( const set_: ISet);
1241begin
1242 WriteByte(ShortInt(set_.ElementType));
1243 WriteI32(set_.Count);
1244end;
1245
1246procedure TBinaryProtocolImpl.WriteSetEnd;
1247begin
1248
1249end;
1250
1251procedure TBinaryProtocolImpl.WriteStructBegin( const struc: IStruct);
1252begin
1253
1254end;
1255
1256procedure TBinaryProtocolImpl.WriteStructEnd;
1257begin
1258
1259end;
1260
1261{ TProtocolException }
1262
1263constructor TProtocolException.Create;
1264begin
1265 inherited Create('');
1266 FType := UNKNOWN;
1267end;
1268
1269constructor TProtocolException.Create(type_: Integer);
1270begin
1271 inherited Create('');
1272 FType := type_;
1273end;
1274
1275constructor TProtocolException.Create(type_: Integer; const msg: string);
1276begin
1277 inherited Create( msg );
1278 FType := type_;
1279end;
1280
1281{ TThriftStringBuilder }
1282
1283function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
1284begin
1285 Result := Append( string( RawByteString(Value)) );
1286end;
1287
1288function TThriftStringBuilder.Append(
1289 const Value: IThriftContainer): TStringBuilder;
1290begin
1291 Result := Append( Value.ToString );
1292end;
1293
1294{ TBinaryProtocolImpl.TFactory }
1295
1296constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
1297begin
1298 inherited Create;
1299 FStrictRead := AStrictRead;
1300 FStrictWrite := AStrictWrite;
1301end;
1302
1303constructor TBinaryProtocolImpl.TFactory.Create;
1304begin
1305 //no inherited;
1306 Create( False, True )
1307end;
1308
1309function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
1310begin
1311 Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite);
1312end;
1313
1314
1315{ TProtocolDecorator }
1316
1317constructor TProtocolDecorator.Create( const aProtocol : IProtocol);
1318begin
1319 ASSERT( aProtocol <> nil);
1320 inherited Create( aProtocol.Transport);
1321 FWrappedProtocol := aProtocol;
1322end;
1323
1324
1325procedure TProtocolDecorator.WriteMessageBegin( const msg: IMessage);
1326begin
1327 FWrappedProtocol.WriteMessageBegin( msg);
1328end;
1329
1330
1331procedure TProtocolDecorator.WriteMessageEnd;
1332begin
1333 FWrappedProtocol.WriteMessageEnd;
1334end;
1335
1336
1337procedure TProtocolDecorator.WriteStructBegin( const struc: IStruct);
1338begin
1339 FWrappedProtocol.WriteStructBegin( struc);
1340end;
1341
1342
1343procedure TProtocolDecorator.WriteStructEnd;
1344begin
1345 FWrappedProtocol.WriteStructEnd;
1346end;
1347
1348
1349procedure TProtocolDecorator.WriteFieldBegin( const field: IField);
1350begin
1351 FWrappedProtocol.WriteFieldBegin( field);
1352end;
1353
1354
1355procedure TProtocolDecorator.WriteFieldEnd;
1356begin
1357 FWrappedProtocol.WriteFieldEnd;
1358end;
1359
1360
1361procedure TProtocolDecorator.WriteFieldStop;
1362begin
1363 FWrappedProtocol.WriteFieldStop;
1364end;
1365
1366
1367procedure TProtocolDecorator.WriteMapBegin( const map: IMap);
1368begin
1369 FWrappedProtocol.WriteMapBegin( map);
1370end;
1371
1372
1373procedure TProtocolDecorator.WriteMapEnd;
1374begin
1375 FWrappedProtocol.WriteMapEnd;
1376end;
1377
1378
1379procedure TProtocolDecorator.WriteListBegin( const list: IList);
1380begin
1381 FWrappedProtocol.WriteListBegin( list);
1382end;
1383
1384
1385procedure TProtocolDecorator.WriteListEnd();
1386begin
1387 FWrappedProtocol.WriteListEnd();
1388end;
1389
1390
1391procedure TProtocolDecorator.WriteSetBegin( const set_: ISet );
1392begin
1393 FWrappedProtocol.WriteSetBegin( set_);
1394end;
1395
1396
1397procedure TProtocolDecorator.WriteSetEnd();
1398begin
1399 FWrappedProtocol.WriteSetEnd();
1400end;
1401
1402
1403procedure TProtocolDecorator.WriteBool( b: Boolean);
1404begin
1405 FWrappedProtocol.WriteBool( b);
1406end;
1407
1408
1409procedure TProtocolDecorator.WriteByte( b: ShortInt);
1410begin
1411 FWrappedProtocol.WriteByte( b);
1412end;
1413
1414
1415procedure TProtocolDecorator.WriteI16( i16: SmallInt);
1416begin
1417 FWrappedProtocol.WriteI16( i16);
1418end;
1419
1420
1421procedure TProtocolDecorator.WriteI32( i32: Integer);
1422begin
1423 FWrappedProtocol.WriteI32( i32);
1424end;
1425
1426
1427procedure TProtocolDecorator.WriteI64( const i64: Int64);
1428begin
1429 FWrappedProtocol.WriteI64( i64);
1430end;
1431
1432
1433procedure TProtocolDecorator.WriteDouble( const d: Double);
1434begin
1435 FWrappedProtocol.WriteDouble( d);
1436end;
1437
1438
1439procedure TProtocolDecorator.WriteString( const s: string );
1440begin
1441 FWrappedProtocol.WriteString( s);
1442end;
1443
1444
1445procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString);
1446begin
1447 FWrappedProtocol.WriteAnsiString( s);
1448end;
1449
1450
1451procedure TProtocolDecorator.WriteBinary( const b: TBytes);
1452begin
1453 FWrappedProtocol.WriteBinary( b);
1454end;
1455
1456
1457function TProtocolDecorator.ReadMessageBegin: IMessage;
1458begin
1459 result := FWrappedProtocol.ReadMessageBegin;
1460end;
1461
1462
1463procedure TProtocolDecorator.ReadMessageEnd();
1464begin
1465 FWrappedProtocol.ReadMessageEnd();
1466end;
1467
1468
1469function TProtocolDecorator.ReadStructBegin: IStruct;
1470begin
1471 result := FWrappedProtocol.ReadStructBegin;
1472end;
1473
1474
1475procedure TProtocolDecorator.ReadStructEnd;
1476begin
1477 FWrappedProtocol.ReadStructEnd;
1478end;
1479
1480
1481function TProtocolDecorator.ReadFieldBegin: IField;
1482begin
1483 result := FWrappedProtocol.ReadFieldBegin;
1484end;
1485
1486
1487procedure TProtocolDecorator.ReadFieldEnd();
1488begin
1489 FWrappedProtocol.ReadFieldEnd();
1490end;
1491
1492
1493function TProtocolDecorator.ReadMapBegin: IMap;
1494begin
1495 result := FWrappedProtocol.ReadMapBegin;
1496end;
1497
1498
1499procedure TProtocolDecorator.ReadMapEnd();
1500begin
1501 FWrappedProtocol.ReadMapEnd();
1502end;
1503
1504
1505function TProtocolDecorator.ReadListBegin: IList;
1506begin
1507 result := FWrappedProtocol.ReadListBegin;
1508end;
1509
1510
1511procedure TProtocolDecorator.ReadListEnd();
1512begin
1513 FWrappedProtocol.ReadListEnd();
1514end;
1515
1516
1517function TProtocolDecorator.ReadSetBegin: ISet;
1518begin
1519 result := FWrappedProtocol.ReadSetBegin;
1520end;
1521
1522
1523procedure TProtocolDecorator.ReadSetEnd();
1524begin
1525 FWrappedProtocol.ReadSetEnd();
1526end;
1527
1528
1529function TProtocolDecorator.ReadBool: Boolean;
1530begin
1531 result := FWrappedProtocol.ReadBool;
1532end;
1533
1534
1535function TProtocolDecorator.ReadByte: ShortInt;
1536begin
1537 result := FWrappedProtocol.ReadByte;
1538end;
1539
1540
1541function TProtocolDecorator.ReadI16: SmallInt;
1542begin
1543 result := FWrappedProtocol.ReadI16;
1544end;
1545
1546
1547function TProtocolDecorator.ReadI32: Integer;
1548begin
1549 result := FWrappedProtocol.ReadI32;
1550end;
1551
1552
1553function TProtocolDecorator.ReadI64: Int64;
1554begin
1555 result := FWrappedProtocol.ReadI64;
1556end;
1557
1558
1559function TProtocolDecorator.ReadDouble:Double;
1560begin
1561 result := FWrappedProtocol.ReadDouble;
1562end;
1563
1564
1565function TProtocolDecorator.ReadBinary: TBytes;
1566begin
1567 result := FWrappedProtocol.ReadBinary;
1568end;
1569
1570
1571function TProtocolDecorator.ReadString: string;
1572begin
1573 result := FWrappedProtocol.ReadString;
1574end;
1575
1576
1577function TProtocolDecorator.ReadAnsiString: AnsiString;
1578begin
1579 result := FWrappedProtocol.ReadAnsiString;
1580end;
1581
1582
1583
1584end.
1585