blob: 38c534798c9c8895d2d494f308ba3254f5575d6b [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,
36 T_U08 = 4,
37 T_U16 = 5,
38 T_I16 = 6,
39 T_U32 = 7,
40 T_I32 = 8,
41 T_U64 = 9,
42 T_I64 = 10,
43 T_STRING = 11,
44 T_UTF7 = 12,
45 T_STRUCT = 13,
46 T_MAP = 14,
47 T_SET = 15,
48 T_LIST = 16,
49 T_UTF8 = 17,
50 T_UTF16 = 18
Mark Slee8d7e1f62006-06-07 06:48:56 +000051};
52
53/**
Marc Slemko16698852006-08-04 03:16:10 +000054 * Enumerated definition of the message types that the Thrift protocol supports.
55 */
56enum TMessageType {
57 T_CALL = 1,
58 T_REPLY = 2
59};
60
61/**
Mark Sleee8540632006-05-30 09:24:40 +000062 * Abstract class for a thrift protocol driver. These are all the methods that
63 * a protocol must implement. Essentially, there must be some way of reading
64 * and writing all the base types, plus a mechanism for writing out structs
65 * with indexed fields. Also notice that all methods are strictly const. This
66 * is by design. Protcol impelementations may NOT keep state, because the
67 * same TProtocol object may be used simultaneously by multiple threads. This
68 * theoretically introduces some limititations into the possible protocol
69 * formats, but with the benefit of performance, clarity, and simplicity.
70 *
71 * @author Mark Slee <mcslee@facebook.com>
72 */
73class TProtocol {
74 public:
75 virtual ~TProtocol() {}
76
77 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +000078 * Writing functions.
Mark Sleee8540632006-05-30 09:24:40 +000079 */
80
Marc Slemko0b4ffa92006-08-11 02:49:29 +000081 virtual uint32_t writeMessageBegin(shared_ptr<TTransport> out,
Marc Slemko91f67482006-08-11 23:58:57 +000082 const std::string name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +000083 const TMessageType messageType,
84 const uint32_t seqid) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000085
Marc Slemko0b4ffa92006-08-11 02:49:29 +000086 virtual uint32_t writeMessageEnd(shared_ptr<TTransport> out) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000087
88
Marc Slemko0b4ffa92006-08-11 02:49:29 +000089 virtual uint32_t writeStructBegin(shared_ptr<TTransport> out,
90 const std::string& name) const = 0;
91
92 virtual uint32_t writeStructEnd(shared_ptr<TTransport> out) const = 0;
93
94 virtual uint32_t writeFieldBegin(shared_ptr<TTransport> out,
95 const std::string& name,
96 const TType fieldType,
97 const int16_t fieldId) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000098
Marc Slemko0b4ffa92006-08-11 02:49:29 +000099 virtual uint32_t writeFieldEnd(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 writeFieldStop(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000102
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000103 virtual uint32_t writeMapBegin(shared_ptr<TTransport> out,
104 const TType keyType,
105 const TType valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000106 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000107
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000108 virtual uint32_t writeMapEnd(shared_ptr<TTransport> out) const = 0;
109
110 virtual uint32_t writeListBegin(shared_ptr<TTransport> out,
111 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000112 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000113
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000114 virtual uint32_t writeListEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000115
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000116 virtual uint32_t writeSetBegin(shared_ptr<TTransport> out,
117 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000118 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000119
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000120 virtual uint32_t writeSetEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000121
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000122 virtual uint32_t writeBool(shared_ptr<TTransport> out,
123 const bool value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000124
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000125 virtual uint32_t writeByte(shared_ptr<TTransport> out,
126 const uint8_t byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000127
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000128 virtual uint32_t writeI16(shared_ptr<TTransport> out,
129 const int16_t i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000130
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000131 virtual uint32_t writeU16(shared_ptr<TTransport> out,
132 const uint16_t u16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000133
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000134 virtual uint32_t writeU32(shared_ptr<TTransport> out,
135 const uint32_t u32) const = 0;
136
137 virtual uint32_t writeI32(shared_ptr<TTransport> out,
138 const int32_t i32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000139
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000140 virtual uint32_t writeU64(shared_ptr<TTransport> out,
141 const uint64_t u64) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000142
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000143 virtual uint32_t writeI64(shared_ptr<TTransport> out,
144 const int64_t i64) const = 0;
145
146 virtual uint32_t writeString(shared_ptr<TTransport> out,
147 const std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000148
149 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000150 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000151 */
152
Marc Slemko5b126d62006-08-11 23:03:42 +0000153 virtual uint32_t readMessageBegin(shared_ptr<TTransport> in,
Marc Slemko91f67482006-08-11 23:58:57 +0000154 std::string& name,
155 TMessageType& messageType,
156 uint32_t& seqid) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000157
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000158 virtual uint32_t readMessageEnd(shared_ptr<TTransport> in) const = 0;
159
160 virtual uint32_t readStructBegin(shared_ptr<TTransport> in,
161 std::string& name) const = 0;
162
163 virtual uint32_t readStructEnd(shared_ptr<TTransport> in) const = 0;
164
165 virtual uint32_t readFieldBegin(shared_ptr<TTransport> in,
166 std::string& name,
167 TType& fieldType,
168 int16_t& fieldId) const = 0;
169
170 virtual uint32_t readFieldEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000171
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000172 virtual uint32_t readMapBegin(shared_ptr<TTransport> in,
173 TType& keyType,
174 TType& valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000175 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000176
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000177 virtual uint32_t readMapEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000178
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000179 virtual uint32_t readListBegin(shared_ptr<TTransport> in,
180 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000181 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000182
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000183 virtual uint32_t readListEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000184
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000185 virtual uint32_t readSetBegin(shared_ptr<TTransport> in,
186 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000187 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000188
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000189 virtual uint32_t readSetEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000190
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000191 virtual uint32_t readBool(shared_ptr<TTransport> in,
192 bool& value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000193
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000194 virtual uint32_t readByte(shared_ptr<TTransport> in,
195 uint8_t& byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000196
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000197 virtual uint32_t readU16(shared_ptr<TTransport> in,
198 uint16_t& u16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000199
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000200 virtual uint32_t readI16(shared_ptr<TTransport> in,
201 int16_t& i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000202
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000203 virtual uint32_t readU32(shared_ptr<TTransport> in,
204 uint32_t& u32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000205
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000206 virtual uint32_t readI32(shared_ptr<TTransport> in,
207 int32_t& i32) const = 0;
208
209 virtual uint32_t readU64(shared_ptr<TTransport> in,
210 uint64_t& u64) const = 0;
211
212 virtual uint32_t readI64(shared_ptr<TTransport> in,
213 int64_t& i64) const = 0;
214
215 virtual uint32_t readString(shared_ptr<TTransport> in,
216 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000217
218 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000219 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000220 */
Marc Slemko16698852006-08-04 03:16:10 +0000221 uint32_t skip(shared_ptr<TTransport> in, TType type) const {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000222 switch (type) {
223 case T_BYTE:
224 {
225 uint8_t byte;
226 return readByte(in, byte);
227 }
228 case T_U32:
229 {
230 uint32_t u32;
231 return readU32(in, u32);
232 }
233 case T_I32:
234 {
235 int32_t i32;
236 return readI32(in, i32);
237 }
238 case T_U64:
239 {
240 uint64_t u64;
241 return readU64(in, u64);
242 }
243 case T_I64:
244 {
245 int64_t i64;
246 return readI64(in, i64);
247 }
248 case T_STRING:
249 {
250 std::string str;
251 return readString(in, str);
252 }
253 case T_STRUCT:
254 {
255 uint32_t result = 0;
256 std::string name;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000257 int16_t fid;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000258 TType ftype;
259 result += readStructBegin(in, name);
260 while (true) {
261 result += readFieldBegin(in, name, ftype, fid);
262 if (ftype == T_STOP) {
263 break;
264 }
265 result += skip(in, ftype);
266 result += readFieldEnd(in);
267 }
268 result += readStructEnd(in);
269 return result;
270 }
271 case T_MAP:
272 {
273 uint32_t result = 0;
274 TType keyType;
275 TType valType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000276 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000277 result += readMapBegin(in, keyType, valType, size);
278 for (i = 0; i < size; i++) {
279 result += skip(in, keyType);
280 result += skip(in, valType);
281 }
282 result += readMapEnd(in);
283 return result;
284 }
285 case T_SET:
286 {
287 uint32_t result = 0;
288 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000289 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000290 result += readSetBegin(in, elemType, size);
291 for (i = 0; i < size; i++) {
292 result += skip(in, elemType);
293 }
294 result += readSetEnd(in);
295 return result;
296 }
297 case T_LIST:
298 {
299 uint32_t result = 0;
300 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000301 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000302 result += readListBegin(in, elemType, size);
303 for (i = 0; i < size; i++) {
304 result += skip(in, elemType);
305 }
306 result += readListEnd(in);
307 return result;
308 }
309 default:
310 return 0;
311 }
312 }
Mark Sleee8540632006-05-30 09:24:40 +0000313
314 protected:
315 TProtocol() {}
316};
317
Marc Slemko6f038a72006-08-03 18:58:09 +0000318}}} // facebook::thrift::protocol
319
Mark Sleee8540632006-05-30 09:24:40 +0000320#endif
Marc Slemko6f038a72006-08-03 18:58:09 +0000321