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
10
* http://www.apache.org/licenses/LICENSE-2.0
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
20
#ifndef _THRIFT_PROTOCOL_TPROTOCOL_H_
21
#define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1
23
#include <transport/TTransport.h>
24
#include <protocol/TProtocolException.h>
26
#include <boost/shared_ptr.hpp>
27
#include <boost/static_assert.hpp>
29
#ifdef HAVE_NETINET_IN_H
30
#include <netinet/in.h>
32
#include <sys/types.h>
38
// Use this to get around strict aliasing rules.
39
// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
40
// The most obvious implementation is to just cast a pointer,
41
// but that doesn't work.
42
// For a pretty in-depth explanation of the problem, see
43
// http://www.cellperformance.com/mike_acton/2006/06/ (...)
44
// understanding_strict_aliasing.html
45
template <typename To, typename From>
46
static inline To bitwise_cast(From from) {
47
BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
49
// BAD!!! These are all broken with -O2.
50
//return *reinterpret_cast<To*>(&from); // BAD!!!
51
//return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
52
//return *(To*)(void*)&from; // BAD!!!
54
// Super clean and paritally blessed by section 3.9 of the standard.
55
//unsigned char c[sizeof(from)];
56
//memcpy(c, &from, sizeof(from));
58
//memcpy(&to, c, sizeof(c));
61
// Slightly more questionable.
62
// Same code emitted by GCC.
64
//memcpy(&to, &from, sizeof(from));
67
// Technically undefined, but almost universally supported,
68
// and the most efficient implementation.
78
namespace apache { namespace thrift { namespace protocol {
80
using apache::thrift::transport::TTransport;
82
#ifdef HAVE_SYS_PARAM_H
83
#include <sys/param.h>
86
#ifndef __THRIFT_BYTE_ORDER
87
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
88
# define __THRIFT_BYTE_ORDER BYTE_ORDER
89
# define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
90
# define __THRIFT_BIG_ENDIAN BIG_ENDIAN
92
# include <boost/config.hpp>
93
# include <boost/detail/endian.hpp>
94
# define __THRIFT_BYTE_ORDER BOOST_BYTE_ORDER
95
# ifdef BOOST_LITTLE_ENDIAN
96
# define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
97
# define __THRIFT_BIG_ENDIAN 0
99
# define __THRIFT_LITTLE_ENDIAN 0
100
# define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
105
#if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
106
# define ntohll(n) (n)
107
# define htonll(n) (n)
108
# if defined(__GNUC__) && defined(__GLIBC__)
109
# include <byteswap.h>
110
# define htolell(n) bswap_64(n)
111
# define letohll(n) bswap_64(n)
112
# else /* GNUC & GLIBC */
113
# define bswap_64(n) \
114
( (((n) & 0xff00000000000000ull) >> 56) \
115
| (((n) & 0x00ff000000000000ull) >> 40) \
116
| (((n) & 0x0000ff0000000000ull) >> 24) \
117
| (((n) & 0x000000ff00000000ull) >> 8) \
118
| (((n) & 0x00000000ff000000ull) << 8) \
119
| (((n) & 0x0000000000ff0000ull) << 24) \
120
| (((n) & 0x000000000000ff00ull) << 40) \
121
| (((n) & 0x00000000000000ffull) << 56) )
122
# define htolell(n) bswap_64(n)
123
# define letohll(n) bswap_64(n)
124
# endif /* GNUC & GLIBC */
125
#elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN
126
# define htolell(n) (n)
127
# define letohll(n) (n)
128
# if defined(__GNUC__) && defined(__GLIBC__)
129
# include <byteswap.h>
130
# define ntohll(n) bswap_64(n)
131
# define htonll(n) bswap_64(n)
132
# else /* GNUC & GLIBC */
133
# define ntohll(n) ( (((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32) )
134
# define htonll(n) ( (((uint64_t)htonl(n)) << 32) + htonl(n >> 32) )
135
# endif /* GNUC & GLIBC */
136
#else /* __THRIFT_BYTE_ORDER */
137
# error "Can't define htonll or ntohll!"
141
* Enumerated definition of the types that the Thrift protocol supports.
142
* Take special note of the T_END type which is used specifically to mark
143
* the end of a sequence of fields.
167
* Enumerated definition of the message types that the Thrift protocol
179
* Helper template for implementing TProtocol::skip().
181
* Templatized to avoid having to make virtual function calls.
183
template <class Protocol_>
184
uint32_t skip(Protocol_& prot, TType type) {
189
return prot.readBool(boolv);
194
return prot.readByte(bytev);
199
return prot.readI16(i16);
204
return prot.readI32(i32);
209
return prot.readI64(i64);
214
return prot.readDouble(dub);
219
return prot.readBinary(str);
227
result += prot.readStructBegin(name);
229
result += prot.readFieldBegin(name, ftype, fid);
230
if (ftype == T_STOP) {
233
result += skip(prot, ftype);
234
result += prot.readFieldEnd();
236
result += prot.readStructEnd();
245
result += prot.readMapBegin(keyType, valType, size);
246
for (i = 0; i < size; i++) {
247
result += skip(prot, keyType);
248
result += skip(prot, valType);
250
result += prot.readMapEnd();
258
result += prot.readSetBegin(elemType, size);
259
for (i = 0; i < size; i++) {
260
result += skip(prot, elemType);
262
result += prot.readSetEnd();
270
result += prot.readListBegin(elemType, size);
271
for (i = 0; i < size; i++) {
272
result += skip(prot, elemType);
274
result += prot.readListEnd();
277
case T_STOP: case T_VOID: case T_U64: case T_UTF8: case T_UTF16:
284
* Abstract class for a thrift protocol driver. These are all the methods that
285
* a protocol must implement. Essentially, there must be some way of reading
286
* and writing all the base types, plus a mechanism for writing out structs
287
* with indexed fields.
289
* TProtocol objects should not be shared across multiple encoding contexts,
290
* as they may need to maintain internal state in some protocols (i.e. XML).
291
* Note that is is acceptable for the TProtocol module to do its own internal
292
* buffered reads/writes to the underlying TTransport where appropriate (i.e.
293
* when parsing an input XML stream, reading should be batched rather than
294
* looking ahead character by character for a close tag).
299
virtual ~TProtocol() {}
305
virtual uint32_t writeMessageBegin_virt(const std::string& name,
306
const TMessageType messageType,
307
const int32_t seqid) = 0;
309
virtual uint32_t writeMessageEnd_virt() = 0;
312
virtual uint32_t writeStructBegin_virt(const char* name) = 0;
314
virtual uint32_t writeStructEnd_virt() = 0;
316
virtual uint32_t writeFieldBegin_virt(const char* name,
317
const TType fieldType,
318
const int16_t fieldId) = 0;
320
virtual uint32_t writeFieldEnd_virt() = 0;
322
virtual uint32_t writeFieldStop_virt() = 0;
324
virtual uint32_t writeMapBegin_virt(const TType keyType,
326
const uint32_t size) = 0;
328
virtual uint32_t writeMapEnd_virt() = 0;
330
virtual uint32_t writeListBegin_virt(const TType elemType,
331
const uint32_t size) = 0;
333
virtual uint32_t writeListEnd_virt() = 0;
335
virtual uint32_t writeSetBegin_virt(const TType elemType,
336
const uint32_t size) = 0;
338
virtual uint32_t writeSetEnd_virt() = 0;
340
virtual uint32_t writeBool_virt(const bool value) = 0;
342
virtual uint32_t writeByte_virt(const int8_t byte) = 0;
344
virtual uint32_t writeI16_virt(const int16_t i16) = 0;
346
virtual uint32_t writeI32_virt(const int32_t i32) = 0;
348
virtual uint32_t writeI64_virt(const int64_t i64) = 0;
350
virtual uint32_t writeDouble_virt(const double dub) = 0;
352
virtual uint32_t writeString_virt(const std::string& str) = 0;
354
virtual uint32_t writeBinary_virt(const std::string& str) = 0;
356
uint32_t writeMessageBegin(const std::string& name,
357
const TMessageType messageType,
358
const int32_t seqid) {
360
return writeMessageBegin_virt(name, messageType, seqid);
363
uint32_t writeMessageEnd() {
365
return writeMessageEnd_virt();
369
uint32_t writeStructBegin(const char* name) {
371
return writeStructBegin_virt(name);
374
uint32_t writeStructEnd() {
376
return writeStructEnd_virt();
379
uint32_t writeFieldBegin(const char* name,
380
const TType fieldType,
381
const int16_t fieldId) {
383
return writeFieldBegin_virt(name, fieldType, fieldId);
386
uint32_t writeFieldEnd() {
388
return writeFieldEnd_virt();
391
uint32_t writeFieldStop() {
393
return writeFieldStop_virt();
396
uint32_t writeMapBegin(const TType keyType,
398
const uint32_t size) {
400
return writeMapBegin_virt(keyType, valType, size);
403
uint32_t writeMapEnd() {
405
return writeMapEnd_virt();
408
uint32_t writeListBegin(const TType elemType, const uint32_t size) {
410
return writeListBegin_virt(elemType, size);
413
uint32_t writeListEnd() {
415
return writeListEnd_virt();
418
uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
420
return writeSetBegin_virt(elemType, size);
423
uint32_t writeSetEnd() {
425
return writeSetEnd_virt();
428
uint32_t writeBool(const bool value) {
430
return writeBool_virt(value);
433
uint32_t writeByte(const int8_t byte) {
435
return writeByte_virt(byte);
438
uint32_t writeI16(const int16_t i16) {
440
return writeI16_virt(i16);
443
uint32_t writeI32(const int32_t i32) {
445
return writeI32_virt(i32);
448
uint32_t writeI64(const int64_t i64) {
450
return writeI64_virt(i64);
453
uint32_t writeDouble(const double dub) {
455
return writeDouble_virt(dub);
458
uint32_t writeString(const std::string& str) {
460
return writeString_virt(str);
463
uint32_t writeBinary(const std::string& str) {
465
return writeBinary_virt(str);
472
virtual uint32_t readMessageBegin_virt(std::string& name,
473
TMessageType& messageType,
476
virtual uint32_t readMessageEnd_virt() = 0;
478
virtual uint32_t readStructBegin_virt(std::string& name) = 0;
480
virtual uint32_t readStructEnd_virt() = 0;
482
virtual uint32_t readFieldBegin_virt(std::string& name,
484
int16_t& fieldId) = 0;
486
virtual uint32_t readFieldEnd_virt() = 0;
488
virtual uint32_t readMapBegin_virt(TType& keyType,
492
virtual uint32_t readMapEnd_virt() = 0;
494
virtual uint32_t readListBegin_virt(TType& elemType,
497
virtual uint32_t readListEnd_virt() = 0;
499
virtual uint32_t readSetBegin_virt(TType& elemType,
502
virtual uint32_t readSetEnd_virt() = 0;
504
virtual uint32_t readBool_virt(bool& value) = 0;
506
virtual uint32_t readBool_virt(std::vector<bool>::reference value) = 0;
508
virtual uint32_t readByte_virt(int8_t& byte) = 0;
510
virtual uint32_t readI16_virt(int16_t& i16) = 0;
512
virtual uint32_t readI32_virt(int32_t& i32) = 0;
514
virtual uint32_t readI64_virt(int64_t& i64) = 0;
516
virtual uint32_t readDouble_virt(double& dub) = 0;
518
virtual uint32_t readString_virt(std::string& str) = 0;
520
virtual uint32_t readBinary_virt(std::string& str) = 0;
522
uint32_t readMessageBegin(std::string& name,
523
TMessageType& messageType,
526
return readMessageBegin_virt(name, messageType, seqid);
529
uint32_t readMessageEnd() {
531
return readMessageEnd_virt();
534
uint32_t readStructBegin(std::string& name) {
536
return readStructBegin_virt(name);
539
uint32_t readStructEnd() {
541
return readStructEnd_virt();
544
uint32_t readFieldBegin(std::string& name,
548
return readFieldBegin_virt(name, fieldType, fieldId);
551
uint32_t readFieldEnd() {
553
return readFieldEnd_virt();
556
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
558
return readMapBegin_virt(keyType, valType, size);
561
uint32_t readMapEnd() {
563
return readMapEnd_virt();
566
uint32_t readListBegin(TType& elemType, uint32_t& size) {
568
return readListBegin_virt(elemType, size);
571
uint32_t readListEnd() {
573
return readListEnd_virt();
576
uint32_t readSetBegin(TType& elemType, uint32_t& size) {
578
return readSetBegin_virt(elemType, size);
581
uint32_t readSetEnd() {
583
return readSetEnd_virt();
586
uint32_t readBool(bool& value) {
588
return readBool_virt(value);
591
uint32_t readByte(int8_t& byte) {
593
return readByte_virt(byte);
596
uint32_t readI16(int16_t& i16) {
598
return readI16_virt(i16);
601
uint32_t readI32(int32_t& i32) {
603
return readI32_virt(i32);
606
uint32_t readI64(int64_t& i64) {
608
return readI64_virt(i64);
611
uint32_t readDouble(double& dub) {
613
return readDouble_virt(dub);
616
uint32_t readString(std::string& str) {
618
return readString_virt(str);
621
uint32_t readBinary(std::string& str) {
623
return readBinary_virt(str);
627
* std::vector is specialized for bool, and its elements are individual bits
628
* rather than bools. We need to define a different version of readBool()
629
* to work with std::vector<bool>.
631
uint32_t readBool(std::vector<bool>::reference value) {
633
return readBool_virt(value);
637
* Method to arbitrarily skip over data.
639
uint32_t skip(TType type) {
641
return skip_virt(type);
643
virtual uint32_t skip_virt(TType type) {
644
return ::apache::thrift::protocol::skip(*this, type);
647
inline boost::shared_ptr<TTransport> getTransport() {
651
// TODO: remove these two calls, they are for backwards
653
inline boost::shared_ptr<TTransport> getInputTransport() {
656
inline boost::shared_ptr<TTransport> getOutputTransport() {
661
TProtocol(boost::shared_ptr<TTransport> ptrans):
665
boost::shared_ptr<TTransport> ptrans_;
672
* Constructs input and output protocol objects given transports.
674
class TProtocolFactory {
676
TProtocolFactory() {}
678
virtual ~TProtocolFactory() {}
680
virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) = 0;
684
* Dummy protocol class.
686
* This class does nothing, and should never be instantiated.
687
* It is used only by the generator code.
689
class TDummyProtocol : public TProtocol {
692
}}} // apache::thrift::protocol
694
#endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1