Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | 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
#import "TBinaryProtocol.h"
21
#import "TProtocolException.h"
22
 
23
int32_t VERSION_1 = 0x80010000;
24
int32_t VERSION_MASK = 0xffff0000;
25
 
26
 
27
static TBinaryProtocolFactory * gSharedFactory = nil;
28
 
29
@implementation TBinaryProtocolFactory
30
 
31
+ (TBinaryProtocolFactory *) sharedFactory {
32
  if (gSharedFactory == nil) {
33
    gSharedFactory = [[TBinaryProtocolFactory alloc] init];
34
  }
35
 
36
  return gSharedFactory;
37
}
38
 
39
- (TBinaryProtocol *) newProtocolOnTransport: (id <TTransport>) transport {
40
  return [[[TBinaryProtocol alloc] initWithTransport: transport] autorelease];
41
}
42
 
43
@end
44
 
45
 
46
 
47
@implementation TBinaryProtocol
48
 
49
- (id) initWithTransport: (id <TTransport>) transport
50
{
51
  return [self initWithTransport: transport strictRead: NO strictWrite: NO];
52
}
53
 
54
- (id) initWithTransport: (id <TTransport>) transport
55
              strictRead: (BOOL) strictRead
56
             strictWrite: (BOOL) strictWrite
57
{
58
  self = [super init];
59
  mTransport = [transport retain];
60
  mStrictRead = strictRead;
61
  mStrictWrite = strictWrite;
62
  return self;
63
}
64
 
65
 
66
- (int32_t) messageSizeLimit
67
{
68
  return mMessageSizeLimit;
69
}
70
 
71
 
72
- (void) setMessageSizeLimit: (int32_t) sizeLimit
73
{
74
  mMessageSizeLimit = sizeLimit;
75
}
76
 
77
 
78
- (void) dealloc
79
{
80
  [mTransport release];
81
  [super dealloc];
82
}
83
 
84
 
85
- (id <TTransport>) transport
86
{
87
  return mTransport;
88
}
89
 
90
 
91
- (NSString *) readStringBody: (int) size
92
{
93
  char * buffer = malloc(size+1);
94
  if (!buffer) {
95
    @throw [TProtocolException exceptionWithName: @"TProtocolException"
96
                                          reason: [NSString stringWithFormat: @"Unable to allocate memory in %s, size: %i",
97
                                                   __PRETTY_FUNCTION__,
98
                                                   size]];;
99
  }
100
  [mTransport readAll: (uint8_t *) buffer offset: 0 length: size];
101
  buffer[size] = 0;
102
  NSString * result = [NSString stringWithUTF8String: buffer];
103
  free(buffer);
104
  return result;
105
}
106
 
107
 
108
- (void) readMessageBeginReturningName: (NSString **) name
109
                                  type: (int *) type
110
                            sequenceID: (int *) sequenceID
111
{
112
  int32_t size = [self readI32];
113
  if (size < 0) {
114
    int version = size & VERSION_MASK;
115
    if (version != VERSION_1) {
116
      @throw [TProtocolException exceptionWithName: @"TProtocolException"
117
                                 reason: @"Bad version in readMessageBegin"];
118
    }
119
    if (type != NULL) {
120
      *type = version & 0x00FF;
121
    }
122
    NSString * messageName = [self readString];
123
    if (name != NULL) {
124
      *name = messageName;
125
    }
126
    int seqID = [self readI32];
127
    if (sequenceID != NULL) {
128
      *sequenceID = seqID;
129
    }
130
  } else {
131
    if (mStrictRead) {
132
      @throw [TProtocolException exceptionWithName: @"TProtocolException"
133
                                 reason: @"Missing version in readMessageBegin, old client?"];
134
    }
135
    if ([self messageSizeLimit] > 0 && size > [self messageSizeLimit]) {
136
      @throw [TProtocolException exceptionWithName: @"TProtocolException"
137
                                            reason: [NSString stringWithFormat: @"Message too big.  Size limit is: %d Message size is: %d",
138
                                                     mMessageSizeLimit,
139
                                                     size]];
140
    }
141
    NSString * messageName = [self readStringBody: size];
142
    if (name != NULL) {
143
      *name = messageName;
144
    }
145
    int messageType = [self readByte];
146
    if (type != NULL) {
147
      *type = messageType;
148
    }
149
    int seqID = [self readI32];
150
    if (sequenceID != NULL) {
151
      *sequenceID = seqID;
152
    }
153
  }
154
}
155
 
156
 
157
- (void) readMessageEnd {}
158
 
159
 
160
- (void) readStructBeginReturningName: (NSString **) name
161
{
162
  if (name != NULL) {
163
    *name = nil;
164
  }
165
}
166
 
