blob: 5dd5a8c6a44b415bc715255b3a6c184db8ac34b2 [file] [log] [blame]
David Reiss4e7530d2007-09-04 21:49:53 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
7#ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_
8#define _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_ 1
9
10#include "TBinaryProtocol.h"
11
12namespace facebook { namespace thrift { namespace protocol {
13
14/**
David Reiss4e7530d2007-09-04 21:49:53 +000015 * !!!WARNING!!!
16 * This class is still highly experimental. Incompatible changes
17 * WILL be made to it without notice. DO NOT USE IT YET unless
18 * you are coordinating your testing with the author.
19 *
David Reissce161a92007-09-11 22:09:42 +000020 * The dense protocol is designed to use as little space as possible.
21 *
22 * There are two types of dense protocol instances. Standalone instances
David Reiss0c90f6f2008-02-06 22:18:40 +000023 * are not used for RPC and just encoded and decode structures of
David Reissce161a92007-09-11 22:09:42 +000024 * a predetermined type. Non-standalone instances are used for RPC.
25 * Currently, only standalone instances exist.
26 *
27 * To use a standalone dense protocol object, you must set the type_spec
28 * property (either in the constructor, or with setTypeSpec) to the local
29 * reflection TypeSpec of the structures you will write to (or read from) the
30 * protocol instance.
31 *
32 * BEST PRACTICES:
33 * - Never use optional for primitives or containers.
34 * - Only use optional for structures if they are very big and very rarely set.
35 * - All integers are variable-length, so you can use i64 without bloating.
36 * - NEVER EVER change the struct definitions IN ANY WAY without either
37 * changing your cache keys or talking to dreiss.
38 *
David Reiss4e7530d2007-09-04 21:49:53 +000039 * TODO(dreiss): New class write with old meta.
40 *
41 * We override all of TBinaryProtocol's methods.
42 * We inherit so that we can can explicitly call TBPs's primitive-writing
43 * methods within our versions.
44 *
45 * @author David Reiss <dreiss@facebook.com>
46 */
47class TDenseProtocol : public TBinaryProtocol {
48 protected:
49 static const int32_t VERSION_MASK = 0xffff0000;
David Reisse67c0e62007-09-07 01:34:12 +000050 // VERSION_1 (0x80010000) is taken by TBinaryProtocol.
David Reiss4e7530d2007-09-04 21:49:53 +000051 static const int32_t VERSION_2 = 0x80020000;
52
53 public:
54 typedef facebook::thrift::reflection::local::TypeSpec TypeSpec;
David Reissce161a92007-09-11 22:09:42 +000055 static const int FP_PREFIX_LEN;
David Reiss4e7530d2007-09-04 21:49:53 +000056
David Reissce161a92007-09-11 22:09:42 +000057 /**
58 * @param tran The transport to use.
59 * @param type_spec The TypeSpec of the structures using this protocol.
60 */
David Reiss4e7530d2007-09-04 21:49:53 +000061 TDenseProtocol(boost::shared_ptr<TTransport> trans,
62 TypeSpec* type_spec = NULL) :
63 TBinaryProtocol(trans),
David Reissce161a92007-09-11 22:09:42 +000064 type_spec_(type_spec),
65 standalone_(true)
66 {}
David Reiss4e7530d2007-09-04 21:49:53 +000067
68 void setTypeSpec(TypeSpec* type_spec) {
69 type_spec_ = type_spec;
70 }
71 TypeSpec* getTypeSpec() {
72 return type_spec_;
73 }
74
75
76 /*
77 * Writing functions.
78 */
79
80 virtual uint32_t writeMessageBegin(const std::string& name,
81 const TMessageType messageType,
82 const int32_t seqid);
83
84 virtual uint32_t writeMessageEnd();
85
86
David Reiss64120002008-04-29 23:12:24 +000087 virtual uint32_t writeStructBegin(const char* name);
David Reiss4e7530d2007-09-04 21:49:53 +000088
89 virtual uint32_t writeStructEnd();
90
David Reiss64120002008-04-29 23:12:24 +000091 virtual uint32_t writeFieldBegin(const char* name,
David Reiss4e7530d2007-09-04 21:49:53 +000092 const TType fieldType,
93 const int16_t fieldId);
94
95 virtual uint32_t writeFieldEnd();
96
97 virtual uint32_t writeFieldStop();
98
99 virtual uint32_t writeMapBegin(const TType keyType,
100 const TType valType,
101 const uint32_t size);
102
103 virtual uint32_t writeMapEnd();
104
105 virtual uint32_t writeListBegin(const TType elemType,
106 const uint32_t size);
107
108 virtual uint32_t writeListEnd();
109
110 virtual uint32_t writeSetBegin(const TType elemType,
111 const uint32_t size);
112
113 virtual uint32_t writeSetEnd();
114
115 virtual uint32_t writeBool(const bool value);
116
117 virtual uint32_t writeByte(const int8_t byte);
118
119 virtual uint32_t writeI16(const int16_t i16);
120
121 virtual uint32_t writeI32(const int32_t i32);
122
123 virtual uint32_t writeI64(const int64_t i64);
124
125 virtual uint32_t writeDouble(const double dub);
126
127 virtual uint32_t writeString(const std::string& str);
128
David Reissc005b1b2008-02-15 01:38:18 +0000129 virtual uint32_t writeBinary(const std::string& str);
130
David Reiss4e7530d2007-09-04 21:49:53 +0000131
132 /*
133 * Helper writing functions (don't do state transitions).
134 */
135 inline uint32_t subWriteI32(const int32_t i32);
136
David Reisse67c0e62007-09-07 01:34:12 +0000137 inline uint32_t subWriteString(const std::string& str);
138
David Reiss4e7530d2007-09-04 21:49:53 +0000139 uint32_t subWriteBool(const bool value) {
140 return TBinaryProtocol::writeBool(value);
141 }
142
David Reiss4e7530d2007-09-04 21:49:53 +0000143
144 /*
145 * Reading functions
146 */
147
148 uint32_t readMessageBegin(std::string& name,
149 TMessageType& messageType,
150 int32_t& seqid);
151
152 uint32_t readMessageEnd();
153
154 uint32_t readStructBegin(std::string& name);
155
156 uint32_t readStructEnd();
157
158 uint32_t readFieldBegin(std::string& name,
159 TType& fieldType,
160 int16_t& fieldId);
161
162 uint32_t readFieldEnd();
163
164 uint32_t readMapBegin(TType& keyType,
165 TType& valType,
166 uint32_t& size);
167
168 uint32_t readMapEnd();
169
170 uint32_t readListBegin(TType& elemType,
171 uint32_t& size);
172
173 uint32_t readListEnd();
174
175 uint32_t readSetBegin(TType& elemType,
176 uint32_t& size);
177
178 uint32_t readSetEnd();
179
180 uint32_t readBool(bool& value);
181
182 uint32_t readByte(int8_t& byte);
183
184 uint32_t readI16(int16_t& i16);
185
186 uint32_t readI32(int32_t& i32);
187
188 uint32_t readI64(int64_t& i64);
189
190 uint32_t readDouble(double& dub);
191
192 uint32_t readString(std::string& str);
193
David Reissc005b1b2008-02-15 01:38:18 +0000194 uint32_t readBinary(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000195
196 /*
197 * Helper reading functions (don't do state transitions).
198 */
David Reisse67c0e62007-09-07 01:34:12 +0000199 inline uint32_t subReadI32(int32_t& i32);
200
201 inline uint32_t subReadString(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000202
203 uint32_t subReadBool(bool& value) {
204 return TBinaryProtocol::readBool(value);
205 }
206
David Reiss4e7530d2007-09-04 21:49:53 +0000207
208 private:
209
David Reissce161a92007-09-11 22:09:42 +0000210 // Implementation functions, documented in the .cpp.
David Reiss4e7530d2007-09-04 21:49:53 +0000211 inline void checkTType(const TType ttype);
212 inline void stateTransition();
213
David Reisse67c0e62007-09-07 01:34:12 +0000214 // Read and write variable-length integers.
215 // Uses the same technique as the MIDI file format.
David Reissce161a92007-09-11 22:09:42 +0000216 inline uint32_t vlqRead(uint64_t& vlq);
217 inline uint32_t vlqWrite(uint64_t vlq);
David Reisse67c0e62007-09-07 01:34:12 +0000218
David Reissce161a92007-09-11 22:09:42 +0000219 // Called before throwing an exception to make the object reusable.
220 void resetState() {
221 ts_stack_.clear();
222 idx_stack_.clear();
223 mkv_stack_.clear();
224 }
225
226 // TypeSpec of the top-level structure to write,
227 // for standalone protocol objects.
David Reiss4e7530d2007-09-04 21:49:53 +0000228 TypeSpec* type_spec_;
229
230 std::vector<TypeSpec*> ts_stack_; // TypeSpec stack.
231 std::vector<int> idx_stack_; // InDeX stack.
232 std::vector<bool> mkv_stack_; // Map Key/Vlue stack.
233 // True = key, False = value.
234
David Reissce161a92007-09-11 22:09:42 +0000235 // True iff this is a standalone instance (no RPC).
236 bool standalone_;
David Reiss4e7530d2007-09-04 21:49:53 +0000237};
238
239}}} // facebook::thrift::protocol
240
241#endif // #ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_