blob: 0007406da5d8c36c30edb4232d5e3e4147b94ab9 [file] [log] [blame]
Mark Sleee8540632006-05-30 09:24:40 +00001#ifndef T_PROTOCOL_H
2#define T_PROTOCOL_H
3
Mark Slee8d7e1f62006-06-07 06:48:56 +00004#include <netinet/in.h>
Mark Sleee8540632006-05-30 09:24:40 +00005#include <sys/types.h>
6#include <string>
7#include <map>
8
Mark Slee8d7e1f62006-06-07 06:48:56 +00009#include "transport/TTransport.h"
10
11#define ntohll(x) (((uint64_t)(ntohl((int)((x << 32) >> 32))) << 32) | (uint32_t)ntohl(((int)(x >> 32))))
12
13#define htonll(x) ntohll(x)
14
Mark Sleee8540632006-05-30 09:24:40 +000015/** Forward declaration for TProtocol */
16struct TBuf;
17
18/**
Mark Slee8d7e1f62006-06-07 06:48:56 +000019 * Enumerated definition of the types that the Thrift protocol supports.
20 * Take special note of the T_END type which is used specifically to mark
21 * the end of a sequence of fields.
22 */
23enum TType {
24 T_STOP = 1,
25 T_BYTE = 2,
26 T_U16 = 3,
27 T_I16 = 4,
28 T_U32 = 5,
29 T_I32 = 6,
30 T_U64 = 7,
31 T_I64 = 8,
32 T_STRING = 9,
33 T_STRUCT = 10,
34 T_MAP = 11,
35 T_SET = 12,
36 T_LIST = 13
37};
38
39/**
Mark Sleee8540632006-05-30 09:24:40 +000040 * Abstract class for a thrift protocol driver. These are all the methods that
41 * a protocol must implement. Essentially, there must be some way of reading
42 * and writing all the base types, plus a mechanism for writing out structs
43 * with indexed fields. Also notice that all methods are strictly const. This
44 * is by design. Protcol impelementations may NOT keep state, because the
45 * same TProtocol object may be used simultaneously by multiple threads. This
46 * theoretically introduces some limititations into the possible protocol
47 * formats, but with the benefit of performance, clarity, and simplicity.
48 *
49 * @author Mark Slee <mcslee@facebook.com>
50 */
51class TProtocol {
52 public:
53 virtual ~TProtocol() {}
54
55 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +000056 * Writing functions.
Mark Sleee8540632006-05-30 09:24:40 +000057 */
58
Mark Slee8d7e1f62006-06-07 06:48:56 +000059 virtual uint32_t writeStructBegin (TTransport* out,
60 const std::string& name) const = 0;
61
62 virtual uint32_t writeStructEnd (TTransport* out) const = 0;
63
64 virtual uint32_t writeFieldBegin (TTransport* out,
65 const std::string& name,
66 const TType fieldType,
67 const uint16_t fieldId) const = 0;
68
69 virtual uint32_t writeFieldEnd (TTransport* out) const = 0;
70
71 virtual uint32_t writeFieldStop (TTransport* out) const = 0;
72
73 virtual uint32_t writeMapBegin (TTransport* out,
74 const TType keyType,
75 const TType valType,
Mark Sleef3c322b2006-06-26 23:52:22 +000076 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000077
78 virtual uint32_t writeMapEnd (TTransport* out) const = 0;
79
80 virtual uint32_t writeListBegin (TTransport* out,
81 const TType elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +000082 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000083
84 virtual uint32_t writeListEnd (TTransport* out) const = 0;
85
86 virtual uint32_t writeSetBegin (TTransport* out,
87 const TType elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +000088 const int32_t size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +000089
90 virtual uint32_t writeSetEnd (TTransport* out) const = 0;
91
92 virtual uint32_t writeByte (TTransport* out,
93 const uint8_t byte) const = 0;
94
95 virtual uint32_t writeU32 (TTransport* out,
96 const uint32_t u32) const = 0;
97
98 virtual uint32_t writeI32 (TTransport* out,
99 const int32_t i32) const = 0;
100
101 virtual uint32_t writeU64 (TTransport* out,
102 const uint64_t u64) const = 0;
103
104 virtual uint32_t writeI64 (TTransport* out,
105 const int64_t i64) const = 0;
106
107 virtual uint32_t writeString (TTransport* out,
108 const std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000109
110 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000111 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000112 */
113
Mark Slee8d7e1f62006-06-07 06:48:56 +0000114 virtual uint32_t readStructBegin (TTransport* in,
115 std::string& name) const = 0;
116
117 virtual uint32_t readStructEnd (TTransport* in) const = 0;
118
119 virtual uint32_t readFieldBegin (TTransport* in,
120 std::string& name,
121 TType& fieldType,
122 uint16_t& fieldId) const = 0;
123
124 virtual uint32_t readFieldEnd (TTransport* in) const = 0;
125
126 virtual uint32_t readMapBegin (TTransport* in,
127 TType& keyType,
128 TType& valType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000129 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000130
131 virtual uint32_t readMapEnd (TTransport* in) const = 0;
132
133 virtual uint32_t readListBegin (TTransport* in,
134 TType& elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000135 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000136
137 virtual uint32_t readListEnd (TTransport* in) const = 0;
138
139 virtual uint32_t readSetBegin (TTransport* in,
140 TType& elemType,
Mark Sleef3c322b2006-06-26 23:52:22 +0000141 int32_t& size) const = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000142
143 virtual uint32_t readSetEnd (TTransport* in) const = 0;
144
145 virtual uint32_t readByte (TTransport* in,
146 uint8_t& byte) const = 0;
147
148 virtual uint32_t readU32 (TTransport* in,
149 uint32_t& u32) const = 0;
150
151 virtual uint32_t readI32 (TTransport* in,
152 int32_t& i32) const = 0;
153
154 virtual uint32_t readU64 (TTransport* in,
155 uint64_t& u64) const = 0;
156
157 virtual uint32_t readI64 (TTransport* in,
158 int64_t& i64) const = 0;
159
160 virtual uint32_t readString (TTransport* in,
161 std::string& str) const = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000162
163 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000164 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000165 */
Mark Slee8d7e1f62006-06-07 06:48:56 +0000166 uint32_t skip(TTransport* in, TType type) const {
167 switch (type) {
168 case T_BYTE:
169 {
170 uint8_t byte;
171 return readByte(in, byte);
172 }
173 case T_U32:
174 {
175 uint32_t u32;
176 return readU32(in, u32);
177 }
178 case T_I32:
179 {
180 int32_t i32;
181 return readI32(in, i32);
182 }
183 case T_U64:
184 {
185 uint64_t u64;
186 return readU64(in, u64);
187 }
188 case T_I64:
189 {
190 int64_t i64;
191 return readI64(in, i64);
192 }
193 case T_STRING:
194 {
195 std::string str;
196 return readString(in, str);
197 }
198 case T_STRUCT:
199 {
200 uint32_t result = 0;
201 std::string name;
202 uint16_t fid;
203 TType ftype;
204 result += readStructBegin(in, name);
205 while (true) {
206 result += readFieldBegin(in, name, ftype, fid);
207 if (ftype == T_STOP) {
208 break;
209 }
210 result += skip(in, ftype);
211 result += readFieldEnd(in);
212 }
213 result += readStructEnd(in);
214 return result;
215 }
216 case T_MAP:
217 {
218 uint32_t result = 0;
219 TType keyType;
220 TType valType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000221 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000222 result += readMapBegin(in, keyType, valType, size);
223 for (i = 0; i < size; i++) {
224 result += skip(in, keyType);
225 result += skip(in, valType);
226 }
227 result += readMapEnd(in);
228 return result;
229 }
230 case T_SET:
231 {
232 uint32_t result = 0;
233 TType elemType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000234 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000235 result += readSetBegin(in, elemType, size);
236 for (i = 0; i < size; i++) {
237 result += skip(in, elemType);
238 }
239 result += readSetEnd(in);
240 return result;
241 }
242 case T_LIST:
243 {
244 uint32_t result = 0;
245 TType elemType;
Mark Sleef3c322b2006-06-26 23:52:22 +0000246 int32_t i, size;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000247 result += readListBegin(in, elemType, size);
248 for (i = 0; i < size; i++) {
249 result += skip(in, elemType);
250 }
251 result += readListEnd(in);
252 return result;
253 }
254 default:
255 return 0;
256 }
257 }
Mark Sleee8540632006-05-30 09:24:40 +0000258
259 protected:
260 TProtocol() {}
261};
262
Mark Sleee8540632006-05-30 09:24:40 +0000263#endif