David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 1 | /* |
| 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 | */ |
| 19 | |
| 20 | #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ |
| 21 | #define _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ 1 |
| 22 | |
Roger Meier | 4285ba2 | 2013-06-10 21:17:23 +0200 | [diff] [blame] | 23 | #include <thrift/protocol/TBinaryProtocol.h> |
zeshuai007 | 86352b4 | 2020-06-15 17:00:33 +0800 | [diff] [blame] | 24 | #include <thrift/transport/TTransportException.h> |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 25 | |
| 26 | #include <limits> |
| 27 | |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 28 | namespace apache { |
| 29 | namespace thrift { |
| 30 | namespace protocol { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 31 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 32 | template <class Transport_, class ByteOrder_> |
| 33 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageBegin(const std::string& name, |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 34 | const TMessageType messageType, |
| 35 | const int32_t seqid) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 36 | if (this->strict_write_) { |
| 37 | int32_t version = (VERSION_1) | ((int32_t)messageType); |
| 38 | uint32_t wsize = 0; |
| 39 | wsize += writeI32(version); |
| 40 | wsize += writeString(name); |
| 41 | wsize += writeI32(seqid); |
| 42 | return wsize; |
| 43 | } else { |
| 44 | uint32_t wsize = 0; |
| 45 | wsize += writeString(name); |
| 46 | wsize += writeByte((int8_t)messageType); |
| 47 | wsize += writeI32(seqid); |
| 48 | return wsize; |
| 49 | } |
| 50 | } |
| 51 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 52 | template <class Transport_, class ByteOrder_> |
| 53 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 54 | return 0; |
| 55 | } |
| 56 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 57 | template <class Transport_, class ByteOrder_> |
| 58 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructBegin(const char* name) { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 59 | (void)name; |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 60 | return 0; |
| 61 | } |
| 62 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 63 | template <class Transport_, class ByteOrder_> |
| 64 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 65 | return 0; |
| 66 | } |
| 67 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 68 | template <class Transport_, class ByteOrder_> |
| 69 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldBegin(const char* name, |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 70 | const TType fieldType, |
| 71 | const int16_t fieldId) { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 72 | (void)name; |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 73 | uint32_t wsize = 0; |
| 74 | wsize += writeByte((int8_t)fieldType); |
| 75 | wsize += writeI16(fieldId); |
| 76 | return wsize; |
| 77 | } |
| 78 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 79 | template <class Transport_, class ByteOrder_> |
| 80 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 81 | return 0; |
| 82 | } |
| 83 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 84 | template <class Transport_, class ByteOrder_> |
| 85 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldStop() { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 86 | return writeByte((int8_t)T_STOP); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 87 | } |
| 88 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 89 | template <class Transport_, class ByteOrder_> |
| 90 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapBegin(const TType keyType, |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 91 | const TType valType, |
| 92 | const uint32_t size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 93 | uint32_t wsize = 0; |
| 94 | wsize += writeByte((int8_t)keyType); |
| 95 | wsize += writeByte((int8_t)valType); |
| 96 | wsize += writeI32((int32_t)size); |
| 97 | return wsize; |
| 98 | } |
| 99 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 100 | template <class Transport_, class ByteOrder_> |
| 101 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 102 | return 0; |
| 103 | } |
| 104 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 105 | template <class Transport_, class ByteOrder_> |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 106 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListBegin(const TType elemType, |
| 107 | const uint32_t size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 108 | uint32_t wsize = 0; |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 109 | wsize += writeByte((int8_t)elemType); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 110 | wsize += writeI32((int32_t)size); |
| 111 | return wsize; |
| 112 | } |
| 113 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 114 | template <class Transport_, class ByteOrder_> |
| 115 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 116 | return 0; |
| 117 | } |
| 118 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 119 | template <class Transport_, class ByteOrder_> |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 120 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetBegin(const TType elemType, |
| 121 | const uint32_t size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 122 | uint32_t wsize = 0; |
| 123 | wsize += writeByte((int8_t)elemType); |
| 124 | wsize += writeI32((int32_t)size); |
| 125 | return wsize; |
| 126 | } |
| 127 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 128 | template <class Transport_, class ByteOrder_> |
| 129 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 130 | return 0; |
| 131 | } |
| 132 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 133 | template <class Transport_, class ByteOrder_> |
| 134 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBool(const bool value) { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 135 | uint8_t tmp = value ? 1 : 0; |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 136 | this->trans_->write(&tmp, 1); |
| 137 | return 1; |
| 138 | } |
| 139 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 140 | template <class Transport_, class ByteOrder_> |
| 141 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeByte(const int8_t byte) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 142 | this->trans_->write((uint8_t*)&byte, 1); |
| 143 | return 1; |
| 144 | } |
| 145 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 146 | template <class Transport_, class ByteOrder_> |
| 147 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI16(const int16_t i16) { |
Sebastian Zenker | 042580f | 2019-01-29 15:48:12 +0100 | [diff] [blame] | 148 | auto net = (int16_t)ByteOrder_::toWire16(i16); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 149 | this->trans_->write((uint8_t*)&net, 2); |
| 150 | return 2; |
| 151 | } |
| 152 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 153 | template <class Transport_, class ByteOrder_> |
| 154 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI32(const int32_t i32) { |
Sebastian Zenker | 042580f | 2019-01-29 15:48:12 +0100 | [diff] [blame] | 155 | auto net = (int32_t)ByteOrder_::toWire32(i32); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 156 | this->trans_->write((uint8_t*)&net, 4); |
| 157 | return 4; |
| 158 | } |
| 159 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 160 | template <class Transport_, class ByteOrder_> |
| 161 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI64(const int64_t i64) { |
Sebastian Zenker | 042580f | 2019-01-29 15:48:12 +0100 | [diff] [blame] | 162 | auto net = (int64_t)ByteOrder_::toWire64(i64); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 163 | this->trans_->write((uint8_t*)&net, 8); |
| 164 | return 8; |
| 165 | } |
| 166 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 167 | template <class Transport_, class ByteOrder_> |
| 168 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeDouble(const double dub) { |
cyy | 863262d | 2019-01-06 10:40:58 +0800 | [diff] [blame] | 169 | static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)"); |
| 170 | static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559"); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 171 | |
Sebastian Zenker | 042580f | 2019-01-29 15:48:12 +0100 | [diff] [blame] | 172 | auto bits = bitwise_cast<uint64_t>(dub); |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 173 | bits = ByteOrder_::toWire64(bits); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 174 | this->trans_->write((uint8_t*)&bits, 8); |
| 175 | return 8; |
| 176 | } |
| 177 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 178 | template <class Transport_, class ByteOrder_> |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 179 | template <typename StrType> |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 180 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeString(const StrType& str) { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 181 | if (str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)())) |
Roger Meier | b69d24d | 2012-10-04 18:02:15 +0000 | [diff] [blame] | 182 | throw TProtocolException(TProtocolException::SIZE_LIMIT); |
Sebastian Zenker | 042580f | 2019-01-29 15:48:12 +0100 | [diff] [blame] | 183 | auto size = static_cast<uint32_t>(str.size()); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 184 | uint32_t result = writeI32((int32_t)size); |
| 185 | if (size > 0) { |
| 186 | this->trans_->write((uint8_t*)str.data(), size); |
| 187 | } |
| 188 | return result + size; |
| 189 | } |
| 190 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 191 | template <class Transport_, class ByteOrder_> |
| 192 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBinary(const std::string& str) { |
| 193 | return TBinaryProtocolT<Transport_, ByteOrder_>::writeString(str); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | /** |
| 197 | * Reading functions |
| 198 | */ |
| 199 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 200 | template <class Transport_, class ByteOrder_> |
| 201 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageBegin(std::string& name, |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 202 | TMessageType& messageType, |
| 203 | int32_t& seqid) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 204 | uint32_t result = 0; |
| 205 | int32_t sz; |
| 206 | result += readI32(sz); |
| 207 | |
| 208 | if (sz < 0) { |
| 209 | // Check for correct version number |
| 210 | int32_t version = sz & VERSION_MASK; |
| 211 | if (version != VERSION_1) { |
| 212 | throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier"); |
| 213 | } |
| 214 | messageType = (TMessageType)(sz & 0x000000ff); |
| 215 | result += readString(name); |
| 216 | result += readI32(seqid); |
| 217 | } else { |
| 218 | if (this->strict_read_) { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 219 | throw TProtocolException(TProtocolException::BAD_VERSION, |
| 220 | "No version identifier... old protocol client in strict mode?"); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 221 | } else { |
| 222 | // Handle pre-versioned input |
| 223 | int8_t type; |
| 224 | result += readStringBody(name, sz); |
| 225 | result += readByte(type); |
| 226 | messageType = (TMessageType)type; |
| 227 | result += readI32(seqid); |
| 228 | } |
| 229 | } |
| 230 | return result; |
| 231 | } |
| 232 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 233 | template <class Transport_, class ByteOrder_> |
| 234 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 235 | return 0; |
| 236 | } |
| 237 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 238 | template <class Transport_, class ByteOrder_> |
| 239 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructBegin(std::string& name) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 240 | name = ""; |
| 241 | return 0; |
| 242 | } |
| 243 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 244 | template <class Transport_, class ByteOrder_> |
| 245 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 246 | return 0; |
| 247 | } |
| 248 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 249 | template <class Transport_, class ByteOrder_> |
| 250 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldBegin(std::string& name, |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 251 | TType& fieldType, |
| 252 | int16_t& fieldId) { |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 253 | (void)name; |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 254 | uint32_t result = 0; |
| 255 | int8_t type; |
| 256 | result += readByte(type); |
| 257 | fieldType = (TType)type; |
| 258 | if (fieldType == T_STOP) { |
| 259 | fieldId = 0; |
| 260 | return result; |
| 261 | } |
| 262 | result += readI16(fieldId); |
| 263 | return result; |
| 264 | } |
| 265 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 266 | template <class Transport_, class ByteOrder_> |
| 267 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 268 | return 0; |
| 269 | } |
| 270 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 271 | template <class Transport_, class ByteOrder_> |
| 272 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapBegin(TType& keyType, |
Konrad Grochowski | 7f4be5f | 2015-11-05 20:23:11 +0100 | [diff] [blame] | 273 | TType& valType, |
| 274 | uint32_t& size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 275 | int8_t k, v; |
| 276 | uint32_t result = 0; |
| 277 | int32_t sizei; |
| 278 | result += readByte(k); |
| 279 | keyType = (TType)k; |
| 280 | result += readByte(v); |
| 281 | valType = (TType)v; |
| 282 | result += readI32(sizei); |
| 283 | if (sizei < 0) { |
| 284 | throw TProtocolException(TProtocolException::NEGATIVE_SIZE); |
| 285 | } else if (this->container_limit_ && sizei > this->container_limit_) { |
| 286 | throw TProtocolException(TProtocolException::SIZE_LIMIT); |
| 287 | } |
| 288 | size = (uint32_t)sizei; |
zeshuai007 | 86352b4 | 2020-06-15 17:00:33 +0800 | [diff] [blame] | 289 | |
| 290 | TMap map(keyType, valType, size); |
| 291 | checkReadBytesAvailable(map); |
| 292 | |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 293 | return result; |
| 294 | } |
| 295 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 296 | template <class Transport_, class ByteOrder_> |
| 297 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 298 | return 0; |
| 299 | } |
| 300 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 301 | template <class Transport_, class ByteOrder_> |
| 302 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListBegin(TType& elemType, uint32_t& size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 303 | int8_t e; |
| 304 | uint32_t result = 0; |
| 305 | int32_t sizei; |
| 306 | result += readByte(e); |
| 307 | elemType = (TType)e; |
| 308 | result += readI32(sizei); |
| 309 | if (sizei < 0) { |
| 310 | throw TProtocolException(TProtocolException::NEGATIVE_SIZE); |
| 311 | } else if (this->container_limit_ && sizei > this->container_limit_) { |
| 312 | throw TProtocolException(TProtocolException::SIZE_LIMIT); |
| 313 | } |
| 314 | size = (uint32_t)sizei; |
zeshuai007 | 86352b4 | 2020-06-15 17:00:33 +0800 | [diff] [blame] | 315 | |
| 316 | TList list(elemType, size); |
| 317 | checkReadBytesAvailable(list); |
| 318 | |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 319 | return result; |
| 320 | } |
| 321 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 322 | template <class Transport_, class ByteOrder_> |
| 323 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 324 | return 0; |
| 325 | } |
| 326 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 327 | template <class Transport_, class ByteOrder_> |
| 328 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetBegin(TType& elemType, uint32_t& size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 329 | int8_t e; |
| 330 | uint32_t result = 0; |
| 331 | int32_t sizei; |
| 332 | result += readByte(e); |
| 333 | elemType = (TType)e; |
| 334 | result += readI32(sizei); |
| 335 | if (sizei < 0) { |
| 336 | throw TProtocolException(TProtocolException::NEGATIVE_SIZE); |
| 337 | } else if (this->container_limit_ && sizei > this->container_limit_) { |
| 338 | throw TProtocolException(TProtocolException::SIZE_LIMIT); |
| 339 | } |
| 340 | size = (uint32_t)sizei; |
zeshuai007 | 86352b4 | 2020-06-15 17:00:33 +0800 | [diff] [blame] | 341 | |
| 342 | TSet set(elemType, size); |
| 343 | checkReadBytesAvailable(set); |
| 344 | |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 345 | return result; |
| 346 | } |
| 347 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 348 | template <class Transport_, class ByteOrder_> |
| 349 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetEnd() { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 350 | return 0; |
| 351 | } |
| 352 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 353 | template <class Transport_, class ByteOrder_> |
| 354 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBool(bool& value) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 355 | uint8_t b[1]; |
| 356 | this->trans_->readAll(b, 1); |
| 357 | value = *(int8_t*)b != 0; |
| 358 | return 1; |
| 359 | } |
| 360 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 361 | template <class Transport_, class ByteOrder_> |
| 362 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readByte(int8_t& byte) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 363 | uint8_t b[1]; |
| 364 | this->trans_->readAll(b, 1); |
| 365 | byte = *(int8_t*)b; |
| 366 | return 1; |
| 367 | } |
| 368 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 369 | template <class Transport_, class ByteOrder_> |
| 370 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI16(int16_t& i16) { |
Christian Lavoie | 2bbc328 | 2011-02-08 23:05:47 +0000 | [diff] [blame] | 371 | union bytes { |
| 372 | uint8_t b[2]; |
| 373 | int16_t all; |
| 374 | } theBytes; |
| 375 | this->trans_->readAll(theBytes.b, 2); |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 376 | i16 = (int16_t)ByteOrder_::fromWire16(theBytes.all); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 377 | return 2; |
| 378 | } |
| 379 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 380 | template <class Transport_, class ByteOrder_> |
| 381 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI32(int32_t& i32) { |
Christian Lavoie | 2bbc328 | 2011-02-08 23:05:47 +0000 | [diff] [blame] | 382 | union bytes { |
| 383 | uint8_t b[4]; |
| 384 | int32_t all; |
| 385 | } theBytes; |
| 386 | this->trans_->readAll(theBytes.b, 4); |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 387 | i32 = (int32_t)ByteOrder_::fromWire32(theBytes.all); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 388 | return 4; |
| 389 | } |
| 390 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 391 | template <class Transport_, class ByteOrder_> |
| 392 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI64(int64_t& i64) { |
Christian Lavoie | 2bbc328 | 2011-02-08 23:05:47 +0000 | [diff] [blame] | 393 | union bytes { |
| 394 | uint8_t b[8]; |
| 395 | int64_t all; |
| 396 | } theBytes; |
| 397 | this->trans_->readAll(theBytes.b, 8); |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 398 | i64 = (int64_t)ByteOrder_::fromWire64(theBytes.all); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 399 | return 8; |
| 400 | } |
| 401 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 402 | template <class Transport_, class ByteOrder_> |
| 403 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readDouble(double& dub) { |
cyy | 863262d | 2019-01-06 10:40:58 +0800 | [diff] [blame] | 404 | static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)"); |
| 405 | static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559"); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 406 | |
Christian Lavoie | 2bbc328 | 2011-02-08 23:05:47 +0000 | [diff] [blame] | 407 | union bytes { |
| 408 | uint8_t b[8]; |
| 409 | uint64_t all; |
| 410 | } theBytes; |
| 411 | this->trans_->readAll(theBytes.b, 8); |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 412 | theBytes.all = ByteOrder_::fromWire64(theBytes.all); |
Christian Lavoie | 2bbc328 | 2011-02-08 23:05:47 +0000 | [diff] [blame] | 413 | dub = bitwise_cast<double>(theBytes.all); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 414 | return 8; |
| 415 | } |
| 416 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 417 | template <class Transport_, class ByteOrder_> |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 418 | template <typename StrType> |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 419 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readString(StrType& str) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 420 | uint32_t result; |
| 421 | int32_t size; |
| 422 | result = readI32(size); |
| 423 | return result + readStringBody(str, size); |
| 424 | } |
| 425 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 426 | template <class Transport_, class ByteOrder_> |
| 427 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBinary(std::string& str) { |
| 428 | return TBinaryProtocolT<Transport_, ByteOrder_>::readString(str); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 429 | } |
| 430 | |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 431 | template <class Transport_, class ByteOrder_> |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 432 | template <typename StrType> |
Ben Craig | 384f976 | 2015-07-08 20:33:03 -0500 | [diff] [blame] | 433 | uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStringBody(StrType& str, int32_t size) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 434 | uint32_t result = 0; |
| 435 | |
| 436 | // Catch error cases |
| 437 | if (size < 0) { |
| 438 | throw TProtocolException(TProtocolException::NEGATIVE_SIZE); |
| 439 | } |
| 440 | if (this->string_limit_ > 0 && size > this->string_limit_) { |
| 441 | throw TProtocolException(TProtocolException::SIZE_LIMIT); |
| 442 | } |
| 443 | |
| 444 | // Catch empty string case |
| 445 | if (size == 0) { |
Roger Meier | 92a90ff | 2012-04-13 14:50:32 +0000 | [diff] [blame] | 446 | str.clear(); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 447 | return result; |
| 448 | } |
| 449 | |
| 450 | // Try to borrow first |
| 451 | const uint8_t* borrow_buf; |
| 452 | uint32_t got = size; |
Sebastian Zenker | 042580f | 2019-01-29 15:48:12 +0100 | [diff] [blame] | 453 | if ((borrow_buf = this->trans_->borrow(nullptr, &got))) { |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 454 | str.assign((const char*)borrow_buf, size); |
| 455 | this->trans_->consume(size); |
| 456 | return size; |
| 457 | } |
| 458 | |
Ben Craig | fd64c15 | 2013-10-09 15:26:05 -0500 | [diff] [blame] | 459 | str.resize(size); |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 460 | this->trans_->readAll(reinterpret_cast<uint8_t*>(&str[0]), size); |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 461 | return (uint32_t)size; |
| 462 | } |
zeshuai007 | 86352b4 | 2020-06-15 17:00:33 +0800 | [diff] [blame] | 463 | |
| 464 | // Return the minimum number of bytes a type will consume on the wire |
| 465 | template <class Transport_, class ByteOrder_> |
| 466 | int TBinaryProtocolT<Transport_, ByteOrder_>::getMinSerializedSize(TType type) |
| 467 | { |
| 468 | switch (type) |
| 469 | { |
| 470 | case T_STOP: return 0; |
| 471 | case T_VOID: return 0; |
| 472 | case T_BOOL: return sizeof(int8_t); |
| 473 | case T_BYTE: return sizeof(int8_t); |
| 474 | case T_DOUBLE: return sizeof(double); |
| 475 | case T_I16: return sizeof(short); |
| 476 | case T_I32: return sizeof(int); |
| 477 | case T_I64: return sizeof(long); |
| 478 | case T_STRING: return sizeof(int); // string length |
| 479 | case T_STRUCT: return 0; // empty struct |
| 480 | case T_MAP: return sizeof(int); // element count |
| 481 | case T_SET: return sizeof(int); // element count |
| 482 | case T_LIST: return sizeof(int); // element count |
| 483 | default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); |
| 484 | } |
| 485 | } |
| 486 | |
Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 487 | } |
| 488 | } |
| 489 | } // apache::thrift::protocol |
David Reiss | e71115b | 2010-10-06 17:09:56 +0000 | [diff] [blame] | 490 | |
| 491 | #endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ |