Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 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;