1 /* 2 * Copyright (c) 2006- Facebook 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 /* 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 */ 24 25 #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_ 26 #define _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_ 1 27 28 #include <thrift/protocol/TProtocol.h> 29 #include <thrift/protocol/TVirtualProtocol.h> 30 31 #include <memory> 32 33 namespace apache 34 { 35 namespace thrift 36 { 37 namespace protocol 38 { 39 40 /** 41 * The default binary protocol for thrift. Writes all data in a very basic 42 * binary format, essentially just spitting out the raw bytes. 43 * 44 */ 45 template <class Transport_, class ByteOrder_ = TNetworkBigEndian> 46 class TBinaryProtocolT : public TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_>> 47 { 48 public: 49 static const int32_t VERSION_MASK = ((int32_t)0xffff0000); 50 static const int32_t VERSION_1 = ((int32_t)0x80010000); 51 // VERSION_2 (0x80020000) was taken by TDenseProtocol (which has since been removed) 52 TBinaryProtocolT(std::shared_ptr<Transport_> trans)53 TBinaryProtocolT(std::shared_ptr<Transport_> trans) 54 : TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_>>(trans), 55 trans_(trans.get()), string_limit_(0), container_limit_(0), strict_read_(false), 56 strict_write_(true) 57 { 58 } 59 TBinaryProtocolT(std::shared_ptr<Transport_> trans,int32_t string_limit,int32_t container_limit,bool strict_read,bool strict_write)60 TBinaryProtocolT(std::shared_ptr<Transport_> trans, int32_t string_limit, 61 int32_t container_limit, bool strict_read, bool strict_write) 62 : TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_>>(trans), 63 trans_(trans.get()), string_limit_(string_limit), 64 container_limit_(container_limit), strict_read_(strict_read), 65 strict_write_(strict_write) 66 { 67 } 68 setStringSizeLimit(int32_t string_limit)69 void setStringSizeLimit(int32_t string_limit) 70 { 71 string_limit_ = string_limit; 72 } 73 setContainerSizeLimit(int32_t container_limit)74 void setContainerSizeLimit(int32_t container_limit) 75 { 76 container_limit_ = container_limit; 77 } 78 setStrict(bool strict_read,bool strict_write)79 void setStrict(bool strict_read, bool strict_write) 80 { 81 strict_read_ = strict_read; 82 strict_write_ = strict_write; 83 } 84 85 /** 86 * Writing functions. 87 */ 88 89 /*ol*/ uint32_t writeMessageBegin(const std::string &name, const TMessageType messageType, 90 const int32_t seqid); 91 92 /*ol*/ uint32_t writeMessageEnd(); 93 94 inline uint32_t writeStructBegin(const char *name); 95 96 inline uint32_t writeStructEnd(); 97 98 inline uint32_t writeFieldBegin(const char *name, const TType fieldType, 99 const int16_t fieldId); 100 101 inline uint32_t writeFieldEnd(); 102 103 inline uint32_t writeFieldStop(); 104 105 inline uint32_t writeMapBegin(const TType keyType, const TType valType, 106 const uint32_t size); 107 108 inline uint32_t writeMapEnd(); 109 110 inline uint32_t writeListBegin(const TType elemType, const uint32_t size); 111 112 inline uint32_t writeListEnd(); 113 114 inline uint32_t writeSetBegin(const TType elemType, const uint32_t size); 115 116 inline uint32_t writeSetEnd(); 117 118 inline uint32_t writeBool(const bool value); 119 120 inline uint32_t writeByte(const int8_t byte); 121 122 inline uint32_t writeI16(const int16_t i16); 123 124 inline uint32_t writeI32(const int32_t i32); 125 126 inline uint32_t writeI64(const int64_t i64); 127 128 inline uint32_t writeDouble(const double dub); 129 130 template <typename StrType> inline uint32_t writeString(const StrType &str); 131 132 inline uint32_t writeBinary(const std::string &str); 133 134 /** 135 * Reading functions 136 */ 137 138 /*ol*/ uint32_t readMessageBegin(std::string &name, TMessageType &messageType, 139 int32_t &seqid); 140 141 /*ol*/ uint32_t readMessageEnd(); 142 143 inline uint32_t readStructBegin(std::string &name); 144 145 inline uint32_t readStructEnd(); 146 147 inline uint32_t readFieldBegin(std::string &name, TType &fieldType, int16_t &fieldId); 148 149 inline uint32_t readFieldEnd(); 150 151 inline uint32_t readMapBegin(TType &keyType, TType &valType, uint32_t &size); 152 153 inline uint32_t readMapEnd(); 154 155 inline uint32_t readListBegin(TType &elemType, uint32_t &size); 156 157 inline uint32_t readListEnd(); 158 159 inline uint32_t readSetBegin(TType &elemType, uint32_t &size); 160 161 inline uint32_t readSetEnd(); 162 163 inline uint32_t readBool(bool &value); 164 // Provide the default readBool() implementation for std::vector<bool> 165 using TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_>>::readBool; 166 167 inline uint32_t readByte(int8_t &byte); 168 169 inline uint32_t readI16(int16_t &i16); 170 171 inline uint32_t readI32(int32_t &i32); 172 173 inline uint32_t readI64(int64_t &i64); 174 175 inline uint32_t readDouble(double &dub); 176 177 template <typename StrType> inline uint32_t readString(StrType &str); 178 179 inline uint32_t readBinary(std::string &str); 180 181 int getMinSerializedSize(TType type) override; 182 checkReadBytesAvailable(TSet & set)183 void checkReadBytesAvailable(TSet &set) override 184 { 185 trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); 186 } 187 checkReadBytesAvailable(TList & list)188 void checkReadBytesAvailable(TList &list) override 189 { 190 trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); 191 } 192 checkReadBytesAvailable(TMap & map)193 void checkReadBytesAvailable(TMap &map) override 194 { 195 int elmSize = 196 getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); 197 trans_->checkReadBytesAvailable(map.size_ * elmSize); 198 } 199 200 protected: 201 template <typename StrType> uint32_t readStringBody(StrType &str, int32_t sz); 202 203 Transport_ *trans_; 204 205 int32_t string_limit_; 206 int32_t container_limit_; 207 208 // Enforce presence of version identifier 209 bool strict_read_; 210 bool strict_write_; 211 }; 212 213 typedef TBinaryProtocolT<TTransport> TBinaryProtocol; 214 typedef TBinaryProtocolT<TTransport, TNetworkLittleEndian> TLEBinaryProtocol; 215 216 /** 217 * Constructs binary protocol handlers 218 */ 219 template <class Transport_, class ByteOrder_ = TNetworkBigEndian> 220 class TBinaryProtocolFactoryT : public TProtocolFactory 221 { 222 public: TBinaryProtocolFactoryT()223 TBinaryProtocolFactoryT() 224 : string_limit_(0), container_limit_(0), strict_read_(false), strict_write_(true) 225 { 226 } 227 TBinaryProtocolFactoryT(int32_t string_limit,int32_t container_limit,bool strict_read,bool strict_write)228 TBinaryProtocolFactoryT(int32_t string_limit, int32_t container_limit, bool strict_read, 229 bool strict_write) 230 : string_limit_(string_limit), container_limit_(container_limit), 231 strict_read_(strict_read), strict_write_(strict_write) 232 { 233 } 234 235 ~TBinaryProtocolFactoryT() override = default; 236 setStringSizeLimit(int32_t string_limit)237 void setStringSizeLimit(int32_t string_limit) 238 { 239 string_limit_ = string_limit; 240 } 241 setContainerSizeLimit(int32_t container_limit)242 void setContainerSizeLimit(int32_t container_limit) 243 { 244 container_limit_ = container_limit; 245 } 246 setStrict(bool strict_read,bool strict_write)247 void setStrict(bool strict_read, bool strict_write) 248 { 249 strict_read_ = strict_read; 250 strict_write_ = strict_write; 251 } 252 getProtocol(std::shared_ptr<TTransport> trans)253 std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override 254 { 255 std::shared_ptr<Transport_> specific_trans = 256 std::dynamic_pointer_cast<Transport_>(trans); 257 TProtocol *prot; 258 if (specific_trans) { 259 prot = new TBinaryProtocolT<Transport_, ByteOrder_>( 260 specific_trans, string_limit_, container_limit_, strict_read_, 261 strict_write_); 262 } else { 263 prot = new TBinaryProtocolT<TTransport, ByteOrder_>( 264 trans, string_limit_, container_limit_, strict_read_, 265 strict_write_); 266 } 267 268 return std::shared_ptr<TProtocol>(prot); 269 } 270 271 private: 272 int32_t string_limit_; 273 int32_t container_limit_; 274 bool strict_read_; 275 bool strict_write_; 276 }; 277 278 typedef TBinaryProtocolFactoryT<TTransport> TBinaryProtocolFactory; 279 typedef TBinaryProtocolFactoryT<TTransport, TNetworkLittleEndian> TLEBinaryProtocolFactory; 280 } // namespace protocol 281 } // namespace thrift 282 } // namespace apache 283 284 #include <thrift/protocol/TBinaryProtocol.tcc> 285 286 #endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_ 287