167
 
168
- (void) readStructEnd {}
169
 
170
 
171
- (void) readFieldBeginReturningName: (NSString **) name
172
                                type: (int *) fieldType
173
                             fieldID: (int *) fieldID
174
{
175
  if (name != NULL) {
176
    *name = nil;
177
  }
178
  int ft = [self readByte];
179
  if (fieldType != NULL) {
180
    *fieldType = ft;
181
  }
182
  if (ft != TType_STOP) {
183
    int fid = [self readI16];
184
    if (fieldID != NULL) {
185
      *fieldID = fid;
186
    }
187
  }
188
}
189
 
190
 
191
- (void) readFieldEnd {}
192
 
193
 
194
- (int32_t) readI32
195
{
196
  uint8_t i32rd[4];
197
  [mTransport readAll: i32rd offset: 0 length: 4];
198
  return
199
    ((i32rd[0] & 0xff) << 24) |
200
    ((i32rd[1] & 0xff) << 16) |
201
    ((i32rd[2] & 0xff) <<  8) |
202
    ((i32rd[3] & 0xff));
203
}
204
 
205
 
206
- (NSString *) readString
207
{
208
  int size = [self readI32];
209
  return [self readStringBody: size];
210
}
211
 
212
 
213
- (BOOL) readBool
214
{
215
  return [self readByte] == 1;
216
}
217
 
218
- (uint8_t) readByte
219
{
220
  uint8_t myByte;
221
  [mTransport readAll: &myByte offset: 0 length: 1];
222
  return myByte;
223
}
224
 
225
- (short) readI16
226
{
227
  uint8_t buff[2];
228
  [mTransport readAll: buff offset: 0 length: 2];
229
  return (short)
230
    (((buff[0] & 0xff) << 8) |
231
     ((buff[1] & 0xff)));
232
  return 0;
233
}
234
 
235
- (int64_t) readI64;
236
{
237
  uint8_t i64rd[8];
238
  [mTransport readAll: i64rd offset: 0 length: 8];
239
  return
240
    ((int64_t)(i64rd[0] & 0xff) << 56) |
241
    ((int64_t)(i64rd[1] & 0xff) << 48) |
242
    ((int64_t)(i64rd[2] & 0xff) << 40) |
243
    ((int64_t)(i64rd[3] & 0xff) << 32) |
244
    ((int64_t)(i64rd[4] & 0xff) << 24) |
245
    ((int64_t)(i64rd[5] & 0xff) << 16) |
246
    ((int64_t)(i64rd[6] & 0xff) <<  8) |
247
    ((int64_t)(i64rd[7] & 0xff));
248
}
249
 
250
- (double) readDouble;
251
{
252
  // FIXME - will this get us into trouble on PowerPC?
253
  int64_t ieee754 = [self readI64];
254
  return *((double *) &ieee754);
255
}
256
 
257
 
258
- (NSData *) readBinary
259
{
260
  int32_t size = [self readI32];
261
  uint8_t * buff = malloc(size);
262
  if (buff == NULL) {
263
    @throw [TProtocolException
264
             exceptionWithName: @"TProtocolException"
265
             reason: [NSString stringWithFormat: @"Out of memory.  Unable to allocate %d bytes trying to read binary data.",
266
                               size]];
267
  }
268
  [mTransport readAll: buff offset: 0 length: size];
269
  return [NSData dataWithBytesNoCopy: buff length: size];
270
}
271
 
272
 
273
- (void) readMapBeginReturningKeyType: (int *) keyType
274
                            valueType: (int *) valueType
275
                                 size: (int *) size
276
{
277
  int kt = [self readByte];
278
  int vt = [self readByte];
279
  int s = [self readI32];
280
  if (keyType != NULL) {
281
    *keyType = kt;
282
  }
283
  if (valueType != NULL) {
284
    *valueType = vt;
285
  }
286
  if (size != NULL) {
287
    *size = s;
288
  }
289
}
290
 
291
- (void) readMapEnd {}
292
 
293
 
294
- (void) readSetBeginReturningElementType: (int *) elementType
295
                                     size: (int *) size
296
{
297
  int et = [self readByte];
298
  int s = [self readI32];
299
  if (elementType != NULL) {
300
    *elementType = et;
301
  }
302
  if (size != NULL) {
303
    *size = s;
304
  }
305
}
306
 
307
 
308
- (void) readSetEnd {}
309
 
310
 
311
- (void) readListBeginReturningElementType: (int *) elementType
312
                                      size: (int *) size
313
{
314
  int et = [self readByte];
315
  int s = [self readI32];
316
  if (elementType != NULL) {
317
    *elementType = et;
318
  }
319
  if (size != NULL) {
320
    *size = s;
321
  }
322
}
323
 
