comparison Cassandra/lib/Thrift/Protocol.pm @ 0:a2f0a2c135cf

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