blob: 092dd8d5313614dc7fc10c0b6ae583885a97da89 [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,
Marc Slemko5b126d62006-08-11 23:03:42 +000033 T_VOID = 1,
34 T_BOOL = 2,
35 T_BYTE = 3,
Marc Slemkod97eb612006-08-24 23:37:36 +000036 T_U08 = 3,
37 T_I08 = 4,
Marc Slemko5b126d62006-08-11 23:03:42 +000038 T_U16 = 5,
39 T_I16 = 6,
40 T_U32 = 7,
41 T_I32 = 8,
42 T_U64 = 9,
43 T_I64 = 10,
44 T_STRING = 11,
Marc Slemkod97eb612006-08-24 23:37:36 +000045 T_UTF7 = 11,
46 T_STRUCT = 12,
47 T_MAP = 13,
48 T_SET = 14,
49 T_LIST = 15,
50 T_UTF8 = 16,
51 T_UTF16 = 17
Mark Slee8d7e1f62006-06-07 06:48:56 +000052};
53
54/**
Marc Slemko16698852006-08-04 03:16:10 +000055 * Enumerated definition of the message types that the Thrift protocol supports.
56 */
57enum TMessageType {
58 T_CALL = 1,
59 T_REPLY = 2
60};
61
62/**
Mark Sleee8540632006-05-30 09:24:40 +000063 * Abstract class for a thrift protocol driver. These are all the methods that
64 * a protocol must implement. Essentially, there must be some way of reading
65 * and writing all the base types, plus a mechanism for writing out structs
66 * with indexed fields. Also notice that all methods are strictly const. This
67 * is by design. Protcol impelementations may NOT keep state, because the
68 * same TProtocol object may be used simultaneously by multiple threads. This
69 * theoretically introduces some limititations into the possible protocol
70 * formats, but with the benefit of performance, clarity, and simplicity.
71 *
72 * @author Mark Slee <mcslee@facebook.com>
73 */
74class TProtocol {
75 public:
76 virtual ~TProtocol() {}
77
78 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +000079 * Writing functions.
Mark Sleee8540632006-05-30 09:24:40 +000080 */
81
Marc Slemko0b4ffa92006-08-11 02:49:29 +000082 virtual uint32_t writeMessageBegin(shared_ptr<TTransport> out,
Marc Slemko91f67482006-08-11 23:58:57 +000083 const std::string name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +000084 const TMessageType messageType,
85 const uint32_t seqid) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000086
Marc Slemko0b4ffa92006-08-11 02:49:29 +000087 virtual uint32_t writeMessageEnd(shared_ptr<TTransport> out) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000088
89
Marc Slemko0b4ffa92006-08-11 02:49:29 +000090 virtual uint32_t writeStructBegin(shared_ptr<TTransport> out,
91 const std::string& name) const = 0;
92
93 virtual uint32_t writeStructEnd(shared_ptr<TTransport> out) const = 0;
94
95 virtual uint32_t writeFieldBegin(shared_ptr<TTransport> out,
96 const std::string& name,
97 const TType fieldType,
98 const int16_t fieldId) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000099
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000100 virtual uint32_t writeFieldEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000101
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000102 virtual uint32_t writeFieldStop(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000103
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000104 virtual uint32_t writeMapBegin(shared_ptr<TTransport> out,
105 const TType keyType,
106 const TType valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000107 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000108
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000109 virtual uint32_t writeMapEnd(shared_ptr<TTransport> out) const = 0;
110
111 virtual uint32_t writeListBegin(shared_ptr<TTransport> out,
112 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000113 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000114
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000115 virtual uint32_t writeListEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000116
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000117 virtual uint32_t writeSetBegin(shared_ptr<TTransport> out,
118 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000119 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000120
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000121 virtual uint32_t writeSetEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000122
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000123 virtual uint32_t writeBool(shared_ptr<TTransport> out,
124 const bool value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000125
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000126 virtual uint32_t writeByte(shared_ptr<TTransport> out,
127 const uint8_t byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000128
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000129 virtual uint32_t writeI16(shared_ptr<TTransport> out,
130 const int16_t i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000131
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000132 virtual uint32_t writeU16(shared_ptr<TTransport> out,
133 const uint16_t u16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000134
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000135 virtual uint32_t writeU32(shared_ptr<TTransport> out,
136 const uint32_t u32) const = 0;
137
138 virtual uint32_t writeI32(shared_ptr<TTransport> out,
139 const int32_t i32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000140
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000141 virtual uint32_t writeU64(shared_ptr<TTransport> out,
142 const uint64_t u64) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000143
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000144 virtual uint32_t writeI64(shared_ptr<TTransport> out,
145 const int64_t i64) const = 0;
146
147 virtual uint32_t writeString(shared_ptr<TTransport> out,
148 const std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000149
150 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000151 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000152 */
153
Marc Slemko5b126d62006-08-11 23:03:42 +0000154 virtual uint32_t readMessageBegin(shared_ptr<TTransport> in,
Marc Slemko91f67482006-08-11 23:58:57 +0000155 std::string& name,
156 TMessageType& messageType,
157 uint32_t& seqid) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000158
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000159 virtual uint32_t readMessageEnd(shared_ptr<TTransport> in) const = 0;
160
161 virtual uint32_t readStructBegin(shared_ptr<TTransport> in,
162 std::string& name) const = 0;
163
164 virtual uint32_t readStructEnd(shared_ptr<TTransport> in) const = 0;
165
166 virtual uint32_t readFieldBegin(shared_ptr<TTransport> in,
167 std::string& name,
168 TType& fieldType,
169 int16_t& fieldId) const = 0;
170
171 virtual uint32_t readFieldEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000172
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000173 virtual uint32_t readMapBegin(shared_ptr<TTransport> in,
174 TType& keyType,
175 TType& valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000176 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000177
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000178 virtual uint32_t readMapEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000179
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000180 virtual uint32_t readListBegin(shared_ptr<TTransport> in,
181 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000182 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000183
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000184 virtual uint32_t readListEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000185
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000186 virtual uint32_t readSetBegin(shared_ptr<TTransport> in,
187 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000188 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000189
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000190 virtual uint32_t readSetEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000191
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000192 virtual uint32_t readBool(shared_ptr<TTransport> in,
193 bool& value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000194
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000195 virtual uint32_t readByte(shared_ptr<TTransport> in,
196 uint8_t& byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000197
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000198 virtual uint32_t readU16(shared_ptr<TTransport> in,
199 uint16_t& u16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000200
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000201 virtual uint32_t readI16(shared_ptr<TTransport> in,
202 int16_t& i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000203
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000204 virtual uint32_t readU32(shared_ptr<TTransport> in,
205 uint32_t& u32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000206
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000207 virtual uint32_t readI32(shared_ptr<TTransport> in,
208 int32_t& i32) const = 0;
209
210 virtual uint32_t readU64(shared_ptr<TTransport> in,
211 uint64_t& u64) const = 0;
212
213 virtual uint32_t readI64(shared_ptr<TTransport> in,
214 int64_t& i64) const = 0;
215
216 virtual uint32_t readString(shared_ptr<TTransport> in,
217 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000218
219 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000220 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000221 */
Marc Slemko16698852006-08-04 03:16:10 +0000222 uint32_t skip(shared_ptr<TTransport> in, TType type) const {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000223 switch (type) {
224 case T_BYTE:
225 {
226 uint8_t byte;
227 return readByte(in, byte);
228 }
229 case T_U32:
230 {
231 uint32_t u32;
232 return readU32(in, u32);
233 }
234 case T_I32:
235 {
236 int32_t i32;
237 return readI32(in, i32);
238 }
239 case T_U64:
240 {
241 uint64_t u64;
242 return readU64(in, u64);
243 }
244 case T_I64:
245 {
246 int64_t i64;
247 return readI64(in, i64);
248 }
249 case T_STRING:
250 {
251 std::string str;
252 return readString(in, str);
253 }
254 case T_STRUCT:
255 {
256 uint32_t result = 0;
257 std::string name;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000258 int16_t fid;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000259 TType ftype;
260 result += readStructBegin(in, name);
261 while (true) {
262 result += readFieldBegin(in, name, ftype, fid);
263 if (ftype == T_STOP) {
264 break;
265 }
266 result += skip(in, ftype);
267 result += readFieldEnd(in);
268 }
269 result += readStructEnd(in);
270 return result;
271 }
272 case T_MAP:
273 {
274 uint32_t result = 0;
275 TType keyType;
276 TType valType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000277 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000278 result += readMapBegin(in, keyType, valType, size);
279 for (i = 0; i < size; i++) {
280 result += skip(in, keyType);
281 result += skip(in, valType);
282 }
283 result += readMapEnd(in);
284 return result;
285 }
286 case T_SET:
287 {
288 uint32_t result = 0;
289 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000290 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000291 result += readSetBegin(in, elemType, size);
292 for (i = 0; i < size; i++) {
293 result += skip(in, elemType);
294 }
295 result += readSetEnd(in);
296 return result;
297 }
298 case T_LIST:
299 {
300 uint32_t result = 0;
301 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000302 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000303 result += readListBegin(in, elemType, size);
304 for (i = 0; i < size; i++) {
305 result += skip(in, elemType);
306 }
307 result += readListEnd(in);
308 return result;
309 }
310 default:
311 return 0;
312 }
313 }
Mark Sleee8540632006-05-30 09:24:40 +0000314
315 protected:
316 TProtocol() {}
317};
318
Marc Slemko6f038a72006-08-03 18:58:09 +0000319}}} // facebook::thrift::protocol
320
Mark Sleee8540632006-05-30 09:24:40 +0000321#endif
Marc Slemko6f038a72006-08-03 18:58:09 +0000322