Back to home page

EIC code displayed by LXR

 
 

    


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

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_TCOMPACTPROTOCOL_H_
0021 #define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_H_ 1
0022 
0023 #include <thrift/protocol/TVirtualProtocol.h>
0024 
0025 #include <stack>
0026 #include <memory>
0027 
0028 namespace apache {
0029 namespace thrift {
0030 namespace protocol {
0031 
0032 /**
0033  * C++ Implementation of the Compact Protocol as described in THRIFT-110
0034  */
0035 template <class Transport_>
0036 class TCompactProtocolT : public TVirtualProtocol<TCompactProtocolT<Transport_> > {
0037 public:
0038   static const int8_t PROTOCOL_ID = (int8_t)0x82u;
0039   static const int8_t VERSION_N = 1;
0040   static const int8_t VERSION_MASK = 0x1f;       // 0001 1111
0041 
0042 protected:
0043   static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000
0044   static const int8_t TYPE_BITS = 0x07;          // 0000 0111
0045   static const int32_t TYPE_SHIFT_AMOUNT = 5;
0046 
0047   Transport_* trans_;
0048 
0049   /**
0050    * (Writing) If we encounter a boolean field begin, save the TField here
0051    * so it can have the value incorporated.
0052    */
0053   struct {
0054     const char* name;
0055     TType fieldType;
0056     int16_t fieldId;
0057   } booleanField_;
0058 
0059   /**
0060    * (Reading) If we read a field header, and it's a boolean field, save
0061    * the boolean value here so that readBool can use it.
0062    */
0063   struct {
0064     bool hasBoolValue;
0065     bool boolValue;
0066   } boolValue_;
0067 
0068   /**
0069    * Used to keep track of the last field for the current and previous structs,
0070    * so we can do the delta stuff.
0071    */
0072 
0073   std::stack<int16_t> lastField_;
0074   int16_t lastFieldId_;
0075 
0076 public:
0077   TCompactProtocolT(std::shared_ptr<Transport_> trans)
0078     : TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
0079       trans_(trans.get()),
0080       lastFieldId_(0),
0081       string_limit_(0),
0082       string_buf_(nullptr),
0083       string_buf_size_(0),
0084       container_limit_(0) {
0085     booleanField_.name = nullptr;
0086     boolValue_.hasBoolValue = false;
0087   }
0088 
0089   TCompactProtocolT(std::shared_ptr<Transport_> trans,
0090                     int32_t string_limit,
0091                     int32_t container_limit)
0092     : TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
0093       trans_(trans.get()),
0094       lastFieldId_(0),
0095       string_limit_(string_limit),
0096       string_buf_(nullptr),
0097       string_buf_size_(0),
0098       container_limit_(container_limit) {
0099     booleanField_.name = nullptr;
0100     boolValue_.hasBoolValue = false;
0101   }
0102 
0103   ~TCompactProtocolT() override { free(string_buf_); }
0104 
0105   /**
0106    * Writing functions
0107    */
0108 
0109   virtual uint32_t writeMessageBegin(const std::string& name,
0110                                      const TMessageType messageType,
0111                                      const int32_t seqid);
0112 
0113   uint32_t writeStructBegin(const char* name);
0114 
0115   uint32_t writeStructEnd();
0116 
0117   uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
0118 
0119   uint32_t writeFieldStop();
0120 
0121   uint32_t writeListBegin(const TType elemType, const uint32_t size);
0122 
0123   uint32_t writeSetBegin(const TType elemType, const uint32_t size);
0124 
0125   virtual uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
0126 
0127   uint32_t writeBool(const bool value);
0128 
0129   uint32_t writeByte(const int8_t byte);
0130 
0131   uint32_t writeI16(const int16_t i16);
0132 
0133   uint32_t writeI32(const int32_t i32);
0134 
0135   uint32_t writeI64(const int64_t i64);
0136 
0137   uint32_t writeDouble(const double dub);
0138 
0139   uint32_t writeString(const std::string& str);
0140 
0141   uint32_t writeBinary(const std::string& str);
0142 
0143   int getMinSerializedSize(TType type) override;
0144 
0145   void checkReadBytesAvailable(TSet& set) override
0146   {
0147       trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_));
0148   }
0149 
0150   void checkReadBytesAvailable(TList& list) override
0151   {
0152       trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_));
0153   }
0154 
0155   void checkReadBytesAvailable(TMap& map) override
0156   {
0157       int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_);
0158       trans_->checkReadBytesAvailable(map.size_ * elmSize);
0159   }
0160 
0161   /**
0162   * These methods are called by structs, but don't actually have any wired
0163   * output or purpose
0164   */
0165   virtual uint32_t writeMessageEnd() { return 0; }
0166   uint32_t writeMapEnd() { return 0; }
0167   uint32_t writeListEnd() { return 0; }
0168   uint32_t writeSetEnd() { return 0; }
0169   uint32_t writeFieldEnd() { return 0; }
0170 
0171 protected:
0172   int32_t writeFieldBeginInternal(const char* name,
0173                                   const TType fieldType,
0174                                   const int16_t fieldId,
0175                                   int8_t typeOverride);
0176   uint32_t writeCollectionBegin(const TType elemType, int32_t size);
0177   uint32_t writeVarint32(uint32_t n);
0178   uint32_t writeVarint64(uint64_t n);
0179   uint64_t i64ToZigzag(const int64_t l);
0180   uint32_t i32ToZigzag(const int32_t n);
0181   inline int8_t getCompactType(const TType ttype);
0182 
0183 public:
0184   uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid);
0185 
0186   uint32_t readStructBegin(std::string& name);
0187 
0188   uint32_t readStructEnd();
0189 
0190   uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId);
0191 
0192   uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size);
0193 
0194   uint32_t readListBegin(TType& elemType, uint32_t& size);
0195 
0196   uint32_t readSetBegin(TType& elemType, uint32_t& size);
0197 
0198   uint32_t readBool(bool& value);
0199   // Provide the default readBool() implementation for std::vector<bool>
0200   using TVirtualProtocol<TCompactProtocolT<Transport_> >::readBool;
0201 
0202   uint32_t readByte(int8_t& byte);
0203 
0204   uint32_t readI16(int16_t& i16);
0205 
0206   uint32_t readI32(int32_t& i32);
0207 
0208   uint32_t readI64(int64_t& i64);
0209 
0210   uint32_t readDouble(double& dub);
0211 
0212   uint32_t readString(std::string& str);
0213 
0214   uint32_t readBinary(std::string& str);
0215 
0216   /*
0217    *These methods are here for the struct to call, but don't have any wire
0218    * encoding.
0219    */
0220   uint32_t readMessageEnd() { return 0; }
0221   uint32_t readFieldEnd() { return 0; }
0222   uint32_t readMapEnd() { return 0; }
0223   uint32_t readListEnd() { return 0; }
0224   uint32_t readSetEnd() { return 0; }
0225 
0226 protected:
0227   uint32_t readVarint32(int32_t& i32);
0228   uint32_t readVarint64(int64_t& i64);
0229   int32_t zigzagToI32(uint32_t n);
0230   int64_t zigzagToI64(uint64_t n);
0231   TType getTType(int8_t type);
0232 
0233   // Buffer for reading strings, save for the lifetime of the protocol to
0234   // avoid memory churn allocating memory on every string read
0235   int32_t string_limit_;
0236   uint8_t* string_buf_;
0237   int32_t string_buf_size_;
0238   int32_t container_limit_;
0239 };
0240 
0241 typedef TCompactProtocolT<TTransport> TCompactProtocol;
0242 
0243 /**
0244  * Constructs compact protocol handlers
0245  */
0246 template <class Transport_>
0247 class TCompactProtocolFactoryT : public TProtocolFactory {
0248 public:
0249   TCompactProtocolFactoryT() : string_limit_(0), container_limit_(0) {}
0250 
0251   TCompactProtocolFactoryT(int32_t string_limit, int32_t container_limit)
0252     : string_limit_(string_limit), container_limit_(container_limit) {}
0253 
0254   ~TCompactProtocolFactoryT() override = default;
0255 
0256   void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
0257 
0258   void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; }
0259 
0260   std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override {
0261     std::shared_ptr<Transport_> specific_trans = std::dynamic_pointer_cast<Transport_>(trans);
0262     TProtocol* prot;
0263     if (specific_trans) {
0264       prot = new TCompactProtocolT<Transport_>(specific_trans, string_limit_, container_limit_);
0265     } else {
0266       prot = new TCompactProtocol(trans, string_limit_, container_limit_);
0267     }
0268 
0269     return std::shared_ptr<TProtocol>(prot);
0270   }
0271 
0272 private:
0273   int32_t string_limit_;
0274   int32_t container_limit_;
0275 };
0276 
0277 typedef TCompactProtocolFactoryT<TTransport> TCompactProtocolFactory;
0278 }
0279 }
0280 } // apache::thrift::protocol
0281 
0282 #include <thrift/protocol/TCompactProtocol.tcc>
0283 
0284 #endif