blob: 2ad5a57175e43de03f9ba6d525bf04f188ab3fb9 [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
Mark Slee4af6ed72006-10-25 19:02:49 +000085 virtual uint32_t writeMessageBegin(const std::string name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +000086 const TMessageType messageType,
Mark Slee4af6ed72006-10-25 19:02:49 +000087 const int32_t seqid) = 0;
Marc Slemko16698852006-08-04 03:16:10 +000088
Mark Slee4af6ed72006-10-25 19:02:49 +000089 virtual uint32_t writeMessageEnd() = 0;
Marc Slemko16698852006-08-04 03:16:10 +000090
91
Mark Slee4af6ed72006-10-25 19:02:49 +000092 virtual uint32_t writeStructBegin(const std::string& name) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +000093
Mark Slee4af6ed72006-10-25 19:02:49 +000094 virtual uint32_t writeStructEnd() = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +000095
Mark Slee4af6ed72006-10-25 19:02:49 +000096 virtual uint32_t writeFieldBegin(const std::string& name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +000097 const TType fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +000098 const int16_t fieldId) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000099
Mark Slee4af6ed72006-10-25 19:02:49 +0000100 virtual uint32_t writeFieldEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000101
Mark Slee4af6ed72006-10-25 19:02:49 +0000102 virtual uint32_t writeFieldStop() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000103
Mark Slee4af6ed72006-10-25 19:02:49 +0000104 virtual uint32_t writeMapBegin(const TType keyType,
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000105 const TType valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000106 const uint32_t size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000107
Mark Slee4af6ed72006-10-25 19:02:49 +0000108 virtual uint32_t writeMapEnd() = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000109
Mark Slee4af6ed72006-10-25 19:02:49 +0000110 virtual uint32_t writeListBegin(const TType elemType,
111 const uint32_t size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000112
Mark Slee4af6ed72006-10-25 19:02:49 +0000113 virtual uint32_t writeListEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000114
Mark Slee4af6ed72006-10-25 19:02:49 +0000115 virtual uint32_t writeSetBegin(const TType elemType,
116 const uint32_t size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000117
Mark Slee4af6ed72006-10-25 19:02:49 +0000118 virtual uint32_t writeSetEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000119
Mark Slee4af6ed72006-10-25 19:02:49 +0000120 virtual uint32_t writeBool(const bool value) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000121
Mark Slee4af6ed72006-10-25 19:02:49 +0000122 virtual uint32_t writeByte(const int8_t byte) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000123
Mark Slee4af6ed72006-10-25 19:02:49 +0000124 virtual uint32_t writeI16(const int16_t i16) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000125
Mark Slee4af6ed72006-10-25 19:02:49 +0000126 virtual uint32_t writeI32(const int32_t i32) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000127
Mark Slee4af6ed72006-10-25 19:02:49 +0000128 virtual uint32_t writeI64(const int64_t i64) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000129
Mark Slee4af6ed72006-10-25 19:02:49 +0000130 virtual uint32_t writeDouble(const double dub) = 0;
Mark Sleec98d0502006-09-06 02:42:25 +0000131
Mark Slee4af6ed72006-10-25 19:02:49 +0000132 virtual uint32_t writeString(const std::string& str) = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000133
134 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000135 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000136 */
137
Mark Slee4af6ed72006-10-25 19:02:49 +0000138 virtual uint32_t readMessageBegin(std::string& name,
Marc Slemko91f67482006-08-11 23:58:57 +0000139 TMessageType& messageType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000140 int32_t& seqid) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000141
Mark Slee4af6ed72006-10-25 19:02:49 +0000142 virtual uint32_t readMessageEnd() = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000143
Mark Slee4af6ed72006-10-25 19:02:49 +0000144 virtual uint32_t readStructBegin(std::string& name) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000145
Mark Slee4af6ed72006-10-25 19:02:49 +0000146 virtual uint32_t readStructEnd() = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000147
Mark Slee4af6ed72006-10-25 19:02:49 +0000148 virtual uint32_t readFieldBegin(std::string& name,
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000149 TType& fieldType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000150 int16_t& fieldId) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000151
Mark Slee4af6ed72006-10-25 19:02:49 +0000152 virtual uint32_t readFieldEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000153
Mark Slee4af6ed72006-10-25 19:02:49 +0000154 virtual uint32_t readMapBegin(TType& keyType,
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000155 TType& valType,
Mark Slee4af6ed72006-10-25 19:02:49 +0000156 uint32_t& size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000157
Mark Slee4af6ed72006-10-25 19:02:49 +0000158 virtual uint32_t readMapEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000159
Mark Slee4af6ed72006-10-25 19:02:49 +0000160 virtual uint32_t readListBegin(TType& elemType,
161 uint32_t& size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000162
Mark Slee4af6ed72006-10-25 19:02:49 +0000163 virtual uint32_t readListEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000164
Mark Slee4af6ed72006-10-25 19:02:49 +0000165 virtual uint32_t readSetBegin(TType& elemType,
166 uint32_t& size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000167
Mark Slee4af6ed72006-10-25 19:02:49 +0000168 virtual uint32_t readSetEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000169
Mark Slee4af6ed72006-10-25 19:02:49 +0000170 virtual uint32_t readBool(bool& value) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000171
Mark Slee4af6ed72006-10-25 19:02:49 +0000172 virtual uint32_t readByte(int8_t& byte) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000173
Mark Slee4af6ed72006-10-25 19:02:49 +0000174 virtual uint32_t readI16(int16_t& i16) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000175
Mark Slee4af6ed72006-10-25 19:02:49 +0000176 virtual uint32_t readI32(int32_t& i32) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000177
Mark Slee4af6ed72006-10-25 19:02:49 +0000178 virtual uint32_t readI64(int64_t& i64) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000179
Mark Slee4af6ed72006-10-25 19:02:49 +0000180 virtual uint32_t readDouble(double& dub) = 0;
Mark Sleec98d0502006-09-06 02:42:25 +0000181
Mark Slee4af6ed72006-10-25 19:02:49 +0000182 virtual uint32_t readString(std::string& str) = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000183
184 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000185 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000186 */
Mark Slee4af6ed72006-10-25 19:02:49 +0000187 uint32_t skip(TType type) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000188 switch (type) {
Mark Slee78f58e22006-09-02 04:17:07 +0000189 case T_BOOL:
190 {
191 bool boolv;
Mark Slee4af6ed72006-10-25 19:02:49 +0000192 return readBool(boolv);
Mark Slee78f58e22006-09-02 04:17:07 +0000193 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000194 case T_BYTE:
195 {
Mark Slee78f58e22006-09-02 04:17:07 +0000196 int8_t bytev;
Mark Slee4af6ed72006-10-25 19:02:49 +0000197 return readByte(bytev);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000198 }
Mark Sleecfc01932006-09-01 22:18:16 +0000199 case T_I16:
Mark Slee8d7e1f62006-06-07 06:48:56 +0000200 {
Mark Sleecfc01932006-09-01 22:18:16 +0000201 int16_t i16;
Mark Slee4af6ed72006-10-25 19:02:49 +0000202 return readI16(i16);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000203 }
204 case T_I32:
205 {
206 int32_t i32;
Mark Slee4af6ed72006-10-25 19:02:49 +0000207 return readI32(i32);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000208 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000209 case T_I64:
210 {
211 int64_t i64;
Mark Slee4af6ed72006-10-25 19:02:49 +0000212 return readI64(i64);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000213 }
Mark Sleec98d0502006-09-06 02:42:25 +0000214 case T_DOUBLE:
215 {
216 double dub;
Mark Slee4af6ed72006-10-25 19:02:49 +0000217 return readDouble(dub);
Mark Sleec98d0502006-09-06 02:42:25 +0000218 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000219 case T_STRING:
220 {
221 std::string str;
Mark Slee4af6ed72006-10-25 19:02:49 +0000222 return readString(str);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000223 }
224 case T_STRUCT:
225 {
226 uint32_t result = 0;
227 std::string name;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000228 int16_t fid;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000229 TType ftype;
Mark Slee4af6ed72006-10-25 19:02:49 +0000230 result += readStructBegin(name);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000231 while (true) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000232 result += readFieldBegin(name, ftype, fid);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000233 if (ftype == T_STOP) {
234 break;
235 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000236 result += skip(ftype);
237 result += readFieldEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000238 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000239 result += readStructEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000240 return result;
241 }
242 case T_MAP:
243 {
244 uint32_t result = 0;
245 TType keyType;
246 TType valType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000247 uint32_t i, size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000248 result += readMapBegin(keyType, valType, size);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000249 for (i = 0; i < size; i++) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000250 result += skip(keyType);
251 result += skip(valType);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000252 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000253 result += readMapEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000254 return result;
255 }
256 case T_SET:
257 {
258 uint32_t result = 0;
259 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000260 uint32_t i, size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000261 result += readSetBegin(elemType, size);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000262 for (i = 0; i < size; i++) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000263 result += skip(elemType);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000264 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000265 result += readSetEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000266 return result;
267 }
268 case T_LIST:
269 {
270 uint32_t result = 0;
271 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000272 uint32_t i, size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000273 result += readListBegin(elemType, size);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000274 for (i = 0; i < size; i++) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000275 result += skip(elemType);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000276 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000277 result += readListEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000278 return result;
279 }
280 default:
281 return 0;
282 }
283 }
Mark Sleee8540632006-05-30 09:24:40 +0000284
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000285 inline shared_ptr<TTransport> getTransport() {
Mark Slee43b6c632007-02-07 00:54:17 +0000286 return ptrans_;
Mark Slee4af6ed72006-10-25 19:02:49 +0000287 }
288
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000289 // TODO: remove these two calls, they are for backwards
290 // compatibility
291 inline shared_ptr<TTransport> getInputTransport() {
Mark Slee43b6c632007-02-07 00:54:17 +0000292 return ptrans_;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000293 }
294 inline shared_ptr<TTransport> getOutputTransport() {
Mark Slee43b6c632007-02-07 00:54:17 +0000295 return ptrans_;
Mark Slee4af6ed72006-10-25 19:02:49 +0000296 }
297
Mark Sleee8540632006-05-30 09:24:40 +0000298 protected:
Mark Slee43b6c632007-02-07 00:54:17 +0000299 TProtocol(shared_ptr<TTransport> ptrans):
300 ptrans_(ptrans) {
301 trans_ = ptrans.get();
302 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000303
Mark Slee43b6c632007-02-07 00:54:17 +0000304 shared_ptr<TTransport> ptrans_;
305 TTransport* trans_;
Mark Slee4af6ed72006-10-25 19:02:49 +0000306
307 private:
Mark Sleee8540632006-05-30 09:24:40 +0000308 TProtocol() {}
309};
310
Mark Slee4af6ed72006-10-25 19:02:49 +0000311/**
312 * Constructs input and output protocol objects given transports.
313 */
314class TProtocolFactory {
315 public:
316 TProtocolFactory() {}
317
318 virtual ~TProtocolFactory() {}
319
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000320 virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) = 0;
Mark Slee4af6ed72006-10-25 19:02:49 +0000321};
322
Marc Slemko6f038a72006-08-03 18:58:09 +0000323}}} // facebook::thrift::protocol
324
Mark Sleef5f2be42006-09-05 21:05:31 +0000325#endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1