blob: 40258277d01b0bbbc1d74cc3400c56711e507d4a [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Mark Sleef5f2be42006-09-05 21:05:31 +000020#ifndef _THRIFT_PROTOCOL_TPROTOCOL_H_
21#define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1
Mark Sleee8540632006-05-30 09:24:40 +000022
Marc Slemko16698852006-08-04 03:16:10 +000023#include <transport/TTransport.h>
Mark Sleef9831082007-02-20 20:59:21 +000024#include <protocol/TProtocolException.h>
Marc Slemko16698852006-08-04 03:16:10 +000025
26#include <boost/shared_ptr.hpp>
David Reisse4d4ea02009-04-02 21:37:17 +000027#include <boost/static_assert.hpp>
Marc Slemko16698852006-08-04 03:16:10 +000028
Mark Slee8d7e1f62006-06-07 06:48:56 +000029#include <netinet/in.h>
Mark Sleee8540632006-05-30 09:24:40 +000030#include <sys/types.h>
31#include <string>
32#include <map>
33
David Reisse4d4ea02009-04-02 21:37:17 +000034
35// Use this to get around strict aliasing rules.
36// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
37// The most obvious implementation is to just cast a pointer,
38// but that doesn't work.
39// For a pretty in-depth explanation of the problem, see
40// http://www.cellperformance.com/mike_acton/2006/06/ (...)
41// understanding_strict_aliasing.html
42template <typename To, typename From>
43static inline To bitwise_cast(From from) {
44 BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
45
46 // BAD!!! These are all broken with -O2.
47 //return *reinterpret_cast<To*>(&from); // BAD!!!
48 //return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
49 //return *(To*)(void*)&from; // BAD!!!
50
51 // Super clean and paritally blessed by section 3.9 of the standard.
52 //unsigned char c[sizeof(from)];
53 //memcpy(c, &from, sizeof(from));
54 //To to;
55 //memcpy(&to, c, sizeof(c));
56 //return to;
57
58 // Slightly more questionable.
59 // Same code emitted by GCC.
60 //To to;
61 //memcpy(&to, &from, sizeof(from));
62 //return to;
63
64 // Technically undefined, but almost universally supported,
65 // and the most efficient implementation.
66 union {
67 From f;
68 To t;
69 } u;
70 u.f = from;
71 return u.t;
72}
73
74
T Jake Lucianib5e62212009-01-31 22:36:20 +000075namespace apache { namespace thrift { namespace protocol {
Marc Slemko6f038a72006-08-03 18:58:09 +000076
T Jake Lucianib5e62212009-01-31 22:36:20 +000077using apache::thrift::transport::TTransport;
Marc Slemko6f038a72006-08-03 18:58:09 +000078
Mark Slee4f261c52007-04-13 00:33:24 +000079#ifdef HAVE_ENDIAN_H
80#include <endian.h>
81#endif
82
Mark Slee1d2ead32007-06-09 01:23:04 +000083#ifndef __BYTE_ORDER
84# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
85# define __BYTE_ORDER BYTE_ORDER
86# define __LITTLE_ENDIAN LITTLE_ENDIAN
87# define __BIG_ENDIAN BIG_ENDIAN
88# else
89# error "Cannot determine endianness"
90# endif
91#endif
92
Mark Sleedc8a2a22006-09-19 22:20:18 +000093#if __BYTE_ORDER == __BIG_ENDIAN
David Reisse4d4ea02009-04-02 21:37:17 +000094# define ntohll(n) (n)
95# define htonll(n) (n)
96# if defined(__GNUC__) && defined(__GLIBC__)
97# include <byteswap.h>
98# define htolell(n) bswap_64(n)
99# define letohll(n) bswap_64(n)
100# else /* GNUC & GLIBC */
101# define bswap_64(n) \
102 ( (((n) & 0xff00000000000000ull) >> 56) \
103 | (((n) & 0x00ff000000000000ull) >> 40) \
104 | (((n) & 0x0000ff0000000000ull) >> 24) \
105 | (((n) & 0x000000ff00000000ull) >> 8) \
106 | (((n) & 0x00000000ff000000ull) << 8) \
107 | (((n) & 0x0000000000ff0000ull) << 24) \
108 | (((n) & 0x000000000000ff00ull) << 40) \
109 | (((n) & 0x00000000000000ffull) << 56) )
110# define ntolell(n) bswap_64(n)
111# define letonll(n) bswap_64(n)
112# endif /* GNUC & GLIBC */
Mark Slee4f261c52007-04-13 00:33:24 +0000113#elif __BYTE_ORDER == __LITTLE_ENDIAN
David Reisse4d4ea02009-04-02 21:37:17 +0000114# define htolell(n) (n)
115# define letohll(n) (n)
Mark Slee4f261c52007-04-13 00:33:24 +0000116# if defined(__GNUC__) && defined(__GLIBC__)
117# include <byteswap.h>
118# define ntohll(n) bswap_64(n)
119# define htonll(n) bswap_64(n)
120# else /* GNUC & GLIBC */
121# define ntohll(n) ( (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32) )
122# define htonll(n) ( (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32) )
123# endif /* GNUC & GLIBC */
124#else /* __BYTE_ORDER */
125# error "Can't define htonll or ntohll!"
Mark Sleedc8a2a22006-09-19 22:20:18 +0000126#endif
Mark Slee8d7e1f62006-06-07 06:48:56 +0000127
Mark Sleee8540632006-05-30 09:24:40 +0000128/**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000129 * Enumerated definition of the types that the Thrift protocol supports.
130 * Take special note of the T_END type which is used specifically to mark
131 * the end of a sequence of fields.
132 */
133enum TType {
Marc Slemkod42a2c22006-08-10 03:30:18 +0000134 T_STOP = 0,
Marc Slemko5b126d62006-08-11 23:03:42 +0000135 T_VOID = 1,
136 T_BOOL = 2,
137 T_BYTE = 3,
Mark Sleecfc01932006-09-01 22:18:16 +0000138 T_I08 = 3,
Marc Slemko5b126d62006-08-11 23:03:42 +0000139 T_I16 = 6,
Marc Slemko5b126d62006-08-11 23:03:42 +0000140 T_I32 = 8,
141 T_U64 = 9,
142 T_I64 = 10,
Mark Sleec98d0502006-09-06 02:42:25 +0000143 T_DOUBLE = 4,
Marc Slemko5b126d62006-08-11 23:03:42 +0000144 T_STRING = 11,
Marc Slemkod97eb612006-08-24 23:37:36 +0000145 T_UTF7 = 11,
146 T_STRUCT = 12,
147 T_MAP = 13,
148 T_SET = 14,
149 T_LIST = 15,
150 T_UTF8 = 16,
151 T_UTF16 = 17
Mark Slee8d7e1f62006-06-07 06:48:56 +0000152};
153
154/**
Mark Sleef5f2be42006-09-05 21:05:31 +0000155 * Enumerated definition of the message types that the Thrift protocol
156 * supports.
Marc Slemko16698852006-08-04 03:16:10 +0000157 */
158enum TMessageType {
159 T_CALL = 1,
Mark Sleef9831082007-02-20 20:59:21 +0000160 T_REPLY = 2,
David Reissdeda1412009-04-02 19:22:31 +0000161 T_EXCEPTION = 3,
162 T_ONEWAY = 4
Marc Slemko16698852006-08-04 03:16:10 +0000163};
164
165/**
Mark Sleee8540632006-05-30 09:24:40 +0000166 * Abstract class for a thrift protocol driver. These are all the methods that
167 * a protocol must implement. Essentially, there must be some way of reading
168 * and writing all the base types, plus a mechanism for writing out structs
Mark Slee5d06fea2007-03-05 22:18:18 +0000169 * with indexed fields.
170 *
171 * TProtocol objects should not be shared across multiple encoding contexts,
172 * as they may need to maintain internal state in some protocols (i.e. XML).
173 * Note that is is acceptable for the TProtocol module to do its own internal
174 * buffered reads/writes to the underlying TTransport where appropriate (i.e.
175 * when parsing an input XML stream, reading should be batched rather than
176 * looking ahead character by character for a close tag).
Mark Sleee8540632006-05-30 09:24:40 +0000177 *
Mark Sleee8540632006-05-30 09:24:40 +0000178 */
179class TProtocol {
180 public:
181 virtual ~TProtocol() {}
182
183 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000184 * Writing functions.
Mark Sleee8540632006-05-30 09:24:40 +0000185 */
186
Mark Slee82a6c0f2007-04-04 21:08:21 +0000187 virtual uint32_t writeMessageBegin(const std::string& name,
188 const TMessageType messageType,
189 const int32_t seqid) = 0;
Marc Slemko16698852006-08-04 03:16:10 +0000190
Mark Slee4af6ed72006-10-25 19:02:49 +0000191 virtual uint32_t writeMessageEnd() = 0;
Marc Slemko16698852006-08-04 03:16:10 +0000192
193
David Reiss64120002008-04-29 23:12:24 +0000194 virtual uint32_t writeStructBegin(const char* name) = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000195
Mark Slee4af6ed72006-10-25 19:02:49 +0000196 virtual uint32_t writeStructEnd() = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000197
David Reiss64120002008-04-29 23:12:24 +0000198 virtual uint32_t writeFieldBegin(const char* name,
David Reiss96d23882007-07-26 21:10:32 +0000199 const TType fieldType,
200 const int16_t fieldId) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000201
Mark Slee4af6ed72006-10-25 19:02:49 +0000202 virtual uint32_t writeFieldEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000203
Mark Slee4af6ed72006-10-25 19:02:49 +0000204 virtual uint32_t writeFieldStop() = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000205
Mark Slee4af6ed72006-10-25 19:02:49 +0000206 virtual uint32_t writeMapBegin(const TType keyType,
David Reiss96d23882007-07-26 21:10:32 +0000207 const TType valType,
208 const uint32_t size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000209
Mark Slee4af6ed72006-10-25 19:02:49 +0000210 virtual uint32_t writeMapEnd() = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000211
Mark Slee4af6ed72006-10-25 19:02:49 +0000212 virtual uint32_t writeListBegin(const TType elemType,
David Reiss96d23882007-07-26 21:10:32 +0000213 const uint32_t size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000214
Mark Slee4af6ed72006-10-25 19:02:49 +0000215 virtual uint32_t writeListEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000216
Mark Slee4af6ed72006-10-25 19:02:49 +0000217 virtual uint32_t writeSetBegin(const TType elemType,
David Reiss96d23882007-07-26 21:10:32 +0000218 const uint32_t size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000219
Mark Slee4af6ed72006-10-25 19:02:49 +0000220 virtual uint32_t writeSetEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000221
Mark Slee4af6ed72006-10-25 19:02:49 +0000222 virtual uint32_t writeBool(const bool value) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000223
Mark Slee4af6ed72006-10-25 19:02:49 +0000224 virtual uint32_t writeByte(const int8_t byte) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000225
Mark Slee4af6ed72006-10-25 19:02:49 +0000226 virtual uint32_t writeI16(const int16_t i16) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000227
Mark Slee4af6ed72006-10-25 19:02:49 +0000228 virtual uint32_t writeI32(const int32_t i32) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000229
Mark Slee4af6ed72006-10-25 19:02:49 +0000230 virtual uint32_t writeI64(const int64_t i64) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000231
Mark Slee4af6ed72006-10-25 19:02:49 +0000232 virtual uint32_t writeDouble(const double dub) = 0;
Mark Sleec98d0502006-09-06 02:42:25 +0000233
Mark Slee4af6ed72006-10-25 19:02:49 +0000234 virtual uint32_t writeString(const std::string& str) = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000235
David Reissc005b1b2008-02-15 01:38:18 +0000236 virtual uint32_t writeBinary(const std::string& str) = 0;
237
Mark Sleee8540632006-05-30 09:24:40 +0000238 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000239 * Reading functions
Mark Sleee8540632006-05-30 09:24:40 +0000240 */
241
Mark Slee4af6ed72006-10-25 19:02:49 +0000242 virtual uint32_t readMessageBegin(std::string& name,
David Reiss96d23882007-07-26 21:10:32 +0000243 TMessageType& messageType,
244 int32_t& seqid) = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000245
Mark Slee4af6ed72006-10-25 19:02:49 +0000246 virtual uint32_t readMessageEnd() = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000247
Mark Slee4af6ed72006-10-25 19:02:49 +0000248 virtual uint32_t readStructBegin(std::string& name) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000249
Mark Slee4af6ed72006-10-25 19:02:49 +0000250 virtual uint32_t readStructEnd() = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000251
Mark Slee4af6ed72006-10-25 19:02:49 +0000252 virtual uint32_t readFieldBegin(std::string& name,
David Reiss96d23882007-07-26 21:10:32 +0000253 TType& fieldType,
254 int16_t& fieldId) = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000255
Mark Slee4af6ed72006-10-25 19:02:49 +0000256 virtual uint32_t readFieldEnd() = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000257
Mark Slee4af6ed72006-10-25 19:02:49 +0000258 virtual uint32_t readMapBegin(TType& keyType,
David Reiss96d23882007-07-26 21:10:32 +0000259 TType& valType,
260 uint32_t& size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000261
Mark Slee4af6ed72006-10-25 19:02:49 +0000262 virtual uint32_t readMapEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000263
Mark Slee4af6ed72006-10-25 19:02:49 +0000264 virtual uint32_t readListBegin(TType& elemType,
David Reiss96d23882007-07-26 21:10:32 +0000265 uint32_t& size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000266
Mark Slee4af6ed72006-10-25 19:02:49 +0000267 virtual uint32_t readListEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000268
Mark Slee4af6ed72006-10-25 19:02:49 +0000269 virtual uint32_t readSetBegin(TType& elemType,
David Reiss96d23882007-07-26 21:10:32 +0000270 uint32_t& size) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000271
Mark Slee4af6ed72006-10-25 19:02:49 +0000272 virtual uint32_t readSetEnd() = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000273
Mark Slee4af6ed72006-10-25 19:02:49 +0000274 virtual uint32_t readBool(bool& value) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000275
Mark Slee4af6ed72006-10-25 19:02:49 +0000276 virtual uint32_t readByte(int8_t& byte) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000277
Mark Slee4af6ed72006-10-25 19:02:49 +0000278 virtual uint32_t readI16(int16_t& i16) = 0;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000279
Mark Slee4af6ed72006-10-25 19:02:49 +0000280 virtual uint32_t readI32(int32_t& i32) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000281
Mark Slee4af6ed72006-10-25 19:02:49 +0000282 virtual uint32_t readI64(int64_t& i64) = 0;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000283
Mark Slee4af6ed72006-10-25 19:02:49 +0000284 virtual uint32_t readDouble(double& dub) = 0;
Mark Sleec98d0502006-09-06 02:42:25 +0000285
Mark Slee4af6ed72006-10-25 19:02:49 +0000286 virtual uint32_t readString(std::string& str) = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000287
David Reissc005b1b2008-02-15 01:38:18 +0000288 virtual uint32_t readBinary(std::string& str) = 0;
289
David Reiss035aed92009-02-10 21:38:48 +0000290 uint32_t readBool(std::vector<bool>::reference ref) {
291 bool value;
292 uint32_t rv = readBool(value);
293 ref = value;
David Reiss57b50062009-02-25 00:59:55 +0000294 return rv;
David Reiss035aed92009-02-10 21:38:48 +0000295 }
296
Mark Sleee8540632006-05-30 09:24:40 +0000297 /**
Mark Slee8d7e1f62006-06-07 06:48:56 +0000298 * Method to arbitrarily skip over data.
Mark Sleee8540632006-05-30 09:24:40 +0000299 */
Mark Slee4af6ed72006-10-25 19:02:49 +0000300 uint32_t skip(TType type) {
Mark Slee8d7e1f62006-06-07 06:48:56 +0000301 switch (type) {
Mark Slee78f58e22006-09-02 04:17:07 +0000302 case T_BOOL:
303 {
304 bool boolv;
Mark Slee4af6ed72006-10-25 19:02:49 +0000305 return readBool(boolv);
Mark Slee78f58e22006-09-02 04:17:07 +0000306 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000307 case T_BYTE:
308 {
Mark Slee78f58e22006-09-02 04:17:07 +0000309 int8_t bytev;
Mark Slee4af6ed72006-10-25 19:02:49 +0000310 return readByte(bytev);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000311 }
Mark Sleecfc01932006-09-01 22:18:16 +0000312 case T_I16:
Mark Slee8d7e1f62006-06-07 06:48:56 +0000313 {
Mark Sleecfc01932006-09-01 22:18:16 +0000314 int16_t i16;
Mark Slee4af6ed72006-10-25 19:02:49 +0000315 return readI16(i16);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000316 }
317 case T_I32:
318 {
319 int32_t i32;
Mark Slee4af6ed72006-10-25 19:02:49 +0000320 return readI32(i32);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000321 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000322 case T_I64:
323 {
324 int64_t i64;
Mark Slee4af6ed72006-10-25 19:02:49 +0000325 return readI64(i64);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000326 }
Mark Sleec98d0502006-09-06 02:42:25 +0000327 case T_DOUBLE:
328 {
329 double dub;
Mark Slee4af6ed72006-10-25 19:02:49 +0000330 return readDouble(dub);
Mark Sleec98d0502006-09-06 02:42:25 +0000331 }
Mark Slee8d7e1f62006-06-07 06:48:56 +0000332 case T_STRING:
333 {
334 std::string str;
David Reissc005b1b2008-02-15 01:38:18 +0000335 return readBinary(str);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000336 }
337 case T_STRUCT:
338 {
339 uint32_t result = 0;
340 std::string name;
Marc Slemko0b4ffa92006-08-11 02:49:29 +0000341 int16_t fid;
Mark Slee8d7e1f62006-06-07 06:48:56 +0000342 TType ftype;
Mark Slee4af6ed72006-10-25 19:02:49 +0000343 result += readStructBegin(name);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000344 while (true) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000345 result += readFieldBegin(name, ftype, fid);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000346 if (ftype == T_STOP) {
347 break;
348 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000349 result += skip(ftype);
350 result += readFieldEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000351 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000352 result += readStructEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000353 return result;
354 }
355 case T_MAP:
356 {
357 uint32_t result = 0;
358 TType keyType;
359 TType valType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000360 uint32_t i, size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000361 result += readMapBegin(keyType, valType, size);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000362 for (i = 0; i < size; i++) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000363 result += skip(keyType);
364 result += skip(valType);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000365 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000366 result += readMapEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000367 return result;
368 }
369 case T_SET:
370 {
371 uint32_t result = 0;
372 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000373 uint32_t i, size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000374 result += readSetBegin(elemType, size);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000375 for (i = 0; i < size; i++) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000376 result += skip(elemType);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000377 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000378 result += readSetEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000379 return result;
380 }
381 case T_LIST:
382 {
383 uint32_t result = 0;
384 TType elemType;
Marc Slemkob09f5882006-08-23 22:03:34 +0000385 uint32_t i, size;
Mark Slee4af6ed72006-10-25 19:02:49 +0000386 result += readListBegin(elemType, size);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000387 for (i = 0; i < size; i++) {
Mark Slee4af6ed72006-10-25 19:02:49 +0000388 result += skip(elemType);
Mark Slee8d7e1f62006-06-07 06:48:56 +0000389 }
Mark Slee4af6ed72006-10-25 19:02:49 +0000390 result += readListEnd();
Mark Slee8d7e1f62006-06-07 06:48:56 +0000391 return result;
392 }
393 default:
394 return 0;
395 }
396 }
Mark Sleee8540632006-05-30 09:24:40 +0000397
Mark Slee5ea15f92007-03-05 22:55:59 +0000398 inline boost::shared_ptr<TTransport> getTransport() {
Mark Slee43b6c632007-02-07 00:54:17 +0000399 return ptrans_;
Mark Slee4af6ed72006-10-25 19:02:49 +0000400 }
401
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000402 // TODO: remove these two calls, they are for backwards
403 // compatibility
Mark Slee5ea15f92007-03-05 22:55:59 +0000404 inline boost::shared_ptr<TTransport> getInputTransport() {
Mark Slee43b6c632007-02-07 00:54:17 +0000405 return ptrans_;
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000406 }
Mark Slee5ea15f92007-03-05 22:55:59 +0000407 inline boost::shared_ptr<TTransport> getOutputTransport() {
Mark Slee43b6c632007-02-07 00:54:17 +0000408 return ptrans_;
Mark Slee4af6ed72006-10-25 19:02:49 +0000409 }
410
Mark Sleee8540632006-05-30 09:24:40 +0000411 protected:
Mark Slee5ea15f92007-03-05 22:55:59 +0000412 TProtocol(boost::shared_ptr<TTransport> ptrans):
Mark Slee43b6c632007-02-07 00:54:17 +0000413 ptrans_(ptrans) {
414 trans_ = ptrans.get();
415 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000416
Mark Slee5ea15f92007-03-05 22:55:59 +0000417 boost::shared_ptr<TTransport> ptrans_;
Mark Slee43b6c632007-02-07 00:54:17 +0000418 TTransport* trans_;
Mark Slee4af6ed72006-10-25 19:02:49 +0000419
420 private:
Mark Sleee8540632006-05-30 09:24:40 +0000421 TProtocol() {}
422};
423
Mark Slee4af6ed72006-10-25 19:02:49 +0000424/**
425 * Constructs input and output protocol objects given transports.
426 */
427class TProtocolFactory {
428 public:
429 TProtocolFactory() {}
430
431 virtual ~TProtocolFactory() {}
432
Aditya Agarwal9abb0d62007-01-24 22:53:54 +0000433 virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) = 0;
Mark Slee4af6ed72006-10-25 19:02:49 +0000434};
435
T Jake Lucianib5e62212009-01-31 22:36:20 +0000436}}} // apache::thrift::protocol
Marc Slemko6f038a72006-08-03 18:58:09 +0000437
Mark Sleef5f2be42006-09-05 21:05:31 +0000438#endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1