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
#include "TBinaryProtocol.h"
21
 
22
#include <limits>
23
 
24
using std::string;
25
 
26
namespace apache { namespace thrift { namespace protocol {
27
 
28
uint32_t TBinaryProtocol::writeMessageBegin(const std::string& name,
29
                                            const TMessageType messageType,
30
                                            const int32_t seqid) {
31
  if (strict_write_) {
32
    int32_t version = (VERSION_1) | ((int32_t)messageType);
33
    uint32_t wsize = 0;
34
    wsize += writeI32(version);
35
    wsize += writeString(name);
36
    wsize += writeI32(seqid);
37
    return wsize;
38
  } else {
39
    uint32_t wsize = 0;
40
    wsize += writeString(name);
41
    wsize += writeByte((int8_t)messageType);
42
    wsize += writeI32(seqid);
43
    return wsize;
44
  }
45
}
46
 
47
uint32_t TBinaryProtocol::writeMessageEnd() {
48
  return 0;
49
}
50
 
51
uint32_t TBinaryProtocol::writeStructBegin(const char* name) {
52
  return 0;
53
}
54
 
55
uint32_t TBinaryProtocol::writeStructEnd() {
56
  return 0;
57
}
58
 
59
uint32_t TBinaryProtocol::writeFieldBegin(const char* name,
60
                                          const TType fieldType,
61
                                          const int16_t fieldId) {
62
  uint32_t wsize = 0;
63
  wsize += writeByte((int8_t)fieldType);
64
  wsize += writeI16(fieldId);
65
  return wsize;
66
}
67
 
68
uint32_t TBinaryProtocol::writeFieldEnd() {
69
  return 0;
70
}
71
 
72
uint32_t TBinaryProtocol::writeFieldStop() {
73
  return
74
    writeByte((int8_t)T_STOP);
75
}
76
 
77
uint32_t TBinaryProtocol::writeMapBegin(const TType keyType,
78
                                        const TType valType,
79
                                        const uint32_t size) {
80
  uint32_t wsize = 0;
81
  wsize += writeByte((int8_t)keyType);
82
  wsize += writeByte((int8_t)valType);
83
  wsize += writeI32((int32_t)size);
84
  return wsize;
85
}
86
 
87
uint32_t TBinaryProtocol::writeMapEnd() {
88
  return 0;
89
}
90
 
91
uint32_t TBinaryProtocol::writeListBegin(const TType elemType,
92
                                         const uint32_t size) {
93
  uint32_t wsize = 0;
94
  wsize += writeByte((int8_t) elemType);
95
  wsize += writeI32((int32_t)size);
96
  return wsize;
97
}
98
 
99
uint32_t TBinaryProtocol::writeListEnd() {
100
  return 0;
101
}
102
 
103
uint32_t TBinaryProtocol::writeSetBegin(const TType elemType,
104
                                        const uint32_t size) {
105
  uint32_t wsize = 0;
106
  wsize += writeByte((int8_t)elemType);
107
  wsize += writeI32((int32_t)size);
108
  return wsize;
109
}
110
 
111
uint32_t TBinaryProtocol::writeSetEnd() {
112
  return 0;
113
}
114
 
115
uint32_t TBinaryProtocol::writeBool(const bool value) {
116
  uint8_t tmp =  value ? 1 : 0;
117
  trans_->write(&tmp, 1);
118
  return 1;
119
}
120
 
121
uint32_t TBinaryProtocol::writeByte(const int8_t byte) {
122
  trans_->write((uint8_t*)&byte, 1);
123
  return 1;
124
}
125
 
126
uint32_t TBinaryProtocol::writeI16(const int16_t i16) {
127
  int16_t net = (int16_t)htons(i16);
128
  trans_->write((uint8_t*)&net, 2);
129
  return 2;
130
}
131
 
132
uint32_t TBinaryProtocol::writeI32(const int32_t i32) {
133
  int32_t net = (int32_t)htonl(i32);
134
  trans_->write((uint8_t*)&net, 4);
135
  return 4;
136
}
137
 
138
uint32_t TBinaryProtocol::writeI64(const int64_t i64) {
139
  int64_t net = (int64_t)htonll(i64);
140
  trans_->write((uint8_t*)&net, 8);
141
  return 8;
142
}
143
 
144
uint32_t TBinaryProtocol::writeDouble(const double dub) {
145
  BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
146
  BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
147
 
148
  uint64_t bits = bitwise_cast<uint64_t>(dub);
149
  bits = htonll(bits);
150
  trans_->write((uint8_t*)&bits, 8);
151
  return 8;
152
}
153
 
154
 
155
uint32_t TBinaryProtocol::writeString(const string& str) {
156
  uint32_t size = str.size();
157
  uint32_t result = writeI32((int32_t)size);
158
  if (size > 0) {
159
    trans_->write((uint8_t*)str.data(), size);
160
  }
161
  return result + size;
162
}
163
 
164
uint32_t TBinaryProtocol::writeBinary(const string& str) {
165
  return TBinaryProtocol::writeString(str);
166
}
167
 
168
/**
169
 * Reading functions
170
 */
171
 
172
uint32_t TBinaryProtocol::readMessageBegin(std::string& name,
173
                                           TMessageType& messageType,
174
                                           int32_t& seqid) {
175
  uint32_t result = 0;
176
  int32_t sz;
177
  result += readI32(sz);
178
 
179
  if (sz < 0) {
180
    // Check for correct version number
181
    int32_t version = sz & VERSION_MASK;
182
    if (version != VERSION_1) {
183
      throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
184
    }
185
    messageType = (TMessageType)(sz & 0x000000ff);
186
    result += readString(name);
187
    result += readI32(seqid);
188
  } else {
189
    if (strict_read_) {
190
      throw TProtocolException(TProtocolException::BAD_VERSION, "No version identifier... old protocol client in strict mode?");
191
    } else {
192
      // Handle pre-versioned input
193
      int8_t type;
194
      result += readStringBody(name, sz);
195
      result += readByte(type);
196
      messageType = (TMessageType)type;
197
      result += readI32(seqid);
198
    }
199
  }
200
  return result;
201
}
202
 
203
uint32_t TBinaryProtocol::readMessageEnd() {
204
  return 0;
205
}
206
 
207
uint32_t TBinaryProtocol::readStructBegin(string& name) {
208
  name = "";
209
  return 0;
210
}
211
 
212
uint32_t TBinaryProtocol::readStructEnd() {
213
  return 0;
214
}
215
 
216
uint32_t TBinaryProtocol::readFieldBegin(string& name,
217
                                         TType& fieldType,
218
                                         int16_t& fieldId) {
219
  uint32_t result = 0;
220
  int8_t type;
221
  result += readByte(type);
222
  fieldType = (TType)type;
223
  if (fieldType == T_STOP) {
224
    fieldId = 0;
225
    return result;
226
  }
227
  result += readI16(fieldId);
228
  return result;
229
}
230
 
231
uint32_t TBinaryProtocol::readFieldEnd() {
232
  return 0;
233
}
234
 
235
uint32_t TBinaryProtocol::readMapBegin(TType& keyType,
236
                                       TType& valType,
237
                                       uint32_t& size) {
238
  int8_t k, v;
239
  uint32_t result = 0;
240
  int32_t sizei;
241
  result += readByte(k);
242
  keyType = (TType)k;
243
  result += readByte(v);
244
  valType = (TType)v;
245
  result += readI32(sizei);
246
  if (sizei < 0) {
247
    throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
248
  } else if (container_limit_ && sizei > container_limit_) {
249
    throw TProtocolException(TProtocolException::SIZE_LIMIT);
250
  }
251
  size = (uint32_t)sizei;
252
  return result;
253
}
254
 
255
uint32_t TBinaryProtocol::readMapEnd() {
256
  return 0;
257
}
258
 
259
uint32_t TBinaryProtocol::readListBegin(TType& elemType,
260
                                        uint32_t& size) {
261
  int8_t e;
262
  uint32_t result = 0;
263
  int32_t sizei;
264
  result += readByte(e);
265
  elemType = (TType)e;
266
  result += readI32(sizei);
267
  if (sizei < 0) {
268
    throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
269
  } else if (container_limit_ && sizei > container_limit_) {
270
    throw TProtocolException(TProtocolException::SIZE_LIMIT);
271
  }
272
  size = (uint32_t)sizei;
273
  return result;
274
}
275
 
276
uint32_t TBinaryProtocol::readListEnd() {
277
  return 0;
278
}
279
 
280
uint32_t TBinaryProtocol::readSetBegin(TType& elemType,
281
                                       uint32_t& size) {
282
  int8_t e;
283
  uint32_t result = 0;
284
  int32_t sizei;
285
  result += readByte(e);
286
  elemType = (TType)e;
287
  result += readI32(sizei);
288
  if (sizei < 0) {
289
    throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
290
  } else if (container_limit_ && sizei > container_limit_) {
291
    throw TProtocolException(TProtocolException::SIZE_LIMIT);
292
  }
293
  size = (uint32_t)sizei;
294
  return result;
295
}
296
 
297
uint32_t TBinaryProtocol::readSetEnd() {
298
  return 0;
299
}
300
 
301
uint32_t TBinaryProtocol::readBool(bool& value) {
302
  uint8_t b[1];
303
  trans_->readAll(b, 1);
304
  value = *(int8_t*)b != 0;
305
  return 1;
306
}
307
 
308
uint32_t TBinaryProtocol::readByte(int8_t& byte) {
309
  uint8_t b[1];
310
  trans_->readAll(b, 1);
311
  byte = *(int8_t*)b;
312
  return 1;
313
}
314
 
315
uint32_t TBinaryProtocol::readI16(int16_t& i16) {
316
  uint8_t b[2];
317
  trans_->readAll(b, 2);
318
  i16 = *(int16_t*)b;
319
  i16 = (int16_t)ntohs(i16);
320
  return 2;
321
}
322
 
323
uint32_t TBinaryProtocol::readI32(int32_t& i32) {
324
  uint8_t b[4];
325
  trans_->readAll(b, 4);
326
  i32 = *(int32_t*)b;
327
  i32 = (int32_t)ntohl(i32);
328
  return 4;
329
}
330
 
331
uint32_t TBinaryProtocol::readI64(int64_t& i64) {
332
  uint8_t b[8];
333
  trans_->readAll(b, 8);
334
  i64 = *(int64_t*)b;
335
  i64 = (int64_t)ntohll(i64);
336
  return 8;
337
}
338
 
339
uint32_t TBinaryProtocol::readDouble(double& dub) {
340
  BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
341
  BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
342
 
343
  uint64_t bits;
344
  uint8_t b[8];
345
  trans_->readAll(b, 8);
346
  bits = *(uint64_t*)b;
347
  bits = ntohll(bits);
348
  dub = bitwise_cast<double>(bits);
349
  return 8;
350
}
351
 
352
uint32_t TBinaryProtocol::readString(string& str) {
353
  uint32_t result;
354
  int32_t size;
355
  result = readI32(size);
356
  return result + readStringBody(str, size);
357
}
358
 
359
uint32_t TBinaryProtocol::readBinary(string& str) {
360
  return TBinaryProtocol::readString(str);
361
}
362
 
363
uint32_t TBinaryProtocol::readStringBody(string& str, int32_t size) {
364
  uint32_t result = 0;
365
 
366
  // Catch error cases
367
  if (size < 0) {
368
    throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
369
  }
370
  if (string_limit_ > 0 && size > string_limit_) {
371
    throw TProtocolException(TProtocolException::SIZE_LIMIT);
372
  }
373
 
374
  // Catch empty string case
375
  if (size == 0) {
376
    str = "";
377
    return result;
378
  }
379
 
380
  // Use the heap here to prevent stack overflow for v. large strings
381
  if (size > string_buf_size_ || string_buf_ == NULL) {
382
    void* new_string_buf = std::realloc(string_buf_, (uint32_t)size);
383
    if (new_string_buf == NULL) {
384
      throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString");
385
    }
386
    string_buf_ = (uint8_t*)new_string_buf;
387
    string_buf_size_ = size;
388
  }
389
  trans_->readAll(string_buf_, size);
390
  str = string((char*)string_buf_, size);
391
  return (uint32_t)size;
392
}
393
 
394
}}} // apache::thrift::protocol