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