324
 
325
- (void) readListEnd {}
326
 
327
 
328
- (void) writeByte: (uint8_t) value
329
{
330
  [mTransport write: &value offset: 0 length: 1];
331
}
332
 
333
 
334
- (void) writeMessageBeginWithName: (NSString *) name
335
                              type: (int) messageType
336
                        sequenceID: (int) sequenceID
337
{
338
  if (mStrictWrite) {
339
    int version = VERSION_1 | messageType;
340
    [self writeI32: version];
341
    [self writeString: name];
342
    [self writeI32: sequenceID];
343
  } else {
344
    [self writeString: name];
345
    [self writeByte: messageType];
346
    [self writeI32: sequenceID];
347
  }
348
}
349
 
350
 
351
- (void) writeMessageEnd {}
352
 
353
 
354
- (void) writeStructBeginWithName: (NSString *) name {}
355
 
356
 
357
- (void) writeStructEnd {}
358
 
359
 
360
- (void) writeFieldBeginWithName: (NSString *) name
361
                            type: (int) fieldType
362
                         fieldID: (int) fieldID
363
{
364
  [self writeByte: fieldType];
365
  [self writeI16: fieldID];
366
}
367
 
368
 
369
- (void) writeI32: (int32_t) value
370
{
371
  uint8_t buff[4];
372
  buff[0] = 0xFF & (value >> 24);
373
  buff[1] = 0xFF & (value >> 16);
374
  buff[2] = 0xFF & (value >> 8);
375
  buff[3] = 0xFF & value;
376
  [mTransport write: buff offset: 0 length: 4];
377
}
378
 
379
- (void) writeI16: (short) value
380
{
381
  uint8_t buff[2];
382
  buff[0] = 0xff & (value >> 8);
383
  buff[1] = 0xff & value;
384
  [mTransport write: buff offset: 0 length: 2];
385
}
386
 
387
 
388
- (void) writeI64: (int64_t) value
389
{
390
  uint8_t buff[8];
391
  buff[0] = 0xFF & (value >> 56);
392
  buff[1] = 0xFF & (value >> 48);
393
  buff[2] = 0xFF & (value >> 40);
394
  buff[3] = 0xFF & (value >> 32);
395
  buff[4] = 0xFF & (value >> 24);
396
  buff[5] = 0xFF & (value >> 16);
397
  buff[6] = 0xFF & (value >> 8);
398
  buff[7] = 0xFF & value;
399
  [mTransport write: buff offset: 0 length: 8];
400
}
401
 
402
- (void) writeDouble: (double) value
403
{
404
  // spit out IEEE 754 bits - FIXME - will this get us in trouble on
405
  // PowerPC?
406
  [self writeI64: *((int64_t *) &value)];
407
}
408
 
409
 
410
- (void) writeString: (NSString *) value
411
{
412
  if (value != nil) {
413
    const char * utf8Bytes = [value UTF8String];
414
    size_t length = strlen(utf8Bytes);
415
    [self writeI32: length];
416
    [mTransport write: (uint8_t *) utf8Bytes offset: 0 length: length];
417
  } else {
418
    // instead of crashing when we get null, let's write out a zero
419
    // length string
420
    [self writeI32: 0];
421
  }
422
}
423
 
424
 
425
- (void) writeBinary: (NSData *) data
426
{
427
  [self writeI32: [data length]];
428
  [mTransport write: [data bytes] offset: 0 length: [data length]];
429
}
430
 
431
- (void) writeFieldStop
432
{
433
  [self writeByte: TType_STOP];
434
}
435
 
436
 
437
- (void) writeFieldEnd {}
438
 
439
 
440
- (void) writeMapBeginWithKeyType: (int) keyType
441
                        valueType: (int) valueType
442
                             size: (int) size
443
{
444
  [self writeByte: keyType];
445
  [self writeByte: valueType];
446
  [self writeI32: size];
447
}
448
 
449
- (void) writeMapEnd {}
450
 
451
 
452
- (void) writeSetBeginWithElementType: (int) elementType
453
                                 size: (int) size
454
{
455
  [self writeByte: elementType];
456
  [self writeI32: size];
457
}
458
 
459
- (void) writeSetEnd {}
460
 
461
 
462
- (void) writeListBeginWithElementType: (int) elementType
463
                                  size: (int) size
464
{
465
  [self writeByte: elementType];
466
  [self writeI32: size];
467
}
468
 
469
- (void) writeListEnd {}
470
 
471
 
472
- (void) writeBool: (BOOL) value
473
{
474
  [self writeByte: (value ? 1 : 0)];
475
}
476
 
477
@end