| Mark Slee | 9f0c651 | 2007-02-28 23:58:26 +0000 | [diff] [blame] | 1 | // 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 Slemko | d42a2c2 | 2006-08-10 03:30:18 +0000 | [diff] [blame] | 7 | #include "TBinaryProtocol.h" | 
 | 8 |  | 
| David Reiss | 32e95f8 | 2008-06-11 01:18:36 +0000 | [diff] [blame] | 9 | #include <limits> | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 10 | #include <boost/static_assert.hpp> | 
 | 11 |  | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 12 | using std::string; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 13 |  | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 14 | // 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 | 
 | 21 | template <typename To, typename From> | 
 | 22 | static inline To bitwise_cast(From from) { | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 23 |   BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To)); | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 24 |  | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 25 |   // 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 Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 29 |  | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 30 |   // 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 Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 36 |  | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 37 |   // Slightly more questionable. | 
 | 38 |   // Same code emitted by GCC. | 
 | 39 |   //To to; | 
 | 40 |   //memcpy(&to, &from, sizeof(from)); | 
 | 41 |   //return to; | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 42 |  | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 43 |   // 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 Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 51 | } | 
 | 52 |  | 
 | 53 |  | 
| T Jake Luciani | b5e6221 | 2009-01-31 22:36:20 +0000 | [diff] [blame] | 54 | namespace apache { namespace thrift { namespace protocol { | 
| Marc Slemko | 6f038a7 | 2006-08-03 18:58:09 +0000 | [diff] [blame] | 55 |  | 
| Mark Slee | 82a6c0f | 2007-04-04 21:08:21 +0000 | [diff] [blame] | 56 | uint32_t TBinaryProtocol::writeMessageBegin(const std::string& name, | 
 | 57 |                                             const TMessageType messageType, | 
 | 58 |                                             const int32_t seqid) { | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 59 |   if (strict_write_) { | 
 | 60 |     int32_t version = (VERSION_1) | ((int32_t)messageType); | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 61 |     uint32_t wsize = 0; | 
 | 62 |     wsize += writeI32(version); | 
 | 63 |     wsize += writeString(name); | 
 | 64 |     wsize += writeI32(seqid); | 
 | 65 |     return wsize; | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 66 |   } else { | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 67 |     uint32_t wsize = 0; | 
 | 68 |     wsize += writeString(name); | 
 | 69 |     wsize += writeByte((int8_t)messageType); | 
 | 70 |     wsize += writeI32(seqid); | 
 | 71 |     return wsize; | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 72 |   } | 
| Marc Slemko | 1669885 | 2006-08-04 03:16:10 +0000 | [diff] [blame] | 73 | } | 
 | 74 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 75 | uint32_t TBinaryProtocol::writeMessageEnd() { | 
| Marc Slemko | 1669885 | 2006-08-04 03:16:10 +0000 | [diff] [blame] | 76 |   return 0; | 
 | 77 | } | 
 | 78 |  | 
| David Reiss | 6412000 | 2008-04-29 23:12:24 +0000 | [diff] [blame] | 79 | uint32_t TBinaryProtocol::writeStructBegin(const char* name) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 80 |   return 0; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 81 | } | 
 | 82 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 83 | uint32_t TBinaryProtocol::writeStructEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 84 |   return 0; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 85 | } | 
 | 86 |  | 
| David Reiss | 6412000 | 2008-04-29 23:12:24 +0000 | [diff] [blame] | 87 | uint32_t TBinaryProtocol::writeFieldBegin(const char* name, | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 88 |                                           const TType fieldType, | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 89 |                                           const int16_t fieldId) { | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 90 |   uint32_t wsize = 0; | 
 | 91 |   wsize += writeByte((int8_t)fieldType); | 
 | 92 |   wsize += writeI16(fieldId); | 
 | 93 |   return wsize; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 94 | } | 
 | 95 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 96 | uint32_t TBinaryProtocol::writeFieldEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 97 |   return 0; | 
 | 98 | } | 
 | 99 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 100 | uint32_t TBinaryProtocol::writeFieldStop() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 101 |   return | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 102 |     writeByte((int8_t)T_STOP); | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 103 | } | 
 | 104 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 105 | uint32_t TBinaryProtocol::writeMapBegin(const TType keyType, | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 106 |                                         const TType valType, | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 107 |                                         const uint32_t size) { | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 108 |   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 Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 113 | } | 
 | 114 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 115 | uint32_t TBinaryProtocol::writeMapEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 116 |   return 0; | 
 | 117 | } | 
 | 118 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 119 | uint32_t TBinaryProtocol::writeListBegin(const TType elemType, | 
 | 120 |                                          const uint32_t size) { | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 121 |   uint32_t wsize = 0; | 
 | 122 |   wsize += writeByte((int8_t) elemType); | 
 | 123 |   wsize += writeI32((int32_t)size); | 
 | 124 |   return wsize; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 125 | } | 
 | 126 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 127 | uint32_t TBinaryProtocol::writeListEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 128 |   return 0; | 
 | 129 | } | 
 | 130 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 131 | uint32_t TBinaryProtocol::writeSetBegin(const TType elemType, | 
 | 132 |                                         const uint32_t size) { | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 133 |   uint32_t wsize = 0; | 
| David Reiss | f79031e | 2007-07-06 21:43:48 +0000 | [diff] [blame] | 134 |   wsize += writeByte((int8_t)elemType); | 
 | 135 |   wsize += writeI32((int32_t)size); | 
 | 136 |   return wsize; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 137 | } | 
 | 138 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 139 | uint32_t TBinaryProtocol::writeSetEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 140 |   return 0; | 
 | 141 | } | 
 | 142 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 143 | uint32_t TBinaryProtocol::writeBool(const bool value) { | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 144 |   uint8_t tmp =  value ? 1 : 0; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 145 |   trans_->write(&tmp, 1); | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 146 |   return 1; | 
 | 147 | } | 
 | 148 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 149 | uint32_t TBinaryProtocol::writeByte(const int8_t byte) { | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 150 |   trans_->write((uint8_t*)&byte, 1); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 151 |   return 1; | 
 | 152 | } | 
 | 153 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 154 | uint32_t TBinaryProtocol::writeI16(const int16_t i16) { | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 155 |   int16_t net = (int16_t)htons(i16); | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 156 |   trans_->write((uint8_t*)&net, 2); | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 157 |   return 2; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 158 | } | 
 | 159 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 160 | uint32_t TBinaryProtocol::writeI32(const int32_t i32) { | 
| Marc Slemko | e6889de | 2006-08-12 00:32:53 +0000 | [diff] [blame] | 161 |   int32_t net = (int32_t)htonl(i32); | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 162 |   trans_->write((uint8_t*)&net, 4); | 
| Marc Slemko | e6889de | 2006-08-12 00:32:53 +0000 | [diff] [blame] | 163 |   return 4; | 
 | 164 | } | 
 | 165 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 166 | uint32_t TBinaryProtocol::writeI64(const int64_t i64) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 167 |   int64_t net = (int64_t)htonll(i64); | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 168 |   trans_->write((uint8_t*)&net, 8); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 169 |   return 8; | 
 | 170 | } | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 171 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 172 | uint32_t TBinaryProtocol::writeDouble(const double dub) { | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 173 |   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 Slee | c98d050 | 2006-09-06 02:42:25 +0000 | [diff] [blame] | 179 |   return 8; | 
 | 180 | } | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 181 |  | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 182 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 183 | uint32_t TBinaryProtocol::writeString(const string& str) { | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 184 |   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 Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 190 | } | 
 | 191 |  | 
