blob: aa67e9c7ba581eb02075fcc68dedca77aed39463 [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,
33 T_BOOL = 1,
Mark Slee8d7e1f62006-06-07 06:48:56 +000034 T_BYTE = 2,
Marc Slemkod42a2c22006-08-10 03:30:18 +000035 T_U08 = 2,
Mark Slee8d7e1f62006-06-07 06:48:56 +000036 T_U16 = 3,
37 T_I16 = 4,
38 T_U32 = 5,
39 T_I32 = 6,
40 T_U64 = 7,
41 T_I64 = 8,
42 T_STRING = 9,
Marc Slemkod42a2c22006-08-10 03:30:18 +000043 T_UTF7 = 9,
Mark Slee8d7e1f62006-06-07 06:48:56 +000044 T_STRUCT = 10,
45 T_MAP = 11,
46 T_SET = 12,
Marc Slemkod42a2c22006-08-10 03:30:18 +000047 T_LIST = 13,
48 T_UTF8 = 14,
49 T_UTF16 = 15
Mark Slee8d7e1f62006-06-07 06:48:56 +000050};
51
52/**
Marc Slemko16698852006-08-04 03:16:10 +000053 * Enumerated definition of the message types that the Thrift protocol supports.
54 */
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 Slemko16698852006-08-04 03:16:10 +000080 virtual uint32_t writeMessageBegin (shared_ptr<TTransport> out,
81 const TMessageType messageType,
82 const uint32_t seqid) const = 0;
83
84 virtual uint32_t writeMessageEnd (shared_ptr<TTransport> out) const = 0;
85
86
87 virtual uint32_t writeStructBegin (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +000088 const std::string& name) const = 0;
89
Marc Slemko16698852006-08-04 03:16:10 +000090 virtual uint32_t writeStructEnd (shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000091
Marc Slemko16698852006-08-04 03:16:10 +000092 virtual uint32_t writeFieldBegin (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +000093 const std::string& name,
94 const TType fieldType,
95 const uint16_t fieldId) const = 0;
96
Marc Slemko16698852006-08-04 03:16:10 +000097 virtual uint32_t writeFieldEnd (shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000098
Marc Slemko16698852006-08-04 03:16:10 +000099 virtual uint32_t writeFieldStop (shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000100
Marc Slemko16698852006-08-04 03:16:10 +0000101 virtual uint32_t writeMapBegin (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000102 const TType keyType,
103 const TType valType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000104 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000105
Marc Slemko16698852006-08-04 03:16:10 +0000106 virtual uint32_t writeMapEnd (shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000107
Marc Slemko16698852006-08-04 03:16:10 +0000108 virtual uint32_t writeListBegin (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000109 const TType elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000110 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000111
Marc Slemko16698852006-08-04 03:16:10 +0000112 virtual uint32_t writeListEnd (shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000113
Marc Slemko16698852006-08-04 03:16:10 +0000114 virtual uint32_t writeSetBegin (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000115 const TType elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000116 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000117
Marc Slemko16698852006-08-04 03:16:10 +0000118 virtual uint32_t writeSetEnd (shared_ptr<TTransport> out) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000119
Marc Slemko16698852006-08-04 03:16:10 +0000120 virtual uint32_t writeByte (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000121 const uint8_t byte) const = 0;
122
Marc Slemko16698852006-08-04 03:16:10 +0000123 virtual uint32_t writeU32 (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000124 const uint32_t u32) const = 0;
125
Marc Slemko16698852006-08-04 03:16:10 +0000126 virtual uint32_t writeI32 (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000127 const int32_t i32) const = 0;
128
Marc Slemko16698852006-08-04 03:16:10 +0000129 virtual uint32_t writeU64 (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000130 const uint64_t u64) const = 0;
131
Marc Slemko16698852006-08-04 03:16:10 +0000132 virtual uint32_t writeI64 (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000133 const int64_t i64) const = 0;
134
Marc Slemko16698852006-08-04 03:16:10 +0000135 virtual uint32_t writeString (shared_ptr<TTransport> out,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000136 const std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000137
138 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000139 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000140 */
141
Marc Slemko16698852006-08-04 03:16:10 +0000142 virtual uint32_t readMessasgeBegin (shared_ptr<TTransport> in,
143 TMessageType& messageType,
144 uint32_t& seqid) const = 0;
145
146 virtual uint32_t readMessageEnd (shared_ptr<TTransport> in) const = 0;
147
148 virtual uint32_t readStructBegin (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000149 std::string& name) const = 0;
150
Marc Slemko16698852006-08-04 03:16:10 +0000151 virtual uint32_t readStructEnd (shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000152
Marc Slemko16698852006-08-04 03:16:10 +0000153 virtual uint32_t readFieldBegin (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000154 std::string& name,
155 TType& fieldType,
156 uint16_t& fieldId) const = 0;
157
Marc Slemko16698852006-08-04 03:16:10 +0000158 virtual uint32_t readFieldEnd (shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000159
Marc Slemko16698852006-08-04 03:16:10 +0000160 virtual uint32_t readMapBegin (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000161 TType& keyType,
162 TType& valType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000163 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000164
Marc Slemko16698852006-08-04 03:16:10 +0000165 virtual uint32_t readMapEnd (shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000166
Marc Slemko16698852006-08-04 03:16:10 +0000167 virtual uint32_t readListBegin (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000168 TType& elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000169 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000170
Marc Slemko16698852006-08-04 03:16:10 +0000171 virtual uint32_t readListEnd (shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000172
Marc Slemko16698852006-08-04 03:16:10 +0000173 virtual uint32_t readSetBegin (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000174 TType& elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000175 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000176
Marc Slemko16698852006-08-04 03:16:10 +0000177 virtual uint32_t readSetEnd (shared_ptr<TTransport> in) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000178
Marc Slemko16698852006-08-04 03:16:10 +0000179 virtual uint32_t readByte (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000180 uint8_t& byte) const = 0;
181
Marc Slemko16698852006-08-04 03:16:10 +0000182 virtual uint32_t readU32 (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000183 uint32_t& u32) const = 0;
184
Marc Slemko16698852006-08-04 03:16:10 +0000185 virtual uint32_t readI32 (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000186 int32_t& i32) const = 0;
187
Marc Slemko16698852006-08-04 03:16:10 +0000188 virtual uint32_t readU64 (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000189 uint64_t& u64) const = 0;
190
Marc Slemko16698852006-08-04 03:16:10 +0000191 virtual uint32_t readI64 (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000192 int64_t& i64) const = 0;
193
Marc Slemko16698852006-08-04 03:16:10 +0000194 virtual uint32_t readString (shared_ptr<TTransport> in,
Mark Slee8d7e1f62006-06-07 06:48:56 +0000195 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000196
197 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000198 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000199 */
Marc Slemko16698852006-08-04 03:16:10 +0000200 uint32_t skip(shared_ptr<TTransport> in, TType type) const {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000201 switch (type) {
202 case T_BYTE:
203 {
204 uint8_t byte;
205 return readByte(in, byte);
206 }
207 case T_U32:
208 {
209 uint32_t u32;
210 return readU32(in, u32);
211 }
212 case T_I32:
213 {
214 int32_t i32;
215 return readI32(in, i32);
216 }
217 case T_U64:
218 {
219 uint64_t u64;
220 return readU64(in, u64);
221 }
222 case T_I64:
223 {
224 int64_t i64;
225 return readI64(in, i64);
226 }
227 case T_STRING:
228 {
229 std::string str;
230 return readString(in, str);
231 }
232 case T_STRUCT:
233 {
234 uint32_t result = 0;
235 std::string name;
236 uint16_t fid;
237 TType ftype;
238 result += readStructBegin(in, name);
239 while (true) {
240 result += readFieldBegin(in, name, ftype, fid);
241 if (ftype == T_STOP) {
242 break;
243 }
244 result += skip(in, ftype);
245 result += readFieldEnd(in);
246 }
247 result += readStructEnd(in);
248 return result;
249 }
250 case T_MAP:
251 {
252 uint32_t result = 0;
253 TType keyType;
254 TType valType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000255 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000256 result += readMapBegin(in, keyType, valType, size);
257 for (i = 0; i < size; i++) {
258 result += skip(in, keyType);
259 result += skip(in, valType);
260 }
261 result += readMapEnd(in);
262 return result;
263 }
264 case T_SET:
265 {
266 uint32_t result = 0;
267 TType elemType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000268 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000269 result += readSetBegin(in, elemType, size);
270 for (i = 0; i < size; i++) {
271 result += skip(in, elemType);
272 }
273 result += readSetEnd(in);
274 return result;
275 }
276 case T_LIST:
277 {
278 uint32_t result = 0;
279 TType elemType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000280 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000281 result += readListBegin(in, elemType, size);
282 for (i = 0; i < size; i++) {
283 result += skip(in, elemType);
284 }
285 result += readListEnd(in);
286 return result;
287 }
288 default:
289 return 0;
290 }
291 }
Mark Sleee8540632006-05-30 09:24:40 +0000292
293 protected:
294 TProtocol() {}
295};
296
Marc Slemko6f038a72006-08-03 18:58:09 +0000297}}} // facebook::thrift::protocol
298
Mark Sleee8540632006-05-30 09:24:40 +0000299#endif
Marc Slemko6f038a72006-08-03 18:58:09 +0000300