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
 
22
use strict;
23
use warnings;
24
 
25
use utf8;
26
use Encode;
27
 
28
use Thrift;
29
use Thrift::Protocol;
30
 
31
use Bit::Vector;
32
 
33
#
34
# Binary implementation of the Thrift protocol.
35
#
36
package Thrift::BinaryProtocol;
37
use base('Thrift::Protocol');
38
 
39
use constant VERSION_MASK   => 0xffff0000;
40
use constant VERSION_1      => 0x80010000;
41
 
42
sub new
43
{
44
    my $classname = shift;
45
    my $trans     = shift;
46
    my $self      = $classname->SUPER::new($trans);
47
 
48
    return bless($self,$classname);
49
}
50
 
51
sub writeMessageBegin
52
{
53
    my $self = shift;
54
    my ($name, $type, $seqid) = @_;
55
 
56
    return
57
        $self->writeI32(VERSION_1 | $type) +
58
        $self->writeString($name) +
59
        $self->writeI32($seqid);
60
}
61
 
62
sub writeMessageEnd
63
{
64
    my $self = shift;
65
    return 0;
66
}
67
 
68
sub writeStructBegin{
69
    my $self = shift;
70
    my $name = shift;
71
    return 0;
72
}
73
 
74
sub writeStructEnd
75
{
76
    my $self = shift;
77
    return 0;
78
}
79
 
80
sub writeFieldBegin
81
{
82
    my $self = shift;
83
    my ($fieldName, $fieldType, $fieldId) = @_;
84
 
85
    return
86
        $self->writeByte($fieldType) +
87
        $self->writeI16($fieldId);
88
}
89
 
90
sub writeFieldEnd
91
{
92
    my $self = shift;
93
    return 0;
94
}
95
 
96
sub writeFieldStop
97
{
98
    my $self = shift;
99
    return $self->writeByte(TType::STOP);
100
}
101
 
102
sub writeMapBegin
103
{
104
    my $self = shift;
105
    my ($keyType, $valType, $size) = @_;
106
 
107
    return
108
        $self->writeByte($keyType) +
109
        $self->writeByte($valType) +
110
        $self->writeI32($size);
111
}
112
 
113
sub writeMapEnd
114
{
115
    my $self = shift;
116
    return 0;
117
}
118
 
119
sub writeListBegin
120
{
121
    my $self = shift;
122
    my ($elemType, $size) = @_;
123
 
124
    return
125
        $self->writeByte($elemType) +
126
        $self->writeI32($size);
127
}
128
 
129
sub writeListEnd
130
{
131
    my $self = shift;
132
    return 0;
133
}
134
 
135
sub writeSetBegin
136
{
137
    my $self = shift;
138
    my ($elemType, $size) = @_;
139
 
140
    return
141
        $self->writeByte($elemType) +
142
        $self->writeI32($size);
143
}
144
 
145
sub writeSetEnd
146
{
147
    my $self = shift;
148
    return 0;
149
}
150
 
151
sub writeBool
152
{
153
    my $self = shift;
154
    my $value = shift;
155
 
156
    my $data = pack('c', $value ? 1 : 0);
157
    $self->{trans}->write($data, 1);
158
    return 1;
159
}
160
 
161
sub writeByte
162
{
163
    my $self = shift;
164
    my $value= shift;
165
 
166
    my $data = pack('c', $value);
167
    $self->{trans}->write($data, 1);
168
    return 1;
169
}
170
 
171
sub writeI16
172
{
173
    my $self = shift;
174
    my $value= shift;
175
 
176
    my $data = pack('n', $value);
177
    $self->{trans}->write($data, 2);
178
    return 2;
179
}
180
 
181
sub writeI32
182
{
183
    my $self = shift;
184
    my $value= shift;
185
 
186
    my $data = pack('N', $value);
187
    $self->{trans}->write($data, 4);
188
    return 4;
189
}
190
 
191
sub writeI64
192
{
193
    my $self = shift;
194
    my $value= shift;
195
    my $data;
196
 
197
    my $vec;
198
    #stop annoying error
199
    $vec = Bit::Vector->new_Dec(64, $value);
200
    $data = pack 'NN', $vec->Chunk_Read(32, 32), $vec->Chunk_Read(32, 0);
201
 
202
    $self->{trans}->write($data, 8);
203
 
204
    return 8;
205
}
206
 
207
 
208
sub writeDouble
209
{
210
    my $self = shift;
211
    my $value= shift;
212
 
213
    my $data = pack('d', $value);
214
    $self->{trans}->write(scalar reverse($data), 8);
215
    return 8;
216
}
217
 
218
sub writeString{
219
    my $self = shift;
220
    my $value= shift;
221
 
222
    if( utf8::is_utf8($value) ){
223
        $value = Encode::encode_utf8($value);
224
    }
225
 
226
    my $len = length($value);
227
 
228
    my $result = $self->writeI32($len);
229
 
230
    if ($len) {
231
        $self->{trans}->write($value,$len);
232
    }
233
    return $result + $len;
234
  }
235
 
236
 
237
#
238
#All references
239
#
240
sub readMessageBegin
241
{
242
    my $self = shift;
243
    my ($name, $type, $seqid) = @_;
244
 
245
    my $version = 0;
246
    my $result = $self->readI32(\$version);
247
    if (($version & VERSION_MASK) > 0) {
248
      if (($version & VERSION_MASK) != VERSION_1) {
249
        die new Thrift::TException('Missing version identifier')
250
      }
251
      $$type = $version & 0x000000ff;
252
      return
253
          $result +
254
          $self->readString($name) +
255
          $self->readI32($seqid);
256
    } else { # old client support code
257
      return
258
        $result +
259
        $self->readStringBody($name, $version) + # version here holds the size of the string
260
        $self->readByte($type) +
261
        $self->readI32($seqid);
262
    }
263
}
264
 
