blob: edd5c8867d7f4dcd40fd940754e7773a5a2e472a [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/**
15 * The dense protocol is designed to use as little space as possible.
16 *
17 * !!!WARNING!!!
18 * This class is still highly experimental. Incompatible changes
19 * WILL be made to it without notice. DO NOT USE IT YET unless
20 * you are coordinating your testing with the author.
21 *
22 * TODO(dreiss): New class write with old meta.
23 *
24 * We override all of TBinaryProtocol's methods.
25 * We inherit so that we can can explicitly call TBPs's primitive-writing
26 * methods within our versions.
27 *
28 * @author David Reiss <dreiss@facebook.com>
29 */
30class TDenseProtocol : public TBinaryProtocol {
31 protected:
32 static const int32_t VERSION_MASK = 0xffff0000;
David Reisse67c0e62007-09-07 01:34:12 +000033 // VERSION_1 (0x80010000) is taken by TBinaryProtocol.
David Reiss4e7530d2007-09-04 21:49:53 +000034 static const int32_t VERSION_2 = 0x80020000;
35
36 public:
37 typedef facebook::thrift::reflection::local::TypeSpec TypeSpec;
38
39 TDenseProtocol(boost::shared_ptr<TTransport> trans,
40 TypeSpec* type_spec = NULL) :
41 TBinaryProtocol(trans),
42 type_spec_(type_spec) {
43 vli_save_16 = 0;
44 vli_save_32 = 0;
45 vli_save_64 = 0;
46 vli_save_sub = 0;
47 negs = 0;
48 }
49
50 TDenseProtocol(boost::shared_ptr<TTransport> trans,
51 TypeSpec* type_spec,
52 int32_t string_limit,
53 int32_t container_limit) :
54 TBinaryProtocol(trans,
55 string_limit,
56 container_limit,
57 true,
58 true),
59 type_spec_(type_spec) {
60 vli_save_16 = 0;
61 vli_save_32 = 0;
62 vli_save_64 = 0;
63 vli_save_sub = 0;
64 negs = 0;
65 }
66
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
86 virtual uint32_t writeStructBegin(const std::string& name);
87
88 virtual uint32_t writeStructEnd();
89
90 virtual uint32_t writeFieldBegin(const std::string& name,
91 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
128
129 /*
130 * Helper writing functions (don't do state transitions).
131 */
132 inline uint32_t subWriteI32(const int32_t i32);
133
David Reisse67c0e62007-09-07 01:34:12 +0000134 inline uint32_t subWriteString(const std::string& str);
135
David Reiss4e7530d2007-09-04 21:49:53 +0000136 uint32_t subWriteBool(const bool value) {
137 return TBinaryProtocol::writeBool(value);
138 }
139
David Reiss4e7530d2007-09-04 21:49:53 +0000140
141 /*
142 * Reading functions
143 */
144
145 uint32_t readMessageBegin(std::string& name,
146 TMessageType& messageType,
147 int32_t& seqid);
148
149 uint32_t readMessageEnd();
150
151 uint32_t readStructBegin(std::string& name);
152
153 uint32_t readStructEnd();
154
155 uint32_t readFieldBegin(std::string& name,
156 TType& fieldType,
157 int16_t& fieldId);
158
159 uint32_t readFieldEnd();
160
161 uint32_t readMapBegin(TType& keyType,
162 TType& valType,
163 uint32_t& size);
164
165 uint32_t readMapEnd();
166
167 uint32_t readListBegin(TType& elemType,
168 uint32_t& size);
169
170 uint32_t readListEnd();
171
172 uint32_t readSetBegin(TType& elemType,
173 uint32_t& size);
174
175 uint32_t readSetEnd();
176
177 uint32_t readBool(bool& value);
178
179 uint32_t readByte(int8_t& byte);
180
181 uint32_t readI16(int16_t& i16);
182
183 uint32_t readI32(int32_t& i32);
184
185 uint32_t readI64(int64_t& i64);
186
187 uint32_t readDouble(double& dub);
188
189 uint32_t readString(std::string& str);
190
191
192 /*
193 * Helper reading functions (don't do state transitions).
194 */
David Reisse67c0e62007-09-07 01:34:12 +0000195 inline uint32_t subReadI32(int32_t& i32);
196
197 inline uint32_t subReadString(std::string& str);
David Reiss4e7530d2007-09-04 21:49:53 +0000198
199 uint32_t subReadBool(bool& value) {
200 return TBinaryProtocol::readBool(value);
201 }
202
David Reiss4e7530d2007-09-04 21:49:53 +0000203
204 private:
205
206 inline void checkTType(const TType ttype);
207 inline void stateTransition();
208
David Reisse67c0e62007-09-07 01:34:12 +0000209 // Read and write variable-length integers.
210 // Uses the same technique as the MIDI file format.
211 inline uint32_t vliRead(uint64_t& vli);
212 inline uint32_t vliWrite(uint64_t vli);
213
David Reiss4e7530d2007-09-04 21:49:53 +0000214 TypeSpec* type_spec_;
215
216 std::vector<TypeSpec*> ts_stack_; // TypeSpec stack.
217 std::vector<int> idx_stack_; // InDeX stack.
218 std::vector<bool> mkv_stack_; // Map Key/Vlue stack.
219 // True = key, False = value.
220
221 // XXX Remove these when wire format is finalized.
222 public:
223 int vli_save_16;
224 int vli_save_32;
225 int vli_save_64;
226 int vli_save_sub;
227 int negs;
228};
229
230}}} // facebook::thrift::protocol
231
232#endif // #ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_