Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:02

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_TPROTOCOL_H_
0021 #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1
0022 
0023 #ifdef _WIN32
0024 // Including Winsock2.h adds problematic macros like min() and max().
0025 // Try to work around:
0026 #ifndef NOMINMAX
0027 #define NOMINMAX
0028 #define _THRIFT_UNDEF_NOMINMAX
0029 #endif
0030 #ifndef WIN32_LEAN_AND_MEAN
0031 #define WIN32_LEAN_AND_MEAN
0032 #define _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN
0033 #endif
0034 // Need to come before any Windows.h includes
0035 #include <winsock2.h>
0036 #ifdef _THRIFT_UNDEF_NOMINMAX
0037 #undef NOMINMAX
0038 #undef _THRIFT_UNDEF_NOMINMAX
0039 #endif
0040 #ifdef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN
0041 #undef WIN32_LEAN_AND_MEAN
0042 #undef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN
0043 #endif
0044 #endif
0045 
0046 #include <thrift/transport/TTransport.h>
0047 #include <thrift/protocol/TProtocolException.h>
0048 #include <thrift/protocol/TEnum.h>
0049 #include <thrift/protocol/TList.h>
0050 #include <thrift/protocol/TSet.h>
0051 #include <thrift/protocol/TMap.h>
0052 #include <thrift/TUuid.h>
0053 
0054 #include <memory>
0055 
0056 #ifdef HAVE_NETINET_IN_H
0057 #include <netinet/in.h>
0058 #endif
0059 #include <sys/types.h>
0060 #include <string>
0061 #include <map>
0062 #include <vector>
0063 #include <climits>
0064 
0065 // Use this to get around strict aliasing rules.
0066 // For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
0067 // The most obvious implementation is to just cast a pointer,
0068 // but that doesn't work.
0069 // For a pretty in-depth explanation of the problem, see
0070 // http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
0071 template <typename To, typename From>
0072 static inline To bitwise_cast(From from) {
0073   static_assert(sizeof(From) == sizeof(To), "sizeof(From) == sizeof(To)");
0074 
0075   // BAD!!!  These are all broken with -O2.
0076   //return *reinterpret_cast<To*>(&from);  // BAD!!!
0077   //return *static_cast<To*>(static_cast<void*>(&from));  // BAD!!!
0078   //return *(To*)(void*)&from;  // BAD!!!
0079 
0080   // Super clean and paritally blessed by section 3.9 of the standard.
0081   //unsigned char c[sizeof(from)];
0082   //memcpy(c, &from, sizeof(from));
0083   //To to;
0084   //memcpy(&to, c, sizeof(c));
0085   //return to;
0086 
0087   // Slightly more questionable.
0088   // Same code emitted by GCC.
0089   //To to;
0090   //memcpy(&to, &from, sizeof(from));
0091   //return to;
0092 
0093   // Technically undefined, but almost universally supported,
0094   // and the most efficient implementation.
0095   union {
0096     From f;
0097     To t;
0098   } u;
0099   u.f = from;
0100   return u.t;
0101 }
0102 
0103 
0104 #ifdef HAVE_SYS_PARAM_H
0105 #include <sys/param.h>
0106 #endif
0107 
0108 #ifdef __ZEPHYR__
0109 #  include <zephyr/sys/byteorder.h>
0110 
0111 #  define __THRIFT_BYTE_ORDER __BYTE_ORDER__
0112 #  define __THRIFT_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
0113 #  define __THRIFT_BIG_ENDIAN __ORDER_BIG_ENDIAN__
0114 
0115 #  if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
0116 #    undef bswap_64
0117 #    undef bswap_32
0118 #    undef bswap_16
0119 #  endif
0120 #endif
0121 
0122 #ifndef __THRIFT_BYTE_ORDER
0123 # if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
0124 #  define __THRIFT_BYTE_ORDER BYTE_ORDER
0125 #  define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
0126 #  define __THRIFT_BIG_ENDIAN BIG_ENDIAN
0127 # else
0128 #  include <boost/predef/other/endian.h>
0129 #  if BOOST_ENDIAN_BIG_BYTE
0130 #    define __THRIFT_BYTE_ORDER 4321
0131 #    define __THRIFT_LITTLE_ENDIAN 0
0132 #    define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
0133 #  elif BOOST_ENDIAN_LITTLE_BYTE
0134 #    define __THRIFT_BYTE_ORDER 1234
0135 #    define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
0136 #    define __THRIFT_BIG_ENDIAN 0
0137 #  endif
0138 #  ifdef BOOST_LITTLE_ENDIAN
0139 #  else
0140 #  endif
0141 # endif
0142 #endif
0143 
0144 #if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
0145 # if !defined(THRIFT_ntohll)
0146 #  define THRIFT_ntohll(n) (n)
0147 #  define THRIFT_htonll(n) (n)
0148 # endif
0149 # if defined(__GNUC__) && defined(__GLIBC__)
0150 #  include <byteswap.h>
0151 #  define THRIFT_htolell(n) bswap_64(n)
0152 #  define THRIFT_letohll(n) bswap_64(n)
0153 #  define THRIFT_htolel(n) bswap_32(n)
0154 #  define THRIFT_letohl(n) bswap_32(n)
0155 #  define THRIFT_htoles(n) bswap_16(n)
0156 #  define THRIFT_letohs(n) bswap_16(n)
0157 # else /* GNUC & GLIBC */
0158 #  define bswap_64(n) \
0159       ( (((n) & 0xff00000000000000ull) >> 56) \
0160       | (((n) & 0x00ff000000000000ull) >> 40) \
0161       | (((n) & 0x0000ff0000000000ull) >> 24) \
0162       | (((n) & 0x000000ff00000000ull) >> 8)  \
0163       | (((n) & 0x00000000ff000000ull) << 8)  \
0164       | (((n) & 0x0000000000ff0000ull) << 24) \
0165       | (((n) & 0x000000000000ff00ull) << 40) \
0166       | (((n) & 0x00000000000000ffull) << 56) )
0167 #  define bswap_32(n) \
0168       ( (((n) & 0xff000000ul) >> 24) \
0169       | (((n) & 0x00ff0000ul) >> 8)  \
0170       | (((n) & 0x0000ff00ul) << 8)  \
0171       | (((n) & 0x000000fful) << 24) )
0172 #  define bswap_16(n) \
0173       ( (((n) & ((unsigned short)0xff00ul)) >> 8)  \
0174       | (((n) & ((unsigned short)0x00fful)) << 8)  )
0175 #  define THRIFT_htolell(n) bswap_64(n)
0176 #  define THRIFT_letohll(n) bswap_64(n)
0177 #  define THRIFT_htolel(n) bswap_32(n)
0178 #  define THRIFT_letohl(n) bswap_32(n)
0179 #  define THRIFT_htoles(n) bswap_16(n)
0180 #  define THRIFT_letohs(n) bswap_16(n)
0181 # endif /* GNUC & GLIBC */
0182 #elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN
0183 #  define THRIFT_htolell(n) (n)
0184 #  define THRIFT_letohll(n) (n)
0185 #  define THRIFT_htolel(n) (n)
0186 #  define THRIFT_letohl(n) (n)
0187 #  define THRIFT_htoles(n) (n)
0188 #  define THRIFT_letohs(n) (n)
0189 # if defined(__GNUC__) && defined(__GLIBC__)
0190 #  include <byteswap.h>
0191 #  define THRIFT_ntohll(n) bswap_64(n)
0192 #  define THRIFT_htonll(n) bswap_64(n)
0193 # elif defined(_MSC_VER) /* Microsoft Visual C++ */
0194 #  define THRIFT_ntohll(n) ( _byteswap_uint64((uint64_t)n) )
0195 #  define THRIFT_htonll(n) ( _byteswap_uint64((uint64_t)n) )
0196 # elif !defined(THRIFT_ntohll) /* Not GNUC/GLIBC or MSVC */
0197 #  define THRIFT_ntohll(n) ( (((uint64_t)ntohl((uint32_t)n)) << 32) + ntohl((uint32_t)(n >> 32)) )
0198 #  define THRIFT_htonll(n) ( (((uint64_t)htonl((uint32_t)n)) << 32) + htonl((uint32_t)(n >> 32)) )
0199 # endif /* GNUC/GLIBC or MSVC or something else */
0200 #else /* __THRIFT_BYTE_ORDER */
0201 # error "Can't define THRIFT_htonll or THRIFT_ntohll!"
0202 #endif
0203 
0204 namespace apache {
0205 namespace thrift {
0206 namespace protocol {
0207 
0208 using apache::thrift::transport::TTransport;
0209 
0210 /**
0211  * Abstract class for a thrift protocol driver. These are all the methods that
0212  * a protocol must implement. Essentially, there must be some way of reading
0213  * and writing all the base types, plus a mechanism for writing out structs
0214  * with indexed fields.
0215  *
0216  * TProtocol objects should not be shared across multiple encoding contexts,
0217  * as they may need to maintain internal state in some protocols (i.e. XML).
0218  * Note that is is acceptable for the TProtocol module to do its own internal
0219  * buffered reads/writes to the underlying TTransport where appropriate (i.e.
0220  * when parsing an input XML stream, reading should be batched rather than
0221  * looking ahead character by character for a close tag).
0222  *
0223  */
0224 class TProtocol {
0225 public:
0226   virtual ~TProtocol();
0227 
0228   /**
0229    * Writing functions.
0230    */
0231 
0232   virtual uint32_t writeMessageBegin_virt(const std::string& name,
0233                                           const TMessageType messageType,
0234                                           const int32_t seqid) = 0;
0235 
0236   virtual uint32_t writeMessageEnd_virt() = 0;
0237 
0238   virtual uint32_t writeStructBegin_virt(const char* name) = 0;
0239 
0240   virtual uint32_t writeStructEnd_virt() = 0;
0241 
0242   virtual uint32_t writeFieldBegin_virt(const char* name,
0243                                         const TType fieldType,
0244                                         const int16_t fieldId) = 0;
0245 
0246   virtual uint32_t writeFieldEnd_virt() = 0;
0247 
0248   virtual uint32_t writeFieldStop_virt() = 0;
0249 
0250   virtual uint32_t writeMapBegin_virt(const TType keyType, const TType valType, const uint32_t size)
0251       = 0;
0252 
0253   virtual uint32_t writeMapEnd_virt() = 0;
0254 
0255   virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) = 0;
0256 
0257   virtual uint32_t writeListEnd_virt() = 0;
0258 
0259   virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) = 0;
0260 
0261   virtual uint32_t writeSetEnd_virt() = 0;
0262 
0263   virtual uint32_t writeBool_virt(const bool value) = 0;
0264 
0265   virtual uint32_t writeByte_virt(const int8_t byte) = 0;
0266 
0267   virtual uint32_t writeI16_virt(const int16_t i16) = 0;
0268 
0269   virtual uint32_t writeI32_virt(const int32_t i32) = 0;
0270 
0271   virtual uint32_t writeI64_virt(const int64_t i64) = 0;
0272 
0273   virtual uint32_t writeDouble_virt(const double dub) = 0;
0274 
0275   virtual uint32_t writeString_virt(const std::string& str) = 0;
0276 
0277   virtual uint32_t writeBinary_virt(const std::string& str) = 0;
0278 
0279   virtual uint32_t writeUUID_virt(const TUuid& uuid) = 0;
0280 
0281   uint32_t writeMessageBegin(const std::string& name,
0282                              const TMessageType messageType,
0283                              const int32_t seqid) {
0284     T_VIRTUAL_CALL();
0285     return writeMessageBegin_virt(name, messageType, seqid);
0286   }
0287 
0288   uint32_t writeMessageEnd() {
0289     T_VIRTUAL_CALL();
0290     return writeMessageEnd_virt();
0291   }
0292 
0293   uint32_t writeStructBegin(const char* name) {
0294     T_VIRTUAL_CALL();
0295     return writeStructBegin_virt(name);
0296   }
0297 
0298   uint32_t writeStructEnd() {
0299     T_VIRTUAL_CALL();
0300     return writeStructEnd_virt();
0301   }
0302 
0303   uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) {
0304     T_VIRTUAL_CALL();
0305     return writeFieldBegin_virt(name, fieldType, fieldId);
0306   }
0307 
0308   uint32_t writeFieldEnd() {
0309     T_VIRTUAL_CALL();
0310     return writeFieldEnd_virt();
0311   }
0312 
0313   uint32_t writeFieldStop() {
0314     T_VIRTUAL_CALL();
0315     return writeFieldStop_virt();
0316   }
0317 
0318   uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size) {
0319     T_VIRTUAL_CALL();
0320     return writeMapBegin_virt(keyType, valType, size);
0321   }
0322 
0323   uint32_t writeMapEnd() {
0324     T_VIRTUAL_CALL();
0325     return writeMapEnd_virt();
0326   }
0327 
0328   uint32_t writeListBegin(const TType elemType, const uint32_t size) {
0329     T_VIRTUAL_CALL();
0330     return writeListBegin_virt(elemType, size);
0331   }
0332 
0333   uint32_t writeListEnd() {
0334     T_VIRTUAL_CALL();
0335     return writeListEnd_virt();
0336   }
0337 
0338   uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
0339     T_VIRTUAL_CALL();
0340     return writeSetBegin_virt(elemType, size);
0341   }
0342 
0343   uint32_t writeSetEnd() {
0344     T_VIRTUAL_CALL();
0345     return writeSetEnd_virt();
0346   }
0347 
0348   uint32_t writeBool(const bool value) {
0349     T_VIRTUAL_CALL();
0350     return writeBool_virt(value);
0351   }
0352 
0353   uint32_t writeByte(const int8_t byte) {
0354     T_VIRTUAL_CALL();
0355     return writeByte_virt(byte);
0356   }
0357 
0358   uint32_t writeI16(const int16_t i16) {
0359     T_VIRTUAL_CALL();
0360     return writeI16_virt(i16);
0361   }
0362 
0363   uint32_t writeI32(const int32_t i32) {
0364     T_VIRTUAL_CALL();
0365     return writeI32_virt(i32);
0366   }
0367 
0368   uint32_t writeI64(const int64_t i64) {
0369     T_VIRTUAL_CALL();
0370     return writeI64_virt(i64);
0371   }
0372 
0373   uint32_t writeDouble(const double dub) {
0374     T_VIRTUAL_CALL();
0375     return writeDouble_virt(dub);
0376   }
0377 
0378   uint32_t writeString(const std::string& str) {
0379     T_VIRTUAL_CALL();
0380     return writeString_virt(str);
0381   }
0382 
0383   uint32_t writeBinary(const std::string& str) {
0384     T_VIRTUAL_CALL();
0385     return writeBinary_virt(str);
0386   }
0387 
0388   uint32_t writeUUID(const TUuid& uuid) {
0389     T_VIRTUAL_CALL();
0390     return writeUUID_virt(uuid);
0391   }
0392 
0393   /**
0394    * Reading functions
0395    */
0396 
0397   virtual uint32_t readMessageBegin_virt(std::string& name,
0398                                          TMessageType& messageType,
0399                                          int32_t& seqid) = 0;
0400 
0401   virtual uint32_t readMessageEnd_virt() = 0;
0402 
0403   virtual uint32_t readStructBegin_virt(std::string& name) = 0;
0404 
0405   virtual uint32_t readStructEnd_virt() = 0;
0406 
0407   virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) = 0;
0408 
0409   virtual uint32_t readFieldEnd_virt() = 0;
0410 
0411   virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) = 0;
0412 
0413   virtual uint32_t readMapEnd_virt() = 0;
0414 
0415   virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) = 0;
0416 
0417   virtual uint32_t readListEnd_virt() = 0;
0418 
0419   virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) = 0;
0420 
0421   virtual uint32_t readSetEnd_virt() = 0;
0422 
0423   virtual uint32_t readBool_virt(bool& value) = 0;
0424 
0425   virtual uint32_t readBool_virt(std::vector<bool>::reference value) = 0;
0426 
0427   virtual uint32_t readByte_virt(int8_t& byte) = 0;
0428 
0429   virtual uint32_t readI16_virt(int16_t& i16) = 0;
0430 
0431   virtual uint32_t readI32_virt(int32_t& i32) = 0;
0432 
0433   virtual uint32_t readI64_virt(int64_t& i64) = 0;
0434 
0435   virtual uint32_t readDouble_virt(double& dub) = 0;
0436 
0437   virtual uint32_t readString_virt(std::string& str) = 0;
0438 
0439   virtual uint32_t readBinary_virt(std::string& str) = 0;
0440 
0441   virtual uint32_t readUUID_virt(TUuid& uuid) = 0;
0442 
0443   uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
0444     T_VIRTUAL_CALL();
0445     return readMessageBegin_virt(name, messageType, seqid);
0446   }
0447 
0448   uint32_t readMessageEnd() {
0449     T_VIRTUAL_CALL();
0450     return readMessageEnd_virt();
0451   }
0452 
0453   uint32_t readStructBegin(std::string& name) {
0454     T_VIRTUAL_CALL();
0455     return readStructBegin_virt(name);
0456   }
0457 
0458   uint32_t readStructEnd() {
0459     T_VIRTUAL_CALL();
0460     return readStructEnd_virt();
0461   }
0462 
0463   uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) {
0464     T_VIRTUAL_CALL();
0465     return readFieldBegin_virt(name, fieldType, fieldId);
0466   }
0467 
0468   uint32_t readFieldEnd() {
0469     T_VIRTUAL_CALL();
0470     return readFieldEnd_virt();
0471   }
0472 
0473   uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
0474     T_VIRTUAL_CALL();
0475     return readMapBegin_virt(keyType, valType, size);
0476   }
0477 
0478   uint32_t readMapEnd() {
0479     T_VIRTUAL_CALL();
0480     return readMapEnd_virt();
0481   }
0482 
0483   uint32_t readListBegin(TType& elemType, uint32_t& size) {
0484     T_VIRTUAL_CALL();
0485     return readListBegin_virt(elemType, size);
0486   }
0487 
0488   uint32_t readListEnd() {
0489     T_VIRTUAL_CALL();
0490     return readListEnd_virt();
0491   }
0492 
0493   uint32_t readSetBegin(TType& elemType, uint32_t& size) {
0494     T_VIRTUAL_CALL();
0495     return readSetBegin_virt(elemType, size);
0496   }
0497 
0498   uint32_t readSetEnd() {
0499     T_VIRTUAL_CALL();
0500     return readSetEnd_virt();
0501   }
0502 
0503   uint32_t readBool(bool& value) {
0504     T_VIRTUAL_CALL();
0505     return readBool_virt(value);
0506   }
0507 
0508   uint32_t readByte(int8_t& byte) {
0509     T_VIRTUAL_CALL();
0510     return readByte_virt(byte);
0511   }
0512 
0513   uint32_t readI16(int16_t& i16) {
0514     T_VIRTUAL_CALL();
0515     return readI16_virt(i16);
0516   }
0517 
0518   uint32_t readI32(int32_t& i32) {
0519     T_VIRTUAL_CALL();
0520     return readI32_virt(i32);
0521   }
0522 
0523   uint32_t readI64(int64_t& i64) {
0524     T_VIRTUAL_CALL();
0525     return readI64_virt(i64);
0526   }
0527 
0528   uint32_t readDouble(double& dub) {
0529     T_VIRTUAL_CALL();
0530     return readDouble_virt(dub);
0531   }
0532 
0533   uint32_t readString(std::string& str) {
0534     T_VIRTUAL_CALL();
0535     return readString_virt(str);
0536   }
0537 
0538   uint32_t readBinary(std::string& str) {
0539     T_VIRTUAL_CALL();
0540     return readBinary_virt(str);
0541   }
0542 
0543   uint32_t readUUID(TUuid& uuid) {
0544     T_VIRTUAL_CALL();
0545     return readUUID_virt(uuid);
0546   }
0547 
0548   /*
0549    * std::vector is specialized for bool, and its elements are individual bits
0550    * rather than bools.   We need to define a different version of readBool()
0551    * to work with std::vector<bool>.
0552    */
0553   uint32_t readBool(std::vector<bool>::reference value) {
0554     T_VIRTUAL_CALL();
0555     return readBool_virt(value);
0556   }
0557 
0558   /**
0559    * Method to arbitrarily skip over data.
0560    */
0561   uint32_t skip(TType type) {
0562     T_VIRTUAL_CALL();
0563     return skip_virt(type);
0564   }
0565   virtual uint32_t skip_virt(TType type);
0566 
0567   inline std::shared_ptr<TTransport> getTransport() { return ptrans_; }
0568 
0569   // TODO: remove these two calls, they are for backwards
0570   // compatibility
0571   inline std::shared_ptr<TTransport> getInputTransport() { return ptrans_; }
0572   inline std::shared_ptr<TTransport> getOutputTransport() { return ptrans_; }
0573 
0574   // input and output recursion depth are kept separate so that one protocol
0575   // can be used concurrently for both input and output.
0576   void incrementInputRecursionDepth() {
0577     if (recursion_limit_ < ++input_recursion_depth_) {
0578       throw TProtocolException(TProtocolException::DEPTH_LIMIT);
0579     }
0580   }
0581   void decrementInputRecursionDepth() { --input_recursion_depth_; }
0582 
0583   void incrementOutputRecursionDepth() {
0584     if (recursion_limit_ < ++output_recursion_depth_) {
0585       throw TProtocolException(TProtocolException::DEPTH_LIMIT);
0586     }
0587   }
0588   void decrementOutputRecursionDepth() { --output_recursion_depth_; }
0589 
0590   uint32_t getRecursionLimit() const {return recursion_limit_;}
0591   void setRecurisionLimit(uint32_t depth) {recursion_limit_ = depth;}
0592 
0593   // Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
0594   virtual int getMinSerializedSize(TType type) {
0595     THRIFT_UNUSED_VARIABLE(type);
0596     return 0;
0597   }
0598 
0599 protected:
0600   TProtocol(std::shared_ptr<TTransport> ptrans)
0601     : ptrans_(ptrans), input_recursion_depth_(0), output_recursion_depth_(0),
0602       recursion_limit_(ptrans->getConfiguration()->getRecursionLimit())
0603   {}
0604 
0605   virtual void checkReadBytesAvailable(TSet& set)
0606   {
0607       ptrans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_));
0608   }
0609 
0610   virtual void checkReadBytesAvailable(TList& list)
0611   {
0612       ptrans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_));
0613   }
0614 
0615   virtual void checkReadBytesAvailable(TMap& map)
0616   {
0617       int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_);
0618       ptrans_->checkReadBytesAvailable(map.size_ * elmSize);
0619   }
0620 
0621   std::shared_ptr<TTransport> ptrans_;
0622 
0623 private:
0624   TProtocol() = default;
0625   uint32_t input_recursion_depth_;
0626   uint32_t output_recursion_depth_;
0627   uint32_t recursion_limit_;
0628 };
0629 
0630 /**
0631  * Constructs input and output protocol objects given transports.
0632  */
0633 class TProtocolFactory {
0634 public:
0635   TProtocolFactory() = default;
0636 
0637   virtual ~TProtocolFactory();
0638 
0639   virtual std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) = 0;
0640   virtual std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> inTrans,
0641                std::shared_ptr<TTransport> outTrans) {
0642     (void)outTrans;
0643     return getProtocol(inTrans);
0644   }
0645 };
0646 
0647 /**
0648  * Dummy protocol class.
0649  *
0650  * This class does nothing, and should never be instantiated.
0651  * It is used only by the generator code.
0652  */
0653 class TDummyProtocol : public TProtocol {};
0654 
0655 // This is the default / legacy choice
0656 struct TNetworkBigEndian
0657 {
0658   static uint16_t toWire16(uint16_t x)   {return htons(x);}
0659   static uint32_t toWire32(uint32_t x)   {return htonl(x);}
0660   static uint64_t toWire64(uint64_t x)   {return THRIFT_htonll(x);}
0661   static uint16_t fromWire16(uint16_t x) {return ntohs(x);}
0662   static uint32_t fromWire32(uint32_t x) {return ntohl(x);}
0663   static uint64_t fromWire64(uint64_t x) {return THRIFT_ntohll(x);}
0664 };
0665 
0666 // On most systems, this will be a bit faster than TNetworkBigEndian
0667 struct TNetworkLittleEndian
0668 {
0669   static uint16_t toWire16(uint16_t x)   {return THRIFT_htoles(x);}
0670   static uint32_t toWire32(uint32_t x)   {return THRIFT_htolel(x);}
0671   static uint64_t toWire64(uint64_t x)   {return THRIFT_htolell(x);}
0672   static uint16_t fromWire16(uint16_t x) {return THRIFT_letohs(x);}
0673   static uint32_t fromWire32(uint32_t x) {return THRIFT_letohl(x);}
0674   static uint64_t fromWire64(uint64_t x) {return THRIFT_letohll(x);}
0675 };
0676 
0677 struct TOutputRecursionTracker {
0678   TProtocol &prot_;
0679   TOutputRecursionTracker(TProtocol &prot) : prot_(prot) {
0680     prot_.incrementOutputRecursionDepth();
0681   }
0682   ~TOutputRecursionTracker() {
0683     prot_.decrementOutputRecursionDepth();
0684   }
0685 };
0686 
0687 struct TInputRecursionTracker {
0688   TProtocol &prot_;
0689   TInputRecursionTracker(TProtocol &prot) : prot_(prot) {
0690     prot_.incrementInputRecursionDepth();
0691   }
0692   ~TInputRecursionTracker() {
0693     prot_.decrementInputRecursionDepth();
0694   }
0695 };
0696 
0697 /**
0698  * Helper template for implementing TProtocol::skip().
0699  *
0700  * Templatized to avoid having to make virtual function calls.
0701  */
0702 template <class Protocol_>
0703 uint32_t skip(Protocol_& prot, TType type) {
0704   TInputRecursionTracker tracker(prot);
0705 
0706   switch (type) {
0707   case T_BOOL: {
0708     bool boolv;
0709     return prot.readBool(boolv);
0710   }
0711   case T_BYTE: {
0712     int8_t bytev = 0;
0713     return prot.readByte(bytev);
0714   }
0715   case T_I16: {
0716     int16_t i16;
0717     return prot.readI16(i16);
0718   }
0719   case T_I32: {
0720     int32_t i32;
0721     return prot.readI32(i32);
0722   }
0723   case T_I64: {
0724     int64_t i64;
0725     return prot.readI64(i64);
0726   }
0727   case T_DOUBLE: {
0728     double dub;
0729     return prot.readDouble(dub);
0730   }
0731   case T_STRING: {
0732     std::string str;
0733     return prot.readBinary(str);
0734   }
0735   case T_STRUCT: {
0736     uint32_t result = 0;
0737     std::string name;
0738     int16_t fid;
0739     TType ftype;
0740     result += prot.readStructBegin(name);
0741     while (true) {
0742       result += prot.readFieldBegin(name, ftype, fid);
0743       if (ftype == T_STOP) {
0744         break;
0745       }
0746       result += skip(prot, ftype);
0747       result += prot.readFieldEnd();
0748     }
0749     result += prot.readStructEnd();
0750     return result;
0751   }
0752   case T_MAP: {
0753     uint32_t result = 0;
0754     TType keyType;
0755     TType valType;
0756     uint32_t i, size;
0757     result += prot.readMapBegin(keyType, valType, size);
0758     for (i = 0; i < size; i++) {
0759       result += skip(prot, keyType);
0760       result += skip(prot, valType);
0761     }
0762     result += prot.readMapEnd();
0763     return result;
0764   }
0765   case T_SET: {
0766     uint32_t result = 0;
0767     TType elemType;
0768     uint32_t i, size;
0769     result += prot.readSetBegin(elemType, size);
0770     for (i = 0; i < size; i++) {
0771       result += skip(prot, elemType);
0772     }
0773     result += prot.readSetEnd();
0774     return result;
0775   }
0776   case T_LIST: {
0777     uint32_t result = 0;
0778     TType elemType;
0779     uint32_t i, size;
0780     result += prot.readListBegin(elemType, size);
0781     for (i = 0; i < size; i++) {
0782       result += skip(prot, elemType);
0783     }
0784     result += prot.readListEnd();
0785     return result;
0786   }
0787   default:
0788     break;
0789   }
0790 
0791   throw TProtocolException(TProtocolException::INVALID_DATA,
0792                            "invalid TType");
0793 }
0794 
0795 }}} // apache::thrift::protocol
0796 
0797 #endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1