blob: cea248bf8cc12ded3b80cb21d44c1aad97aa7706 [file] [log] [blame]
Marc Slemkod42a2c22006-08-10 03:30:18 +00001#include "TBinaryProtocol.h"
2
Mark Slee8d7e1f62006-06-07 06:48:56 +00003using std::string;
Mark Sleee8540632006-05-30 09:24:40 +00004
Marc Slemko6f038a72006-08-03 18:58:09 +00005namespace facebook { namespace thrift { namespace protocol {
6
Mark Slee4af6ed72006-10-25 19:02:49 +00007uint32_t TBinaryProtocol::writeMessageBegin(const std::string name,
Marc Slemko16698852006-08-04 03:16:10 +00008 const TMessageType messageType,
Mark Slee4af6ed72006-10-25 19:02:49 +00009 const int32_t seqid) {
Marc Slemko16698852006-08-04 03:16:10 +000010 return
Mark Slee4af6ed72006-10-25 19:02:49 +000011 writeString(name) +
12 writeByte((int8_t)messageType) +
13 writeI32(seqid);
Marc Slemko16698852006-08-04 03:16:10 +000014}
15
Mark Slee4af6ed72006-10-25 19:02:49 +000016uint32_t TBinaryProtocol::writeMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +000017 return 0;
18}
19
Mark Slee4af6ed72006-10-25 19:02:49 +000020uint32_t TBinaryProtocol::writeStructBegin(const string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000021 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000022}
23
Mark Slee4af6ed72006-10-25 19:02:49 +000024uint32_t TBinaryProtocol::writeStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000025 return 0;
Mark Sleee8540632006-05-30 09:24:40 +000026}
27
Mark Slee4af6ed72006-10-25 19:02:49 +000028uint32_t TBinaryProtocol::writeFieldBegin(const string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +000029 const TType fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +000030 const int16_t fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000031 return
Mark Slee4af6ed72006-10-25 19:02:49 +000032 writeByte((int8_t)fieldType) +
33 writeI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +000034}
35
Mark Slee4af6ed72006-10-25 19:02:49 +000036uint32_t TBinaryProtocol::writeFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000037 return 0;
38}
39
Mark Slee4af6ed72006-10-25 19:02:49 +000040uint32_t TBinaryProtocol::writeFieldStop() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000041 return
Mark Slee4af6ed72006-10-25 19:02:49 +000042 writeByte((int8_t)T_STOP);
Mark Slee8d7e1f62006-06-07 06:48:56 +000043}
44
Mark Slee4af6ed72006-10-25 19:02:49 +000045uint32_t TBinaryProtocol::writeMapBegin(const TType keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +000046 const TType valType,
Mark Slee4af6ed72006-10-25 19:02:49 +000047 const uint32_t size) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000048 return
Mark Slee4af6ed72006-10-25 19:02:49 +000049 writeByte((int8_t)keyType) +
50 writeByte((int8_t)valType) +
51 writeI32((int32_t)size);
Mark Slee8d7e1f62006-06-07 06:48:56 +000052}
53
Mark Slee4af6ed72006-10-25 19:02:49 +000054uint32_t TBinaryProtocol::writeMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000055 return 0;
56}
57
Mark Slee4af6ed72006-10-25 19:02:49 +000058uint32_t TBinaryProtocol::writeListBegin(const TType elemType,
59 const uint32_t size) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000060 return
Mark Slee4af6ed72006-10-25 19:02:49 +000061 writeByte((int8_t) elemType) +
62 writeI32((int32_t)size);
Mark Slee8d7e1f62006-06-07 06:48:56 +000063}
64
Mark Slee4af6ed72006-10-25 19:02:49 +000065uint32_t TBinaryProtocol::writeListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000066 return 0;
67}
68
Mark Slee4af6ed72006-10-25 19:02:49 +000069uint32_t TBinaryProtocol::writeSetBegin(const TType elemType,
70 const uint32_t size) {
Mark Slee8d7e1f62006-06-07 06:48:56 +000071 return
Mark Slee4af6ed72006-10-25 19:02:49 +000072 writeByte((int8_t)elemType) +
73 writeI32((int32_t)size);
Mark Slee8d7e1f62006-06-07 06:48:56 +000074}
75
Mark Slee4af6ed72006-10-25 19:02:49 +000076uint32_t TBinaryProtocol::writeSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +000077 return 0;
78}
79
Mark Slee4af6ed72006-10-25 19:02:49 +000080uint32_t TBinaryProtocol::writeBool(const bool value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +000081 uint8_t tmp = value ? 1 : 0;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000082 trans_->write(&tmp, 1);
Marc Slemko0b4ffa92006-08-11 02:49:29 +000083 return 1;
84}
85
Mark Slee4af6ed72006-10-25 19:02:49 +000086uint32_t TBinaryProtocol::writeByte(const int8_t byte) {
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000087 trans_->write((uint8_t*)&byte, 1);
Mark Slee8d7e1f62006-06-07 06:48:56 +000088 return 1;
89}
90
Mark Slee4af6ed72006-10-25 19:02:49 +000091uint32_t TBinaryProtocol::writeI16(const int16_t i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +000092 int16_t net = (int16_t)htons(i16);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000093 trans_->write((uint8_t*)&net, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +000094 return 2;
Mark Slee8d7e1f62006-06-07 06:48:56 +000095}
96
Mark Slee4af6ed72006-10-25 19:02:49 +000097uint32_t TBinaryProtocol::writeI32(const int32_t i32) {
Marc Slemkoe6889de2006-08-12 00:32:53 +000098 int32_t net = (int32_t)htonl(i32);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +000099 trans_->write((uint8_t*)&net, 4);
Marc Slemkoe6889de2006-08-12 00:32:53 +0000100 return 4;
101}
102
Mark Slee4af6ed72006-10-25 19:02:49 +0000103uint32_t TBinaryProtocol::writeI64(const int64_t i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000104 int64_t net = (int64_t)htonll(i64);
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000105 trans_->write((uint8_t*)&net, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000106 return 8;
107}
Mark Sleec98d0502006-09-06 02:42:25 +0000108
Mark Slee4af6ed72006-10-25 19:02:49 +0000109uint32_t TBinaryProtocol::writeDouble(const double dub) {
Mark Sleec98d0502006-09-06 02:42:25 +0000110 uint8_t b[8];
111 uint8_t* d = (uint8_t*)&dub;
112 b[0] = d[7];
113 b[1] = d[6];
114 b[2] = d[5];
115 b[3] = d[4];
116 b[4] = d[3];
117 b[5] = d[2];
118 b[6] = d[1];
119 b[7] = d[0];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000120 trans_->write((uint8_t*)b, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000121 return 8;
122}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000123
Mark Sleec98d0502006-09-06 02:42:25 +0000124
Mark Slee4af6ed72006-10-25 19:02:49 +0000125uint32_t TBinaryProtocol::writeString(const string& str) {
Mark Sleef9831082007-02-20 20:59:21 +0000126 uint32_t size = str.size();
127 uint32_t result = writeI32((int32_t)size);
128 if (size > 0) {
129 trans_->write((uint8_t*)str.data(), size);
130 }
131 return result + size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000132}
133
134/**
135 * Reading functions
136 */
137
Mark Slee4af6ed72006-10-25 19:02:49 +0000138uint32_t TBinaryProtocol::readMessageBegin(std::string& name,
Marc Slemkoe6889de2006-08-12 00:32:53 +0000139 TMessageType& messageType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000140 int32_t& seqid) {
Marc Slemko16698852006-08-04 03:16:10 +0000141
142 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000143 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000144 result+= readString(name);
145 result+= readByte(type);
Marc Slemko16698852006-08-04 03:16:10 +0000146 messageType = (TMessageType)type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000147 result+= readI32(seqid);
Marc Slemko16698852006-08-04 03:16:10 +0000148 return result;
149}
150
Mark Slee4af6ed72006-10-25 19:02:49 +0000151uint32_t TBinaryProtocol::readMessageEnd() {
Marc Slemko16698852006-08-04 03:16:10 +0000152 return 0;
153}
154
Mark Slee4af6ed72006-10-25 19:02:49 +0000155uint32_t TBinaryProtocol::readStructBegin(string& name) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000156 name = "";
157 return 0;
158}
159
Mark Slee4af6ed72006-10-25 19:02:49 +0000160uint32_t TBinaryProtocol::readStructEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000161 return 0;
162}
163
Mark Slee4af6ed72006-10-25 19:02:49 +0000164uint32_t TBinaryProtocol::readFieldBegin(string& name,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000165 TType& fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000166 int16_t& fieldId) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000167 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000168 int8_t type;
Mark Slee4af6ed72006-10-25 19:02:49 +0000169 result += readByte(type);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000170 fieldType = (TType)type;
171 if (fieldType == T_STOP) {
172 fieldId = 0;
173 return result;
174 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000175 result += readI16(fieldId);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000176 return result;
177}
Mark Sleee8540632006-05-30 09:24:40 +0000178
Mark Slee4af6ed72006-10-25 19:02:49 +0000179uint32_t TBinaryProtocol::readFieldEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000180 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000181}
Mark Slee8d7e1f62006-06-07 06:48:56 +0000182
Mark Slee4af6ed72006-10-25 19:02:49 +0000183uint32_t TBinaryProtocol::readMapBegin(TType& keyType,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000184 TType& valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000185 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000186 int8_t k, v;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000187 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000188 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000189 result += readByte(k);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000190 keyType = (TType)k;
Mark Slee4af6ed72006-10-25 19:02:49 +0000191 result += readByte(v);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000192 valType = (TType)v;
Mark Slee4af6ed72006-10-25 19:02:49 +0000193 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000194 if (sizei < 0) {
195 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
196 } else if (container_limit_ && sizei > container_limit_) {
197 throw TProtocolException(TProtocolException::SIZE_LIMIT);
198 }
Mark Sleecfc01932006-09-01 22:18:16 +0000199 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000200 return result;
201}
202
Mark Slee4af6ed72006-10-25 19:02:49 +0000203uint32_t TBinaryProtocol::readMapEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000204 return 0;
205}
206
Mark Slee4af6ed72006-10-25 19:02:49 +0000207uint32_t TBinaryProtocol::readListBegin(TType& elemType,
208 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000209 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000210 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000211 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000212 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000213 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000214 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000215 if (sizei < 0) {
216 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
217 } else if (container_limit_ && sizei > container_limit_) {
218 throw TProtocolException(TProtocolException::SIZE_LIMIT);
219 }
Mark Sleecfc01932006-09-01 22:18:16 +0000220 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000221 return result;
222}
223
Mark Slee4af6ed72006-10-25 19:02:49 +0000224uint32_t TBinaryProtocol::readListEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000225 return 0;
226}
227
Mark Slee4af6ed72006-10-25 19:02:49 +0000228uint32_t TBinaryProtocol::readSetBegin(TType& elemType,
229 uint32_t& size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000230 int8_t e;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000231 uint32_t result = 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000232 int32_t sizei;
Mark Slee4af6ed72006-10-25 19:02:49 +0000233 result += readByte(e);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000234 elemType = (TType)e;
Mark Slee4af6ed72006-10-25 19:02:49 +0000235 result += readI32(sizei);
Mark Sleef9831082007-02-20 20:59:21 +0000236 if (sizei < 0) {
237 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
238 } else if (container_limit_ && sizei > container_limit_) {
239 throw TProtocolException(TProtocolException::SIZE_LIMIT);
240 }
Mark Sleecfc01932006-09-01 22:18:16 +0000241 size = (uint32_t)sizei;
Mark Sleee8540632006-05-30 09:24:40 +0000242 return result;
243}
244
Mark Slee4af6ed72006-10-25 19:02:49 +0000245uint32_t TBinaryProtocol::readSetEnd() {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000246 return 0;
Mark Sleee8540632006-05-30 09:24:40 +0000247}
248
Mark Slee4af6ed72006-10-25 19:02:49 +0000249uint32_t TBinaryProtocol::readBool(bool& value) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000250 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000251 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000252 value = *(int8_t*)b != 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000253 return 1;
254}
255
Mark Slee4af6ed72006-10-25 19:02:49 +0000256uint32_t TBinaryProtocol::readByte(int8_t& byte) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000257 uint8_t b[1];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000258 trans_->readAll(b, 1);
Mark Sleecfc01932006-09-01 22:18:16 +0000259 byte = *(int8_t*)b;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000260 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000261}
262
Mark Slee4af6ed72006-10-25 19:02:49 +0000263uint32_t TBinaryProtocol::readI16(int16_t& i16) {
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000264 uint8_t b[2];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000265 trans_->readAll(b, 2);
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000266 i16 = *(int16_t*)b;
267 i16 = (int16_t)ntohs(i16);
268 return 2;
269}
270
Mark Slee4af6ed72006-10-25 19:02:49 +0000271uint32_t TBinaryProtocol::readI32(int32_t& i32) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000272 uint8_t b[4];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000273 trans_->readAll(b, 4);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000274 i32 = *(int32_t*)b;
275 i32 = (int32_t)ntohl(i32);
276 return 4;
Mark Sleee8540632006-05-30 09:24:40 +0000277}
278
Mark Slee4af6ed72006-10-25 19:02:49 +0000279uint32_t TBinaryProtocol::readI64(int64_t& i64) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000280 uint8_t b[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000281 trans_->readAll(b, 8);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000282 i64 = *(int64_t*)b;
283 i64 = (int64_t)ntohll(i64);
284 return 8;
Mark Sleee8540632006-05-30 09:24:40 +0000285}
286
Mark Slee4af6ed72006-10-25 19:02:49 +0000287uint32_t TBinaryProtocol::readDouble(double& dub) {
Mark Sleec98d0502006-09-06 02:42:25 +0000288 uint8_t b[8];
289 uint8_t d[8];
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000290 trans_->readAll(b, 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000291 d[0] = b[7];
292 d[1] = b[6];
293 d[2] = b[5];
294 d[3] = b[4];
295 d[4] = b[3];
296 d[5] = b[2];
297 d[6] = b[1];
298 d[7] = b[0];
299 dub = *(double*)d;
300 return 8;
301}
302
Mark Slee4af6ed72006-10-25 19:02:49 +0000303uint32_t TBinaryProtocol::readString(string& str) {
Mark Sleef3c322b2006-06-26 23:52:22 +0000304 uint32_t result;
Mark Sleecfc01932006-09-01 22:18:16 +0000305 int32_t size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000306 result = readI32(size);
Mark Sleecfc01932006-09-01 22:18:16 +0000307
Mark Sleef9831082007-02-20 20:59:21 +0000308 // Catch error cases
309 if (size < 0) {
310 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
311 }
312 if (string_limit_ > 0 && size > string_limit_) {
313 throw TProtocolException(TProtocolException::SIZE_LIMIT);
314 }
315
316 // Catch empty string case
317 if (size == 0) {
318 str = "";
319 return result;
320 }
Mark Slee6e536442006-06-30 18:28:50 +0000321
322 // Use the heap here to prevent stack overflow for v. large strings
Mark Sleef9831082007-02-20 20:59:21 +0000323 if (size > string_buf_size_ || string_buf_ == NULL) {
324 string_buf_ = (uint8_t*)realloc(string_buf_, (uint32_t)size);
325 if (string_buf_ == NULL) {
326 string_buf_size_ = 0;
327 throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString");
328 }
329 string_buf_size_ = size;
330 }
331 trans_->readAll(string_buf_, size);
332 str = string((char*)string_buf_, size);
Mark Slee6e536442006-06-30 18:28:50 +0000333
Mark Sleef3c322b2006-06-26 23:52:22 +0000334 return result + (uint32_t)size;
Mark Sleee8540632006-05-30 09:24:40 +0000335}
Mark Sleecfc01932006-09-01 22:18:16 +0000336
Marc Slemko6f038a72006-08-03 18:58:09 +0000337}}} // facebook::thrift::protocol