blob: 60d85dcdb02939ce86fa9c2de48453a4856809c0 [file] [log] [blame]
Mark Sleef5f2be42006-09-05 21:05:31 +00001#ifndef _THRIFT_PROTOCOL_TPROTOCOL_H_
2#define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1
Mark Sleee8540632006-05-30 09:24:40 +00003
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 Sleedc8a2a22006-09-19 22:20:18 +000019#if __BYTE_ORDER == __BIG_ENDIAN
20#define ntohll(n) (n)
21#define htonll(n) (n)
22#else
23#define ntohll(n) ( (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32) )
24#define htonll(n) ( (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32) )
25#endif
Mark Slee8d7e1f62006-06-07 06:48:56 +000026
Mark Sleef5f2be42006-09-05 21:05:31 +000027// Forward declaration for TProtocol
Mark Sleee8540632006-05-30 09:24:40 +000028struct TBuf;
29
30/**
Mark Slee8d7e1f62006-06-07 06:48:56 +000031 * Enumerated definition of the types that the Thrift protocol supports.
32 * Take special note of the T_END type which is used specifically to mark
33 * the end of a sequence of fields.
34 */
35enum TType {
Marc Slemkod42a2c22006-08-10 03:30:18 +000036 T_STOP = 0,
Marc Slemko5b126d62006-08-11 23:03:42 +000037 T_VOID = 1,
38 T_BOOL = 2,
39 T_BYTE = 3,
Mark Sleecfc01932006-09-01 22:18:16 +000040 T_I08 = 3,
Marc Slemko5b126d62006-08-11 23:03:42 +000041 T_I16 = 6,
Marc Slemko5b126d62006-08-11 23:03:42 +000042 T_I32 = 8,
43 T_U64 = 9,
44 T_I64 = 10,
Mark Sleec98d0502006-09-06 02:42:25 +000045 T_DOUBLE = 4,
Marc Slemko5b126d62006-08-11 23:03:42 +000046 T_STRING = 11,
Marc Slemkod97eb612006-08-24 23:37:36 +000047 T_UTF7 = 11,
48 T_STRUCT = 12,
49 T_MAP = 13,
50 T_SET = 14,
51 T_LIST = 15,
52 T_UTF8 = 16,
53 T_UTF16 = 17
Mark Slee8d7e1f62006-06-07 06:48:56 +000054};
55
56/**
Mark Sleef5f2be42006-09-05 21:05:31 +000057 * Enumerated definition of the message types that the Thrift protocol
58 * supports.
Marc Slemko16698852006-08-04 03:16:10 +000059 */
60enum TMessageType {
61 T_CALL = 1,
62 T_REPLY = 2
63};
64
65/**
Mark Sleee8540632006-05-30 09:24:40 +000066 * Abstract class for a thrift protocol driver. These are all the methods that
67 * a protocol must implement. Essentially, there must be some way of reading
68 * and writing all the base types, plus a mechanism for writing out structs
69 * with indexed fields. Also notice that all methods are strictly const. This
70 * is by design. Protcol impelementations may NOT keep state, because the
71 * same TProtocol object may be used simultaneously by multiple threads. This
72 * theoretically introduces some limititations into the possible protocol
73 * formats, but with the benefit of performance, clarity, and simplicity.
74 *
75 * @author Mark Slee <mcslee@facebook.com>
76 */
77class TProtocol {
78 public:
79 virtual ~TProtocol() {}
80
81 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +000082 * Writing functions.
Mark Sleee8540632006-05-30 09:24:40 +000083 */
84
Marc Slemko0b4ffa92006-08-11 02:49:29 +000085 virtual uint32_t writeMessageBegin(shared_ptr<TTransport> out,
Marc Slemko91f67482006-08-11 23:58:57 +000086 const std::string name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +000087 const TMessageType messageType,
Mark Sleecfc01932006-09-01 22:18:16 +000088 const int32_t seqid) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000089
Marc Slemko0b4ffa92006-08-11 02:49:29 +000090 virtual uint32_t writeMessageEnd(shared_ptr<TTransport> out) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000091
92
Marc Slemko0b4ffa92006-08-11 02:49:29 +000093 virtual uint32_t writeStructBegin(shared_ptr<TTransport> out,
94 const std::string& name) const = 0;
95
96 virtual uint32_t writeStructEnd(shared_ptr<TTransport> out) const = 0;
97
98 virtual uint32_t writeFieldBegin(shared_ptr<TTransport> out,
99 const std::string& name,
100 const TType fieldType,
101 const int16_t fieldId) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000102
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000103 virtual uint32_t writeFieldEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000104
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000105 virtual uint32_t writeFieldStop(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000106
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000107 virtual uint32_t writeMapBegin(shared_ptr<TTransport> out,
108 const TType keyType,
109 const TType valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000110 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000111
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000112 virtual uint32_t writeMapEnd(shared_ptr<TTransport> out) const = 0;
113
114 virtual uint32_t writeListBegin(shared_ptr<TTransport> out,
115 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000116 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000117
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000118 virtual uint32_t writeListEnd(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 writeSetBegin(shared_ptr<TTransport> out,
121 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000122 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000123
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000124 virtual uint32_t writeSetEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000125
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000126 virtual uint32_t writeBool(shared_ptr<TTransport> out,
127 const bool value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000128
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000129 virtual uint32_t writeByte(shared_ptr<TTransport> out,
Mark Sleecfc01932006-09-01 22:18:16 +0000130 const int8_t byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000131
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000132 virtual uint32_t writeI16(shared_ptr<TTransport> out,
133 const int16_t i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000134
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000135 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 writeI64(shared_ptr<TTransport> out,
139 const int64_t i64) const = 0;
140
Mark Sleec98d0502006-09-06 02:42:25 +0000141 virtual uint32_t writeDouble(shared_ptr<TTransport> out,
142 const double dub) const = 0;
143
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000144 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 Slemko5b126d62006-08-11 23:03:42 +0000151 virtual uint32_t readMessageBegin(shared_ptr<TTransport> in,
Marc Slemko91f67482006-08-11 23:58:57 +0000152 std::string& name,
153 TMessageType& messageType,
Mark Sleecfc01932006-09-01 22:18:16 +0000154 int32_t& seqid) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000155
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000156 virtual uint32_t readMessageEnd(shared_ptr<TTransport> in) const = 0;
157
158 virtual uint32_t readStructBegin(shared_ptr<TTransport> in,
159 std::string& name) const = 0;
160
161 virtual uint32_t readStructEnd(shared_ptr<TTransport> in) const = 0;
162
163 virtual uint32_t readFieldBegin(shared_ptr<TTransport> in,
164 std::string& name,
165 TType& fieldType,
166 int16_t& fieldId) const = 0;
167
168 virtual uint32_t readFieldEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000169
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000170 virtual uint32_t readMapBegin(shared_ptr<TTransport> in,
171 TType& keyType,
172 TType& valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000173 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000174
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000175 virtual uint32_t readMapEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000176
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000177 virtual uint32_t readListBegin(shared_ptr<TTransport> in,
178 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000179 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000180
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000181 virtual uint32_t readListEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000182
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000183 virtual uint32_t readSetBegin(shared_ptr<TTransport> in,
184 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000185 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000186
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000187 virtual uint32_t readSetEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000188
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000189 virtual uint32_t readBool(shared_ptr<TTransport> in,
190 bool& value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000191
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000192 virtual uint32_t readByte(shared_ptr<TTransport> in,
Mark Sleecfc01932006-09-01 22:18:16 +0000193 int8_t& byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000194
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000195 virtual uint32_t readI16(shared_ptr<TTransport> in,
196 int16_t& i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000197
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000198 virtual uint32_t readI32(shared_ptr<TTransport> in,
199 int32_t& i32) const = 0;
200
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000201 virtual uint32_t readI64(shared_ptr<TTransport> in,
202 int64_t& i64) const = 0;
203
Mark Sleec98d0502006-09-06 02:42:25 +0000204 virtual uint32_t readDouble(shared_ptr<TTransport> in,
205 double& dub) const = 0;
206
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000207 virtual uint32_t readString(shared_ptr<TTransport> in,
208 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000209
210 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000211 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000212 */
Marc Slemko16698852006-08-04 03:16:10 +0000213 uint32_t skip(shared_ptr<TTransport> in, TType type) const {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000214 switch (type) {
Mark Slee78f58e22006-09-02 04:17:07 +0000215 case T_BOOL:
216 {
217 bool boolv;
218 return readBool(in, boolv);
219 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000220 case T_BYTE:
221 {
Mark Slee78f58e22006-09-02 04:17:07 +0000222 int8_t bytev;
223 return readByte(in, bytev);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000224 }
Mark Sleecfc01932006-09-01 22:18:16 +0000225 case T_I16:
Mark Slee8d7e1f62006-06-07 06:48:56 +0000226 {
Mark Sleecfc01932006-09-01 22:18:16 +0000227 int16_t i16;
228 return readI16(in, i16);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000229 }
230 case T_I32:
231 {
232 int32_t i32;
233 return readI32(in, i32);
234 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000235 case T_I64:
236 {
237 int64_t i64;
238 return readI64(in, i64);
239 }
Mark Sleec98d0502006-09-06 02:42:25 +0000240 case T_DOUBLE:
241 {
242 double dub;
243 return readDouble(in, dub);
244 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000245 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;
Marc Slemkob09f5882006-08-23 22:03:34 +0000273 uint32_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;
Marc Slemkob09f5882006-08-23 22:03:34 +0000286 uint32_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;
Marc Slemkob09f5882006-08-23 22:03:34 +0000298 uint32_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 Sleef5f2be42006-09-05 21:05:31 +0000317#endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1