blob: 8c89ba5a57d201a3bd1d13fb79292fcb993288a2 [file] [log] [blame]
Mark Sleee8540632006-05-30 09:24:40 +00001#ifndef T_PROTOCOL_H
2#define T_PROTOCOL_H
3
Marc Slemko16698852006-08-04 03:16:10 +00004#include <transport/TTransport.h>
5
6#include <boost/shared_ptr.hpp>
7
Mark Slee8d7e1f62006-06-07 06:48:56 +00008#include <netinet/in.h>
Mark Sleee8540632006-05-30 09:24:40 +00009#include <sys/types.h>
10#include <string>
11#include <map>
12
Marc Slemko6f038a72006-08-03 18:58:09 +000013namespace facebook { namespace thrift { namespace protocol {
14
Marc Slemko16698852006-08-04 03:16:10 +000015using namespace boost;
16
Marc Slemko6f038a72006-08-03 18:58:09 +000017using namespace facebook::thrift::transport;
18
Mark Slee8d7e1f62006-06-07 06:48:56 +000019#define ntohll(x) (((uint64_t)(ntohl((int)((x << 32) >> 32))) << 32) | (uint32_t)ntohl(((int)(x >> 32))))
20
21#define htonll(x) ntohll(x)
22
Mark Sleee8540632006-05-30 09:24:40 +000023/** Forward declaration for TProtocol */
24struct TBuf;
25
26/**
Mark Slee8d7e1f62006-06-07 06:48:56 +000027 * Enumerated definition of the types that the Thrift protocol supports.
28 * Take special note of the T_END type which is used specifically to mark
29 * the end of a sequence of fields.
30 */
31enum TType {
Marc Slemkod42a2c22006-08-10 03:30:18 +000032 T_STOP = 0,
33 T_BOOL = 1,
Mark Slee8d7e1f62006-06-07 06:48:56 +000034 T_BYTE = 2,
Marc Slemkod42a2c22006-08-10 03:30:18 +000035 T_U08 = 2,
Mark Slee8d7e1f62006-06-07 06:48:56 +000036 T_U16 = 3,
37 T_I16 = 4,
38 T_U32 = 5,
39 T_I32 = 6,
40 T_U64 = 7,
41 T_I64 = 8,
42 T_STRING = 9,
Marc Slemkod42a2c22006-08-10 03:30:18 +000043 T_UTF7 = 9,
Mark Slee8d7e1f62006-06-07 06:48:56 +000044 T_STRUCT = 10,
45 T_MAP = 11,
46 T_SET = 12,
Marc Slemkod42a2c22006-08-10 03:30:18 +000047 T_LIST = 13,
48 T_UTF8 = 14,
49 T_UTF16 = 15
Mark Slee8d7e1f62006-06-07 06:48:56 +000050};
51
52/**
Marc Slemko16698852006-08-04 03:16:10 +000053 * Enumerated definition of the message types that the Thrift protocol supports.
54 */
55enum TMessageType {
56 T_CALL = 1,
57 T_REPLY = 2
58};
59
60/**
Mark Sleee8540632006-05-30 09:24:40 +000061 * Abstract class for a thrift protocol driver. These are all the methods that
62 * a protocol must implement. Essentially, there must be some way of reading
63 * and writing all the base types, plus a mechanism for writing out structs
64 * with indexed fields. Also notice that all methods are strictly const. This
65 * is by design. Protcol impelementations may NOT keep state, because the
66 * same TProtocol object may be used simultaneously by multiple threads. This
67 * theoretically introduces some limititations into the possible protocol
68 * formats, but with the benefit of performance, clarity, and simplicity.
69 *
70 * @author Mark Slee <mcslee@facebook.com>
71 */
72class TProtocol {
73 public:
74 virtual ~TProtocol() {}
75
76 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +000077 * Writing functions.
Mark Sleee8540632006-05-30 09:24:40 +000078 */
79
Marc Slemko0b4ffa92006-08-11 02:49:29 +000080 virtual uint32_t writeMessageBegin(shared_ptr<TTransport> out,
81 const TMessageType messageType,
82 const uint32_t seqid) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000083
Marc Slemko0b4ffa92006-08-11 02:49:29 +000084 virtual uint32_t writeMessageEnd(shared_ptr<TTransport> out) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000085
86
Marc Slemko0b4ffa92006-08-11 02:49:29 +000087 virtual uint32_t writeStructBegin(shared_ptr<TTransport> out,
88 const std::string& name) const = 0;
89
90 virtual uint32_t writeStructEnd(shared_ptr<TTransport> out) const = 0;
91
92 virtual uint32_t writeFieldBegin(shared_ptr<TTransport> out,
93 const std::string& name,
94 const TType fieldType,
95 const int16_t fieldId) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000096
Marc Slemko0b4ffa92006-08-11 02:49:29 +000097 virtual uint32_t writeFieldEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000098
Marc Slemko0b4ffa92006-08-11 02:49:29 +000099 virtual uint32_t writeFieldStop(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000100
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000101 virtual uint32_t writeMapBegin(shared_ptr<TTransport> out,
102 const TType keyType,
103 const TType valType,
104 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000105
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000106 virtual uint32_t writeMapEnd(shared_ptr<TTransport> out) const = 0;
107
108 virtual uint32_t writeListBegin(shared_ptr<TTransport> out,
109 const TType elemType,
110 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000111
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000112 virtual uint32_t writeListEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000113
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000114 virtual uint32_t writeSetBegin(shared_ptr<TTransport> out,
115 const TType elemType,
116 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000117
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000118 virtual uint32_t writeSetEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000119
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000120 virtual uint32_t writeBool(shared_ptr<TTransport> out,
121 const bool value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000122
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000123 virtual uint32_t writeByte(shared_ptr<TTransport> out,
124 const uint8_t byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000125
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000126 virtual uint32_t writeI16(shared_ptr<TTransport> out,
127 const int16_t i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000128
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000129 virtual uint32_t writeU16(shared_ptr<TTransport> out,
130 const uint16_t u16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000131
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000132 virtual uint32_t writeU32(shared_ptr<TTransport> out,
133 const uint32_t u32) const = 0;
134
135 virtual uint32_t writeI32(shared_ptr<TTransport> out,
136 const int32_t i32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000137
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000138 virtual uint32_t writeU64(shared_ptr<TTransport> out,
139 const uint64_t u64) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000140
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000141 virtual uint32_t writeI64(shared_ptr<TTransport> out,
142 const int64_t i64) const = 0;
143
144 virtual uint32_t writeString(shared_ptr<TTransport> out,
145 const std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000146
147 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000148 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000149 */
150
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000151 virtual uint32_t readMessasgeBegin(shared_ptr<TTransport> in,
152 TMessageType& messageType,
153 uint32_t& seqid) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000154
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000155 virtual uint32_t readMessageEnd(shared_ptr<TTransport> in) const = 0;
156
157 virtual uint32_t readStructBegin(shared_ptr<TTransport> in,
158 std::string& name) const = 0;
159
160 virtual uint32_t readStructEnd(shared_ptr<TTransport> in) const = 0;
161
162 virtual uint32_t readFieldBegin(shared_ptr<TTransport> in,
163 std::string& name,
164 TType& fieldType,
165 int16_t& fieldId) const = 0;
166
167 virtual uint32_t readFieldEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000168
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000169 virtual uint32_t readMapBegin(shared_ptr<TTransport> in,
170 TType& keyType,
171 TType& valType,
172 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000173
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000174 virtual uint32_t readMapEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000175
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000176 virtual uint32_t readListBegin(shared_ptr<TTransport> in,
177 TType& elemType,
178 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000179
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000180 virtual uint32_t readListEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000181
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000182 virtual uint32_t readSetBegin(shared_ptr<TTransport> in,
183 TType& elemType,
184 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000185
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000186 virtual uint32_t readSetEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000187
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000188 virtual uint32_t readBool(shared_ptr<TTransport> in,
189 bool& value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000190
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000191 virtual uint32_t readByte(shared_ptr<TTransport> in,
192 uint8_t& byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000193
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000194 virtual uint32_t readU16(shared_ptr<TTransport> in,
195 uint16_t& u16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000196
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000197 virtual uint32_t readI16(shared_ptr<TTransport> in,
198 int16_t& i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000199
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000200 virtual uint32_t readU32(shared_ptr<TTransport> in,
201 uint32_t& u32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000202
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000203 virtual uint32_t readI32(shared_ptr<TTransport> in,
204 int32_t& i32) const = 0;
205
206 virtual uint32_t readU64(shared_ptr<TTransport> in,
207 uint64_t& u64) const = 0;
208
209 virtual uint32_t readI64(shared_ptr<TTransport> in,
210 int64_t& i64) const = 0;
211
212 virtual uint32_t readString(shared_ptr<TTransport> in,
213 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000214
215 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000216 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000217 */
Marc Slemko16698852006-08-04 03:16:10 +0000218 uint32_t skip(shared_ptr<TTransport> in, TType type) const {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000219 switch (type) {
220 case T_BYTE:
221 {
222 uint8_t byte;
223 return readByte(in, byte);
224 }
225 case T_U32:
226 {
227 uint32_t u32;
228 return readU32(in, u32);
229 }
230 case T_I32:
231 {
232 int32_t i32;
233 return readI32(in, i32);
234 }
235 case T_U64:
236 {
237 uint64_t u64;
238 return readU64(in, u64);
239 }
240 case T_I64:
241 {
242 int64_t i64;
243 return readI64(in, i64);
244 }
245 case T_STRING:
246 {
247 std::string str;
248 return readString(in, str);
249 }
250 case T_STRUCT:
251 {
252 uint32_t result = 0;
253 std::string name;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000254 int16_t fid;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000255 TType ftype;
256 result += readStructBegin(in, name);
257 while (true) {
258 result += readFieldBegin(in, name, ftype, fid);
259 if (ftype == T_STOP) {
260 break;
261 }
262 result += skip(in, ftype);
263 result += readFieldEnd(in);
264 }
265 result += readStructEnd(in);
266 return result;
267 }
268 case T_MAP:
269 {
270 uint32_t result = 0;
271 TType keyType;
272 TType valType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000273 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000274 result += readMapBegin(in, keyType, valType, size);
275 for (i = 0; i < size; i++) {
276 result += skip(in, keyType);
277 result += skip(in, valType);
278 }
279 result += readMapEnd(in);
280 return result;
281 }
282 case T_SET:
283 {
284 uint32_t result = 0;
285 TType elemType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000286 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000287 result += readSetBegin(in, elemType, size);
288 for (i = 0; i < size; i++) {
289 result += skip(in, elemType);
290 }
291 result += readSetEnd(in);
292 return result;
293 }
294 case T_LIST:
295 {
296 uint32_t result = 0;
297 TType elemType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000298 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000299 result += readListBegin(in, elemType, size);
300 for (i = 0; i < size; i++) {
301 result += skip(in, elemType);
302 }
303 result += readListEnd(in);
304 return result;
305 }
306 default:
307 return 0;
308 }
309 }
Mark Sleee8540632006-05-30 09:24:40 +0000310
311 protected:
312 TProtocol() {}
313};
314
Marc Slemko6f038a72006-08-03 18:58:09 +0000315}}} // facebook::thrift::protocol
316
Mark Sleee8540632006-05-30 09:24:40 +0000317#endif
Marc Slemko6f038a72006-08-03 18:58:09 +0000318