blob: 591a01fd1d97ee625f01f04a28313f8ea9897c12 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
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 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Marc Slemkod42a2c22006-08-10 03:30:18 +000020#include "TBinaryProtocol.h"
21
David Reiss32e95f82008-06-11 01:18:36 +000022#include <limits>
Mark Slee4f261c52007-04-13 00:33:24 +000023#include <boost/static_assert.hpp>
24
Mark Slee8d7e1f62006-06-07 06:48:56 +000025using std::string;
Mark Sleee8540632006-05-30 09:24:40 +000026
Mark Slee4f261c52007-04-13 00:33:24 +000027// Use this to get around strict aliasing rules.
28// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
29// The most obvious implementation is to just cast a pointer,
30// but that doesn't work.
31// For a pretty in-depth explanation of the problem, see
32// http://www.cellperformance.com/mike_acton/2006/06/ (...)
33// understanding_strict_aliasing.html
34template <typename To, typename From>
35static inline To bitwise_cast(From from) {
Mark Slee808454e2007-06-20 21:51:57 +000036 BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
Mark Slee4f261c52007-04-13 00:33:24 +000037
Mark Slee808454e2007-06-20 21:51:57 +000038 // BAD!!! These are all broken with -O2.
39 //return *reinterpret_cast<To*>(&from); // BAD!!!
40 //return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
41 //return *(To*)(void*)&from; // BAD!!!
David Reiss0c90f6f2008-02-06 22:18:40 +000042
Mark Slee808454e2007-06-20 21:51:57 +000043 // Super clean and paritally blessed by section 3.9 of the standard.
44 //unsigned char c[sizeof(from)];
45 //memcpy(c, &from, sizeof(from));
46 //To to;
47 //memcpy(&to, c, sizeof(c));
48 //return to;
Mark Slee4f261c52007-04-13 00:33:24 +000049
Mark Slee808454e2007-06-20 21:51:57 +000050 // Slightly more questionable.
51 // Same code emitted by GCC.
52 //To to;
53 //memcpy(&to, &from, sizeof(from));
54 //return to;
Mark Slee4f261c52007-04-13 00:33:24 +000055
Mark Slee808454e2007-06-20 21:51:57 +000056 // Technically undefined, but almost universally supported,
57 // and the most efficient implementation.
58 union {
59 From f;
60 To t;
61 } u;
62 u.f = from;
63 return u.t;
Mark Slee4f261c52007-04-13 00:33:24 +000064}
65
66
T Jake Lucianib5e62212009-01-31 22:36:20 +000067namespace apache { namespace thrift { namespace protocol {
Marc Slemko6f038a72006-08-03 18:58:09 +000068
Mark Slee82a6c0f2007-04-04 21:08:21 +000069uint32_t TBinaryProtocol::writeMessageBegin(const std::string& name,
70 const TMessageType messageType,
71 const int32_t seqid) {
Mark Slee808454e2007-06-20 21:51:57 +000072 if (strict_write_) {
73 int32_t version = (VERSION_1) | ((int32_t)messageType);
David Reissf79031e2007-07-06 21:43:48 +000074 uint32_t wsize = 0;
75 wsize += writeI32(version);
76 wsize += writeString(name);
77 wsize += writeI32(seqid);
78 return wsize;
Mark Slee808454e2007-06-20 21:51:57 +000079 } else {
David Reissf79031e2007-07-06 21:43:48 +000080 uint32_t wsize = 0;
81 wsize += writeString(name);
82 wsize += writeByte((int8_t)messageType);
83 wsize += writeI32(seqid);
84 return wsize;
Mark Slee808454e2007-06-20 21:51:57 +000085 }
Marc Slemko16698852006-08-04 03:16:10 +000086}
87
Mark Slee4af6ed72006-10-25 19:02:49 +000088uint32_t TBinaryProtocol::writeMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +000089 return 0;
90}
91
David Reiss64120002008-04-29 23:12:24 +000092uint32_t TBinaryProtocol::writeStructBegin(const char* name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000093 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000094}
95
Mark Slee4af6ed72006-10-25 19:02:49 +000096uint32_t TBinaryProtocol::writeStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000097 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000098}
99
David Reiss64120002008-04-29 23:12:24 +0000100uint32_t TBinaryProtocol::writeFieldBegin(const char* name,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000101 const TType fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000102 const int16_t fieldId) {
David Reissf79031e2007-07-06 21:43:48 +0000103 uint32_t wsize = 0;
104 wsize += writeByte((int8_t)fieldType);
105 wsize += writeI16(fieldId);
106 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000107}
108
Mark Slee4af6ed72006-10-25 19:02:49 +0000109uint32_t TBinaryProtocol::writeFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000110 return 0;
111}
112
Mark Slee4af6ed72006-10-25 19:02:49 +0000113uint32_t TBinaryProtocol::writeFieldStop() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000114 return
Mark Slee4af6ed72006-10-25 19:02:49 +0000115 writeByte((int8_t)T_STOP);
David Reiss0c90f6f2008-02-06 22:18:40 +0000116}
117
Mark Slee4af6ed72006-10-25 19:02:49 +0000118uint32_t TBinaryProtocol::writeMapBegin(const TType keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000119 const TType valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000120 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000121 uint32_t wsize = 0;
122 wsize += writeByte((int8_t)keyType);
123 wsize += writeByte((int8_t)valType);
124 wsize += writeI32((int32_t)size);
125 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000126}
127
Mark Slee4af6ed72006-10-25 19:02:49 +0000128uint32_t TBinaryProtocol::writeMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000129 return 0;
130}
131
Mark Slee4af6ed72006-10-25 19:02:49 +0000132uint32_t TBinaryProtocol::writeListBegin(const TType elemType,
133 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000134 uint32_t wsize = 0;
135 wsize += writeByte((int8_t) elemType);
136 wsize += writeI32((int32_t)size);
137 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000138}
139
Mark Slee4af6ed72006-10-25 19:02:49 +0000140uint32_t TBinaryProtocol::writeListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000141 return 0;
142}
143
Mark Slee4af6ed72006-10-25 19:02:49 +0000144uint32_t TBinaryProtocol::writeSetBegin(const TType elemType,
145 const uint32_t size) {
David Reissf79031e2007-07-06 21:43:48 +0000146 uint32_t wsize = 0;
David Reissf79031e2007-07-06 21:43:48 +0000147 wsize += writeByte((int8_t)elemType);
148 wsize += writeI32((int32_t)size);
149 return wsize;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000150}
151
Mark Slee4af6ed72006-10-25 19:02:49 +0000152uint32_t TBinaryProtocol::writeSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000153 return 0;
154}
155
Mark Slee4af6ed72006-10-25 19:02:49 +0000156uint32_t TBinaryProtocol::writeBool(const bool value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000157 uint8_t tmp = value ? 1 : 0;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000158 trans_->write(&tmp, 1);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000159 return 1;
160}
161
Mark Slee4af6ed72006-10-25 19:02:49 +0000162uint32_t TBinaryProtocol::writeByte(const int8_t byte) {
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000163 trans_->write((uint8_t*)&byte, 1);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000164 return 1;
165}
166
Mark Slee4af6ed72006-10-25 19:02:49 +0000167uint32_t TBinaryProtocol::writeI16(const int16_t i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000168 int16_t net = (int16_t)htons(i16);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000169 trans_->write((uint8_t*)&net, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000170 return 2;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000171}
172
Mark Slee4af6ed72006-10-25 19:02:49 +0000173uint32_t TBinaryProtocol::writeI32(const int32_t i32) {
Marc Slemkoe6889de2006-08-12 00:32:53 +0000174 int32_t net = (int32_t)htonl(i32);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000175 trans_->write((uint8_t*)&net, 4);
Marc Slemkoe6889de2006-08-12 00:32:53 +0000176 return 4;
177}
178
Mark Slee4af6ed72006-10-25 19:02:49 +0000179uint32_t TBinaryProtocol::writeI64(const int64_t i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000180 int64_t net = (int64_t)htonll(i64);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000181 trans_->write((uint8_t*)&net, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000182 return 8;
183}
David Reiss0c90f6f2008-02-06 22:18:40 +0000184
Mark Slee4af6ed72006-10-25 19:02:49 +0000185uint32_t TBinaryProtocol::writeDouble(const double dub) {
Mark Slee4f261c52007-04-13 00:33:24 +0000186 BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
187 BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
188
189 uint64_t bits = bitwise_cast<uint64_t>(dub);
190 bits = htonll(bits);
191 trans_->write((uint8_t*)&bits, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000192 return 8;
193}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000194
David Reiss0c90f6f2008-02-06 22:18:40 +0000195
Mark Slee4af6ed72006-10-25 19:02:49 +0000196uint32_t TBinaryProtocol::writeString(const string& str) {
Mark Sleef9831082007-02-20 20:59:21 +0000197 uint32_t size = str.size();
198 uint32_t result = writeI32((int32_t)size);
199 if (size > 0) {
200 trans_->write((uint8_t*)str.data(), size);
201 }
202 return result + size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000203}
204
David Reissc005b1b2008-02-15 01:38:18 +0000205uint32_t TBinaryProtocol::writeBinary(const string& str) {
206 return TBinaryProtocol::writeString(str);
207}
208
Mark Slee8d7e1f62006-06-07 06:48:56 +0000209/**
210 * Reading functions
211 */
212
Mark Slee4af6ed72006-10-25 19:02:49 +0000213uint32_t TBinaryProtocol::readMessageBegin(std::string& name,
David Reiss96d23882007-07-26 21:10:32 +0000214 TMessageType& messageType,
215 int32_t& seqid) {
Marc Slemko16698852006-08-04 03:16:10 +0000216 uint32_t result = 0;
Mark Slee808454e2007-06-20 21:51:57 +0000217 int32_t sz;
218 result += readI32(sz);
219
220 if (sz < 0) {
221 // Check for correct version number
222 int32_t version = sz & VERSION_MASK;
223 if (version != VERSION_1) {
224 throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
225 }
226 messageType = (TMessageType)(sz & 0x000000ff);
227 result += readString(name);
228 result += readI32(seqid);
229 } else {
230 if (strict_read_) {
231 throw TProtocolException(TProtocolException::BAD_VERSION, "No version identifier... old protocol client in strict mode?");
232 } else {
233 // Handle pre-versioned input
234 int8_t type;
235 result += readStringBody(name, sz);
236 result += readByte(type);
237 messageType = (TMessageType)type;
238 result += readI32(seqid);
239 }
240 }
Marc Slemko16698852006-08-04 03:16:10 +0000241 return result;
242}
243
Mark Slee4af6ed72006-10-25 19:02:49 +0000244uint32_t TBinaryProtocol::readMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +0000245 return 0;
246}
247
Mark Slee4af6ed72006-10-25 19:02:49 +0000248uint32_t TBinaryProtocol::readStructBegin(string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000249 name = "";
250 return 0;
251}
252
Mark Slee4af6ed72006-10-25 19:02:49 +0000253uint32_t TBinaryProtocol::readStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000254 return 0;
255}
256
Mark Slee4af6ed72006-10-25 19:02:49 +0000257uint32_t TBinaryProtocol::readFieldBegin(string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000258 TType& fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000259 int16_t& fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000260 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000261 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000262 result += readByte(type);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000263 fieldType = (TType)type;
264 if (fieldType == T_STOP) {
265 fieldId = 0;
266 return result;
267 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000268 result += readI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000269 return result;
270}
David Reiss0c90f6f2008-02-06 22:18:40 +0000271
Mark Slee4af6ed72006-10-25 19:02:49 +0000272uint32_t TBinaryProtocol::readFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000273 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000274}
David Reiss0c90f6f2008-02-06 22:18:40 +0000275
Mark Slee4af6ed72006-10-25 19:02:49 +0000276uint32_t TBinaryProtocol::readMapBegin(TType& keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000277 TType& valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000278 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000279 int8_t k, v;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000280 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000281 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000282 result += readByte(k);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000283 keyType = (TType)k;
Mark Slee4af6ed72006-10-25 19:02:49 +0000284 result += readByte(v);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000285 valType = (TType)v;
Mark Slee4af6ed72006-10-25 19:02:49 +0000286 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000287 if (sizei < 0) {
288 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
289 } else if (container_limit_ && sizei > container_limit_) {
290 throw TProtocolException(TProtocolException::SIZE_LIMIT);
291 }
Mark Sleecfc01932006-09-01 22:18:16 +0000292 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000293 return result;
294}
295
Mark Slee4af6ed72006-10-25 19:02:49 +0000296uint32_t TBinaryProtocol::readMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000297 return 0;
298}
299
Mark Slee4af6ed72006-10-25 19:02:49 +0000300uint32_t TBinaryProtocol::readListBegin(TType& elemType,
301 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000302 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000303 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000304 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000305 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000306 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000307 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000308 if (sizei < 0) {
309 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
310 } else if (container_limit_ && sizei > container_limit_) {
311 throw TProtocolException(TProtocolException::SIZE_LIMIT);
312 }
Mark Sleecfc01932006-09-01 22:18:16 +0000313 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000314 return result;
315}
316
Mark Slee4af6ed72006-10-25 19:02:49 +0000317uint32_t TBinaryProtocol::readListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000318 return 0;
319}
320
Mark Slee4af6ed72006-10-25 19:02:49 +0000321uint32_t TBinaryProtocol::readSetBegin(TType& elemType,
322 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000323 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000324 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000325 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000326 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000327 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000328 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000329 if (sizei < 0) {
330 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
331 } else if (container_limit_ && sizei > container_limit_) {
332 throw TProtocolException(TProtocolException::SIZE_LIMIT);
333 }
Mark Sleecfc01932006-09-01 22:18:16 +0000334 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000335 return result;
336}
337
Mark Slee4af6ed72006-10-25 19:02:49 +0000338uint32_t TBinaryProtocol::readSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000339 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000340}
341
Mark Slee4af6ed72006-10-25 19:02:49 +0000342uint32_t TBinaryProtocol::readBool(bool& value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000343 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000344 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000345 value = *(int8_t*)b != 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000346 return 1;
347}
348
Mark Slee4af6ed72006-10-25 19:02:49 +0000349uint32_t TBinaryProtocol::readByte(int8_t& byte) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000350 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000351 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000352 byte = *(int8_t*)b;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000353 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000354}
355
Mark Slee4af6ed72006-10-25 19:02:49 +0000356uint32_t TBinaryProtocol::readI16(int16_t& i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000357 uint8_t b[2];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000358 trans_->readAll(b, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000359 i16 = *(int16_t*)b;
360 i16 = (int16_t)ntohs(i16);
361 return 2;
362}
363
Mark Slee4af6ed72006-10-25 19:02:49 +0000364uint32_t TBinaryProtocol::readI32(int32_t& i32) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000365 uint8_t b[4];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000366 trans_->readAll(b, 4);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000367 i32 = *(int32_t*)b;
368 i32 = (int32_t)ntohl(i32);
369 return 4;
Mark Sleee8540632006-05-30 09:24:40 +0000370}
371
Mark Slee4af6ed72006-10-25 19:02:49 +0000372uint32_t TBinaryProtocol::readI64(int64_t& i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000373 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000374 trans_->readAll(b, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000375 i64 = *(int64_t*)b;
376 i64 = (int64_t)ntohll(i64);
377 return 8;
Mark Sleee8540632006-05-30 09:24:40 +0000378}
379
Mark Slee4af6ed72006-10-25 19:02:49 +0000380uint32_t TBinaryProtocol::readDouble(double& dub) {
Mark Slee4f261c52007-04-13 00:33:24 +0000381 BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
382 BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
383
384 uint64_t bits;
Mark Sleec98d0502006-09-06 02:42:25 +0000385 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000386 trans_->readAll(b, 8);
Mark Slee4f261c52007-04-13 00:33:24 +0000387 bits = *(uint64_t*)b;
388 bits = ntohll(bits);
389 dub = bitwise_cast<double>(bits);
Mark Sleec98d0502006-09-06 02:42:25 +0000390 return 8;
391}
392
Mark Slee4af6ed72006-10-25 19:02:49 +0000393uint32_t TBinaryProtocol::readString(string& str) {
Mark Sleef3c322b2006-06-26 23:52:22 +0000394 uint32_t result;
Mark Sleecfc01932006-09-01 22:18:16 +0000395 int32_t size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000396 result = readI32(size);
Mark Slee808454e2007-06-20 21:51:57 +0000397 return result + readStringBody(str, size);
398}
399
David Reissc005b1b2008-02-15 01:38:18 +0000400uint32_t TBinaryProtocol::readBinary(string& str) {
401 return TBinaryProtocol::readString(str);
402}
403
Mark Slee808454e2007-06-20 21:51:57 +0000404uint32_t TBinaryProtocol::readStringBody(string& str, int32_t size) {
405 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000406
Mark Sleef9831082007-02-20 20:59:21 +0000407 // Catch error cases
408 if (size < 0) {
409 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
410 }
411 if (string_limit_ > 0 && size > string_limit_) {
412 throw TProtocolException(TProtocolException::SIZE_LIMIT);
413 }
414
415 // Catch empty string case
416 if (size == 0) {
417 str = "";
418 return result;
419 }
Mark Slee6e536442006-06-30 18:28:50 +0000420
421 // Use the heap here to prevent stack overflow for v. large strings
Mark Sleef9831082007-02-20 20:59:21 +0000422 if (size > string_buf_size_ || string_buf_ == NULL) {
David Reiss58b4fa72008-04-01 04:17:58 +0000423 void* new_string_buf = std::realloc(string_buf_, (uint32_t)size);
424 if (new_string_buf == NULL) {
Mark Sleef9831082007-02-20 20:59:21 +0000425 throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString");
426 }
David Reiss58b4fa72008-04-01 04:17:58 +0000427 string_buf_ = (uint8_t*)new_string_buf;
Mark Sleef9831082007-02-20 20:59:21 +0000428 string_buf_size_ = size;
429 }
430 trans_->readAll(string_buf_, size);
431 str = string((char*)string_buf_, size);
Mark Slee808454e2007-06-20 21:51:57 +0000432 return (uint32_t)size;
Mark Sleee8540632006-05-30 09:24:40 +0000433}
Mark Sleecfc01932006-09-01 22:18:16 +0000434
T Jake Lucianib5e62212009-01-31 22:36:20 +0000435}}} // apache::thrift::protocol