265
sub readMessageEnd
266
{
267
    my $self = shift;
268
    return 0;
269
}
270
 
271
sub readStructBegin
272
{
273
    my $self = shift;
274
    my $name = shift;
275
 
276
    $$name = '';
277
 
278
    return 0;
279
}
280
 
281
sub readStructEnd
282
{
283
    my $self = shift;
284
    return 0;
285
}
286
 
287
sub readFieldBegin
288
{
289
    my $self = shift;
290
    my ($name, $fieldType, $fieldId) = @_;
291
 
292
    my $result = $self->readByte($fieldType);
293
 
294
    if ($$fieldType == TType::STOP) {
295
      $$fieldId = 0;
296
      return $result;
297
    }
298
 
299
    $result += $self->readI16($fieldId);
300
 
301
    return $result;
302
}
303
 
304
sub readFieldEnd() {
305
    my $self = shift;
306
    return 0;
307
}
308
 
309
sub readMapBegin
310
{
311
    my $self = shift;
312
    my ($keyType, $valType, $size) = @_;
313
 
314
    return
315
        $self->readByte($keyType) +
316
        $self->readByte($valType) +
317
        $self->readI32($size);
318
}
319
 
320
sub readMapEnd()
321
{
322
    my $self = shift;
323
    return 0;
324
}
325
 
326
sub readListBegin
327
{
328
    my $self = shift;
329
    my ($elemType, $size) = @_;
330
 
331
    return
332
        $self->readByte($elemType) +
333
        $self->readI32($size);
334
}
335
 
336
sub readListEnd
337
{
338
    my $self = shift;
339
    return 0;
340
}
341
 
342
sub readSetBegin
343
{
344
    my $self = shift;
345
    my ($elemType, $size) = @_;
346
 
347
    return
348
        $self->readByte($elemType) +
349
        $self->readI32($size);
350
}
351
 
352
sub readSetEnd
353
{
354
    my $self = shift;
355
    return 0;
356
}
357
 
358
sub readBool
359
{
360
    my $self  = shift;
361
    my $value = shift;
362
 
363
    my $data = $self->{trans}->readAll(1);
364
    my @arr = unpack('c', $data);
365
    $$value = $arr[0] == 1;
366
    return 1;
367
}
368
 
369
sub readByte
370
{
371
    my $self  = shift;
372
    my $value = shift;
373
 
374
    my $data = $self->{trans}->readAll(1);
375
    my @arr = unpack('c', $data);
376
    $$value = $arr[0];
377
    return 1;
378
}
379
 
380
sub readI16
381
{
382
    my $self  = shift;
383
    my $value = shift;
384
 
385
    my $data  = $self->{trans}->readAll(2);
386
 
387
    my @arr   = unpack('n', $data);
388
 
389
    $$value = $arr[0];
390
 
391
    if ($$value > 0x7fff) {
392
      $$value = 0 - (($$value - 1) ^ 0xffff);
393
    }
394
 
395
    return 2;
396
}
397
 
398
sub readI32
399
{
400
    my $self = shift;
401
    my $value= shift;
402
 
403
    my $data = $self->{trans}->readAll(4);
404
    my @arr = unpack('N', $data);
405
 
406
    $$value = $arr[0];
407
    if ($$value > 0x7fffffff) {
408
      $$value = 0 - (($$value - 1) ^ 0xffffffff);
409
    }
410
    return 4;
411
}
412
 
413
sub readI64
414
{
415
    my $self  = shift;
416
    my $value = shift;
417
 
418
    my $data = $self->{trans}->readAll(8);
419
 
420
    my ($hi,$lo)=unpack('NN',$data);
421
 
422
    my $vec = new Bit::Vector(64);
423
 
424
    $vec->Chunk_Store(32,32,$hi);
425
    $vec->Chunk_Store(32,0,$lo);
426
 
427
    $$value = $vec->to_Dec();
428
 
429
    return 8;
430
}
431
 
432
sub readDouble
433
{
434
    my $self  = shift;
435
    my $value = shift;
436
 
437
    my $data = scalar reverse($self->{trans}->readAll(8));
438
    my @arr = unpack('d', $data);
439
 
440
    $$value = $arr[0];
441
 
442
    return 8;
443
}
444
 
445
sub readString
446
{
447
    my $self  = shift;
448
    my $value = shift;
449
 
450
    my $len;
451
    my $result = $self->readI32(\$len);
452
 
453
    if ($len) {
454
      $$value = $self->{trans}->readAll($len);
455
    } else {
456
      $$value = '';
457
    }
458
 
459
    return $result + $len;
460
}
461
 
462
sub readStringBody
463
{
464
    my $self  = shift;
465
    my $value = shift;
466
    my $len   = shift;
467
 
468
    if ($len) {
469
      $$value = $self->{trans}->readAll($len);
470
    } else {
471
      $$value = '';
472
    }
473
 
474
    return $len;
475
}
476
 
477
#
478
# Binary Protocol Factory
479
#
480
package Thrift::BinaryProtocolFactory;
481
use base('TProtocolFactory');
482
 
483
sub new
484
{
485
    my $classname = shift;
486
    my $self      = $classname->SUPER::new();
487
 
488
    return bless($self,$classname);
489
}
490
 
491
sub getProtocol{
492
    my $self  = shift;
493
    my $trans = shift;
494
 
495
    return new Thrift::BinaryProtocol($trans);
496
}
497
 
498
1;