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_TDEBUGPROTOCOL_H_
0021 #define _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ 1
0022 
0023 #include <thrift/protocol/TVirtualProtocol.h>
0024 
0025 #include <memory>
0026 
0027 namespace apache {
0028 namespace thrift {
0029 namespace protocol {
0030 
0031 /*
0032 
0033 !!! EXPERIMENTAL CODE !!!
0034 
0035 This protocol is very much a work in progress.
0036 It doesn't handle many cases properly.
0037 It throws exceptions in many cases.
0038 It probably segfaults in many cases.
0039 Bug reports and feature requests are welcome.
0040 Complaints are not. :R
0041 
0042 */
0043 
0044 /**
0045  * Protocol that prints the payload in a nice human-readable format.
0046  * Reading from this protocol is not supported.
0047  *
0048  */
0049 class TDebugProtocol : public TVirtualProtocol<TDebugProtocol> {
0050 private:
0051   enum write_state_t { UNINIT, STRUCT, LIST, SET, MAP_KEY, MAP_VALUE };
0052 
0053 public:
0054   TDebugProtocol(std::shared_ptr<TTransport> trans)
0055     : TVirtualProtocol<TDebugProtocol>(trans),
0056       trans_(trans.get()),
0057       string_limit_(DEFAULT_STRING_LIMIT),
0058       string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE) {
0059     write_state_.push_back(UNINIT);
0060   }
0061 
0062   static const int32_t DEFAULT_STRING_LIMIT = 256;
0063   static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
0064 
0065   void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
0066 
0067   void setStringPrefixSize(int32_t string_prefix_size) { string_prefix_size_ = string_prefix_size; }
0068 
0069   uint32_t writeMessageBegin(const std::string& name,
0070                              const TMessageType messageType,
0071                              const int32_t seqid);
0072 
0073   uint32_t writeMessageEnd();
0074 
0075   uint32_t writeStructBegin(const char* name);
0076 
0077   uint32_t writeStructEnd();
0078 
0079   uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
0080 
0081   uint32_t writeFieldEnd();
0082 
0083   uint32_t writeFieldStop();
0084 
0085   uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
0086 
0087   uint32_t writeMapEnd();
0088 
0089   uint32_t writeListBegin(const TType elemType, const uint32_t size);
0090 
0091   uint32_t writeListEnd();
0092 
0093   uint32_t writeSetBegin(const TType elemType, const uint32_t size);
0094 
0095   uint32_t writeSetEnd();
0096 
0097   uint32_t writeBool(const bool value);
0098 
0099   uint32_t writeByte(const int8_t byte);
0100 
0101   uint32_t writeI16(const int16_t i16);
0102 
0103   uint32_t writeI32(const int32_t i32);
0104 
0105   uint32_t writeI64(const int64_t i64);
0106 
0107   uint32_t writeDouble(const double dub);
0108 
0109   uint32_t writeString(const std::string& str);
0110 
0111   uint32_t writeBinary(const std::string& str);
0112 
0113   uint32_t writeUUID(const TUuid& uuid);
0114 
0115 private:
0116   void indentUp();
0117   void indentDown();
0118   uint32_t writePlain(const std::string& str);
0119   uint32_t writeIndented(const std::string& str);
0120   uint32_t startItem();
0121   uint32_t endItem();
0122   uint32_t writeItem(const std::string& str);
0123 
0124   static std::string fieldTypeName(TType type);
0125 
0126   TTransport* trans_;
0127 
0128   int32_t string_limit_;
0129   int32_t string_prefix_size_;
0130 
0131   std::string indent_str_;
0132   static const int indent_inc = 2;
0133 
0134   std::vector<write_state_t> write_state_;
0135   std::vector<int> list_idx_;
0136 };
0137 
0138 /**
0139  * Constructs debug protocol handlers
0140  */
0141 class TDebugProtocolFactory : public TProtocolFactory {
0142 public:
0143   TDebugProtocolFactory() = default;
0144   ~TDebugProtocolFactory() override = default;
0145 
0146   std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override {
0147     return std::shared_ptr<TProtocol>(new TDebugProtocol(trans));
0148   }
0149 };
0150 }
0151 }
0152 } // apache::thrift::protocol
0153 
0154 // TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
0155 #include <thrift/transport/TBufferTransports.h>
0156 
0157 namespace apache {
0158 namespace thrift {
0159 
0160 template <typename ThriftStruct>
0161 std::string ThriftDebugString(const ThriftStruct& ts) {
0162   using namespace apache::thrift::transport;
0163   using namespace apache::thrift::protocol;
0164   auto* buffer = new TMemoryBuffer;
0165   std::shared_ptr<TTransport> trans(buffer);
0166   TDebugProtocol protocol(trans);
0167 
0168   ts.write(&protocol);
0169 
0170   uint8_t* buf;
0171   uint32_t size;
0172   buffer->getBuffer(&buf, &size);
0173   return std::string((char*)buf, (unsigned int)size);
0174 }
0175 
0176 // TODO(dreiss): This is badly broken.  Don't use it unless you are me.
0177 #if 0
0178 template<typename Object>
0179 std::string DebugString(const std::vector<Object>& vec) {
0180   using namespace apache::thrift::transport;
0181   using namespace apache::thrift::protocol;
0182   TMemoryBuffer* buffer = new TMemoryBuffer;
0183   std::shared_ptr<TTransport> trans(buffer);
0184   TDebugProtocol protocol(trans);
0185 
0186   // I am gross!
0187   protocol.writeStructBegin("SomeRandomVector");
0188 
0189   // TODO: Fix this with a trait.
0190   protocol.writeListBegin((TType)99, vec.size());
0191   typename std::vector<Object>::const_iterator it;
0192   for (it = vec.begin(); it != vec.end(); ++it) {
0193     it->write(&protocol);
0194   }
0195   protocol.writeListEnd();
0196 
0197   uint8_t* buf;
0198   uint32_t size;
0199   buffer->getBuffer(&buf, &size);
0200   return std::string((char*)buf, (unsigned int)size);
0201 }
0202 #endif // 0
0203 }
0204 } // apache::thrift
0205 
0206 #endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_