blob: 544ef885a360d34c258f2deced30fffb50e0da43 [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 Slee8d7e1f62006-06-07 06:48:56 +00009using std::string;
Mark Sleee8540632006-05-30 09:24:40 +000010
Marc Slemko6f038a72006-08-03 18:58:09 +000011namespace facebook { namespace thrift { namespace protocol {
12
Mark Slee82a6c0f2007-04-04 21:08:21 +000013uint32_t TBinaryProtocol::writeMessageBegin(const std::string& name,
14 const TMessageType messageType,
15 const int32_t seqid) {
Marc Slemko16698852006-08-04 03:16:10 +000016 return
Mark Slee4af6ed72006-10-25 19:02:49 +000017 writeString(name) +
18 writeByte((int8_t)messageType) +
19 writeI32(seqid);
Marc Slemko16698852006-08-04 03:16:10 +000020}
21
Mark Slee4af6ed72006-10-25 19:02:49 +000022uint32_t TBinaryProtocol::writeMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +000023 return 0;
24}
25
Mark Slee4af6ed72006-10-25 19:02:49 +000026uint32_t TBinaryProtocol::writeStructBegin(const string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000027 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000028}
29
Mark Slee4af6ed72006-10-25 19:02:49 +000030uint32_t TBinaryProtocol::writeStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000031 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000032}
33
Mark Slee4af6ed72006-10-25 19:02:49 +000034uint32_t TBinaryProtocol::writeFieldBegin(const string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +000035 const TType fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +000036 const int16_t fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000037 return
Mark Slee4af6ed72006-10-25 19:02:49 +000038 writeByte((int8_t)fieldType) +
39 writeI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +000040}
41
Mark Slee4af6ed72006-10-25 19:02:49 +000042uint32_t TBinaryProtocol::writeFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000043 return 0;
44}
45
Mark Slee4af6ed72006-10-25 19:02:49 +000046uint32_t TBinaryProtocol::writeFieldStop() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000047 return
Mark Slee4af6ed72006-10-25 19:02:49 +000048 writeByte((int8_t)T_STOP);
Mark Slee8d7e1f62006-06-07 06:48:56 +000049}
50
Mark Slee4af6ed72006-10-25 19:02:49 +000051uint32_t TBinaryProtocol::writeMapBegin(const TType keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +000052 const TType valType,
Mark Slee4af6ed72006-10-25 19:02:49 +000053 const uint32_t size) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000054 return
Mark Slee4af6ed72006-10-25 19:02:49 +000055 writeByte((int8_t)keyType) +
56 writeByte((int8_t)valType) +
57 writeI32((int32_t)size);
Mark Slee8d7e1f62006-06-07 06:48:56 +000058}
59
Mark Slee4af6ed72006-10-25 19:02:49 +000060uint32_t TBinaryProtocol::writeMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000061 return 0;
62}
63
Mark Slee4af6ed72006-10-25 19:02:49 +000064uint32_t TBinaryProtocol::writeListBegin(const TType elemType,
65 const uint32_t size) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000066 return
Mark Slee4af6ed72006-10-25 19:02:49 +000067 writeByte((int8_t) elemType) +
68 writeI32((int32_t)size);
Mark Slee8d7e1f62006-06-07 06:48:56 +000069}
70
Mark Slee4af6ed72006-10-25 19:02:49 +000071uint32_t TBinaryProtocol::writeListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000072 return 0;
73}
74
Mark Slee4af6ed72006-10-25 19:02:49 +000075uint32_t TBinaryProtocol::writeSetBegin(const TType elemType,
76 const uint32_t size) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000077 return
Mark Slee4af6ed72006-10-25 19:02:49 +000078 writeByte((int8_t)elemType) +
79 writeI32((int32_t)size);
Mark Slee8d7e1f62006-06-07 06:48:56 +000080}
81
Mark Slee4af6ed72006-10-25 19:02:49 +000082uint32_t TBinaryProtocol::writeSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000083 return 0;
84}
85
Mark Slee4af6ed72006-10-25 19:02:49 +000086uint32_t TBinaryProtocol::writeBool(const bool value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +000087 uint8_t tmp = value ? 1 : 0;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000088 trans_->write(&tmp, 1);
Marc Slemko0b4ffa92006-08-11 02:49:29 +000089 return 1;
90}
91
Mark Slee4af6ed72006-10-25 19:02:49 +000092uint32_t TBinaryProtocol::writeByte(const int8_t byte) {
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000093 trans_->write((uint8_t*)&byte, 1);
Mark Slee8d7e1f62006-06-07 06:48:56 +000094 return 1;
95}
96
Mark Slee4af6ed72006-10-25 19:02:49 +000097uint32_t TBinaryProtocol::writeI16(const int16_t i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +000098 int16_t net = (int16_t)htons(i16);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000099 trans_->write((uint8_t*)&net, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000100 return 2;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000101}
102
Mark Slee4af6ed72006-10-25 19:02:49 +0000103uint32_t TBinaryProtocol::writeI32(const int32_t i32) {
Marc Slemkoe6889de2006-08-12 00:32:53 +0000104 int32_t net = (int32_t)htonl(i32);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000105 trans_->write((uint8_t*)&net, 4);
Marc Slemkoe6889de2006-08-12 00:32:53 +0000106 return 4;
107}
108
Mark Slee4af6ed72006-10-25 19:02:49 +0000109uint32_t TBinaryProtocol::writeI64(const int64_t i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000110 int64_t net = (int64_t)htonll(i64);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000111 trans_->write((uint8_t*)&net, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000112 return 8;
113}
Mark Sleec98d0502006-09-06 02:42:25 +0000114
Mark Slee4af6ed72006-10-25 19:02:49 +0000115uint32_t TBinaryProtocol::writeDouble(const double dub) {
Mark Sleec98d0502006-09-06 02:42:25 +0000116 uint8_t b[8];
117 uint8_t* d = (uint8_t*)&dub;
118 b[0] = d[7];
119 b[1] = d[6];
120 b[2] = d[5];
121 b[3] = d[4];
122 b[4] = d[3];
123 b[5] = d[2];
124 b[6] = d[1];
125 b[7] = d[0];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000126 trans_->write((uint8_t*)b, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000127 return 8;
128}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000129
Mark Sleec98d0502006-09-06 02:42:25 +0000130
Mark Slee4af6ed72006-10-25 19:02:49 +0000131uint32_t TBinaryProtocol::writeString(const string& str) {
Mark Sleef9831082007-02-20 20:59:21 +0000132 uint32_t size = str.size();
133 uint32_t result = writeI32((int32_t)size);
134 if (size > 0) {
135 trans_->write((uint8_t*)str.data(), size);
136 }
137 return result + size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000138}
139
140/**
141 * Reading functions
142 */
143
Mark Slee4af6ed72006-10-25 19:02:49 +0000144uint32_t TBinaryProtocol::readMessageBegin(std::string& name,
Marc Slemkoe6889de2006-08-12 00:32:53 +0000145 TMessageType& messageType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000146 int32_t& seqid) {
Marc Slemko16698852006-08-04 03:16:10 +0000147
148 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000149 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000150 result+= readString(name);
151 result+= readByte(type);
Marc Slemko16698852006-08-04 03:16:10 +0000152 messageType = (TMessageType)type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000153 result+= readI32(seqid);
Marc Slemko16698852006-08-04 03:16:10 +0000154 return result;
155}
156
Mark Slee4af6ed72006-10-25 19:02:49 +0000157uint32_t TBinaryProtocol::readMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +0000158 return 0;
159}
160
Mark Slee4af6ed72006-10-25 19:02:49 +0000161uint32_t TBinaryProtocol::readStructBegin(string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000162 name = "";
163 return 0;
164}
165
Mark Slee4af6ed72006-10-25 19:02:49 +0000166uint32_t TBinaryProtocol::readStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000167 return 0;
168}
169
Mark Slee4af6ed72006-10-25 19:02:49 +0000170uint32_t TBinaryProtocol::readFieldBegin(string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000171 TType& fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000172 int16_t& fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000173 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000174 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000175 result += readByte(type);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000176 fieldType = (TType)type;
177 if (fieldType == T_STOP) {
178 fieldId = 0;
179 return result;
180 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000181 result += readI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000182 return result;
183}
Mark Sleee8540632006-05-30 09:24:40 +0000184
Mark Slee4af6ed72006-10-25 19:02:49 +0000185uint32_t TBinaryProtocol::readFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000186 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000187}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000188
Mark Slee4af6ed72006-10-25 19:02:49 +0000189uint32_t TBinaryProtocol::readMapBegin(TType& keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000190 TType& valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000191 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000192 int8_t k, v;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000193 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000194 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000195 result += readByte(k);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000196 keyType = (TType)k;
Mark Slee4af6ed72006-10-25 19:02:49 +0000197 result += readByte(v);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000198 valType = (TType)v;
Mark Slee4af6ed72006-10-25 19:02:49 +0000199 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000200 if (sizei < 0) {
201 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
202 } else if (container_limit_ && sizei > container_limit_) {
203 throw TProtocolException(TProtocolException::SIZE_LIMIT);
204 }
Mark Sleecfc01932006-09-01 22:18:16 +0000205 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000206 return result;
207}
208
Mark Slee4af6ed72006-10-25 19:02:49 +0000209uint32_t TBinaryProtocol::readMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000210 return 0;
211}
212
Mark Slee4af6ed72006-10-25 19:02:49 +0000213uint32_t TBinaryProtocol::readListBegin(TType& elemType,
214 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000215 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000216 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000217 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000218 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000219 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000220 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000221 if (sizei < 0) {
222 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
223 } else if (container_limit_ && sizei > container_limit_) {
224 throw TProtocolException(TProtocolException::SIZE_LIMIT);
225 }
Mark Sleecfc01932006-09-01 22:18:16 +0000226 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000227 return result;
228}
229
Mark Slee4af6ed72006-10-25 19:02:49 +0000230uint32_t TBinaryProtocol::readListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000231 return 0;
232}
233
Mark Slee4af6ed72006-10-25 19:02:49 +0000234uint32_t TBinaryProtocol::readSetBegin(TType& elemType,
235 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000236 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000237 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000238 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000239 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000240 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000241 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000242 if (sizei < 0) {
243 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
244 } else if (container_limit_ && sizei > container_limit_) {
245 throw TProtocolException(TProtocolException::SIZE_LIMIT);
246 }
Mark Sleecfc01932006-09-01 22:18:16 +0000247 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000248 return result;
249}
250
Mark Slee4af6ed72006-10-25 19:02:49 +0000251uint32_t TBinaryProtocol::readSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000252 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000253}
254
Mark Slee4af6ed72006-10-25 19:02:49 +0000255uint32_t TBinaryProtocol::readBool(bool& value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000256 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000257 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000258 value = *(int8_t*)b != 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000259 return 1;
260}
261
Mark Slee4af6ed72006-10-25 19:02:49 +0000262uint32_t TBinaryProtocol::readByte(int8_t& byte) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000263 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000264 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000265 byte = *(int8_t*)b;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000266 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000267}
268
Mark Slee4af6ed72006-10-25 19:02:49 +0000269uint32_t TBinaryProtocol::readI16(int16_t& i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000270 uint8_t b[2];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000271 trans_->readAll(b, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000272 i16 = *(int16_t*)b;
273 i16 = (int16_t)ntohs(i16);
274 return 2;
275}
276
Mark Slee4af6ed72006-10-25 19:02:49 +0000277uint32_t TBinaryProtocol::readI32(int32_t& i32) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000278 uint8_t b[4];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000279 trans_->readAll(b, 4);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000280 i32 = *(int32_t*)b;
281 i32 = (int32_t)ntohl(i32);
282 return 4;
Mark Sleee8540632006-05-30 09:24:40 +0000283}
284
Mark Slee4af6ed72006-10-25 19:02:49 +0000285uint32_t TBinaryProtocol::readI64(int64_t& i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000286 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000287 trans_->readAll(b, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000288 i64 = *(int64_t*)b;
289 i64 = (int64_t)ntohll(i64);
290 return 8;
Mark Sleee8540632006-05-30 09:24:40 +0000291}
292
Mark Slee4af6ed72006-10-25 19:02:49 +0000293uint32_t TBinaryProtocol::readDouble(double& dub) {
Mark Sleec98d0502006-09-06 02:42:25 +0000294 uint8_t b[8];
295 uint8_t d[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000296 trans_->readAll(b, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000297 d[0] = b[7];
298 d[1] = b[6];
299 d[2] = b[5];
300 d[3] = b[4];
301 d[4] = b[3];
302 d[5] = b[2];
303 d[6] = b[1];
304 d[7] = b[0];
305 dub = *(double*)d;
306 return 8;
307}
308
Mark Slee4af6ed72006-10-25 19:02:49 +0000309uint32_t TBinaryProtocol::readString(string& str) {
Mark Sleef3c322b2006-06-26 23:52:22 +0000310 uint32_t result;
Mark Sleecfc01932006-09-01 22:18:16 +0000311 int32_t size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000312 result = readI32(size);
Mark Sleecfc01932006-09-01 22:18:16 +0000313
Mark Sleef9831082007-02-20 20:59:21 +0000314 // Catch error cases
315 if (size < 0) {
316 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
317 }
318 if (string_limit_ > 0 && size > string_limit_) {
319 throw TProtocolException(TProtocolException::SIZE_LIMIT);
320 }
321
322 // Catch empty string case
323 if (size == 0) {
324 str = "";
325 return result;
326 }
Mark Slee6e536442006-06-30 18:28:50 +0000327
328 // Use the heap here to prevent stack overflow for v. large strings
Mark Sleef9831082007-02-20 20:59:21 +0000329 if (size > string_buf_size_ || string_buf_ == NULL) {
330 string_buf_ = (uint8_t*)realloc(string_buf_, (uint32_t)size);
331 if (string_buf_ == NULL) {
332 string_buf_size_ = 0;
333 throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString");
334 }
335 string_buf_size_ = size;
336 }
337 trans_->readAll(string_buf_, size);
338 str = string((char*)string_buf_, size);
Mark Slee6e536442006-06-30 18:28:50 +0000339
Mark Sleef3c322b2006-06-26 23:52:22 +0000340 return result + (uint32_t)size;
Mark Sleee8540632006-05-30 09:24:40 +0000341}
Mark Sleecfc01932006-09-01 22:18:16 +0000342
Marc Slemko6f038a72006-08-03 18:58:09 +0000343}}} // facebook::thrift::protocol