blob: 65d6f3c23c18e1997281308bcc8dfe2090d97436 [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 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 Sleef5f2be42006-09-05 21:05:31 +000023// Forward declaration for TProtocol
Mark Sleee8540632006-05-30 09:24:40 +000024struct 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,
Mark Sleecfc01932006-09-01 22:18:16 +000036 T_I08 = 3,
Marc Slemko5b126d62006-08-11 23:03:42 +000037 T_I16 = 6,
Marc Slemko5b126d62006-08-11 23:03:42 +000038 T_I32 = 8,
39 T_U64 = 9,
40 T_I64 = 10,
41 T_STRING = 11,
Marc Slemkod97eb612006-08-24 23:37:36 +000042 T_UTF7 = 11,
43 T_STRUCT = 12,
44 T_MAP = 13,
45 T_SET = 14,
46 T_LIST = 15,
47 T_UTF8 = 16,
48 T_UTF16 = 17
Mark Slee8d7e1f62006-06-07 06:48:56 +000049};
50
51/**
Mark Sleef5f2be42006-09-05 21:05:31 +000052 * Enumerated definition of the message types that the Thrift protocol
53 * supports.
Marc Slemko16698852006-08-04 03:16:10 +000054 */
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,
Marc Slemko91f67482006-08-11 23:58:57 +000081 const std::string name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +000082 const TMessageType messageType,
Mark Sleecfc01932006-09-01 22:18:16 +000083 const int32_t seqid) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000084
Marc Slemko0b4ffa92006-08-11 02:49:29 +000085 virtual uint32_t writeMessageEnd(shared_ptr<TTransport> out) const = 0;
Marc Slemko16698852006-08-04 03:16:10 +000086
87
Marc Slemko0b4ffa92006-08-11 02:49:29 +000088 virtual uint32_t writeStructBegin(shared_ptr<TTransport> out,
89 const std::string& name) const = 0;
90
91 virtual uint32_t writeStructEnd(shared_ptr<TTransport> out) const = 0;
92
93 virtual uint32_t writeFieldBegin(shared_ptr<TTransport> out,
94 const std::string& name,
95 const TType fieldType,
96 const int16_t fieldId) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000097
Marc Slemko0b4ffa92006-08-11 02:49:29 +000098 virtual uint32_t writeFieldEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000099
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000100 virtual uint32_t writeFieldStop(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 writeMapBegin(shared_ptr<TTransport> out,
103 const TType keyType,
104 const TType valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000105 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000106
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000107 virtual uint32_t writeMapEnd(shared_ptr<TTransport> out) const = 0;
108
109 virtual uint32_t writeListBegin(shared_ptr<TTransport> out,
110 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000111 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000112
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000113 virtual uint32_t writeListEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000114
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000115 virtual uint32_t writeSetBegin(shared_ptr<TTransport> out,
116 const TType elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000117 const uint32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000118
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000119 virtual uint32_t writeSetEnd(shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000120
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000121 virtual uint32_t writeBool(shared_ptr<TTransport> out,
122 const bool value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000123
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000124 virtual uint32_t writeByte(shared_ptr<TTransport> out,
Mark Sleecfc01932006-09-01 22:18:16 +0000125 const int8_t byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000126
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000127 virtual uint32_t writeI16(shared_ptr<TTransport> out,
128 const int16_t i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000129
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000130 virtual uint32_t writeI32(shared_ptr<TTransport> out,
131 const int32_t i32) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000132
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000133 virtual uint32_t writeI64(shared_ptr<TTransport> out,
134 const int64_t i64) const = 0;
135
136 virtual uint32_t writeString(shared_ptr<TTransport> out,
137 const std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000138
139 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000140 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000141 */
142
Marc Slemko5b126d62006-08-11 23:03:42 +0000143 virtual uint32_t readMessageBegin(shared_ptr<TTransport> in,
Marc Slemko91f67482006-08-11 23:58:57 +0000144 std::string& name,
145 TMessageType& messageType,
Mark Sleecfc01932006-09-01 22:18:16 +0000146 int32_t& seqid) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000147
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000148 virtual uint32_t readMessageEnd(shared_ptr<TTransport> in) const = 0;
149
150 virtual uint32_t readStructBegin(shared_ptr<TTransport> in,
151 std::string& name) const = 0;
152
153 virtual uint32_t readStructEnd(shared_ptr<TTransport> in) const = 0;
154
155 virtual uint32_t readFieldBegin(shared_ptr<TTransport> in,
156 std::string& name,
157 TType& fieldType,
158 int16_t& fieldId) const = 0;
159
160 virtual uint32_t readFieldEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000161
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000162 virtual uint32_t readMapBegin(shared_ptr<TTransport> in,
163 TType& keyType,
164 TType& valType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000165 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000166
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000167 virtual uint32_t readMapEnd(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 readListBegin(shared_ptr<TTransport> in,
170 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000171 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000172
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000173 virtual uint32_t readListEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000174
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000175 virtual uint32_t readSetBegin(shared_ptr<TTransport> in,
176 TType& elemType,
Marc Slemkob09f5882006-08-23 22:03:34 +0000177 uint32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000178
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000179 virtual uint32_t readSetEnd(shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000180
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000181 virtual uint32_t readBool(shared_ptr<TTransport> in,
182 bool& value) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000183
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000184 virtual uint32_t readByte(shared_ptr<TTransport> in,
Mark Sleecfc01932006-09-01 22:18:16 +0000185 int8_t& byte) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000186
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000187 virtual uint32_t readI16(shared_ptr<TTransport> in,
188 int16_t& i16) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000189
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000190 virtual uint32_t readI32(shared_ptr<TTransport> in,
191 int32_t& i32) const = 0;
192
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000193 virtual uint32_t readI64(shared_ptr<TTransport> in,
194 int64_t& i64) const = 0;
195
196 virtual uint32_t readString(shared_ptr<TTransport> in,
197 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000198
199 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000200 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000201 */
Marc Slemko16698852006-08-04 03:16:10 +0000202 uint32_t skip(shared_ptr<TTransport> in, TType type) const {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000203 switch (type) {
Mark Slee78f58e22006-09-02 04:17:07 +0000204 case T_BOOL:
205 {
206 bool boolv;
207 return readBool(in, boolv);
208 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000209 case T_BYTE:
210 {
Mark Slee78f58e22006-09-02 04:17:07 +0000211 int8_t bytev;
212 return readByte(in, bytev);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000213 }
Mark Sleecfc01932006-09-01 22:18:16 +0000214 case T_I16:
Mark Slee8d7e1f62006-06-07 06:48:56 +0000215 {
Mark Sleecfc01932006-09-01 22:18:16 +0000216 int16_t i16;
217 return readI16(in, i16);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000218 }
219 case T_I32:
220 {
221 int32_t i32;
222 return readI32(in, i32);
223 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000224 case T_I64:
225 {
226 int64_t i64;
227 return readI64(in, i64);
228 }
229 case T_STRING:
230 {
231 std::string str;
232 return readString(in, str);
233 }
234 case T_STRUCT:
235 {
236 uint32_t result = 0;
237 std::string name;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000238 int16_t fid;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000239 TType ftype;
240 result += readStructBegin(in, name);
241 while (true) {
242 result += readFieldBegin(in, name, ftype, fid);
243 if (ftype == T_STOP) {
244 break;
245 }
246 result += skip(in, ftype);
247 result += readFieldEnd(in);
248 }
249 result += readStructEnd(in);
250 return result;
251 }
252 case T_MAP:
253 {
254 uint32_t result = 0;
255 TType keyType;
256 TType valType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000257 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000258 result += readMapBegin(in, keyType, valType, size);
259 for (i = 0; i < size; i++) {
260 result += skip(in, keyType);
261 result += skip(in, valType);
262 }
263 result += readMapEnd(in);
264 return result;
265 }
266 case T_SET:
267 {
268 uint32_t result = 0;
269 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000270 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000271 result += readSetBegin(in, elemType, size);
272 for (i = 0; i < size; i++) {
273 result += skip(in, elemType);
274 }
275 result += readSetEnd(in);
276 return result;
277 }
278 case T_LIST:
279 {
280 uint32_t result = 0;
281 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000282 uint32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000283 result += readListBegin(in, elemType, size);
284 for (i = 0; i < size; i++) {
285 result += skip(in, elemType);
286 }
287 result += readListEnd(in);
288 return result;
289 }
290 default:
291 return 0;
292 }
293 }
Mark Sleee8540632006-05-30 09:24:40 +0000294
295 protected:
296 TProtocol() {}
297};
298
Marc Slemko6f038a72006-08-03 18:58:09 +0000299}}} // facebook::thrift::protocol
300
Mark Sleef5f2be42006-09-05 21:05:31 +0000301#endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1