THRIFT-922. cpp: Convert protocol classes to use non-virtual functions
Updated the thrift protocol classes to use non-virtual calls for most
functions. The correct implementation is determined at compile time via
templates now. Only the base TProtocol class falls back to using
virtual function calls.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005135 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/protocol/TProtocol.h b/lib/cpp/src/protocol/TProtocol.h
index 2e24f75..6bf7e3b 100644
--- a/lib/cpp/src/protocol/TProtocol.h
+++ b/lib/cpp/src/protocol/TProtocol.h
@@ -165,6 +165,111 @@
T_ONEWAY = 4
};
+
+/**
+ * Helper template for implementing TProtocol::skip().
+ *
+ * Templatized to avoid having to make virtual function calls.
+ */
+template <class Protocol_>
+uint32_t skip(Protocol_& prot, TType type) {
+ switch (type) {
+ case T_BOOL:
+ {
+ bool boolv;
+ return prot.readBool(boolv);
+ }
+ case T_BYTE:
+ {
+ int8_t bytev;
+ return prot.readByte(bytev);
+ }
+ case T_I16:
+ {
+ int16_t i16;
+ return prot.readI16(i16);
+ }
+ case T_I32:
+ {
+ int32_t i32;
+ return prot.readI32(i32);
+ }
+ case T_I64:
+ {
+ int64_t i64;
+ return prot.readI64(i64);
+ }
+ case T_DOUBLE:
+ {
+ double dub;
+ return prot.readDouble(dub);
+ }
+ case T_STRING:
+ {
+ std::string str;
+ return prot.readBinary(str);
+ }
+ case T_STRUCT:
+ {
+ uint32_t result = 0;
+ std::string name;
+ int16_t fid;
+ TType ftype;
+ result += prot.readStructBegin(name);
+ while (true) {
+ result += prot.readFieldBegin(name, ftype, fid);
+ if (ftype == T_STOP) {
+ break;
+ }
+ result += skip(prot, ftype);
+ result += prot.readFieldEnd();
+ }
+ result += prot.readStructEnd();
+ return result;
+ }
+ case T_MAP:
+ {
+ uint32_t result = 0;
+ TType keyType;
+ TType valType;
+ uint32_t i, size;
+ result += prot.readMapBegin(keyType, valType, size);
+ for (i = 0; i < size; i++) {
+ result += skip(prot, keyType);
+ result += skip(prot, valType);
+ }
+ result += prot.readMapEnd();
+ return result;
+ }
+ case T_SET:
+ {
+ uint32_t result = 0;
+ TType elemType;
+ uint32_t i, size;
+ result += prot.readSetBegin(elemType, size);
+ for (i = 0; i < size; i++) {
+ result += skip(prot, elemType);
+ }
+ result += prot.readSetEnd();
+ return result;
+ }
+ case T_LIST:
+ {
+ uint32_t result = 0;
+ TType elemType;
+ uint32_t i, size;
+ result += prot.readListBegin(elemType, size);
+ for (i = 0; i < size; i++) {
+ result += skip(prot, elemType);
+ }
+ result += prot.readListEnd();
+ return result;
+ }
+ default:
+ return 0;
+ }
+}
+
/**
* Abstract class for a thrift protocol driver. These are all the methods that
* a protocol must implement. Essentially, there must be some way of reading
@@ -187,108 +292,324 @@
* Writing functions.
*/
- virtual uint32_t writeMessageBegin(const std::string& name,
- const TMessageType messageType,
- const int32_t seqid) = 0;
+ virtual uint32_t writeMessageBegin_virt(const std::string& name,
+ const TMessageType messageType,
+ const int32_t seqid) = 0;
- virtual uint32_t writeMessageEnd() = 0;
+ virtual uint32_t writeMessageEnd_virt() = 0;
- virtual uint32_t writeStructBegin(const char* name) = 0;
+ virtual uint32_t writeStructBegin_virt(const char* name) = 0;
- virtual uint32_t writeStructEnd() = 0;
+ virtual uint32_t writeStructEnd_virt() = 0;
- virtual uint32_t writeFieldBegin(const char* name,
- const TType fieldType,
- const int16_t fieldId) = 0;
+ virtual uint32_t writeFieldBegin_virt(const char* name,
+ const TType fieldType,
+ const int16_t fieldId) = 0;
- virtual uint32_t writeFieldEnd() = 0;
+ virtual uint32_t writeFieldEnd_virt() = 0;
- virtual uint32_t writeFieldStop() = 0;
+ virtual uint32_t writeFieldStop_virt() = 0;
- virtual uint32_t writeMapBegin(const TType keyType,
- const TType valType,
- const uint32_t size) = 0;
+ virtual uint32_t writeMapBegin_virt(const TType keyType,
+ const TType valType,
+ const uint32_t size) = 0;
- virtual uint32_t writeMapEnd() = 0;
+ virtual uint32_t writeMapEnd_virt() = 0;
- virtual uint32_t writeListBegin(const TType elemType,
- const uint32_t size) = 0;
+ virtual uint32_t writeListBegin_virt(const TType elemType,
+ const uint32_t size) = 0;
- virtual uint32_t writeListEnd() = 0;
+ virtual uint32_t writeListEnd_virt() = 0;
- virtual uint32_t writeSetBegin(const TType elemType,
- const uint32_t size) = 0;
+ virtual uint32_t writeSetBegin_virt(const TType elemType,
+ const uint32_t size) = 0;
- virtual uint32_t writeSetEnd() = 0;
+ virtual uint32_t writeSetEnd_virt() = 0;
- virtual uint32_t writeBool(const bool value) = 0;
+ virtual uint32_t writeBool_virt(const bool value) = 0;
- virtual uint32_t writeByte(const int8_t byte) = 0;
+ virtual uint32_t writeByte_virt(const int8_t byte) = 0;
- virtual uint32_t writeI16(const int16_t i16) = 0;
+ virtual uint32_t writeI16_virt(const int16_t i16) = 0;
- virtual uint32_t writeI32(const int32_t i32) = 0;
+ virtual uint32_t writeI32_virt(const int32_t i32) = 0;
- virtual uint32_t writeI64(const int64_t i64) = 0;
+ virtual uint32_t writeI64_virt(const int64_t i64) = 0;
- virtual uint32_t writeDouble(const double dub) = 0;
+ virtual uint32_t writeDouble_virt(const double dub) = 0;
- virtual uint32_t writeString(const std::string& str) = 0;
+ virtual uint32_t writeString_virt(const std::string& str) = 0;
- virtual uint32_t writeBinary(const std::string& str) = 0;
+ virtual uint32_t writeBinary_virt(const std::string& str) = 0;
+
+ uint32_t writeMessageBegin(const std::string& name,
+ const TMessageType messageType,
+ const int32_t seqid) {
+ T_VIRTUAL_CALL();
+ return writeMessageBegin_virt(name, messageType, seqid);
+ }
+
+ uint32_t writeMessageEnd() {
+ T_VIRTUAL_CALL();
+ return writeMessageEnd_virt();
+ }
+
+
+ uint32_t writeStructBegin(const char* name) {
+ T_VIRTUAL_CALL();
+ return writeStructBegin_virt(name);
+ }
+
+ uint32_t writeStructEnd() {
+ T_VIRTUAL_CALL();
+ return writeStructEnd_virt();
+ }
+
+ uint32_t writeFieldBegin(const char* name,
+ const TType fieldType,
+ const int16_t fieldId) {
+ T_VIRTUAL_CALL();
+ return writeFieldBegin_virt(name, fieldType, fieldId);
+ }
+
+ uint32_t writeFieldEnd() {
+ T_VIRTUAL_CALL();
+ return writeFieldEnd_virt();
+ }
+
+ uint32_t writeFieldStop() {
+ T_VIRTUAL_CALL();
+ return writeFieldStop_virt();
+ }
+
+ uint32_t writeMapBegin(const TType keyType,
+ const TType valType,
+ const uint32_t size) {
+ T_VIRTUAL_CALL();
+ return writeMapBegin_virt(keyType, valType, size);
+ }
+
+ uint32_t writeMapEnd() {
+ T_VIRTUAL_CALL();
+ return writeMapEnd_virt();
+ }
+
+ uint32_t writeListBegin(const TType elemType, const uint32_t size) {
+ T_VIRTUAL_CALL();
+ return writeListBegin_virt(elemType, size);
+ }
+
+ uint32_t writeListEnd() {
+ T_VIRTUAL_CALL();
+ return writeListEnd_virt();
+ }
+
+ uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
+ T_VIRTUAL_CALL();
+ return writeSetBegin_virt(elemType, size);
+ }
+
+ uint32_t writeSetEnd() {
+ T_VIRTUAL_CALL();
+ return writeSetEnd_virt();
+ }
+
+ uint32_t writeBool(const bool value) {
+ T_VIRTUAL_CALL();
+ return writeBool_virt(value);
+ }
+
+ uint32_t writeByte(const int8_t byte) {
+ T_VIRTUAL_CALL();
+ return writeByte_virt(byte);
+ }
+
+ uint32_t writeI16(const int16_t i16) {
+ T_VIRTUAL_CALL();
+ return writeI16_virt(i16);
+ }
+
+ uint32_t writeI32(const int32_t i32) {
+ T_VIRTUAL_CALL();
+ return writeI32_virt(i32);
+ }
+
+ uint32_t writeI64(const int64_t i64) {
+ T_VIRTUAL_CALL();
+ return writeI64_virt(i64);
+ }
+
+ uint32_t writeDouble(const double dub) {
+ T_VIRTUAL_CALL();
+ return writeDouble_virt(dub);
+ }
+
+ uint32_t writeString(const std::string& str) {
+ T_VIRTUAL_CALL();
+ return writeString_virt(str);
+ }
+
+ uint32_t writeBinary(const std::string& str) {
+ T_VIRTUAL_CALL();
+ return writeBinary_virt(str);
+ }
/**
* Reading functions
*/
- virtual uint32_t readMessageBegin(std::string& name,
- TMessageType& messageType,
- int32_t& seqid) = 0;
+ virtual uint32_t readMessageBegin_virt(std::string& name,
+ TMessageType& messageType,
+ int32_t& seqid) = 0;
- virtual uint32_t readMessageEnd() = 0;
+ virtual uint32_t readMessageEnd_virt() = 0;
- virtual uint32_t readStructBegin(std::string& name) = 0;
+ virtual uint32_t readStructBegin_virt(std::string& name) = 0;
- virtual uint32_t readStructEnd() = 0;
+ virtual uint32_t readStructEnd_virt() = 0;
- virtual uint32_t readFieldBegin(std::string& name,
- TType& fieldType,
- int16_t& fieldId) = 0;
+ virtual uint32_t readFieldBegin_virt(std::string& name,
+ TType& fieldType,
+ int16_t& fieldId) = 0;
- virtual uint32_t readFieldEnd() = 0;
+ virtual uint32_t readFieldEnd_virt() = 0;
- virtual uint32_t readMapBegin(TType& keyType,
- TType& valType,
- uint32_t& size) = 0;
+ virtual uint32_t readMapBegin_virt(TType& keyType,
+ TType& valType,
+ uint32_t& size) = 0;
- virtual uint32_t readMapEnd() = 0;
+ virtual uint32_t readMapEnd_virt() = 0;
- virtual uint32_t readListBegin(TType& elemType,
- uint32_t& size) = 0;
+ virtual uint32_t readListBegin_virt(TType& elemType,
+ uint32_t& size) = 0;
- virtual uint32_t readListEnd() = 0;
+ virtual uint32_t readListEnd_virt() = 0;
- virtual uint32_t readSetBegin(TType& elemType,
- uint32_t& size) = 0;
+ virtual uint32_t readSetBegin_virt(TType& elemType,
+ uint32_t& size) = 0;
- virtual uint32_t readSetEnd() = 0;
+ virtual uint32_t readSetEnd_virt() = 0;
- virtual uint32_t readBool(bool& value) = 0;
+ virtual uint32_t readBool_virt(bool& value) = 0;
- virtual uint32_t readByte(int8_t& byte) = 0;
+ virtual uint32_t readByte_virt(int8_t& byte) = 0;
- virtual uint32_t readI16(int16_t& i16) = 0;
+ virtual uint32_t readI16_virt(int16_t& i16) = 0;
- virtual uint32_t readI32(int32_t& i32) = 0;
+ virtual uint32_t readI32_virt(int32_t& i32) = 0;
- virtual uint32_t readI64(int64_t& i64) = 0;
+ virtual uint32_t readI64_virt(int64_t& i64) = 0;
- virtual uint32_t readDouble(double& dub) = 0;
+ virtual uint32_t readDouble_virt(double& dub) = 0;
- virtual uint32_t readString(std::string& str) = 0;
+ virtual uint32_t readString_virt(std::string& str) = 0;
- virtual uint32_t readBinary(std::string& str) = 0;
+ virtual uint32_t readBinary_virt(std::string& str) = 0;
+
+ uint32_t readMessageBegin(std::string& name,
+ TMessageType& messageType,
+ int32_t& seqid) {
+ T_VIRTUAL_CALL();
+ return readMessageBegin_virt(name, messageType, seqid);
+ }
+
+ uint32_t readMessageEnd() {
+ T_VIRTUAL_CALL();
+ return readMessageEnd_virt();
+ }
+
+ uint32_t readStructBegin(std::string& name) {
+ T_VIRTUAL_CALL();
+ return readStructBegin_virt(name);
+ }
+
+ uint32_t readStructEnd() {
+ T_VIRTUAL_CALL();
+ return readStructEnd_virt();
+ }
+
+ uint32_t readFieldBegin(std::string& name,
+ TType& fieldType,
+ int16_t& fieldId) {
+ T_VIRTUAL_CALL();
+ return readFieldBegin_virt(name, fieldType, fieldId);
+ }
+
+ uint32_t readFieldEnd() {
+ T_VIRTUAL_CALL();
+ return readFieldEnd_virt();
+ }
+
+ uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
+ T_VIRTUAL_CALL();
+ return readMapBegin_virt(keyType, valType, size);
+ }
+
+ uint32_t readMapEnd() {
+ T_VIRTUAL_CALL();
+ return readMapEnd_virt();
+ }
+
+ uint32_t readListBegin(TType& elemType, uint32_t& size) {
+ T_VIRTUAL_CALL();
+ return readListBegin_virt(elemType, size);
+ }
+
+ uint32_t readListEnd() {
+ T_VIRTUAL_CALL();
+ return readListEnd_virt();
+ }
+
+ uint32_t readSetBegin(TType& elemType, uint32_t& size) {
+ T_VIRTUAL_CALL();
+ return readSetBegin_virt(elemType, size);
+ }
+
+ uint32_t readSetEnd() {
+ T_VIRTUAL_CALL();
+ return readSetEnd_virt();
+ }
+
+ uint32_t readBool(bool& value) {
+ T_VIRTUAL_CALL();
+ return readBool_virt(value);
+ }
+
+ uint32_t readByte(int8_t& byte) {
+ T_VIRTUAL_CALL();
+ return readByte_virt(byte);
+ }
+
+ uint32_t readI16(int16_t& i16) {
+ T_VIRTUAL_CALL();
+ return readI16_virt(i16);
+ }
+
+ uint32_t readI32(int32_t& i32) {
+ T_VIRTUAL_CALL();
+ return readI32_virt(i32);
+ }
+
+ uint32_t readI64(int64_t& i64) {
+ T_VIRTUAL_CALL();
+ return readI64_virt(i64);
+ }
+
+ uint32_t readDouble(double& dub) {
+ T_VIRTUAL_CALL();
+ return readDouble_virt(dub);
+ }
+
+ uint32_t readString(std::string& str) {
+ T_VIRTUAL_CALL();
+ return readString_virt(str);
+ }
+
+ uint32_t readBinary(std::string& str) {
+ T_VIRTUAL_CALL();
+ return readBinary_virt(str);
+ }
uint32_t readBool(std::vector<bool>::reference ref) {
bool value;
@@ -301,101 +622,11 @@
* Method to arbitrarily skip over data.
*/
uint32_t skip(TType type) {
- switch (type) {
- case T_BOOL:
- {
- bool boolv;
- return readBool(boolv);
- }
- case T_BYTE:
- {
- int8_t bytev;
- return readByte(bytev);
- }
- case T_I16:
- {
- int16_t i16;
- return readI16(i16);
- }
- case T_I32:
- {
- int32_t i32;
- return readI32(i32);
- }
- case T_I64:
- {
- int64_t i64;
- return readI64(i64);
- }
- case T_DOUBLE:
- {
- double dub;
- return readDouble(dub);
- }
- case T_STRING:
- {
- std::string str;
- return readBinary(str);
- }
- case T_STRUCT:
- {
- uint32_t result = 0;
- std::string name;
- int16_t fid;
- TType ftype;
- result += readStructBegin(name);
- while (true) {
- result += readFieldBegin(name, ftype, fid);
- if (ftype == T_STOP) {
- break;
- }
- result += skip(ftype);
- result += readFieldEnd();
- }
- result += readStructEnd();
- return result;
- }
- case T_MAP:
- {
- uint32_t result = 0;
- TType keyType;
- TType valType;
- uint32_t i, size;
- result += readMapBegin(keyType, valType, size);
- for (i = 0; i < size; i++) {
- result += skip(keyType);
- result += skip(valType);
- }
- result += readMapEnd();
- return result;
- }
- case T_SET:
- {
- uint32_t result = 0;
- TType elemType;
- uint32_t i, size;
- result += readSetBegin(elemType, size);
- for (i = 0; i < size; i++) {
- result += skip(elemType);
- }
- result += readSetEnd();
- return result;
- }
- case T_LIST:
- {
- uint32_t result = 0;
- TType elemType;
- uint32_t i, size;
- result += readListBegin(elemType, size);
- for (i = 0; i < size; i++) {
- result += skip(elemType);
- }
- result += readListEnd();
- return result;
- }
- default:
- return 0;
- }
+ T_VIRTUAL_CALL();
+ return skip_virt(type);
+ }
+ virtual uint32_t skip_virt(TType type) {
+ return ::apache::thrift::protocol::skip(*this, type);
}
inline boost::shared_ptr<TTransport> getTransport() {