| David Reiss | c005b1b | 2008-02-15 01:38:18 +0000 | [diff] [blame] | 192 | uint32_t TBinaryProtocol::writeBinary(const string& str) { | 
 | 193 |   return TBinaryProtocol::writeString(str); | 
 | 194 | } | 
 | 195 |  | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 196 | /** | 
 | 197 |  * Reading functions | 
 | 198 |  */ | 
 | 199 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 200 | uint32_t TBinaryProtocol::readMessageBegin(std::string& name, | 
| David Reiss | 96d2388 | 2007-07-26 21:10:32 +0000 | [diff] [blame] | 201 |                                            TMessageType& messageType, | 
 | 202 |                                            int32_t& seqid) { | 
| Marc Slemko | 1669885 | 2006-08-04 03:16:10 +0000 | [diff] [blame] | 203 |   uint32_t result = 0; | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 204 |   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 Slemko | 1669885 | 2006-08-04 03:16:10 +0000 | [diff] [blame] | 228 |   return result; | 
 | 229 | } | 
 | 230 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 231 | uint32_t TBinaryProtocol::readMessageEnd() { | 
| Marc Slemko | 1669885 | 2006-08-04 03:16:10 +0000 | [diff] [blame] | 232 |   return 0; | 
 | 233 | } | 
 | 234 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 235 | uint32_t TBinaryProtocol::readStructBegin(string& name) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 236 |   name = ""; | 
 | 237 |   return 0; | 
 | 238 | } | 
 | 239 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 240 | uint32_t TBinaryProtocol::readStructEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 241 |   return 0; | 
 | 242 | } | 
 | 243 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 244 | uint32_t TBinaryProtocol::readFieldBegin(string& name, | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 245 |                                          TType& fieldType, | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 246 |                                          int16_t& fieldId) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 247 |   uint32_t result = 0; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 248 |   int8_t type; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 249 |   result += readByte(type); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 250 |   fieldType = (TType)type; | 
 | 251 |   if (fieldType == T_STOP) { | 
 | 252 |     fieldId = 0; | 
 | 253 |     return result; | 
 | 254 |   } | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 255 |   result += readI16(fieldId); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 256 |   return result; | 
 | 257 | } | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 258 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 259 | uint32_t TBinaryProtocol::readFieldEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 260 |   return 0; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 261 | } | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 262 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 263 | uint32_t TBinaryProtocol::readMapBegin(TType& keyType, | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 264 |                                        TType& valType, | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 265 |                                        uint32_t& size) { | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 266 |   int8_t k, v; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 267 |   uint32_t result = 0; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 268 |   int32_t sizei; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 269 |   result += readByte(k); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 270 |   keyType = (TType)k; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 271 |   result += readByte(v); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 272 |   valType = (TType)v; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 273 |   result += readI32(sizei); | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 274 |   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 Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 279 |   size = (uint32_t)sizei; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 280 |   return result; | 
 | 281 | } | 
 | 282 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 283 | uint32_t TBinaryProtocol::readMapEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 284 |   return 0; | 
 | 285 | } | 
 | 286 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 287 | uint32_t TBinaryProtocol::readListBegin(TType& elemType, | 
 | 288 |                                         uint32_t& size) { | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 289 |   int8_t e; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 290 |   uint32_t result = 0; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 291 |   int32_t sizei; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 292 |   result += readByte(e); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 293 |   elemType = (TType)e; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 294 |   result += readI32(sizei); | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 295 |   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 Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 300 |   size = (uint32_t)sizei; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 301 |   return result; | 
 | 302 | } | 
 | 303 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 304 | uint32_t TBinaryProtocol::readListEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 305 |   return 0; | 
 | 306 | } | 
 | 307 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 308 | uint32_t TBinaryProtocol::readSetBegin(TType& elemType, | 
 | 309 |                                        uint32_t& size) { | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 310 |   int8_t e; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 311 |   uint32_t result = 0; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 312 |   int32_t sizei; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 313 |   result += readByte(e); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 314 |   elemType = (TType)e; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 315 |   result += readI32(sizei); | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 316 |   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 Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 321 |   size = (uint32_t)sizei; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 322 |   return result; | 
 | 323 | } | 
 | 324 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 325 | uint32_t TBinaryProtocol::readSetEnd() { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 326 |   return 0; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 327 | } | 
 | 328 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 329 | uint32_t TBinaryProtocol::readBool(bool& value) { | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 330 |   uint8_t b[1]; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 331 |   trans_->readAll(b, 1); | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 332 |   value = *(int8_t*)b != 0; | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 333 |   return 1; | 
 | 334 | } | 
 | 335 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 336 | uint32_t TBinaryProtocol::readByte(int8_t& byte) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 337 |   uint8_t b[1]; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 338 |   trans_->readAll(b, 1); | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 339 |   byte = *(int8_t*)b; | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 340 |   return 1; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 341 | } | 
 | 342 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 343 | uint32_t TBinaryProtocol::readI16(int16_t& i16) { | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 344 |   uint8_t b[2]; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 345 |   trans_->readAll(b, 2); | 
| Marc Slemko | 0b4ffa9 | 2006-08-11 02:49:29 +0000 | [diff] [blame] | 346 |   i16 = *(int16_t*)b; | 
 | 347 |   i16 = (int16_t)ntohs(i16); | 
 | 348 |   return 2; | 
 | 349 | } | 
 | 350 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 351 | uint32_t TBinaryProtocol::readI32(int32_t& i32) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 352 |   uint8_t b[4]; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 353 |   trans_->readAll(b, 4); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 354 |   i32 = *(int32_t*)b; | 
 | 355 |   i32 = (int32_t)ntohl(i32); | 
 | 356 |   return 4; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 357 | } | 
 | 358 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 359 | uint32_t TBinaryProtocol::readI64(int64_t& i64) { | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 360 |   uint8_t b[8]; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 361 |   trans_->readAll(b, 8); | 
| Mark Slee | 8d7e1f6 | 2006-06-07 06:48:56 +0000 | [diff] [blame] | 362 |   i64 = *(int64_t*)b; | 
 | 363 |   i64 = (int64_t)ntohll(i64); | 
 | 364 |   return 8; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 365 | } | 
 | 366 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 367 | uint32_t TBinaryProtocol::readDouble(double& dub) { | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 368 |   BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t)); | 
 | 369 |   BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559); | 
 | 370 |  | 
 | 371 |   uint64_t bits; | 
