blob: 014f1f09242a1444ab351ee4ebe535fe41e0a3ab [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
T Jake Lucianib5e62212009-01-31 22:36:20 +000012namespace apache { namespace thrift { namespace protocol {
David Reiss4e7530d2007-09-04 21:49:53 +000013
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 *
David Reiss4e7530d2007-09-04 21:49:53 +000045 */
46class TDenseProtocol : public TBinaryProtocol {
47 protected:
48 static const int32_t VERSION_MASK = 0xffff0000;
David Reisse67c0e62007-09-07 01:34:12 +000049 // VERSION_1 (0x80010000) is taken by TBinaryProtocol.
David Reiss4e7530d2007-09-04 21:49:53 +000050 static const int32_t VERSION_2 = 0x80020000;
51
52 public:
T Jake Lucianib5e62212009-01-31 22:36:20 +000053 typedef apache::thrift::reflection::local::TypeSpec TypeSpec;
David Reissce161a92007-09-11 22:09:42 +000054 static const int FP_PREFIX_LEN;
David Reiss4e7530d2007-09-04 21:49:53 +000055
David Reissce161a92007-09-11 22:09:42 +000056 /**
57 * @param tran The transport to use.
58 * @param type_spec The TypeSpec of the structures using this protocol.
59 */
David Reiss4e7530d2007-09-04 21:49:53 +000060 TDenseProtocol(boost::shared_ptr<TTransport> trans,
61 TypeSpec* type_spec = NULL) :
62 TBinaryProtocol(trans),
David Reissce161a92007-09-11 22:09:42 +000063 type_spec_(type_spec),
64 standalone_(true)
65 {}
David Reiss4e7530d2007-09-04 21:49:53 +000066
67 void setTypeSpec(TypeSpec* type_spec) {
68 type_spec_ = type_spec;
69 }
70 TypeSpec* getTypeSpec() {
71 return type_spec_;
72 }
73
74
75 /*
76 * Writing functions.
77 */
78
79 virtual uint32_t writeMessageBegin(const std::string& name,
80 const TMessageType messageType,
81 const int32_t seqid);
82
83 virtual uint32_t writeMessageEnd();
84
85
David Reiss64120002008-04-29 23:12:24 +000086 virtual uint32_t writeStructBegin(const char* name);
David Reiss4e7530d2007-09-04 21:49:53 +000087
88 virtual uint32_t writeStructEnd();
89
David Reiss64120002008-04-29 23:12:24 +000090 virtual uint32_t writeFieldBegin(const char* name,
David Reiss4e7530d2007-09-04 21:49:53 +000091 const TType fieldType,
92 const int16_t fieldId);
93
94 virtual uint32_t writeFieldEnd();
95
96 virtual uint32_t writeFieldStop();
97
98 virtual uint32_t writeMapBegin(const TType keyType,
99 const TType valType,
100 const uint32_t size);
101
102 virtual uint32_t writeMapEnd();
103
104 virtual uint32_t writeListBegin(const TType elemType,
105 const uint32_t size);
106
107 virtual uint32_t writeListEnd();
108
109 virtual uint32_t writeSetBegin(const TType elemType,
110 const uint32_t size);
111
112 virtual uint32_t writeSetEnd();
113
114 virtual uint32_t writeBool(const bool value);
115
116 virtual uint32_t writeByte(const int8_t byte);
117
118 virtual uint32_t writeI16(const int16_t i16);
119
120 virtual uint32_t writeI32(const int32_t i32);
121
122 virtual uint32_t writeI64(const int64_t i64);
123
124 virtual uint32_t writeDouble(const double dub);
125
126 virtual uint32_t writeString(const std::string& str);
127
David Reissc005b1b2008-02-15 01:38:18 +0000128 virtual uint32_t writeBinary(const std::string& str);
129
David Reiss4e7530d2007-09-04 21:49:53 +0000130
131 /*
132 * Helper writing functions (don't do state transitions).
133 */
134 inline uint32_t subWriteI32(const int32_t i32);
135
David Reisse67c0e62007-09-07 01:34:12 +0000136 inline uint32_t subWriteString(const std::string& str);
137
David Reiss4e7530d2007-09-04 21:49:53 +0000138 uint32_t subWriteBool(const bool value) {
139 return TBinaryProtocol::writeBool(value);
140 }
141
David Reiss4e7530d2007-09-04 21:49:53 +0000142
143 /*
144 * Reading functions
145 */
146
147 uint32_t readMessageBegin(std::string& name,
148 TMessageType& messageType,
149 int32_t& seqid);
150
151 uint32_t readMessageEnd();
152
153 uint32_t readStructBegin(std::string& name);
154
155 uint32_t readStructEnd();
156
157 uint32_t readFieldBegin(std::string& name,
158 TType& fieldType,
159 int16_t& fieldId);
160
161 uint32_t readFieldEnd();
162
163 uint32_t readMapBegin(TType& keyType,
164 TType& valType,
165 uint32_t& size);
166
167 uint32_t readMapEnd();
168
169 uint32_t readListBegin(TType& elemType,
170 uint32_t& size);
171
172 uint32_t readListEnd();
173
174 uint32_t readSetBegin(TType& elemType,
175 uint32_t& size);
176
177 uint32_t readSetEnd();
178
179 uint32_t readBool(bool& value);
180
181 uint32_t readByte(int8_t& byte);
182
183 uint32_t readI16(int16_t& i16);
184
185 uint32_t readI32(int32_t& i32);
186
187 uint32_t readI64(int64_t& i64);
188
189 uint32_t readDouble(double& dub);
190
191 uint32_t readString(std::string& str);
192
David Reissc005b1b2008-02-15 01:38:18 +0000193 uint32_t readBinary(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000194
195 /*
196 * Helper reading functions (don't do state transitions).
197 */
David Reisse67c0e62007-09-07 01:34:12 +0000198 inline uint32_t subReadI32(int32_t& i32);
199
200 inline uint32_t subReadString(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000201
202 uint32_t subReadBool(bool& value) {
203 return TBinaryProtocol::readBool(value);
204 }
205
David Reiss4e7530d2007-09-04 21:49:53 +0000206
207 private:
208
David Reissce161a92007-09-11 22:09:42 +0000209 // Implementation functions, documented in the .cpp.
David Reiss4e7530d2007-09-04 21:49:53 +0000210 inline void checkTType(const TType ttype);
211 inline void stateTransition();
212
David Reisse67c0e62007-09-07 01:34:12 +0000213 // Read and write variable-length integers.
214 // Uses the same technique as the MIDI file format.
David Reissce161a92007-09-11 22:09:42 +0000215 inline uint32_t vlqRead(uint64_t& vlq);
216 inline uint32_t vlqWrite(uint64_t vlq);
David Reisse67c0e62007-09-07 01:34:12 +0000217
David Reissce161a92007-09-11 22:09:42 +0000218 // Called before throwing an exception to make the object reusable.
219 void resetState() {
220 ts_stack_.clear();
221 idx_stack_.clear();
222 mkv_stack_.clear();
223 }
224
225 // TypeSpec of the top-level structure to write,
226 // for standalone protocol objects.
David Reiss4e7530d2007-09-04 21:49:53 +0000227 TypeSpec* type_spec_;
228
229 std::vector<TypeSpec*> ts_stack_; // TypeSpec stack.
230 std::vector<int> idx_stack_; // InDeX stack.
231 std::vector<bool> mkv_stack_; // Map Key/Vlue stack.
232 // True = key, False = value.
233
David Reissce161a92007-09-11 22:09:42 +0000234 // True iff this is a standalone instance (no RPC).
235 bool standalone_;
David Reiss4e7530d2007-09-04 21:49:53 +0000236};
237
T Jake Lucianib5e62212009-01-31 22:36:20 +0000238}}} // apache::thrift::protocol
David Reiss4e7530d2007-09-04 21:49:53 +0000239
240#endif // #ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_