blob: b3e9fbcc7a7eaef197fcff4469f1b59ab3a77db6 [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
Mark Slee4f261c52007-04-13 00:33:24 +00009#include <boost/static_assert.hpp>
10
Mark Slee8d7e1f62006-06-07 06:48:56 +000011using std::string;
Mark Sleee8540632006-05-30 09:24:40 +000012
Mark Slee4f261c52007-04-13 00:33:24 +000013// Use this to get around strict aliasing rules.
14// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
15// The most obvious implementation is to just cast a pointer,
16// but that doesn't work.
17// For a pretty in-depth explanation of the problem, see
18// http://www.cellperformance.com/mike_acton/2006/06/ (...)
19// understanding_strict_aliasing.html
20template <typename To, typename From>
21static inline To bitwise_cast(From from) {
Mark Slee808454e2007-06-20 21:51:57 +000022 BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
Mark Slee4f261c52007-04-13 00:33:24 +000023
Mark Slee808454e2007-06-20 21:51:57 +000024 // BAD!!! These are all broken with -O2.
25 //return *reinterpret_cast<To*>(&from); // BAD!!!
26 //return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
27 //return *(To*)(void*)&from; // BAD!!!
David Reiss0c90f6f2008-02-06 22:18:40 +000028
Mark Slee808454e2007-06-20 21:51:57 +000029 // Super clean and paritally blessed by section 3.9 of the standard.
30 //unsigned char c[sizeof(from)];
31 //memcpy(c, &from, sizeof(from));
32 //To to;
33 //memcpy(&to, c, sizeof(c));
34 //return to;
Mark Slee4f261c52007-04-13 00:33:24 +000035
Mark Slee808454e2007-06-20 21:51:57 +000036 // Slightly more questionable.
37 // Same code emitted by GCC.
38 //To to;
39 //memcpy(&to, &from, sizeof(from));
40 //return to;
Mark Slee4f261c52007-04-13 00:33:24 +000041
Mark Slee808454e2007-06-20 21:51:57 +000042 // Technically undefined, but almost universally supported,
43 // and the most efficient implementation.
44 union {
45 From f;
46 To t;
47 } u;
48 u.f = from;
49 return u.t;
Mark Slee4f261c52007-04-13 00:33:24 +000050}
51
52
David Reiss0c90f6f2008-02-06 22:18:40 +000053namespace facebook { namespace thrift { namespace protocol {
Marc Slemko6f038a72006-08-03 18:58:09 +000054
Mark Slee82a6c0f2007-04-04 21:08:21 +000055uint32_t TBinaryProtocol::writeMessageBegin(const std::string& name,
56 const TMessageType messageType,
57 const int32_t seqid) {
Mark Slee808454e2007-06-20 21:51:57 +000058 if (strict_write_) {
59 int32_t version = (VERSION_1) | ((int32_t)messageType);
David Reissf79031e2007-07-06 21:43:48 +000060 uint32_t wsize = 0;
61 wsize += writeI32(version);
62 wsize += writeString(name);
63 wsize += writeI32(seqid);
64 return wsize;
Mark Slee808454e2007-06-20 21:51:57 +000065 } else {
David Reissf79031e2007-07-06 21:43:48 +000066 uint32_t wsize = 0;
67 wsize += writeString(name);
68 wsize += writeByte((int8_t)messageType);
69 wsize += writeI32(seqid);
70 return wsize;
Mark Slee808454e2007-06-20 21:51:57 +000071 }
Marc Slemko16698852006-08-04 03:16:10 +000072}
73
Mark Slee4af6ed72006-10-25 19:02:49 +000074uint32_t TBinaryProtocol::writeMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +000075 return 0;
76}
77
Mark Slee4af6ed72006-10-25 19:02:49 +000078uint32_t TBinaryProtocol::writeStructBegin(const string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000079 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000080}
81
Mark Slee4af6ed72006-10-25 19:02:49 +000082uint32_t TBinaryProtocol::writeStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000083 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000084}
85
Mark Slee4af6ed72006-10-25 19:02:49 +000086uint32_t TBinaryProtocol::writeFieldBegin(const string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +000087 const TType fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +000088 const int16_t fieldId) {
David Reissf79031e2007-07-06 21:43:48 +000089 uint32_t wsize = 0;
90 wsize += writeByte((int8_t)fieldType);
91 wsize += writeI16(fieldId);
92 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +000093}
94
Mark Slee4af6ed72006-10-25 19:02:49 +000095uint32_t TBinaryProtocol::writeFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000096 return 0;
97}
98
Mark Slee4af6ed72006-10-25 19:02:49 +000099uint32_t TBinaryProtocol::writeFieldStop() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000100 return
Mark Slee4af6ed72006-10-25 19:02:49 +0000101 writeByte((int8_t)T_STOP);
David Reiss0c90f6f2008-02-06 22:18:40 +0000102}
103
Mark Slee4af6ed72006-10-25 19:02:49 +0000104uint32_t TBinaryProtocol::writeMapBegin(const TType keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000105 const TType valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000106 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000107 uint32_t wsize = 0;
108 wsize += writeByte((int8_t)keyType);
109 wsize += writeByte((int8_t)valType);
110 wsize += writeI32((int32_t)size);
111 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000112}
113
Mark Slee4af6ed72006-10-25 19:02:49 +0000114uint32_t TBinaryProtocol::writeMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000115 return 0;
116}
117
Mark Slee4af6ed72006-10-25 19:02:49 +0000118uint32_t TBinaryProtocol::writeListBegin(const TType elemType,
119 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000120 uint32_t wsize = 0;
121 wsize += writeByte((int8_t) elemType);
122 wsize += writeI32((int32_t)size);
123 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000124}
125
Mark Slee4af6ed72006-10-25 19:02:49 +0000126uint32_t TBinaryProtocol::writeListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000127 return 0;
128}
129
Mark Slee4af6ed72006-10-25 19:02:49 +0000130uint32_t TBinaryProtocol::writeSetBegin(const TType elemType,
131 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000132 uint32_t wsize = 0;
David Reissf79031e2007-07-06 21:43:48 +0000133 wsize += writeByte((int8_t)elemType);
134 wsize += writeI32((int32_t)size);
135 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000136}
137
Mark Slee4af6ed72006-10-25 19:02:49 +0000138uint32_t TBinaryProtocol::writeSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000139 return 0;
140}
141
Mark Slee4af6ed72006-10-25 19:02:49 +0000142uint32_t TBinaryProtocol::writeBool(const bool value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000143 uint8_t tmp = value ? 1 : 0;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000144 trans_->write(&tmp, 1);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000145 return 1;
146}
147
Mark Slee4af6ed72006-10-25 19:02:49 +0000148uint32_t TBinaryProtocol::writeByte(const int8_t byte) {
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000149 trans_->write((uint8_t*)&byte, 1);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000150 return 1;
151}
152
Mark Slee4af6ed72006-10-25 19:02:49 +0000153uint32_t TBinaryProtocol::writeI16(const int16_t i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000154 int16_t net = (int16_t)htons(i16);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000155 trans_->write((uint8_t*)&net, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000156 return 2;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000157}
158
Mark Slee4af6ed72006-10-25 19:02:49 +0000159uint32_t TBinaryProtocol::writeI32(const int32_t i32) {
Marc Slemkoe6889de2006-08-12 00:32:53 +0000160 int32_t net = (int32_t)htonl(i32);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000161 trans_->write((uint8_t*)&net, 4);
Marc Slemkoe6889de2006-08-12 00:32:53 +0000162 return 4;
163}
164
Mark Slee4af6ed72006-10-25 19:02:49 +0000165uint32_t TBinaryProtocol::writeI64(const int64_t i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000166 int64_t net = (int64_t)htonll(i64);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000167 trans_->write((uint8_t*)&net, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000168 return 8;
169}
David Reiss0c90f6f2008-02-06 22:18:40 +0000170
Mark Slee4af6ed72006-10-25 19:02:49 +0000171uint32_t TBinaryProtocol::writeDouble(const double dub) {
Mark Slee4f261c52007-04-13 00:33:24 +0000172 BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
173 BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
174
175 uint64_t bits = bitwise_cast<uint64_t>(dub);
176 bits = htonll(bits);
177 trans_->write((uint8_t*)&bits, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000178 return 8;
179}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000180
David Reiss0c90f6f2008-02-06 22:18:40 +0000181
Mark Slee4af6ed72006-10-25 19:02:49 +0000182uint32_t TBinaryProtocol::writeString(const string& str) {
Mark Sleef9831082007-02-20 20:59:21 +0000183 uint32_t size = str.size();
184 uint32_t result = writeI32((int32_t)size);
185 if (size > 0) {
186 trans_->write((uint8_t*)str.data(), size);
187 }
188 return result + size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000189}
190
David Reissc005b1b2008-02-15 01:38:18 +0000191uint32_t TBinaryProtocol::writeBinary(const string& str) {
192 return TBinaryProtocol::writeString(str);
193}
194
Mark Slee8d7e1f62006-06-07 06:48:56 +0000195/**
196 * Reading functions
197 */
198
Mark Slee4af6ed72006-10-25 19:02:49 +0000199uint32_t TBinaryProtocol::readMessageBegin(std::string& name,
David Reiss96d23882007-07-26 21:10:32 +0000200 TMessageType& messageType,
201 int32_t& seqid) {
Marc Slemko16698852006-08-04 03:16:10 +0000202 uint32_t result = 0;
Mark Slee808454e2007-06-20 21:51:57 +0000203 int32_t sz;
204 result += readI32(sz);
205
206 if (sz < 0) {
207 // Check for correct version number
208 int32_t version = sz & VERSION_MASK;
209 if (version != VERSION_1) {
210 throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
211 }
212 messageType = (TMessageType)(sz & 0x000000ff);
213 result += readString(name);
214 result += readI32(seqid);
215 } else {
216 if (strict_read_) {
217 throw TProtocolException(TProtocolException::BAD_VERSION, "No version identifier... old protocol client in strict mode?");
218 } else {
219 // Handle pre-versioned input
220 int8_t type;
221 result += readStringBody(name, sz);
222 result += readByte(type);
223 messageType = (TMessageType)type;
224 result += readI32(seqid);
225 }
226 }
Marc Slemko16698852006-08-04 03:16:10 +0000227 return result;
228}
229
Mark Slee4af6ed72006-10-25 19:02:49 +0000230uint32_t TBinaryProtocol::readMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +0000231 return 0;
232}
233
Mark Slee4af6ed72006-10-25 19:02:49 +0000234uint32_t TBinaryProtocol::readStructBegin(string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000235 name = "";
236 return 0;
237}
238
Mark Slee4af6ed72006-10-25 19:02:49 +0000239uint32_t TBinaryProtocol::readStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000240 return 0;
241}
242
Mark Slee4af6ed72006-10-25 19:02:49 +0000243uint32_t TBinaryProtocol::readFieldBegin(string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000244 TType& fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000245 int16_t& fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000246 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000247 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000248 result += readByte(type);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000249 fieldType = (TType)type;
250 if (fieldType == T_STOP) {
251 fieldId = 0;
252 return result;
253 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000254 result += readI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000255 return result;
256}
David Reiss0c90f6f2008-02-06 22:18:40 +0000257
Mark Slee4af6ed72006-10-25 19:02:49 +0000258uint32_t TBinaryProtocol::readFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000259 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000260}
David Reiss0c90f6f2008-02-06 22:18:40 +0000261
Mark Slee4af6ed72006-10-25 19:02:49 +0000262uint32_t TBinaryProtocol::readMapBegin(TType& keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000263 TType& valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000264 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000265 int8_t k, v;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000266 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000267 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000268 result += readByte(k);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000269 keyType = (TType)k;
Mark Slee4af6ed72006-10-25 19:02:49 +0000270 result += readByte(v);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000271 valType = (TType)v;
Mark Slee4af6ed72006-10-25 19:02:49 +0000272 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000273 if (sizei < 0) {
274 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
275 } else if (container_limit_ && sizei > container_limit_) {
276 throw TProtocolException(TProtocolException::SIZE_LIMIT);
277 }
Mark Sleecfc01932006-09-01 22:18:16 +0000278 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000279 return result;
280}
281
Mark Slee4af6ed72006-10-25 19:02:49 +0000282uint32_t TBinaryProtocol::readMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000283 return 0;
284}
285
Mark Slee4af6ed72006-10-25 19:02:49 +0000286uint32_t TBinaryProtocol::readListBegin(TType& elemType,
287 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000288 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000289 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000290 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000291 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000292 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000293 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000294 if (sizei < 0) {
295 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
296 } else if (container_limit_ && sizei > container_limit_) {
297 throw TProtocolException(TProtocolException::SIZE_LIMIT);
298 }
Mark Sleecfc01932006-09-01 22:18:16 +0000299 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000300 return result;
301}
302
Mark Slee4af6ed72006-10-25 19:02:49 +0000303uint32_t TBinaryProtocol::readListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000304 return 0;
305}
306
Mark Slee4af6ed72006-10-25 19:02:49 +0000307uint32_t TBinaryProtocol::readSetBegin(TType& elemType,
308 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000309 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000310 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000311 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000312 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000313 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000314 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000315 if (sizei < 0) {
316 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
317 } else if (container_limit_ && sizei > container_limit_) {
318 throw TProtocolException(TProtocolException::SIZE_LIMIT);
319 }
Mark Sleecfc01932006-09-01 22:18:16 +0000320 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000321 return result;
322}
323
Mark Slee4af6ed72006-10-25 19:02:49 +0000324uint32_t TBinaryProtocol::readSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000325 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000326}
327
Mark Slee4af6ed72006-10-25 19:02:49 +0000328uint32_t TBinaryProtocol::readBool(bool& value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000329 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000330 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000331 value = *(int8_t*)b != 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000332 return 1;
333}
334
Mark Slee4af6ed72006-10-25 19:02:49 +0000335uint32_t TBinaryProtocol::readByte(int8_t& byte) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000336 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000337 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000338 byte = *(int8_t*)b;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000339 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000340}
341
Mark Slee4af6ed72006-10-25 19:02:49 +0000342uint32_t TBinaryProtocol::readI16(int16_t& i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000343 uint8_t b[2];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000344 trans_->readAll(b, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000345 i16 = *(int16_t*)b;
346 i16 = (int16_t)ntohs(i16);
347 return 2;
348}
349
Mark Slee4af6ed72006-10-25 19:02:49 +0000350uint32_t TBinaryProtocol::readI32(int32_t& i32) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000351 uint8_t b[4];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000352 trans_->readAll(b, 4);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000353 i32 = *(int32_t*)b;
354 i32 = (int32_t)ntohl(i32);
355 return 4;
Mark Sleee8540632006-05-30 09:24:40 +0000356}
357
Mark Slee4af6ed72006-10-25 19:02:49 +0000358uint32_t TBinaryProtocol::readI64(int64_t& i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000359 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000360 trans_->readAll(b, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000361 i64 = *(int64_t*)b;
362 i64 = (int64_t)ntohll(i64);
363 return 8;
Mark Sleee8540632006-05-30 09:24:40 +0000364}
365
Mark Slee4af6ed72006-10-25 19:02:49 +0000366uint32_t TBinaryProtocol::readDouble(double& dub) {
Mark Slee4f261c52007-04-13 00:33:24 +0000367 BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
368 BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
369
370 uint64_t bits;
Mark Sleec98d0502006-09-06 02:42:25 +0000371 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000372 trans_->readAll(b, 8);
Mark Slee4f261c52007-04-13 00:33:24 +0000373 bits = *(uint64_t*)b;
374 bits = ntohll(bits);
375 dub = bitwise_cast<double>(bits);
Mark Sleec98d0502006-09-06 02:42:25 +0000376 return 8;
377}
378
Mark Slee4af6ed72006-10-25 19:02:49 +0000379uint32_t TBinaryProtocol::readString(string& str) {
Mark Sleef3c322b2006-06-26 23:52:22 +0000380 uint32_t result;
Mark Sleecfc01932006-09-01 22:18:16 +0000381 int32_t size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000382 result = readI32(size);
Mark Slee808454e2007-06-20 21:51:57 +0000383 return result + readStringBody(str, size);
384}
385
David Reissc005b1b2008-02-15 01:38:18 +0000386uint32_t TBinaryProtocol::readBinary(string& str) {
387 return TBinaryProtocol::readString(str);
388}
389
Mark Slee808454e2007-06-20 21:51:57 +0000390uint32_t TBinaryProtocol::readStringBody(string& str, int32_t size) {
391 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000392
Mark Sleef9831082007-02-20 20:59:21 +0000393 // Catch error cases
394 if (size < 0) {
395 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
396 }
397 if (string_limit_ > 0 && size > string_limit_) {
398 throw TProtocolException(TProtocolException::SIZE_LIMIT);
399 }
400
401 // Catch empty string case
402 if (size == 0) {
403 str = "";
404 return result;
405 }
Mark Slee6e536442006-06-30 18:28:50 +0000406
407 // Use the heap here to prevent stack overflow for v. large strings
Mark Sleef9831082007-02-20 20:59:21 +0000408 if (size > string_buf_size_ || string_buf_ == NULL) {
David Reissd7a16f42008-02-19 22:47:29 +0000409 string_buf_ = (uint8_t*)std::realloc(string_buf_, (uint32_t)size);
Mark Sleef9831082007-02-20 20:59:21 +0000410 if (string_buf_ == NULL) {
411 string_buf_size_ = 0;
412 throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString");
413 }
414 string_buf_size_ = size;
415 }
416 trans_->readAll(string_buf_, size);
417 str = string((char*)string_buf_, size);
Mark Slee808454e2007-06-20 21:51:57 +0000418 return (uint32_t)size;
Mark Sleee8540632006-05-30 09:24:40 +0000419}
Mark Sleecfc01932006-09-01 22:18:16 +0000420
Marc Slemko6f038a72006-08-03 18:58:09 +0000421}}} // facebook::thrift::protocol