| Mark Slee | c98d050 | 2006-09-06 02:42:25 +0000 | [diff] [blame] | 372 |   uint8_t b[8]; | 
| Aditya Agarwal | 9abb0d6 | 2007-01-24 22:53:54 +0000 | [diff] [blame] | 373 |   trans_->readAll(b, 8); | 
| Mark Slee | 4f261c5 | 2007-04-13 00:33:24 +0000 | [diff] [blame] | 374 |   bits = *(uint64_t*)b; | 
 | 375 |   bits = ntohll(bits); | 
 | 376 |   dub = bitwise_cast<double>(bits); | 
| Mark Slee | c98d050 | 2006-09-06 02:42:25 +0000 | [diff] [blame] | 377 |   return 8; | 
 | 378 | } | 
 | 379 |  | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 380 | uint32_t TBinaryProtocol::readString(string& str) { | 
| Mark Slee | f3c322b | 2006-06-26 23:52:22 +0000 | [diff] [blame] | 381 |   uint32_t result; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 382 |   int32_t size; | 
| Mark Slee | 4af6ed7 | 2006-10-25 19:02:49 +0000 | [diff] [blame] | 383 |   result = readI32(size); | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 384 |   return result + readStringBody(str, size); | 
 | 385 | } | 
 | 386 |  | 
