THRIFT-922. cpp: Templatize binary and compact protocol
Convert TBinaryProtocol and TCompactProtocol to template classes, taking
the transport class as a template parameter. This allows them to make
non-virtual calls when using the template, improving serialization
performance.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005136 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/protocol/TCompactProtocol.h b/lib/cpp/src/protocol/TCompactProtocol.h
index 77c4454..2150cde 100644
--- a/lib/cpp/src/protocol/TCompactProtocol.h
+++ b/lib/cpp/src/protocol/TCompactProtocol.h
@@ -30,7 +30,9 @@
/**
* C++ Implementation of the Compact Protocol as described in THRIFT-110
*/
-class TCompactProtocol : public TVirtualProtocol<TCompactProtocol> {
+template <class Transport_>
+class TCompactProtocolT
+ : public TVirtualProtocol< TCompactProtocolT<Transport_> > {
protected:
static const int8_t PROTOCOL_ID = 0x82;
@@ -39,6 +41,8 @@
static const int8_t TYPE_MASK = 0xE0; // 1110 0000
static const int32_t TYPE_SHIFT_AMOUNT = 5;
+ Transport_* trans_;
+
/**
* (Writing) If we encounter a boolean field begin, save the TField here
* so it can have the value incorporated.
@@ -66,27 +70,10 @@
std::stack<int16_t> lastField_;
int16_t lastFieldId_;
- enum Types {
- CT_STOP = 0x00,
- CT_BOOLEAN_TRUE = 0x01,
- CT_BOOLEAN_FALSE = 0x02,
- CT_BYTE = 0x03,
- CT_I16 = 0x04,
- CT_I32 = 0x05,
- CT_I64 = 0x06,
- CT_DOUBLE = 0x07,
- CT_BINARY = 0x08,
- CT_LIST = 0x09,
- CT_SET = 0x0A,
- CT_MAP = 0x0B,
- CT_STRUCT = 0x0C,
- };
-
- static const int8_t TTypeToCType[16];
-
public:
- TCompactProtocol(boost::shared_ptr<TTransport> trans) :
- TVirtualProtocol<TCompactProtocol>(trans),
+ TCompactProtocolT(boost::shared_ptr<Transport_> trans) :
+ TVirtualProtocol< TCompactProtocolT<Transport_> >(trans),
+ trans_(trans.get()),
lastFieldId_(0),
string_limit_(0),
string_buf_(NULL),
@@ -96,10 +83,11 @@
boolValue_.hasBoolValue = false;
}
- TCompactProtocol(boost::shared_ptr<TTransport> trans,
- int32_t string_limit,
- int32_t container_limit) :
- TVirtualProtocol<TCompactProtocol>(trans),
+ TCompactProtocolT(boost::shared_ptr<Transport_> trans,
+ int32_t string_limit,
+ int32_t container_limit) :
+ TVirtualProtocol< TCompactProtocolT<Transport_> >(trans),
+ trans_(trans.get()),
lastFieldId_(0),
string_limit_(string_limit),
string_buf_(NULL),
@@ -109,7 +97,7 @@
boolValue_.hasBoolValue = false;
}
- ~TCompactProtocol() {
+ ~TCompactProtocolT() {
free(string_buf_);
}
@@ -244,20 +232,23 @@
int32_t container_limit_;
};
+typedef TCompactProtocolT<TTransport> TCompactProtocol;
+
/**
* Constructs compact protocol handlers
*/
-class TCompactProtocolFactory : public TProtocolFactory {
+template <class Transport_>
+class TCompactProtocolFactoryT : public TProtocolFactory {
public:
- TCompactProtocolFactory() :
+ TCompactProtocolFactoryT() :
string_limit_(0),
container_limit_(0) {}
- TCompactProtocolFactory(int32_t string_limit, int32_t container_limit) :
+ TCompactProtocolFactoryT(int32_t string_limit, int32_t container_limit) :
string_limit_(string_limit),
container_limit_(container_limit) {}
- virtual ~TCompactProtocolFactory() {}
+ virtual ~TCompactProtocolFactoryT() {}
void setStringSizeLimit(int32_t string_limit) {
string_limit_ = string_limit;
@@ -268,7 +259,17 @@
}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
- return boost::shared_ptr<TProtocol>(new TCompactProtocol(trans, string_limit_, container_limit_));
+ boost::shared_ptr<Transport_> specific_trans =
+ boost::dynamic_pointer_cast<Transport_>(trans);
+ TProtocol* prot;
+ if (specific_trans) {
+ prot = new TCompactProtocolT<Transport_>(specific_trans, string_limit_,
+ container_limit_);
+ } else {
+ prot = new TCompactProtocol(trans, string_limit_, container_limit_);
+ }
+
+ return boost::shared_ptr<TProtocol>(prot);
}
private:
@@ -277,6 +278,10 @@
};
+typedef TCompactProtocolFactoryT<TTransport> TCompactProtocolFactory;
+
}}} // apache::thrift::protocol
+#include "TCompactProtocol.tcc"
+
#endif