blob: 2da5c11497d97269d58a68243df51944666b5070 [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Marc Slemkod42a2c22006-08-10 03:30:18 +00007#include "TBinaryProtocol.h"
8
David Reiss32e95f82008-06-11 01:18:36 +00009#include <limits>
Mark Slee4f261c52007-04-13 00:33:24 +000010#include <boost/static_assert.hpp>
11
Mark Slee8d7e1f62006-06-07 06:48:56 +000012using std::string;
Mark Sleee8540632006-05-30 09:24:40 +000013
Mark Slee4f261c52007-04-13 00:33:24 +000014// Use this to get around strict aliasing rules.
15// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
16// The most obvious implementation is to just cast a pointer,
17// but that doesn't work.
18// For a pretty in-depth explanation of the problem, see
19// http://www.cellperformance.com/mike_acton/2006/06/ (...)
20// understanding_strict_aliasing.html
21template <typename To, typename From>
22static inline To bitwise_cast(From from) {
Mark Slee808454e2007-06-20 21:51:57 +000023 BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
Mark Slee4f261c52007-04-13 00:33:24 +000024
Mark Slee808454e2007-06-20 21:51:57 +000025 // BAD!!! These are all broken with -O2.
26 //return *reinterpret_cast<To*>(&from); // BAD!!!
27 //return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
28 //return *(To*)(void*)&from; // BAD!!!
David Reiss0c90f6f2008-02-06 22:18:40 +000029
Mark Slee808454e2007-06-20 21:51:57 +000030 // Super clean and paritally blessed by section 3.9 of the standard.
31 //unsigned char c[sizeof(from)];
32 //memcpy(c, &from, sizeof(from));
33 //To to;
34 //memcpy(&to, c, sizeof(c));
35 //return to;
Mark Slee4f261c52007-04-13 00:33:24 +000036
Mark Slee808454e2007-06-20 21:51:57 +000037 // Slightly more questionable.
38 // Same code emitted by GCC.
39 //To to;
40 //memcpy(&to, &from, sizeof(from));
41 //return to;
Mark Slee4f261c52007-04-13 00:33:24 +000042
Mark Slee808454e2007-06-20 21:51:57 +000043 // Technically undefined, but almost universally supported,
44 // and the most efficient implementation.
45 union {
46 From f;
47 To t;
48 } u;
49 u.f = from;
50 return u.t;
Mark Slee4f261c52007-04-13 00:33:24 +000051}
52
53
T Jake Lucianib5e62212009-01-31 22:36:20 +000054namespace apache { namespace thrift { namespace protocol {
Marc Slemko6f038a72006-08-03 18:58:09 +000055
Mark Slee82a6c0f2007-04-04 21:08:21 +000056uint32_t TBinaryProtocol::writeMessageBegin(const std::string& name,
57 const TMessageType messageType,
58 const int32_t seqid) {
Mark Slee808454e2007-06-20 21:51:57 +000059 if (strict_write_) {
60 int32_t version = (VERSION_1) | ((int32_t)messageType);
David Reissf79031e2007-07-06 21:43:48 +000061 uint32_t wsize = 0;
62 wsize += writeI32(version);
63 wsize += writeString(name);
64 wsize += writeI32(seqid);
65 return wsize;
Mark Slee808454e2007-06-20 21:51:57 +000066 } else {
David Reissf79031e2007-07-06 21:43:48 +000067 uint32_t wsize = 0;
68 wsize += writeString(name);
69 wsize += writeByte((int8_t)messageType);
70 wsize += writeI32(seqid);
71 return wsize;
Mark Slee808454e2007-06-20 21:51:57 +000072 }
Marc Slemko16698852006-08-04 03:16:10 +000073}
74
Mark Slee4af6ed72006-10-25 19:02:49 +000075uint32_t TBinaryProtocol::writeMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +000076 return 0;
77}
78
David Reiss64120002008-04-29 23:12:24 +000079uint32_t TBinaryProtocol::writeStructBegin(const char* name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000080 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000081}
82
Mark Slee4af6ed72006-10-25 19:02:49 +000083uint32_t TBinaryProtocol::writeStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000084 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000085}
86
David Reiss64120002008-04-29 23:12:24 +000087uint32_t TBinaryProtocol::writeFieldBegin(const char* name,
Mark Slee8d7e1f62006-06-07 06:48:56 +000088 const TType fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +000089 const int16_t fieldId) {
David Reissf79031e2007-07-06 21:43:48 +000090 uint32_t wsize = 0;
91 wsize += writeByte((int8_t)fieldType);
92 wsize += writeI16(fieldId);
93 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +000094}
95
Mark Slee4af6ed72006-10-25 19:02:49 +000096uint32_t TBinaryProtocol::writeFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000097 return 0;
98}
99
Mark Slee4af6ed72006-10-25 19:02:49 +0000100uint32_t TBinaryProtocol::writeFieldStop() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000101 return
Mark Slee4af6ed72006-10-25 19:02:49 +0000102 writeByte((int8_t)T_STOP);
David Reiss0c90f6f2008-02-06 22:18:40 +0000103}
104
Mark Slee4af6ed72006-10-25 19:02:49 +0000105uint32_t TBinaryProtocol::writeMapBegin(const TType keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000106 const TType valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000107 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000108 uint32_t wsize = 0;
109 wsize += writeByte((int8_t)keyType);
110 wsize += writeByte((int8_t)valType);
111 wsize += writeI32((int32_t)size);
112 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000113}
114
Mark Slee4af6ed72006-10-25 19:02:49 +0000115uint32_t TBinaryProtocol::writeMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000116 return 0;
117}
118
Mark Slee4af6ed72006-10-25 19:02:49 +0000119uint32_t TBinaryProtocol::writeListBegin(const TType elemType,
120 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000121 uint32_t wsize = 0;
122 wsize += writeByte((int8_t) elemType);
123 wsize += writeI32((int32_t)size);
124 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000125}
126
Mark Slee4af6ed72006-10-25 19:02:49 +0000127uint32_t TBinaryProtocol::writeListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000128 return 0;
129}
130
Mark Slee4af6ed72006-10-25 19:02:49 +0000131uint32_t TBinaryProtocol::writeSetBegin(const TType elemType,
132 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000133 uint32_t wsize = 0;
David Reissf79031e2007-07-06 21:43:48 +0000134 wsize += writeByte((int8_t)elemType);
135 wsize += writeI32((int32_t)size);
136 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000137}
138
Mark Slee4af6ed72006-10-25 19:02:49 +0000139uint32_t TBinaryProtocol::writeSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000140 return 0;
141}
142
Mark Slee4af6ed72006-10-25 19:02:49 +0000143uint32_t TBinaryProtocol::writeBool(const bool value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000144 uint8_t tmp = value ? 1 : 0;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000145 trans_->write(&tmp, 1);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000146 return 1;
147}
148
Mark Slee4af6ed72006-10-25 19:02:49 +0000149uint32_t TBinaryProtocol::writeByte(const int8_t byte) {
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000150 trans_->write((uint8_t*)&byte, 1);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000151 return 1;
152}
153
Mark Slee4af6ed72006-10-25 19:02:49 +0000154uint32_t TBinaryProtocol::writeI16(const int16_t i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000155 int16_t net = (int16_t)htons(i16);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000156 trans_->write((uint8_t*)&net, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000157 return 2;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000158}
159
Mark Slee4af6ed72006-10-25 19:02:49 +0000160uint32_t TBinaryProtocol::writeI32(const int32_t i32) {
Marc Slemkoe6889de2006-08-12 00:32:53 +0000161 int32_t net = (int32_t)htonl(i32);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000162 trans_->write((uint8_t*)&net, 4);
Marc Slemkoe6889de2006-08-12 00:32:53 +0000163 return 4;
164}
165
Mark Slee4af6ed72006-10-25 19:02:49 +0000166uint32_t TBinaryProtocol::writeI64(const int64_t i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000167 int64_t net = (int64_t)htonll(i64);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000168 trans_->write((uint8_t*)&net, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000169 return 8;
170}
David Reiss0c90f6f2008-02-06 22:18:40 +0000171
Mark Slee4af6ed72006-10-25 19:02:49 +0000172uint32_t TBinaryProtocol::writeDouble(const double dub) {
Mark Slee4f261c52007-04-13 00:33:24 +0000173 BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
174 BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
175
176 uint64_t bits = bitwise_cast<uint64_t>(dub);
177 bits = htonll(bits);
178 trans_->write((uint8_t*)&bits, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000179 return 8;
180}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000181
David Reiss0c90f6f2008-02-06 22:18:40 +0000182
Mark Slee4af6ed72006-10-25 19:02:49 +0000183uint32_t TBinaryProtocol::writeString(const string& str) {
Mark Sleef9831082007-02-20 20:59:21 +0000184 uint32_t size = str.size();
185 uint32_t result = writeI32((int32_t)size);
186 if (size > 0) {
187 trans_->write((uint8_t*)str.data(), size);
188 }
189 return result + size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000190}
191
David Reissc005b1b2008-02-15 01:38:18 +0000192uint32_t TBinaryProtocol::writeBinary(const string& str) {
193 return TBinaryProtocol::writeString(str);
194}
195
Mark Slee8d7e1f62006-06-07 06:48:56 +0000196/**
197 * Reading functions
198 */
199
Mark Slee4af6ed72006-10-25 19:02:49 +0000200uint32_t TBinaryProtocol::readMessageBegin(std::string& name,
David Reiss96d23882007-07-26 21:10:32 +0000201 TMessageType& messageType,
202 int32_t& seqid) {
Marc Slemko16698852006-08-04 03:16:10 +0000203 uint32_t result = 0;
Mark Slee808454e2007-06-20 21:51:57 +0000204 int32_t sz;
205 result += readI32(sz);
206
207 if (sz < 0) {
208 // Check for correct version number
209 int32_t version = sz & VERSION_MASK;
210 if (version != VERSION_1) {
211 throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
212 }
213 messageType = (TMessageType)(sz & 0x000000ff);
214 result += readString(name);
215 result += readI32(seqid);
216 } else {
217 if (strict_read_) {
218 throw TProtocolException(TProtocolException::BAD_VERSION, "No version identifier... old protocol client in strict mode?");
219 } else {
220 // Handle pre-versioned input
221 int8_t type;
222 result += readStringBody(name, sz);
223 result += readByte(type);
224 messageType = (TMessageType)type;
225 result += readI32(seqid);
226 }
227 }
Marc Slemko16698852006-08-04 03:16:10 +0000228 return result;
229}
230
Mark Slee4af6ed72006-10-25 19:02:49 +0000231uint32_t TBinaryProtocol::readMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +0000232 return 0;
233}
234
Mark Slee4af6ed72006-10-25 19:02:49 +0000235uint32_t TBinaryProtocol::readStructBegin(string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000236 name = "";
237 return 0;
238}
239
Mark Slee4af6ed72006-10-25 19:02:49 +0000240uint32_t TBinaryProtocol::readStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000241 return 0;
242}
243
Mark Slee4af6ed72006-10-25 19:02:49 +0000244uint32_t TBinaryProtocol::readFieldBegin(string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000245 TType& fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000246 int16_t& fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000247 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000248 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000249 result += readByte(type);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000250 fieldType = (TType)type;
251 if (fieldType == T_STOP) {
252 fieldId = 0;
253 return result;
254 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000255 result += readI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000256 return result;
257}
David Reiss0c90f6f2008-02-06 22:18:40 +0000258
Mark Slee4af6ed72006-10-25 19:02:49 +0000259uint32_t TBinaryProtocol::readFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000260 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000261}
David Reiss0c90f6f2008-02-06 22:18:40 +0000262
Mark Slee4af6ed72006-10-25 19:02:49 +0000263uint32_t TBinaryProtocol::readMapBegin(TType& keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000264 TType& valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000265 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000266 int8_t k, v;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000267 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000268 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000269 result += readByte(k);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000270 keyType = (TType)k;
Mark Slee4af6ed72006-10-25 19:02:49 +0000271 result += readByte(v);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000272 valType = (TType)v;
Mark Slee4af6ed72006-10-25 19:02:49 +0000273 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000274 if (sizei < 0) {
275 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
276 } else if (container_limit_ && sizei > container_limit_) {
277 throw TProtocolException(TProtocolException::SIZE_LIMIT);
278 }
Mark Sleecfc01932006-09-01 22:18:16 +0000279 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000280 return result;
281}
282
Mark Slee4af6ed72006-10-25 19:02:49 +0000283uint32_t TBinaryProtocol::readMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000284 return 0;
285}
286
Mark Slee4af6ed72006-10-25 19:02:49 +0000287uint32_t TBinaryProtocol::readListBegin(TType& elemType,
288 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000289 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000290 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000291 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000292 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000293 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000294 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000295 if (sizei < 0) {
296 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
297 } else if (container_limit_ && sizei > container_limit_) {
298 throw TProtocolException(TProtocolException::SIZE_LIMIT);
299 }
Mark Sleecfc01932006-09-01 22:18:16 +0000300 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000301 return result;
302}
303
Mark Slee4af6ed72006-10-25 19:02:49 +0000304uint32_t TBinaryProtocol::readListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000305 return 0;
306}
307
Mark Slee4af6ed72006-10-25 19:02:49 +0000308uint32_t TBinaryProtocol::readSetBegin(TType& elemType,
309 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000310 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000311 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000312 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000313 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000314 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000315 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000316 if (sizei < 0) {
317 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
318 } else if (container_limit_ && sizei > container_limit_) {
319 throw TProtocolException(TProtocolException::SIZE_LIMIT);
320 }
Mark Sleecfc01932006-09-01 22:18:16 +0000321 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000322 return result;
323}
324
Mark Slee4af6ed72006-10-25 19:02:49 +0000325uint32_t TBinaryProtocol::readSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000326 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000327}
328
Mark Slee4af6ed72006-10-25 19:02:49 +0000329uint32_t TBinaryProtocol::readBool(bool& value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000330 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000331 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000332 value = *(int8_t*)b != 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000333 return 1;
334}
335
Mark Slee4af6ed72006-10-25 19:02:49 +0000336uint32_t TBinaryProtocol::readByte(int8_t& byte) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000337 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000338 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000339 byte = *(int8_t*)b;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000340 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000341}
342
Mark Slee4af6ed72006-10-25 19:02:49 +0000343uint32_t TBinaryProtocol::readI16(int16_t& i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000344 uint8_t b[2];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000345 trans_->readAll(b, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000346 i16 = *(int16_t*)b;
347 i16 = (int16_t)ntohs(i16);
348 return 2;
349}
350
Mark Slee4af6ed72006-10-25 19:02:49 +0000351uint32_t TBinaryProtocol::readI32(int32_t& i32) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000352 uint8_t b[4];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000353 trans_->readAll(b, 4);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000354 i32 = *(int32_t*)b;
355 i32 = (int32_t)ntohl(i32);
356 return 4;
Mark Sleee8540632006-05-30 09:24:40 +0000357}
358
Mark Slee4af6ed72006-10-25 19:02:49 +0000359uint32_t TBinaryProtocol::readI64(int64_t& i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000360 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000361 trans_->readAll(b, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000362 i64 = *(int64_t*)b;
363 i64 = (int64_t)ntohll(i64);
364 return 8;
Mark Sleee8540632006-05-30 09:24:40 +0000365}
366
Mark Slee4af6ed72006-10-25 19:02:49 +0000367uint32_t TBinaryProtocol::readDouble(double& dub) {
Mark Slee4f261c52007-04-13 00:33:24 +0000368 BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
369 BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
370
371 uint64_t bits;
Mark Sleec98d0502006-09-06 02:42:25 +0000372 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000373 trans_->readAll(b, 8);
Mark Slee4f261c52007-04-13 00:33:24 +0000374 bits = *(uint64_t*)b;
375 bits = ntohll(bits);
376 dub = bitwise_cast<double>(bits);
Mark Sleec98d0502006-09-06 02:42:25 +0000377 return 8;
378}
379
Mark Slee4af6ed72006-10-25 19:02:49 +0000380uint32_t TBinaryProtocol::readString(string& str) {
Mark Sleef3c322b2006-06-26 23:52:22 +0000381 uint32_t result;
Mark Sleecfc01932006-09-01 22:18:16 +0000382 int32_t size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000383 result = readI32(size);
Mark Slee808454e2007-06-20 21:51:57 +0000384 return result + readStringBody(str, size);
385}
386
David Reissc005b1b2008-02-15 01:38:18 +0000387uint32_t TBinaryProtocol::readBinary(string& str) {
388 return TBinaryProtocol::readString(str);
389}
390
Mark Slee808454e2007-06-20 21:51:57 +0000391uint32_t TBinaryProtocol::readStringBody(string& str, int32_t size) {
392 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000393
Mark Sleef9831082007-02-20 20:59:21 +0000394 // Catch error cases
395 if (size < 0) {
396 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
397 }
398 if (string_limit_ > 0 && size > string_limit_) {
399 throw TProtocolException(TProtocolException::SIZE_LIMIT);
400 }
401
402 // Catch empty string case
403 if (size == 0) {
404 str = "";
405 return result;
406 }
Mark Slee6e536442006-06-30 18:28:50 +0000407
408 // Use the heap here to prevent stack overflow for v. large strings
Mark Sleef9831082007-02-20 20:59:21 +0000409 if (size > string_buf_size_ || string_buf_ == NULL) {
David Reiss58b4fa72008-04-01 04:17:58 +0000410 void* new_string_buf = std::realloc(string_buf_, (uint32_t)size);
411 if (new_string_buf == NULL) {
Mark Sleef9831082007-02-20 20:59:21 +0000412 throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString");
413 }
David Reiss58b4fa72008-04-01 04:17:58 +0000414 string_buf_ = (uint8_t*)new_string_buf;
Mark Sleef9831082007-02-20 20:59:21 +0000415 string_buf_size_ = size;
416 }
417 trans_->readAll(string_buf_, size);
418 str = string((char*)string_buf_, size);
Mark Slee808454e2007-06-20 21:51:57 +0000419 return (uint32_t)size;
Mark Sleee8540632006-05-30 09:24:40 +0000420}
Mark Sleecfc01932006-09-01 22:18:16 +0000421
T Jake Lucianib5e62212009-01-31 22:36:20 +0000422}}} // apache::thrift::protocol