Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/thrift/protocol/TBinaryProtocol.tcc is written in an unsupported language. File is not indexed.

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements. See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership. The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License. You may obtain a copy of the License at
0009  *
0010  *   http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing,
0013  * software distributed under the License is distributed on an
0014  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015  * KIND, either express or implied. See the License for the
0016  * specific language governing permissions and limitations
0017  * under the License.
0018  */
0019 
0020 #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_
0021 #define _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ 1
0022 
0023 #include <thrift/protocol/TBinaryProtocol.h>
0024 #include <thrift/transport/TTransportException.h>
0025 
0026 #include <limits>
0027 
0028 namespace apache {
0029 namespace thrift {
0030 namespace protocol {
0031 
0032 template <class Transport_, class ByteOrder_>
0033 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageBegin(const std::string& name,
0034                                                                      const TMessageType messageType,
0035                                                                      const int32_t seqid) {
0036   if (this->strict_write_) {
0037     int32_t version = (VERSION_1) | ((int32_t)messageType);
0038     uint32_t wsize = 0;
0039     wsize += writeI32(version);
0040     wsize += writeString(name);
0041     wsize += writeI32(seqid);
0042     return wsize;
0043   } else {
0044     uint32_t wsize = 0;
0045     wsize += writeString(name);
0046     wsize += writeByte((int8_t)messageType);
0047     wsize += writeI32(seqid);
0048     return wsize;
0049   }
0050 }
0051 
0052 template <class Transport_, class ByteOrder_>
0053 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageEnd() {
0054   return 0;
0055 }
0056 
0057 template <class Transport_, class ByteOrder_>
0058 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructBegin(const char* name) {
0059   (void)name;
0060   return 0;
0061 }
0062 
0063 template <class Transport_, class ByteOrder_>
0064 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructEnd() {
0065   return 0;
0066 }
0067 
0068 template <class Transport_, class ByteOrder_>
0069 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldBegin(const char* name,
0070                                                                    const TType fieldType,
0071                                                                    const int16_t fieldId) {
0072   (void)name;
0073   uint32_t wsize = 0;
0074   wsize += writeByte((int8_t)fieldType);
0075   wsize += writeI16(fieldId);
0076   return wsize;
0077 }
0078 
0079 template <class Transport_, class ByteOrder_>
0080 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldEnd() {
0081   return 0;
0082 }
0083 
0084 template <class Transport_, class ByteOrder_>
0085 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldStop() {
0086   return writeByte((int8_t)T_STOP);
0087 }
0088 
0089 template <class Transport_, class ByteOrder_>
0090 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapBegin(const TType keyType,
0091                                                                  const TType valType,
0092                                                                  const uint32_t size) {
0093   uint32_t wsize = 0;
0094   wsize += writeByte((int8_t)keyType);
0095   wsize += writeByte((int8_t)valType);
0096   wsize += writeI32((int32_t)size);
0097   return wsize;
0098 }
0099 
0100 template <class Transport_, class ByteOrder_>
0101 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapEnd() {
0102   return 0;
0103 }
0104 
0105 template <class Transport_, class ByteOrder_>
0106 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListBegin(const TType elemType,
0107                                                                   const uint32_t size) {
0108   uint32_t wsize = 0;
0109   wsize += writeByte((int8_t)elemType);
0110   wsize += writeI32((int32_t)size);
0111   return wsize;
0112 }
0113 
0114 template <class Transport_, class ByteOrder_>
0115 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListEnd() {
0116   return 0;
0117 }
0118 
0119 template <class Transport_, class ByteOrder_>
0120 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetBegin(const TType elemType,
0121                                                                  const uint32_t size) {
0122   uint32_t wsize = 0;
0123   wsize += writeByte((int8_t)elemType);
0124   wsize += writeI32((int32_t)size);
0125   return wsize;
0126 }
0127 
0128 template <class Transport_, class ByteOrder_>
0129 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetEnd() {
0130   return 0;
0131 }
0132 
0133 template <class Transport_, class ByteOrder_>
0134 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBool(const bool value) {
0135   uint8_t tmp = value ? 1 : 0;
0136   this->trans_->write(&tmp, 1);
0137   return 1;
0138 }
0139 
0140 template <class Transport_, class ByteOrder_>
0141 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeByte(const int8_t byte) {
0142   this->trans_->write((uint8_t*)&byte, 1);
0143   return 1;
0144 }
0145 
0146 template <class Transport_, class ByteOrder_>
0147 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI16(const int16_t i16) {
0148   auto net = (int16_t)ByteOrder_::toWire16(i16);
0149   this->trans_->write((uint8_t*)&net, 2);
0150   return 2;
0151 }
0152 
0153 template <class Transport_, class ByteOrder_>
0154 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI32(const int32_t i32) {
0155   auto net = (int32_t)ByteOrder_::toWire32(i32);
0156   this->trans_->write((uint8_t*)&net, 4);
0157   return 4;
0158 }
0159 
0160 template <class Transport_, class ByteOrder_>
0161 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI64(const int64_t i64) {
0162   auto net = (int64_t)ByteOrder_::toWire64(i64);
0163   this->trans_->write((uint8_t*)&net, 8);
0164   return 8;
0165 }
0166 
0167 template <class Transport_, class ByteOrder_>
0168 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeDouble(const double dub) {
0169   static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
0170   static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
0171 
0172   auto bits = bitwise_cast<uint64_t>(dub);
0173   bits = ByteOrder_::toWire64(bits);
0174   this->trans_->write((uint8_t*)&bits, 8);
0175   return 8;
0176 }
0177 
0178 template <class Transport_, class ByteOrder_>
0179 template <typename StrType>
0180 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeString(const StrType& str) {
0181   if (str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)()))
0182     throw TProtocolException(TProtocolException::SIZE_LIMIT);
0183   auto size = static_cast<uint32_t>(str.size());
0184   uint32_t result = writeI32((int32_t)size);
0185   if (size > 0) {
0186     this->trans_->write((uint8_t*)str.data(), size);
0187   }
0188   return result + size;
0189 }
0190 
0191 template <class Transport_, class ByteOrder_>
0192 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBinary(const std::string& str) {
0193   return TBinaryProtocolT<Transport_, ByteOrder_>::writeString(str);
0194 }
0195 
0196 template <class Transport_, class ByteOrder_>
0197 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeUUID(const TUuid& uuid) {
0198   // TODO: Consider endian swapping, see lib/delphi/src/Thrift.Utils.pas:377
0199   this->trans_->write(uuid.data(), uuid.size());
0200   return 16;
0201 }
0202 
0203 /**
0204  * Reading functions
0205  */
0206 
0207 template <class Transport_, class ByteOrder_>
0208 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageBegin(std::string& name,
0209                                                                     TMessageType& messageType,
0210                                                                     int32_t& seqid) {
0211   uint32_t result = 0;
0212   int32_t sz;
0213   result += readI32(sz);
0214 
0215   if (sz < 0) {
0216     // Check for correct version number
0217     int32_t version = sz & VERSION_MASK;
0218     if (version != VERSION_1) {
0219       throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
0220     }
0221     messageType = (TMessageType)(sz & 0x000000ff);
0222     result += readString(name);
0223     result += readI32(seqid);
0224   } else {
0225     if (this->strict_read_) {
0226       throw TProtocolException(TProtocolException::BAD_VERSION,
0227                                "No version identifier... old protocol client in strict mode?");
0228     } else {
0229       // Handle pre-versioned input
0230       int8_t type;
0231       result += readStringBody(name, sz);
0232       result += readByte(type);
0233       messageType = (TMessageType)type;
0234       result += readI32(seqid);
0235     }
0236   }
0237   return result;
0238 }
0239 
0240 template <class Transport_, class ByteOrder_>
0241 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageEnd() {
0242   return 0;
0243 }
0244 
0245 template <class Transport_, class ByteOrder_>
0246 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructBegin(std::string& name) {
0247   name = "";
0248   return 0;
0249 }
0250 
0251 template <class Transport_, class ByteOrder_>
0252 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructEnd() {
0253   return 0;
0254 }
0255 
0256 template <class Transport_, class ByteOrder_>
0257 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldBegin(std::string& name,
0258                                                                   TType& fieldType,
0259                                                                   int16_t& fieldId) {
0260   (void)name;
0261   uint32_t result = 0;
0262   int8_t type;
0263   result += readByte(type);
0264   fieldType = (TType)type;
0265   if (fieldType == T_STOP) {
0266     fieldId = 0;
0267     return result;
0268   }
0269   result += readI16(fieldId);
0270   return result;
0271 }
0272 
0273 template <class Transport_, class ByteOrder_>
0274 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldEnd() {
0275   return 0;
0276 }
0277 
0278 template <class Transport_, class ByteOrder_>
0279 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapBegin(TType& keyType,
0280                                                                 TType& valType,
0281                                                                 uint32_t& size) {
0282   int8_t k, v;
0283   uint32_t result = 0;
0284   int32_t sizei;
0285   result += readByte(k);
0286   keyType = (TType)k;
0287   result += readByte(v);
0288   valType = (TType)v;
0289   result += readI32(sizei);
0290   if (sizei < 0) {
0291     throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
0292   } else if (this->container_limit_ && sizei > this->container_limit_) {
0293     throw TProtocolException(TProtocolException::SIZE_LIMIT);
0294   }
0295   size = (uint32_t)sizei;
0296 
0297   TMap map(keyType, valType, size);
0298   checkReadBytesAvailable(map);
0299 
0300   return result;
0301 }
0302 
0303 template <class Transport_, class ByteOrder_>
0304 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapEnd() {
0305   return 0;
0306 }
0307 
0308 template <class Transport_, class ByteOrder_>
0309 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListBegin(TType& elemType, uint32_t& size) {
0310   int8_t e;
0311   uint32_t result = 0;
0312   int32_t sizei;
0313   result += readByte(e);
0314   elemType = (TType)e;
0315   result += readI32(sizei);
0316   if (sizei < 0) {
0317     throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
0318   } else if (this->container_limit_ && sizei > this->container_limit_) {
0319     throw TProtocolException(TProtocolException::SIZE_LIMIT);
0320   }
0321   size = (uint32_t)sizei;
0322 
0323   TList list(elemType, size);
0324   checkReadBytesAvailable(list);
0325 
0326   return result;
0327 }
0328 
0329 template <class Transport_, class ByteOrder_>
0330 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListEnd() {
0331   return 0;
0332 }
0333 
0334 template <class Transport_, class ByteOrder_>
0335 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetBegin(TType& elemType, uint32_t& size) {
0336   int8_t e;
0337   uint32_t result = 0;
0338   int32_t sizei;
0339   result += readByte(e);
0340   elemType = (TType)e;
0341   result += readI32(sizei);
0342   if (sizei < 0) {
0343     throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
0344   } else if (this->container_limit_ && sizei > this->container_limit_) {
0345     throw TProtocolException(TProtocolException::SIZE_LIMIT);
0346   }
0347   size = (uint32_t)sizei;
0348 
0349   TSet set(elemType, size);
0350   checkReadBytesAvailable(set);
0351 
0352   return result;
0353 }
0354 
0355 template <class Transport_, class ByteOrder_>
0356 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetEnd() {
0357   return 0;
0358 }
0359 
0360 template <class Transport_, class ByteOrder_>
0361 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBool(bool& value) {
0362   uint8_t b[1];
0363   this->trans_->readAll(b, 1);
0364   value = *(int8_t*)b != 0;
0365   return 1;
0366 }
0367 
0368 template <class Transport_, class ByteOrder_>
0369 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readByte(int8_t& byte) {
0370   uint8_t b[1];
0371   this->trans_->readAll(b, 1);
0372   byte = *(int8_t*)b;
0373   return 1;
0374 }
0375 
0376 template <class Transport_, class ByteOrder_>
0377 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI16(int16_t& i16) {
0378   union bytes {
0379     uint8_t b[2];
0380     int16_t all;
0381   } theBytes;
0382   this->trans_->readAll(theBytes.b, 2);
0383   i16 = (int16_t)ByteOrder_::fromWire16(theBytes.all);
0384   return 2;
0385 }
0386 
0387 template <class Transport_, class ByteOrder_>
0388 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI32(int32_t& i32) {
0389   union bytes {
0390     uint8_t b[4];
0391     int32_t all;
0392   } theBytes;
0393   this->trans_->readAll(theBytes.b, 4);
0394   i32 = (int32_t)ByteOrder_::fromWire32(theBytes.all);
0395   return 4;
0396 }
0397 
0398 template <class Transport_, class ByteOrder_>
0399 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI64(int64_t& i64) {
0400   union bytes {
0401     uint8_t b[8];
0402     int64_t all;
0403   } theBytes;
0404   this->trans_->readAll(theBytes.b, 8);
0405   i64 = (int64_t)ByteOrder_::fromWire64(theBytes.all);
0406   return 8;
0407 }
0408 
0409 template <class Transport_, class ByteOrder_>
0410 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readDouble(double& dub) {
0411   static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
0412   static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
0413 
0414   union bytes {
0415     uint8_t b[8];
0416     uint64_t all;
0417   } theBytes;
0418   this->trans_->readAll(theBytes.b, 8);
0419   theBytes.all = ByteOrder_::fromWire64(theBytes.all);
0420   dub = bitwise_cast<double>(theBytes.all);
0421   return 8;
0422 }
0423 
0424 template <class Transport_, class ByteOrder_>
0425 template <typename StrType>
0426 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readString(StrType& str) {
0427   uint32_t result;
0428   int32_t size;
0429   result = readI32(size);
0430   return result + readStringBody(str, size);
0431 }
0432 
0433 template <class Transport_, class ByteOrder_>
0434 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBinary(std::string& str) {
0435   return TBinaryProtocolT<Transport_, ByteOrder_>::readString(str);
0436 }
0437 
0438 template <class Transport_, class ByteOrder_>
0439 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readUUID(TUuid& uuid) {
0440   this->trans_->readAll(uuid.begin(), uuid.size());
0441   return 16;
0442 }
0443 
0444 template <class Transport_, class ByteOrder_>
0445 template <typename StrType>
0446 uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStringBody(StrType& str, int32_t size) {
0447   uint32_t result = 0;
0448 
0449   // Catch error cases
0450   if (size < 0) {
0451     throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
0452   }
0453   if (this->string_limit_ > 0 && size > this->string_limit_) {
0454     throw TProtocolException(TProtocolException::SIZE_LIMIT);
0455   }
0456 
0457   // Catch empty string case
0458   if (size == 0) {
0459     str.clear();
0460     return result;
0461   }
0462 
0463   // Try to borrow first
0464   uint32_t got = size;
0465   const uint8_t* borrow_buf = this->trans_->borrow(nullptr, &got);
0466   if (borrow_buf) {
0467     str.assign((const char*)borrow_buf, size);
0468     this->trans_->consume(size);
0469     return size;
0470   }
0471 
0472   str.resize(size);
0473   this->trans_->readAll(reinterpret_cast<uint8_t*>(&str[0]), size);
0474   return (uint32_t)size;
0475 }
0476 
0477 // Return the minimum number of bytes a type will consume on the wire
0478 template <class Transport_, class ByteOrder_>
0479 int TBinaryProtocolT<Transport_, ByteOrder_>::getMinSerializedSize(TType type)
0480 {
0481   switch (type)
0482   {
0483       case T_STOP: return 0;
0484       case T_VOID: return 0;
0485       case T_BOOL: return sizeof(int8_t);
0486       case T_BYTE: return sizeof(int8_t);
0487       case T_DOUBLE: return sizeof(double);
0488       case T_I16: return sizeof(short);
0489       case T_I32: return sizeof(int);
0490       case T_I64: return sizeof(long);
0491       case T_STRING: return sizeof(int);  // string length
0492       case T_STRUCT: return 0;  // empty struct
0493       case T_MAP: return sizeof(int);  // element count
0494       case T_SET: return sizeof(int);  // element count
0495       case T_LIST: return sizeof(int);  // element count
0496       default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code");
0497   }
0498 }
0499 
0500 }
0501 }
0502 } // apache::thrift::protocol
0503 
0504 #endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_