File Coverage

blib/lib/Thrift/Protocol.pm
Criterion Covered Total %
statement 32 204 15.6
branch 0 52 0.0
condition 0 3 0.0
subroutine 10 55 18.1
pod 0 43 0.0
total 42 357 11.7


line stmt bran cond sub pod time code
1             #
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             #require 5.6.0;
21 4     4   25 use strict;
  4         7  
  4         118  
22 4     4   80 use warnings;
  4         9  
  4         122  
23              
24 4     4   23 use Thrift;
  4         8  
  4         178  
25              
26             #
27             # Protocol exceptions
28             #
29             package # hide
30             TProtocolException;
31 4     4   29 use base('Thrift::TException');
  4         13  
  4         2328  
32              
33 4     4   24 use constant UNKNOWN => 0;
  4         8  
  4         201  
34 4     4   25 use constant INVALID_DATA => 1;
  4         8  
  4         170  
35 4     4   19 use constant NEGATIVE_SIZE => 2;
  4         6  
  4         187  
36 4     4   19 use constant SIZE_LIMIT => 3;
  4         9  
  4         159  
37 4     4   26 use constant BAD_VERSION => 4;
  4         7  
  4         9407  
38              
39             sub new {
40 0     0   0 my $classname = shift;
41              
42 0         0 my $self = $classname->SUPER::new();
43              
44 0         0 return bless($self,$classname);
45             }
46              
47             #
48             # Protocol base class module.
49             #
50             package # hide
51             Thrift::Protocol;
52              
53             sub new {
54 1     1 0 3 my $classname = shift;
55 1         4 my $self = {};
56              
57 1         3 my $trans = shift;
58 1         4 $self->{trans}= $trans;
59              
60 1         4 return bless($self,$classname);
61             }
62              
63             sub getTransport
64             {
65 0     0 0   my $self = shift;
66              
67 0           return $self->{trans};
68             }
69              
70             #
71             # Writes the message header
72             #
73             # @param string $name Function name
74             # @param int $type message type TMessageType::CALL or TMessageType::REPLY
75             # @param int $seqid The sequence id of this message
76             #
77             sub writeMessageBegin
78             {
79 0     0 0   my ($name, $type, $seqid);
80 0           die "abstract";
81             }
82              
83             #
84             # Close the message
85             #
86             sub writeMessageEnd {
87 0     0 0   die "abstract";
88             }
89              
90             #
91             # Writes a struct header.
92             #
93             # @param string $name Struct name
94             # @throws TException on write error
95             # @return int How many bytes written
96             #
97             sub writeStructBegin {
98 0     0 0   my ($name);
99              
100 0           die "abstract";
101             }
102              
103             #
104             # Close a struct.
105             #
106             # @throws TException on write error
107             # @return int How many bytes written
108             #
109             sub writeStructEnd {
110 0     0 0   die "abstract";
111             }
112              
113             #
114             # Starts a field.
115             #
116             # @param string $name Field name
117             # @param int $type Field type
118             # @param int $fid Field id
119             # @throws TException on write error
120             # @return int How many bytes written
121             #
122             sub writeFieldBegin {
123 0     0 0   my ($fieldName, $fieldType, $fieldId);
124              
125 0           die "abstract";
126             }
127              
128             sub writeFieldEnd {
129 0     0 0   die "abstract";
130             }
131              
132             sub writeFieldStop {
133 0     0 0   die "abstract";
134             }
135              
136             sub writeMapBegin {
137 0     0 0   my ($keyType, $valType, $size);
138              
139 0           die "abstract";
140             }
141              
142             sub writeMapEnd {
143 0     0 0   die "abstract";
144             }
145              
146             sub writeListBegin {
147 0     0 0   my ($elemType, $size);
148 0           die "abstract";
149             }
150              
151             sub writeListEnd {
152 0     0 0   die "abstract";
153             }
154              
155             sub writeSetBegin {
156 0     0 0   my ($elemType, $size);
157 0           die "abstract";
158             }
159              
160             sub writeSetEnd {
161 0     0 0   die "abstract";
162             }
163              
164             sub writeBool {
165 0     0 0   my ($bool);
166 0           die "abstract";
167             }
168              
169             sub writeByte {
170 0     0 0   my ($byte);
171 0           die "abstract";
172             }
173              
174             sub writeI16 {
175 0     0 0   my ($i16);
176 0           die "abstract";
177             }
178              
179             sub writeI32 {
180 0     0 0   my ($i32);
181 0           die "abstract";
182             }
183              
184             sub writeI64 {
185 0     0 0   my ($i64);
186 0           die "abstract";
187             }
188              
189             sub writeDouble {
190 0     0 0   my ($dub);
191 0           die "abstract";
192             }
193              
194             sub writeString
195             {
196 0     0 0   my ($str);
197 0           die "abstract";
198             }
199              
200             #
201             # Reads the message header
202             #
203             # @param string $name Function name
204             # @param int $type message type TMessageType::CALL or TMessageType::REPLY
205             # @parem int $seqid The sequence id of this message
206             #
207             sub readMessageBegin
208             {
209 0     0 0   my ($name, $type, $seqid);
210 0           die "abstract";
211             }
212              
213             #
214             # Read the close of message
215             #
216             sub readMessageEnd
217             {
218 0     0 0   die "abstract";
219             }
220              
221             sub readStructBegin
222             {
223 0     0 0   my($name);
224              
225 0           die "abstract";
226             }
227              
228             sub readStructEnd
229             {
230 0     0 0   die "abstract";
231             }
232              
233             sub readFieldBegin
234             {
235 0     0 0   my ($name, $fieldType, $fieldId);
236 0           die "abstract";
237             }
238              
239             sub readFieldEnd
240             {
241 0     0 0   die "abstract";
242             }
243              
244             sub readMapBegin
245             {
246 0     0 0   my ($keyType, $valType, $size);
247 0           die "abstract";
248             }
249              
250             sub readMapEnd
251             {
252 0     0 0   die "abstract";
253             }
254              
255             sub readListBegin
256             {
257 0     0 0   my ($elemType, $size);
258 0           die "abstract";
259             }
260              
261             sub readListEnd
262             {
263 0     0 0   die "abstract";
264             }
265              
266             sub readSetBegin
267             {
268 0     0 0   my ($elemType, $size);
269 0           die "abstract";
270             }
271              
272             sub readSetEnd
273             {
274 0     0 0   die "abstract";
275             }
276              
277             sub readBool
278             {
279 0     0 0   my ($bool);
280 0           die "abstract";
281             }
282              
283             sub readByte
284             {
285 0     0 0   my ($byte);
286 0           die "abstract";
287             }
288              
289             sub readI16
290             {
291 0     0 0   my ($i16);
292 0           die "abstract";
293             }
294              
295             sub readI32
296             {
297 0     0 0   my ($i32);
298 0           die "abstract";
299             }
300              
301             sub readI64
302             {
303 0     0 0   my ($i64);
304 0           die "abstract";
305             }
306              
307             sub readDouble
308             {
309 0     0 0   my ($dub);
310 0           die "abstract";
311             }
312              
313             sub readString
314             {
315 0     0 0   my ($str);
316 0           die "abstract";
317             }
318              
319             #
320             # The skip function is a utility to parse over unrecognized data without
321             # causing corruption.
322             #
323             # @param TType $type What type is it
324             #
325             sub skip
326             {
327 0     0 0   my $self = shift;
328 0           my $type = shift;
329              
330 0           my $ref;
331             my $i;
332              
333 0 0         if($type == TType::BOOL)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
334             {
335 0           return $self->readBool(\$ref);
336             }
337             elsif($type == TType::BYTE){
338 0           return $self->readByte(\$ref);
339             }
340             elsif($type == TType::I16){
341 0           return $self->readI16(\$ref);
342             }
343             elsif($type == TType::I32){
344 0           return $self->readI32(\$ref);
345             }
346             elsif($type == TType::I64){
347 0           return $self->readI64(\$ref);
348             }
349             elsif($type == TType::DOUBLE){
350 0           return $self->readDouble(\$ref);
351             }
352             elsif($type == TType::STRING)
353             {
354 0           return $self->readString(\$ref);
355             }
356             elsif($type == TType::STRUCT)
357             {
358 0           $self->readStructBegin(\$ref);
359 0           while (1) {
360 0           my ($ftype,$fid);
361 0           $self->readFieldBegin(\$ref, \$ftype, \$fid);
362 0 0         if ($ftype == TType::STOP) {
363 0           last;
364             }
365 0           $self->skip($ftype);
366 0           $self->readFieldEnd();
367             }
368 0           $self->readStructEnd();
369 0           return;
370             }
371             elsif($type == TType::MAP)
372             {
373 0           my($keyType,$valType,$size);
374 0           $self->readMapBegin(\$keyType, \$valType, \$size);
375 0           for ($i = 0; $i < $size; $i++) {
376 0           $self->skip($keyType);
377 0           $self->skip($valType);
378             }
379 0           $self->readMapEnd();
380 0           return;
381             }
382             elsif($type == TType::SET)
383             {
384 0           my ($elemType,$size);
385 0           $self->readSetBegin(\$elemType, \$size);
386 0           for ($i = 0; $i < $size; $i++) {
387 0           $self->skip($elemType);
388             }
389 0           $self->readSetEnd();
390 0           return;
391             }
392             elsif($type == TType::LIST)
393             {
394 0           my ($elemType,$size);
395 0           $self->readListBegin(\$elemType, \$size);
396 0           for ($i = 0; $i < $size; $i++) {
397 0           $self->skip($elemType);
398             }
399 0           $self->readListEnd();
400 0           return;
401             }
402              
403 0           die new Thrift::TException("Type $type not recognised --- corrupt data?");
404              
405             }
406              
407             #
408             # Utility for skipping binary data
409             #
410             # @param TTransport $itrans TTransport object
411             # @param int $type Field type
412             #
413             sub skipBinary
414             {
415 0     0 0   my $self = shift;
416 0           my $itrans = shift;
417 0           my $type = shift;
418              
419 0 0 0       if($type == TType::BOOL)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
420             {
421 0           return $itrans->readAll(1);
422             }
423             elsif($type == TType::BYTE)
424             {
425 0           return $itrans->readAll(1);
426             }
427             elsif($type == TType::I16)
428             {
429 0           return $itrans->readAll(2);
430             }
431             elsif($type == TType::I32)
432             {
433 0           return $itrans->readAll(4);
434             }
435             elsif($type == TType::I64)
436             {
437 0           return $itrans->readAll(8);
438             }
439             elsif($type == TType::DOUBLE)
440             {
441 0           return $itrans->readAll(8);
442             }
443             elsif( $type == TType::STRING )
444             {
445 0           my @len = unpack('N', $itrans->readAll(4));
446 0           my $len = $len[0];
447 0 0         if ($len > 0x7fffffff) {
448 0           $len = 0 - (($len - 1) ^ 0xffffffff);
449             }
450 0           return 4 + $itrans->readAll($len);
451             }
452             elsif( $type == TType::STRUCT )
453             {
454 0           my $result = 0;
455 0           while (1) {
456 0           my $ftype = 0;
457 0           my $fid = 0;
458 0           my $data = $itrans->readAll(1);
459 0           my @arr = unpack('c', $data);
460 0           $ftype = $arr[0];
461 0 0         if ($ftype == TType::STOP) {
462 0           last;
463             }
464             # I16 field id
465 0           $result += $itrans->readAll(2);
466 0           $result += $self->skipBinary($itrans, $ftype);
467             }
468 0           return $result;
469             }
470             elsif($type == TType::MAP)
471             {
472             # Ktype
473 0           my $data = $itrans->readAll(1);
474 0           my @arr = unpack('c', $data);
475 0           my $ktype = $arr[0];
476             # Vtype
477 0           $data = $itrans->readAll(1);
478 0           @arr = unpack('c', $data);
479 0           my $vtype = $arr[0];
480             # Size
481 0           $data = $itrans->readAll(4);
482 0           @arr = unpack('N', $data);
483 0           my $size = $arr[0];
484 0 0         if ($size > 0x7fffffff) {
485 0           $size = 0 - (($size - 1) ^ 0xffffffff);
486             }
487 0           my $result = 6;
488 0           for (my $i = 0; $i < $size; $i++) {
489 0           $result += $self->skipBinary($itrans, $ktype);
490 0           $result += $self->skipBinary($itrans, $vtype);
491             }
492 0           return $result;
493             }
494             elsif($type == TType::SET || $type == TType::LIST)
495             {
496             # Vtype
497 0           my $data = $itrans->readAll(1);
498 0           my @arr = unpack('c', $data);
499 0           my $vtype = $arr[0];
500             # Size
501 0           $data = $itrans->readAll(4);
502 0           @arr = unpack('N', $data);
503 0           my $size = $arr[0];
504 0 0         if ($size > 0x7fffffff) {
505 0           $size = 0 - (($size - 1) ^ 0xffffffff);
506             }
507 0           my $result = 5;
508 0           for (my $i = 0; $i < $size; $i++) {
509 0           $result += $self->skipBinary($itrans, $vtype);
510             }
511 0           return $result;
512             }
513              
514 0           die new Thrift::TException("Type $type not recognised --- corrupt data?");
515             }
516              
517             #
518             # Protocol factory creates protocol objects from transports
519             #
520             package # hide
521             TProtocolFactory;
522              
523              
524             sub new {
525 0     0     my $classname = shift;
526 0           my $self = {};
527              
528 0           return bless($self,$classname);
529             }
530              
531             #
532             # Build a protocol from the base transport
533             #
534             # @return TProtcol protocol
535             #
536             sub getProtocol
537             {
538 0     0     my ($trans);
539 0           die "interface";
540             }
541              
542              
543             1;