| David Reiss | c005b1b | 2008-02-15 01:38:18 +0000 | [diff] [blame] | 387 | uint32_t TBinaryProtocol::readBinary(string& str) { | 
 | 388 |   return TBinaryProtocol::readString(str); | 
 | 389 | } | 
 | 390 |  | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 391 | uint32_t TBinaryProtocol::readStringBody(string& str, int32_t size) { | 
 | 392 |   uint32_t result = 0; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 393 |  | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 394 |   // 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 Slee | 6e53644 | 2006-06-30 18:28:50 +0000 | [diff] [blame] | 407 |  | 
 | 408 |   // Use the heap here to prevent stack overflow for v. large strings | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 409 |   if (size > string_buf_size_ || string_buf_ == NULL) { | 
| David Reiss | 58b4fa7 | 2008-04-01 04:17:58 +0000 | [diff] [blame] | 410 |     void* new_string_buf = std::realloc(string_buf_, (uint32_t)size); | 
 | 411 |     if (new_string_buf == NULL) { | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 412 |       throw TProtocolException(TProtocolException::UNKNOWN, "Out of memory in TBinaryProtocol::readString"); | 
 | 413 |     } | 
| David Reiss | 58b4fa7 | 2008-04-01 04:17:58 +0000 | [diff] [blame] | 414 |     string_buf_ = (uint8_t*)new_string_buf; | 
| Mark Slee | f983108 | 2007-02-20 20:59:21 +0000 | [diff] [blame] | 415 |     string_buf_size_ = size; | 
 | 416 |   } | 
 | 417 |   trans_->readAll(string_buf_, size); | 
 | 418 |   str = string((char*)string_buf_, size); | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 419 |   return (uint32_t)size; | 
| Mark Slee | e854063 | 2006-05-30 09:24:40 +0000 | [diff] [blame] | 420 | } | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 421 |  | 
| T Jake Luciani | b5e6221 | 2009-01-31 22:36:20 +0000 | [diff] [blame] | 422 | }}} // apache::thrift::protocol |