blob: 7655a479a2dfd5b40d8d4a1692a8d3073b60ddbe [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
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 */
David Reiss4e7530d2007-09-04 21:49:53 +000019
20#ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_
21#define _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_ 1
22
23#include "TBinaryProtocol.h"
24
T Jake Lucianib5e62212009-01-31 22:36:20 +000025namespace apache { namespace thrift { namespace protocol {
David Reiss4e7530d2007-09-04 21:49:53 +000026
27/**
David Reiss4e7530d2007-09-04 21:49:53 +000028 * !!!WARNING!!!
29 * This class is still highly experimental. Incompatible changes
30 * WILL be made to it without notice. DO NOT USE IT YET unless
31 * you are coordinating your testing with the author.
32 *
David Reissce161a92007-09-11 22:09:42 +000033 * The dense protocol is designed to use as little space as possible.
34 *
35 * There are two types of dense protocol instances. Standalone instances
David Reiss0c90f6f2008-02-06 22:18:40 +000036 * are not used for RPC and just encoded and decode structures of
David Reissce161a92007-09-11 22:09:42 +000037 * a predetermined type. Non-standalone instances are used for RPC.
38 * Currently, only standalone instances exist.
39 *
40 * To use a standalone dense protocol object, you must set the type_spec
41 * property (either in the constructor, or with setTypeSpec) to the local
42 * reflection TypeSpec of the structures you will write to (or read from) the
43 * protocol instance.
44 *
45 * BEST PRACTICES:
46 * - Never use optional for primitives or containers.
47 * - Only use optional for structures if they are very big and very rarely set.
48 * - All integers are variable-length, so you can use i64 without bloating.
49 * - NEVER EVER change the struct definitions IN ANY WAY without either
50 * changing your cache keys or talking to dreiss.
51 *
David Reiss4e7530d2007-09-04 21:49:53 +000052 * TODO(dreiss): New class write with old meta.
53 *
54 * We override all of TBinaryProtocol's methods.
55 * We inherit so that we can can explicitly call TBPs's primitive-writing
56 * methods within our versions.
57 *
David Reiss4e7530d2007-09-04 21:49:53 +000058 */
59class TDenseProtocol : public TBinaryProtocol {
60 protected:
61 static const int32_t VERSION_MASK = 0xffff0000;
David Reisse67c0e62007-09-07 01:34:12 +000062 // VERSION_1 (0x80010000) is taken by TBinaryProtocol.
David Reiss4e7530d2007-09-04 21:49:53 +000063 static const int32_t VERSION_2 = 0x80020000;
64
65 public:
T Jake Lucianib5e62212009-01-31 22:36:20 +000066 typedef apache::thrift::reflection::local::TypeSpec TypeSpec;
David Reissce161a92007-09-11 22:09:42 +000067 static const int FP_PREFIX_LEN;
David Reiss4e7530d2007-09-04 21:49:53 +000068
David Reissce161a92007-09-11 22:09:42 +000069 /**
70 * @param tran The transport to use.
71 * @param type_spec The TypeSpec of the structures using this protocol.
72 */
David Reiss4e7530d2007-09-04 21:49:53 +000073 TDenseProtocol(boost::shared_ptr<TTransport> trans,
74 TypeSpec* type_spec = NULL) :
75 TBinaryProtocol(trans),
David Reissce161a92007-09-11 22:09:42 +000076 type_spec_(type_spec),
77 standalone_(true)
78 {}
David Reiss4e7530d2007-09-04 21:49:53 +000079
80 void setTypeSpec(TypeSpec* type_spec) {
81 type_spec_ = type_spec;
82 }
83 TypeSpec* getTypeSpec() {
84 return type_spec_;
85 }
86
87
88 /*
89 * Writing functions.
90 */
91
92 virtual uint32_t writeMessageBegin(const std::string& name,
93 const TMessageType messageType,
94 const int32_t seqid);
95
96 virtual uint32_t writeMessageEnd();
97
98
David Reiss64120002008-04-29 23:12:24 +000099 virtual uint32_t writeStructBegin(const char* name);
David Reiss4e7530d2007-09-04 21:49:53 +0000100
101 virtual uint32_t writeStructEnd();
102
David Reiss64120002008-04-29 23:12:24 +0000103 virtual uint32_t writeFieldBegin(const char* name,
David Reiss4e7530d2007-09-04 21:49:53 +0000104 const TType fieldType,
105 const int16_t fieldId);
106
107 virtual uint32_t writeFieldEnd();
108
109 virtual uint32_t writeFieldStop();
110
111 virtual uint32_t writeMapBegin(const TType keyType,
112 const TType valType,
113 const uint32_t size);
114
115 virtual uint32_t writeMapEnd();
116
117 virtual uint32_t writeListBegin(const TType elemType,
118 const uint32_t size);
119
120 virtual uint32_t writeListEnd();
121
122 virtual uint32_t writeSetBegin(const TType elemType,
123 const uint32_t size);
124
125 virtual uint32_t writeSetEnd();
126
127 virtual uint32_t writeBool(const bool value);
128
129 virtual uint32_t writeByte(const int8_t byte);
130
131 virtual uint32_t writeI16(const int16_t i16);
132
133 virtual uint32_t writeI32(const int32_t i32);
134
135 virtual uint32_t writeI64(const int64_t i64);
136
137 virtual uint32_t writeDouble(const double dub);
138
139 virtual uint32_t writeString(const std::string& str);
140
David Reissc005b1b2008-02-15 01:38:18 +0000141 virtual uint32_t writeBinary(const std::string& str);
142
David Reiss4e7530d2007-09-04 21:49:53 +0000143
144 /*
145 * Helper writing functions (don't do state transitions).
146 */
147 inline uint32_t subWriteI32(const int32_t i32);
148
David Reisse67c0e62007-09-07 01:34:12 +0000149 inline uint32_t subWriteString(const std::string& str);
150
David Reiss4e7530d2007-09-04 21:49:53 +0000151 uint32_t subWriteBool(const bool value) {
152 return TBinaryProtocol::writeBool(value);
153 }
154
David Reiss4e7530d2007-09-04 21:49:53 +0000155
156 /*
157 * Reading functions
158 */
159
160 uint32_t readMessageBegin(std::string& name,
161 TMessageType& messageType,
162 int32_t& seqid);
163
164 uint32_t readMessageEnd();
165
166 uint32_t readStructBegin(std::string& name);
167
168 uint32_t readStructEnd();
169
170 uint32_t readFieldBegin(std::string& name,
171 TType& fieldType,
172 int16_t& fieldId);
173
174 uint32_t readFieldEnd();
175
176 uint32_t readMapBegin(TType& keyType,
177 TType& valType,
178 uint32_t& size);
179
180 uint32_t readMapEnd();
181
182 uint32_t readListBegin(TType& elemType,
183 uint32_t& size);
184
185 uint32_t readListEnd();
186
187 uint32_t readSetBegin(TType& elemType,
188 uint32_t& size);
189
190 uint32_t readSetEnd();
191
192 uint32_t readBool(bool& value);
193
194 uint32_t readByte(int8_t& byte);
195
196 uint32_t readI16(int16_t& i16);
197
198 uint32_t readI32(int32_t& i32);
199
200 uint32_t readI64(int64_t& i64);
201
202 uint32_t readDouble(double& dub);
203
204 uint32_t readString(std::string& str);
205
David Reissc005b1b2008-02-15 01:38:18 +0000206 uint32_t readBinary(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000207
208 /*
209 * Helper reading functions (don't do state transitions).
210 */
David Reisse67c0e62007-09-07 01:34:12 +0000211 inline uint32_t subReadI32(int32_t& i32);
212
213 inline uint32_t subReadString(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000214
215 uint32_t subReadBool(bool& value) {
216 return TBinaryProtocol::readBool(value);
217 }
218
David Reiss4e7530d2007-09-04 21:49:53 +0000219
220 private:
221
David Reissce161a92007-09-11 22:09:42 +0000222 // Implementation functions, documented in the .cpp.
David Reiss4e7530d2007-09-04 21:49:53 +0000223 inline void checkTType(const TType ttype);
224 inline void stateTransition();
225
David Reisse67c0e62007-09-07 01:34:12 +0000226 // Read and write variable-length integers.
227 // Uses the same technique as the MIDI file format.
David Reissce161a92007-09-11 22:09:42 +0000228 inline uint32_t vlqRead(uint64_t& vlq);
229 inline uint32_t vlqWrite(uint64_t vlq);
David Reisse67c0e62007-09-07 01:34:12 +0000230
David Reissce161a92007-09-11 22:09:42 +0000231 // Called before throwing an exception to make the object reusable.
232 void resetState() {
233 ts_stack_.clear();
234 idx_stack_.clear();
235 mkv_stack_.clear();
236 }
237
238 // TypeSpec of the top-level structure to write,
239 // for standalone protocol objects.
David Reiss4e7530d2007-09-04 21:49:53 +0000240 TypeSpec* type_spec_;
241
242 std::vector<TypeSpec*> ts_stack_; // TypeSpec stack.
243 std::vector<int> idx_stack_; // InDeX stack.
244 std::vector<bool> mkv_stack_; // Map Key/Vlue stack.
245 // True = key, False = value.
246
David Reissce161a92007-09-11 22:09:42 +0000247 // True iff this is a standalone instance (no RPC).
248 bool standalone_;
David Reiss4e7530d2007-09-04 21:49:53 +0000249};
250
T Jake Lucianib5e62212009-01-31 22:36:20 +0000251}}} // apache::thrift::protocol
David Reiss4e7530d2007-09-04 21:49:53 +0000252
253#endif // #ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_