THRIFT-2199:Remove dense protocol
Client: C++ library and compiler
Patch: Randy Abernethy
diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index d6107bc..4c7caeb 100755
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -43,7 +43,6 @@
src/thrift/processor/PeekProcessor.cpp
src/thrift/protocol/TBase64Utils.cpp
src/thrift/protocol/TDebugProtocol.cpp
- src/thrift/protocol/TDenseProtocol.cpp
src/thrift/protocol/TJSONProtocol.cpp
src/thrift/protocol/TMultiplexedProtocol.cpp
src/thrift/protocol/TProtocol.cpp
diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
index 7f2d431..4e5cde7 100755
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -72,7 +72,6 @@
src/thrift/concurrency/Util.cpp \
src/thrift/processor/PeekProcessor.cpp \
src/thrift/protocol/TDebugProtocol.cpp \
- src/thrift/protocol/TDenseProtocol.cpp \
src/thrift/protocol/TJSONProtocol.cpp \
src/thrift/protocol/TBase64Utils.cpp \
src/thrift/protocol/TMultiplexedProtocol.cpp \
@@ -153,7 +152,6 @@
src/thrift/TDispatchProcessor.h \
src/thrift/Thrift.h \
src/thrift/TOutput.h \
- src/thrift/TReflectionLocal.h \
src/thrift/TProcessor.h \
src/thrift/TApplicationException.h \
src/thrift/TLogging.h \
@@ -184,7 +182,6 @@
src/thrift/protocol/TBinaryProtocol.tcc \
src/thrift/protocol/TCompactProtocol.h \
src/thrift/protocol/TCompactProtocol.tcc \
- src/thrift/protocol/TDenseProtocol.h \
src/thrift/protocol/TDebugProtocol.h \
src/thrift/protocol/TBase64Utils.h \
src/thrift/protocol/TJSONProtocol.h \
diff --git a/lib/cpp/libthrift.vcxproj b/lib/cpp/libthrift.vcxproj
index 1fc08b8..b4f1c50 100644
--- a/lib/cpp/libthrift.vcxproj
+++ b/lib/cpp/libthrift.vcxproj
@@ -46,7 +46,6 @@
<ClCompile Include="src\thrift\processor\PeekProcessor.cpp"/>
<ClCompile Include="src\thrift\protocol\TBase64Utils.cpp" />
<ClCompile Include="src\thrift\protocol\TDebugProtocol.cpp"/>
- <ClCompile Include="src\thrift\protocol\TDenseProtocol.cpp"/>
<ClCompile Include="src\thrift\protocol\TJSONProtocol.cpp"/>
<ClCompile Include="src\thrift\protocol\TMultiplexedProtocol.cpp"/>
<ClCompile Include="src\thrift\server\TSimpleServer.cpp"/>
@@ -84,7 +83,6 @@
<ClInclude Include="src\thrift\processor\TMultiplexedProcessor.h" />
<ClInclude Include="src\thrift\protocol\TBinaryProtocol.h" />
<ClInclude Include="src\thrift\protocol\TDebugProtocol.h" />
- <ClInclude Include="src\thrift\protocol\TDenseProtocol.h" />
<ClInclude Include="src\thrift\protocol\TJSONProtocol.h" />
<ClInclude Include="src\thrift\protocol\TMultiplexedProtocol.h" />
<ClInclude Include="src\thrift\protocol\TProtocol.h" />
diff --git a/lib/cpp/libthrift.vcxproj.filters b/lib/cpp/libthrift.vcxproj.filters
index 4effa87..ec21886 100644
--- a/lib/cpp/libthrift.vcxproj.filters
+++ b/lib/cpp/libthrift.vcxproj.filters
@@ -27,9 +27,6 @@
<ClCompile Include="src\thrift\protocol\TDebugProtocol.cpp">
<Filter>protocol</Filter>
</ClCompile>
- <ClCompile Include="src\thrift\protocol\TDenseProtocol.cpp">
- <Filter>protocol</Filter>
- </ClCompile>
<ClCompile Include="src\thrift\protocol\TBase64Utils.cpp">
<Filter>protocol</Filter>
</ClCompile>
@@ -206,9 +203,6 @@
<ClInclude Include="src\thrift\protocol\TMultiplexedProtocol.h">
<Filter>protocol</Filter>
</ClInclude>
- <ClInclude Include="src\thrift\protocol\TDenseProtocol.h">
- <Filter>protocol</Filter>
- </ClInclude>
<ClInclude Include="src\thrift\protocol\TDebugProtocol.h">
<Filter>protocol</Filter>
</ClInclude>
@@ -280,4 +274,4 @@
<Filter>windows\tr1</Filter>
</None>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/lib/cpp/src/thrift/TReflectionLocal.h b/lib/cpp/src/thrift/TReflectionLocal.h
deleted file mode 100644
index 2fc53c8..0000000
--- a/lib/cpp/src/thrift/TReflectionLocal.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef _THRIFT_TREFLECTIONLOCAL_H_
-#define _THRIFT_TREFLECTIONLOCAL_H_ 1
-
-#include <stdint.h>
-#include <cstring>
-#include <thrift/protocol/TProtocol.h>
-
-/**
- * Local Reflection is a blanket term referring to the the structure
- * and generation of this particular representation of Thrift types.
- * (It is called local because it cannot be serialized by Thrift).
- *
- */
-
-namespace apache {
-namespace thrift {
-namespace reflection {
-namespace local {
-
-using apache::thrift::protocol::TType;
-
-// We include this many bytes of the structure's fingerprint when serializing
-// a top-level structure. Long enough to make collisions unlikely, short
-// enough to not significantly affect the amount of memory used.
-const int FP_PREFIX_LEN = 4;
-
-struct FieldMeta {
- int16_t tag;
- bool is_optional;
-};
-
-struct TypeSpec {
- TType ttype;
- uint8_t fp_prefix[FP_PREFIX_LEN];
-
- // Use an anonymous union here so we can fit two TypeSpecs in one cache line.
- union {
- struct {
- // Use parallel arrays here for denser packing (of the arrays).
- FieldMeta* metas;
- TypeSpec** specs;
- } tstruct;
- struct {
- TypeSpec* subtype1;
- TypeSpec* subtype2;
- } tcontainer;
- };
-
- // Static initialization of unions isn't really possible,
- // so take the plunge and use constructors.
- // Hopefully they'll be evaluated at compile time.
-
- TypeSpec(TType ttype) : ttype(ttype) { std::memset(fp_prefix, 0, FP_PREFIX_LEN); }
-
- TypeSpec(TType ttype, const uint8_t* fingerprint, FieldMeta* metas, TypeSpec** specs)
- : ttype(ttype) {
- std::memcpy(fp_prefix, fingerprint, FP_PREFIX_LEN);
- tstruct.metas = metas;
- tstruct.specs = specs;
- }
-
- TypeSpec(TType ttype, TypeSpec* subtype1, TypeSpec* subtype2) : ttype(ttype) {
- std::memset(fp_prefix, 0, FP_PREFIX_LEN);
- tcontainer.subtype1 = subtype1;
- tcontainer.subtype2 = subtype2;
- }
-};
-}
-}
-}
-} // apache::thrift::reflection::local
-
-#endif // #ifndef _THRIFT_TREFLECTIONLOCAL_H_
diff --git a/lib/cpp/src/thrift/Thrift.h b/lib/cpp/src/thrift/Thrift.h
index 962b921..e8e70eb 100644
--- a/lib/cpp/src/thrift/Thrift.h
+++ b/lib/cpp/src/thrift/Thrift.h
@@ -96,13 +96,6 @@
std::string message_;
};
-// Forward declare this structure used by TDenseProtocol
-namespace reflection {
-namespace local {
-struct TypeSpec;
-}
-}
-
class TDelayedException {
public:
template <class E>
diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
index 7291988..e0650cf 100644
--- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
@@ -39,7 +39,7 @@
protected:
static const int32_t VERSION_MASK = ((int32_t)0xffff0000);
static const int32_t VERSION_1 = ((int32_t)0x80010000);
- // VERSION_2 (0x80020000) is taken by TDenseProtocol.
+ // VERSION_2 (0x80020000) was taken by TDenseProtocol (which has since been removed)
public:
TBinaryProtocolT(boost::shared_ptr<Transport_> trans)
diff --git a/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp b/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp
deleted file mode 100644
index 259c68e..0000000
--- a/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
-
-IMPLEMENTATION DETAILS
-
-TDenseProtocol was designed to have a smaller serialized form than
-TBinaryProtocol. This is accomplished using two techniques. The first is
-variable-length integer encoding. We use the same technique that the Standard
-MIDI File format uses for "variable-length quantities"
-(http://en.wikipedia.org/wiki/Variable-length_quantity).
-All integers (including i16, but not byte) are first cast to uint64_t,
-then written out as variable-length quantities. This has the unfortunate side
-effect that all negative numbers require 10 bytes, but negative numbers tend
-to be far less common than positive ones.
-
-The second technique eliminating the field ids used by TBinaryProtocol. This
-decision required support from the Thrift compiler and also sacrifices some of
-the backward and forward compatibility of TBinaryProtocol.
-
-We considered implementing this technique by generating separate readers and
-writers for the dense protocol (this is how Pillar, Thrift's predecessor,
-worked), but this idea had a few problems:
-- Our abstractions go out the window.
-- We would have to maintain a second code generator.
-- Preserving compatibility with old versions of the structures would be a
- nightmare.
-
-Therefore, we chose an alternate implementation that stored the description of
-the data neither in the data itself (like TBinaryProtocol) nor in the
-serialization code (like Pillar), but instead in a separate data structure,
-called a TypeSpec. TypeSpecs are generated by the Thrift compiler
-(specifically in the t_cpp_generator), and their structure should be
-documented there (TODO(dreiss): s/should be/is/).
-
-We maintain a stack of TypeSpecs within the protocol so it knows where the
-generated code is in the reading/writing process. For example, if we are
-writing an i32 contained in a struct bar, contained in a struct foo, then the
-stack would look like: TOP , i32 , struct bar , struct foo , BOTTOM.
-The following invariant: whenever we are about to read/write an object
-(structBegin, containerBegin, or a scalar), the TypeSpec on the top of the
-stack must match the type being read/written. The main reasons that this
-invariant must be maintained is that if we ever start reading a structure, we
-must have its exact TypeSpec in order to pass the right tags to the
-deserializer.
-
-We use the following strategies for maintaining this invariant:
-
-- For structures, we have a separate stack of indexes, one for each structure
- on the TypeSpec stack. These are indexes into the list of fields in the
- structure's TypeSpec. When we {read,write}FieldBegin, we push on the
- TypeSpec for the field.
-- When we begin writing a list or set, we push on the TypeSpec for the
- element type.
-- For maps, we have a separate stack of booleans, one for each map on the
- TypeSpec stack. The boolean is true if we are writing the key for that
- map, and false if we are writing the value. Maps are the trickiest case
- because the generated code does not call any protocol method between
- the key and the value. As a result, we potentially have to switch
- between map key state and map value state after reading/writing any object.
-- This job is handled by the stateTransition method. It is called after
- reading/writing every object. It pops the current TypeSpec off the stack,
- then optionally pushes a new one on, depending on what the next TypeSpec is.
- If it is a struct, the job is left to the next writeFieldBegin. If it is a
- set or list, the just-popped typespec is pushed back on. If it is a map,
- the top of the key/value stack is toggled, and the appropriate TypeSpec
- is pushed.
-
-Optional fields are a little tricky also. We write a zero byte if they are
-absent and prefix them with an 0x01 byte if they are present
-*/
-
-#include <stdint.h>
-#include <thrift/protocol/TDenseProtocol.h>
-#include <thrift/TReflectionLocal.h>
-
-// Leaving this on for now. Disabling it will turn off asserts, which should
-// give a performance boost. When we have *really* thorough test cases,
-// we should drop this.
-#define DEBUG_TDENSEPROTOCOL
-
-// NOTE: Assertions should *only* be used to detect bugs in code,
-// either in TDenseProtocol itself, or in code using it.
-// (For example, using the wrong TypeSpec.)
-// Invalid data should NEVER cause an assertion failure,
-// no matter how grossly corrupted, nor how ingeniously crafted.
-#ifdef DEBUG_TDENSEPROTOCOL
-#undef NDEBUG
-#else
-#define NDEBUG
-#endif
-#include <cassert>
-
-using std::string;
-
-#ifdef __GNUC__
-#define UNLIKELY(val) (__builtin_expect((val), 0))
-#else
-#define UNLIKELY(val) (val)
-#endif
-
-namespace apache {
-namespace thrift {
-namespace protocol {
-
-const int TDenseProtocol::FP_PREFIX_LEN = apache::thrift::reflection::local::FP_PREFIX_LEN;
-
-// Top TypeSpec. TypeSpec of the structure being encoded.
-#define TTS (ts_stack_.back()) // type = TypeSpec*
-// InDeX. Index into TTS of the current/next field to encode.
-#define IDX (idx_stack_.back()) // type = int
-// Field TypeSpec. TypeSpec of the current/next field to encode.
-#define FTS (TTS->tstruct.specs[IDX]) // type = TypeSpec*
-// Field MeTa. Metadata of the current/next field to encode.
-#define FMT (TTS->tstruct.metas[IDX]) // type = FieldMeta
-// SubType 1/2. TypeSpec of the first/second subtype of this container.
-#define ST1 (TTS->tcontainer.subtype1)
-#define ST2 (TTS->tcontainer.subtype2)
-
-/**
- * Checks that @c ttype is indeed the ttype that we should be writing,
- * according to our typespec. Aborts if the test fails and debugging in on.
- */
-inline void TDenseProtocol::checkTType(const TType ttype) {
- assert(!ts_stack_.empty());
- assert(TTS->ttype == ttype);
-}
-
-/**
- * Makes sure that the TypeSpec stack is correct for the next object.
- * See top-of-file comments.
- */
-inline void TDenseProtocol::stateTransition() {
- TypeSpec* old_tts = ts_stack_.back();
- ts_stack_.pop_back();
-
- // If this is the end of the top-level write, we should have just popped
- // the TypeSpec passed to the constructor.
- if (ts_stack_.empty()) {
- assert(old_tts == type_spec_);
- return;
- }
-
- switch (TTS->ttype) {
-
- case T_STRUCT:
- assert(old_tts == FTS);
- break;
-
- case T_LIST:
- case T_SET:
- assert(old_tts == ST1);
- ts_stack_.push_back(old_tts);
- break;
-
- case T_MAP:
- assert(old_tts == (mkv_stack_.back() ? ST1 : ST2));
- mkv_stack_.back() = !mkv_stack_.back();
- ts_stack_.push_back(mkv_stack_.back() ? ST1 : ST2);
- break;
-
- default:
- assert(!"Invalid TType in stateTransition.");
- break;
- }
-}
-
-/*
- * Variable-length quantity functions.
- */
-
-inline uint32_t TDenseProtocol::vlqRead(uint64_t& vlq) {
- uint32_t used = 0;
- uint64_t val = 0;
- uint8_t buf[10]; // 64 bits / (7 bits/byte) = 10 bytes.
- uint32_t buf_size = sizeof(buf);
- const uint8_t* borrowed = trans_->borrow(buf, &buf_size);
-
- // Fast path. TODO(dreiss): Make it faster.
- if (borrowed != NULL) {
- while (true) {
- uint8_t byte = borrowed[used];
- used++;
- val = (val << 7) | (byte & 0x7f);
- if (!(byte & 0x80)) {
- vlq = val;
- trans_->consume(used);
- return used;
- }
- // Have to check for invalid data so we don't crash.
- if (UNLIKELY(used == sizeof(buf))) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA,
- "Variable-length int over 10 bytes.");
- }
- }
- }
-
- // Slow path.
- else {
- while (true) {
- uint8_t byte;
- used += trans_->readAll(&byte, 1);
- val = (val << 7) | (byte & 0x7f);
- if (!(byte & 0x80)) {
- vlq = val;
- return used;
- }
- // Might as well check for invalid data on the slow path too.
- if (UNLIKELY(used >= sizeof(buf))) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA,
- "Variable-length int over 10 bytes.");
- }
- }
- }
-}
-
-inline uint32_t TDenseProtocol::vlqWrite(uint64_t vlq) {
- uint8_t buf[10]; // 64 bits / (7 bits/byte) = 10 bytes.
- int32_t pos = sizeof(buf) - 1;
-
- // Write the thing from back to front.
- buf[pos] = vlq & 0x7f;
- vlq >>= 7;
- pos--;
-
- while (vlq > 0) {
- assert(pos >= 0);
- buf[pos] = static_cast<uint8_t>(vlq | 0x80);
- vlq >>= 7;
- pos--;
- }
-
- // Back up one step before writing.
- pos++;
-
- trans_->write(buf + pos, static_cast<uint32_t>(sizeof(buf) - pos));
- return static_cast<uint32_t>(sizeof(buf) - pos);
-}
-
-/*
- * Writing functions.
- */
-
-uint32_t TDenseProtocol::writeMessageBegin(const std::string& name,
- const TMessageType messageType,
- const int32_t seqid) {
- throw TException("TDenseProtocol doesn't work with messages (yet).");
-
- int32_t version = (VERSION_2) | ((int32_t)messageType);
- uint32_t wsize = 0;
- wsize += subWriteI32(version);
- wsize += subWriteString(name);
- wsize += subWriteI32(seqid);
- return wsize;
-}
-
-uint32_t TDenseProtocol::writeMessageEnd() {
- return 0;
-}
-
-uint32_t TDenseProtocol::writeStructBegin(const char* name) {
- (void)name;
- uint32_t xfer = 0;
-
- // The TypeSpec stack should be empty if this is the top-level read/write.
- // If it is, we push the TypeSpec passed to the constructor.
- if (ts_stack_.empty()) {
- assert(standalone_);
-
- if (type_spec_ == NULL) {
- resetState();
- throw TException("TDenseProtocol: No type specified.");
- } else {
- assert(type_spec_->ttype == T_STRUCT);
- ts_stack_.push_back(type_spec_);
- // Write out a prefix of the structure fingerprint.
- trans_->write(type_spec_->fp_prefix, FP_PREFIX_LEN);
- xfer += FP_PREFIX_LEN;
- }
- }
-
- // We need a new field index for this structure.
- idx_stack_.push_back(0);
- return 0;
-}
-
-uint32_t TDenseProtocol::writeStructEnd() {
- idx_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::writeFieldBegin(const char* name,
- const TType fieldType,
- const int16_t fieldId) {
- (void)name;
- uint32_t xfer = 0;
-
- // Skip over optional fields.
- while (FMT.tag != fieldId) {
- // TODO(dreiss): Old meta here.
- assert(FTS->ttype != T_STOP);
- assert(FMT.is_optional);
- // Write a zero byte so the reader can skip it.
- xfer += subWriteBool(false);
- // And advance to the next field.
- IDX++;
- }
-
- // TODO(dreiss): give a better exception.
- assert(FTS->ttype == fieldType);
-
- if (FMT.is_optional) {
- subWriteBool(true);
- xfer += 1;
- }
-
- // writeFieldStop shares all lot of logic up to this point.
- // Instead of replicating it all, we just call this method from that one
- // and use a gross special case here.
- if (UNLIKELY(FTS->ttype != T_STOP)) {
- // For normal fields, push the TypeSpec that we're about to use.
- ts_stack_.push_back(FTS);
- }
- return xfer;
-}
-
-uint32_t TDenseProtocol::writeFieldEnd() {
- // Just move on to the next field.
- IDX++;
- return 0;
-}
-
-uint32_t TDenseProtocol::writeFieldStop() {
- return TDenseProtocol::writeFieldBegin("", T_STOP, 0);
-}
-
-uint32_t TDenseProtocol::writeMapBegin(const TType keyType,
- const TType valType,
- const uint32_t size) {
- checkTType(T_MAP);
-
- assert(keyType == ST1->ttype);
- assert(valType == ST2->ttype);
-
- ts_stack_.push_back(ST1);
- mkv_stack_.push_back(true);
-
- return subWriteI32((int32_t)size);
-}
-
-uint32_t TDenseProtocol::writeMapEnd() {
- // Pop off the value type, as well as our entry in the map key/value stack.
- // stateTransition takes care of popping off our TypeSpec.
- ts_stack_.pop_back();
- mkv_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::writeListBegin(const TType elemType, const uint32_t size) {
- checkTType(T_LIST);
-
- assert(elemType == ST1->ttype);
- ts_stack_.push_back(ST1);
- return subWriteI32((int32_t)size);
-}
-
-uint32_t TDenseProtocol::writeListEnd() {
- // Pop off the element type. stateTransition takes care of popping off ours.
- ts_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::writeSetBegin(const TType elemType, const uint32_t size) {
- checkTType(T_SET);
-
- assert(elemType == ST1->ttype);
- ts_stack_.push_back(ST1);
- return subWriteI32((int32_t)size);
-}
-
-uint32_t TDenseProtocol::writeSetEnd() {
- // Pop off the element type. stateTransition takes care of popping off ours.
- ts_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::writeBool(const bool value) {
- checkTType(T_BOOL);
- stateTransition();
- return TBinaryProtocol::writeBool(value);
-}
-
-uint32_t TDenseProtocol::writeByte(const int8_t byte) {
- checkTType(T_BYTE);
- stateTransition();
- return TBinaryProtocol::writeByte(byte);
-}
-
-uint32_t TDenseProtocol::writeI16(const int16_t i16) {
- checkTType(T_I16);
- stateTransition();
- return vlqWrite(i16);
-}
-
-uint32_t TDenseProtocol::writeI32(const int32_t i32) {
- checkTType(T_I32);
- stateTransition();
- return vlqWrite(i32);
-}
-
-uint32_t TDenseProtocol::writeI64(const int64_t i64) {
- checkTType(T_I64);
- stateTransition();
- return vlqWrite(i64);
-}
-
-uint32_t TDenseProtocol::writeDouble(const double dub) {
- checkTType(T_DOUBLE);
- stateTransition();
- return TBinaryProtocol::writeDouble(dub);
-}
-
-uint32_t TDenseProtocol::writeString(const std::string& str) {
- checkTType(T_STRING);
- stateTransition();
- return subWriteString(str);
-}
-
-uint32_t TDenseProtocol::writeBinary(const std::string& str) {
- return TDenseProtocol::writeString(str);
-}
-
-inline uint32_t TDenseProtocol::subWriteI32(const int32_t i32) {
- return vlqWrite(i32);
-}
-
-uint32_t TDenseProtocol::subWriteString(const std::string& str) {
- if (str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)()))
- throw TProtocolException(TProtocolException::SIZE_LIMIT);
- uint32_t size = static_cast<uint32_t>(str.size());
- uint32_t xfer = subWriteI32((int32_t)size);
- if (size > 0) {
- trans_->write((uint8_t*)str.data(), size);
- }
- return xfer + size;
-}
-
-/*
- * Reading functions
- *
- * These have a lot of the same logic as the writing functions, so if
- * something is confusing, look for comments in the corresponding writer.
- */
-
-uint32_t TDenseProtocol::readMessageBegin(std::string& name,
- TMessageType& messageType,
- int32_t& seqid) {
- throw TException("TDenseProtocol doesn't work with messages (yet).");
-
- uint32_t xfer = 0;
- int32_t sz;
- xfer += subReadI32(sz);
-
- if (sz < 0) {
- // Check for correct version number
- int32_t version = sz & VERSION_MASK;
- if (version != VERSION_2) {
- throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
- }
- messageType = (TMessageType)(sz & 0x000000ff);
- xfer += subReadString(name);
- xfer += subReadI32(seqid);
- } else {
- throw TProtocolException(TProtocolException::BAD_VERSION,
- "No version identifier... old protocol client in strict mode?");
- }
- return xfer;
-}
-
-uint32_t TDenseProtocol::readMessageEnd() {
- return 0;
-}
-
-uint32_t TDenseProtocol::readStructBegin(string& name) {
- (void)name;
- uint32_t xfer = 0;
-
- if (ts_stack_.empty()) {
- assert(standalone_);
-
- if (type_spec_ == NULL) {
- resetState();
- throw TException("TDenseProtocol: No type specified.");
- } else {
- assert(type_spec_->ttype == T_STRUCT);
- ts_stack_.push_back(type_spec_);
-
- // Check the fingerprint prefix.
- uint8_t buf[FP_PREFIX_LEN];
- xfer += trans_->read(buf, FP_PREFIX_LEN);
- if (std::memcmp(buf, type_spec_->fp_prefix, FP_PREFIX_LEN) != 0) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA,
- "Fingerprint in data does not match type_spec.");
- }
- }
- }
-
- // We need a new field index for this structure.
- idx_stack_.push_back(0);
- return 0;
-}
-
-uint32_t TDenseProtocol::readStructEnd() {
- idx_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::readFieldBegin(string& name, TType& fieldType, int16_t& fieldId) {
- (void)name;
- uint32_t xfer = 0;
-
- // For optional fields, check to see if they are there.
- while (FMT.is_optional) {
- bool is_present;
- xfer += subReadBool(is_present);
- if (is_present) {
- break;
- }
- IDX++;
- }
-
- // Once we hit a mandatory field, or an optional field that is present,
- // we know that FMT and FTS point to the appropriate field.
-
- fieldId = FMT.tag;
- fieldType = FTS->ttype;
-
- // Normally, we push the TypeSpec that we are about to read,
- // but no reading is done for T_STOP.
- if (FTS->ttype != T_STOP) {
- ts_stack_.push_back(FTS);
- }
- return xfer;
-}
-
-uint32_t TDenseProtocol::readFieldEnd() {
- IDX++;
- return 0;
-}
-
-uint32_t TDenseProtocol::readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
- checkTType(T_MAP);
-
- uint32_t xfer = 0;
- int32_t sizei;
- xfer += subReadI32(sizei);
- if (sizei < 0) {
- resetState();
- throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
- } else if (container_limit_ && sizei > container_limit_) {
- resetState();
- throw TProtocolException(TProtocolException::SIZE_LIMIT);
- }
- size = (uint32_t)sizei;
-
- keyType = ST1->ttype;
- valType = ST2->ttype;
-
- ts_stack_.push_back(ST1);
- mkv_stack_.push_back(true);
-
- return xfer;
-}
-
-uint32_t TDenseProtocol::readMapEnd() {
- ts_stack_.pop_back();
- mkv_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::readListBegin(TType& elemType, uint32_t& size) {
- checkTType(T_LIST);
-
- uint32_t xfer = 0;
- int32_t sizei;
- xfer += subReadI32(sizei);
- if (sizei < 0) {
- resetState();
- throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
- } else if (container_limit_ && sizei > container_limit_) {
- resetState();
- throw TProtocolException(TProtocolException::SIZE_LIMIT);
- }
- size = (uint32_t)sizei;
-
- elemType = ST1->ttype;
-
- ts_stack_.push_back(ST1);
-
- return xfer;
-}
-
-uint32_t TDenseProtocol::readListEnd() {
- ts_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::readSetBegin(TType& elemType, uint32_t& size) {
- checkTType(T_SET);
-
- uint32_t xfer = 0;
- int32_t sizei;
- xfer += subReadI32(sizei);
- if (sizei < 0) {
- resetState();
- throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
- } else if (container_limit_ && sizei > container_limit_) {
- resetState();
- throw TProtocolException(TProtocolException::SIZE_LIMIT);
- }
- size = (uint32_t)sizei;
-
- elemType = ST1->ttype;
-
- ts_stack_.push_back(ST1);
-
- return xfer;
-}
-
-uint32_t TDenseProtocol::readSetEnd() {
- ts_stack_.pop_back();
- stateTransition();
- return 0;
-}
-
-uint32_t TDenseProtocol::readBool(bool& value) {
- checkTType(T_BOOL);
- stateTransition();
- return TBinaryProtocol::readBool(value);
-}
-
-uint32_t TDenseProtocol::readByte(int8_t& byte) {
- checkTType(T_BYTE);
- stateTransition();
- return TBinaryProtocol::readByte(byte);
-}
-
-uint32_t TDenseProtocol::readI16(int16_t& i16) {
- checkTType(T_I16);
- stateTransition();
- uint64_t u64;
- uint32_t rv = vlqRead(u64);
- int64_t val = (int64_t)u64;
- if (UNLIKELY(val > INT16_MAX || val < INT16_MIN)) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA, "i16 out of range.");
- }
- i16 = (int16_t)val;
- return rv;
-}
-
-uint32_t TDenseProtocol::readI32(int32_t& i32) {
- checkTType(T_I32);
- stateTransition();
- uint64_t u64;
- uint32_t rv = vlqRead(u64);
- int64_t val = (int64_t)u64;
- if (UNLIKELY(val > INT32_MAX || val < INT32_MIN)) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA, "i32 out of range.");
- }
- i32 = (int32_t)val;
- return rv;
-}
-
-uint32_t TDenseProtocol::readI64(int64_t& i64) {
- checkTType(T_I64);
- stateTransition();
- uint64_t u64;
- uint32_t rv = vlqRead(u64);
- int64_t val = (int64_t)u64;
- if (UNLIKELY(val > INT64_MAX || val < INT64_MIN)) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA, "i64 out of range.");
- }
- i64 = (int64_t)val;
- return rv;
-}
-
-uint32_t TDenseProtocol::readDouble(double& dub) {
- checkTType(T_DOUBLE);
- stateTransition();
- return TBinaryProtocol::readDouble(dub);
-}
-
-uint32_t TDenseProtocol::readString(std::string& str) {
- checkTType(T_STRING);
- stateTransition();
- return subReadString(str);
-}
-
-uint32_t TDenseProtocol::readBinary(std::string& str) {
- return TDenseProtocol::readString(str);
-}
-
-uint32_t TDenseProtocol::subReadI32(int32_t& i32) {
- uint64_t u64;
- uint32_t rv = vlqRead(u64);
- int64_t val = (int64_t)u64;
- if (UNLIKELY(val > INT32_MAX || val < INT32_MIN)) {
- resetState();
- throw TProtocolException(TProtocolException::INVALID_DATA, "i32 out of range.");
- }
- i32 = (int32_t)val;
- return rv;
-}
-
-uint32_t TDenseProtocol::subReadString(std::string& str) {
- uint32_t xfer;
- int32_t size;
- xfer = subReadI32(size);
- return xfer + readStringBody(str, size);
-}
-}
-}
-} // apache::thrift::protocol
diff --git a/lib/cpp/src/thrift/protocol/TDenseProtocol.h b/lib/cpp/src/thrift/protocol/TDenseProtocol.h
deleted file mode 100644
index d7a119a..0000000
--- a/lib/cpp/src/thrift/protocol/TDenseProtocol.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_
-#define _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_ 1
-
-#include <thrift/protocol/TBinaryProtocol.h>
-
-namespace apache {
-namespace thrift {
-namespace protocol {
-
-/**
- * !!!WARNING!!!
- * This class is still highly experimental. Incompatible changes
- * WILL be made to it without notice. DO NOT USE IT YET unless
- * you are coordinating your testing with the author.
- *
- * The dense protocol is designed to use as little space as possible.
- *
- * There are two types of dense protocol instances. Standalone instances
- * are not used for RPC and just encoded and decode structures of
- * a predetermined type. Non-standalone instances are used for RPC.
- * Currently, only standalone instances exist.
- *
- * To use a standalone dense protocol object, you must set the type_spec
- * property (either in the constructor, or with setTypeSpec) to the local
- * reflection TypeSpec of the structures you will write to (or read from) the
- * protocol instance.
- *
- * BEST PRACTICES:
- * - Never use optional for primitives or containers.
- * - Only use optional for structures if they are very big and very rarely set.
- * - All integers are variable-length, so you can use i64 without bloating.
- * - NEVER EVER change the struct definitions IN ANY WAY without either
- * changing your cache keys or talking to dreiss.
- *
- * TODO(dreiss): New class write with old meta.
- *
- * We override all of TBinaryProtocol's methods.
- * We inherit so that we can explicitly call TBPs's primitive-writing
- * methods within our versions.
- *
- */
-class TDenseProtocol : public TVirtualProtocol<TDenseProtocol, TBinaryProtocol> {
-protected:
- static const int32_t VERSION_MASK = ((int32_t)0xffff0000);
- // VERSION_1 (0x80010000) is taken by TBinaryProtocol.
- static const int32_t VERSION_2 = ((int32_t)0x80020000);
-
-public:
- typedef apache::thrift::reflection::local::TypeSpec TypeSpec;
- static const int FP_PREFIX_LEN;
-
- /**
- * @param tran The transport to use.
- * @param type_spec The TypeSpec of the structures using this protocol.
- */
- TDenseProtocol(boost::shared_ptr<TTransport> trans, TypeSpec* type_spec = NULL)
- : TVirtualProtocol<TDenseProtocol, TBinaryProtocol>(trans),
- type_spec_(type_spec),
- standalone_(true) {}
-
- void setTypeSpec(TypeSpec* type_spec) { type_spec_ = type_spec; }
- TypeSpec* getTypeSpec() { return type_spec_; }
-
- /*
- * Writing functions.
- */
-
- uint32_t writeMessageBegin(const std::string& name,
- const TMessageType messageType,
- const int32_t seqid);
-
- uint32_t writeMessageEnd();
-
- uint32_t writeStructBegin(const char* name);
-
- uint32_t writeStructEnd();
-
- uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
-
- uint32_t writeFieldEnd();
-
- uint32_t writeFieldStop();
-
- uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
-
- uint32_t writeMapEnd();
-
- uint32_t writeListBegin(const TType elemType, const uint32_t size);
-
- uint32_t writeListEnd();
-
- uint32_t writeSetBegin(const TType elemType, const uint32_t size);
-
- uint32_t writeSetEnd();
-
- uint32_t writeBool(const bool value);
-
- uint32_t writeByte(const int8_t byte);
-
- uint32_t writeI16(const int16_t i16);
-
- uint32_t writeI32(const int32_t i32);
-
- uint32_t writeI64(const int64_t i64);
-
- uint32_t writeDouble(const double dub);
-
- uint32_t writeString(const std::string& str);
-
- uint32_t writeBinary(const std::string& str);
-
- /*
- * Helper writing functions (don't do state transitions).
- */
- inline uint32_t subWriteI32(const int32_t i32);
-
- inline uint32_t subWriteString(const std::string& str);
-
- uint32_t subWriteBool(const bool value) { return TBinaryProtocol::writeBool(value); }
-
- /*
- * Reading functions
- */
-
- uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid);
-
- uint32_t readMessageEnd();
-
- uint32_t readStructBegin(std::string& name);
-
- uint32_t readStructEnd();
-
- uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId);
-
- uint32_t readFieldEnd();
-
- uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size);
-
- uint32_t readMapEnd();
-
- uint32_t readListBegin(TType& elemType, uint32_t& size);
-
- uint32_t readListEnd();
-
- uint32_t readSetBegin(TType& elemType, uint32_t& size);
-
- uint32_t readSetEnd();
-
- uint32_t readBool(bool& value);
- // Provide the default readBool() implementation for std::vector<bool>
- using TVirtualProtocol<TDenseProtocol, TBinaryProtocol>::readBool;
-
- uint32_t readByte(int8_t& byte);
-
- uint32_t readI16(int16_t& i16);
-
- uint32_t readI32(int32_t& i32);
-
- uint32_t readI64(int64_t& i64);
-
- uint32_t readDouble(double& dub);
-
- uint32_t readString(std::string& str);
-
- uint32_t readBinary(std::string& str);
-
- /*
- * Helper reading functions (don't do state transitions).
- */
- inline uint32_t subReadI32(int32_t& i32);
-
- inline uint32_t subReadString(std::string& str);
-
- uint32_t subReadBool(bool& value) { return TBinaryProtocol::readBool(value); }
-
-private:
- // Implementation functions, documented in the .cpp.
- inline void checkTType(const TType ttype);
- inline void stateTransition();
-
- // Read and write variable-length integers.
- // Uses the same technique as the MIDI file format.
- inline uint32_t vlqRead(uint64_t& vlq);
- inline uint32_t vlqWrite(uint64_t vlq);
-
- // Called before throwing an exception to make the object reusable.
- void resetState() {
- ts_stack_.clear();
- idx_stack_.clear();
- mkv_stack_.clear();
- }
-
- // TypeSpec of the top-level structure to write,
- // for standalone protocol objects.
- TypeSpec* type_spec_;
-
- std::vector<TypeSpec*> ts_stack_; // TypeSpec stack.
- std::vector<int> idx_stack_; // InDeX stack.
- std::vector<bool> mkv_stack_; // Map Key/Vlue stack.
- // True = key, False = value.
-
- // True iff this is a standalone instance (no RPC).
- bool standalone_;
-};
-}
-}
-} // apache::thrift::protocol
-
-#endif // #ifndef _THRIFT_PROTOCOL_TDENSEPROTOCOL_H_
diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt
index 80c6852..9913f6c 100644
--- a/lib/cpp/test/CMakeLists.txt
+++ b/lib/cpp/test/CMakeLists.txt
@@ -325,7 +325,7 @@
add_custom_command(OUTPUT gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h
- COMMAND thrift-compiler --gen cpp:dense ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift
+ COMMAND thrift-compiler --gen cpp ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift
)
add_custom_command(OUTPUT gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h
@@ -337,7 +337,7 @@
)
add_custom_command(OUTPUT gen-cpp/OptionalRequiredTest_types.cpp gen-cpp/OptionalRequiredTest_types.h
- COMMAND thrift-compiler --gen cpp:dense ${PROJECT_SOURCE_DIR}/test/OptionalRequiredTest.thrift
+ COMMAND thrift-compiler --gen cpp ${PROJECT_SOURCE_DIR}/test/OptionalRequiredTest.thrift
)
add_custom_command(OUTPUT gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h
@@ -345,11 +345,11 @@
)
add_custom_command(OUTPUT gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp
- COMMAND thrift-compiler --gen cpp:dense ${PROJECT_SOURCE_DIR}/test/StressTest.thrift
+ COMMAND thrift-compiler --gen cpp ${PROJECT_SOURCE_DIR}/test/StressTest.thrift
)
add_custom_command(OUTPUT gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h
- COMMAND thrift-compiler --gen cpp:dense ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
+ COMMAND thrift-compiler --gen cpp ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
)
add_custom_command(OUTPUT gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h
diff --git a/lib/cpp/test/DenseProtoTest.cpp b/lib/cpp/test/DenseProtoTest.cpp
deleted file mode 100644
index 0beaa38..0000000
--- a/lib/cpp/test/DenseProtoTest.cpp
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
-../compiler/cpp/thrift --gen cpp:dense DebugProtoTest.thrift
-../compiler/cpp/thrift --gen cpp:dense OptionalRequiredTest.thrift
-g++ -Wall -g -I../lib/cpp/src -I/usr/local/include/boost-1_33_1 \
- gen-cpp/OptionalRequiredTest_types.cpp \
- gen-cpp/DebugProtoTest_types.cpp \
- DenseProtoTest.cpp ../lib/cpp/.libs/libthrift.a -o DenseProtoTest
-./DenseProtoTest
-*/
-
-// I do this to reach into the guts of TDenseProtocol. Sorry.
-#define private public
-#define inline
-
-#undef NDEBUG
-#include <cstdlib>
-#include <cassert>
-#include <cmath>
-#include <string>
-#include "gen-cpp/DebugProtoTest_types.h"
-#include "gen-cpp/OptionalRequiredTest_types.h"
-#include <thrift/protocol/TDenseProtocol.h>
-#include <thrift/transport/TBufferTransports.h>
-
-#define BOOST_TEST_MODULE DenseProtoTest
-#include <boost/test/unit_test.hpp>
-
-using std::string;
-using boost::shared_ptr;
-using namespace thrift::test;
-using namespace thrift::test::debug;
-using namespace apache::thrift::transport;
-using namespace apache::thrift::protocol;
-
-// Can't use memcmp here. GCC is too smart.
-bool my_memeq(const char* str1, const char* str2, int len) {
- for (int i = 0; i < len; i++) {
- if (str1[i] != str2[i]) {
- return false;
- }
- }
- return true;
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_1) {
- OneOfEach ooe;
- ooe.im_true = true;
- ooe.im_false = false;
- ooe.a_bite = 0xd6;
- ooe.integer16 = 27000;
- ooe.integer32 = 1 << 24;
- ooe.integer64 = (uint64_t)6000 * 1000 * 1000;
- ooe.double_precision = M_PI;
- ooe.some_characters = "Debug THIS!";
- ooe.zomg_unicode = "\xd7\n\a\t";
-
- // cout << apache::thrift::ThriftDebugString(ooe) << endl << endl;
-
- Nesting n;
- n.my_ooe = ooe;
- n.my_ooe.integer16 = 16;
- n.my_ooe.integer32 = 32;
- n.my_ooe.integer64 = 64;
- n.my_ooe.double_precision = (std::sqrt(5) + 1) / 2;
- n.my_ooe.some_characters = ":R (me going \"rrrr\")";
- n.my_ooe.zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20"
- "\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"
- "\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80\xbc";
- n.my_bonk.type = 31337;
- n.my_bonk.message = "I am a bonk... xor!";
-
- // cout << apache::thrift::ThriftDebugString(n) << endl << endl;
-
- HolyMoley hm;
-
- hm.big.push_back(ooe);
- hm.big.push_back(n.my_ooe);
- hm.big[0].a_bite = 0x22;
- hm.big[1].a_bite = 0x33;
-
- std::vector<std::string> stage1;
- stage1.push_back("and a one");
- stage1.push_back("and a two");
- hm.contain.insert(stage1);
- stage1.clear();
- stage1.push_back("then a one, two");
- stage1.push_back("three!");
- stage1.push_back("FOUR!!");
- hm.contain.insert(stage1);
- stage1.clear();
- hm.contain.insert(stage1);
-
- std::vector<Bonk> stage2;
- hm.bonks["nothing"] = stage2;
- stage2.resize(stage2.size() + 1);
- stage2.back().type = 1;
- stage2.back().message = "Wait.";
- stage2.resize(stage2.size() + 1);
- stage2.back().type = 2;
- stage2.back().message = "What?";
- hm.bonks["something"] = stage2;
- stage2.clear();
- stage2.resize(stage2.size() + 1);
- stage2.back().type = 3;
- stage2.back().message = "quoth";
- stage2.resize(stage2.size() + 1);
- stage2.back().type = 4;
- stage2.back().message = "the raven";
- stage2.resize(stage2.size() + 1);
- stage2.back().type = 5;
- stage2.back().message = "nevermore";
- hm.bonks["poe"] = stage2;
-
- // cout << apache::thrift::ThriftDebugString(hm) << endl << endl;
-
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- proto->setTypeSpec(HolyMoley::local_reflection);
-
- hm.write(proto.get());
- HolyMoley hm2;
- hm2.read(proto.get());
-
- BOOST_CHECK(hm == hm2);
-}
-
-/*
- * Following Testcases are currently disabled, because vlqWrite and vlqRead are
- * private members.
- */
-#if 0
-#define checkout(i, c) \
- { \
- uint64_t vlq; \
- buffer->resetBuffer(); \
- proto->vlqWrite(i); \
- proto->getTransport()->flush(); \
- BOOST_CHECK(my_memeq(buffer->getBufferAsString().data(), c, sizeof(c) - 1));\
- proto->vlqRead(vlq); \
- assert(vlq == i); \
- }
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_2) {
- // Let's test out the variable-length ints, shall we?
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
-
- proto->setTypeSpec(HolyMoley::local_reflection);
-
- checkout(0x00000000, "\x00");
- checkout(0x00000040, "\x40");
- checkout(0x0000007F, "\x7F");
- checkout(0x00000080, "\x81\x00");
- checkout(0x00002000, "\xC0\x00");
- checkout(0x00003FFF, "\xFF\x7F");
- checkout(0x00004000, "\x81\x80\x00");
- checkout(0x00100000, "\xC0\x80\x00");
- checkout(0x001FFFFF, "\xFF\xFF\x7F");
- checkout(0x00200000, "\x81\x80\x80\x00");
- checkout(0x08000000, "\xC0\x80\x80\x00");
- checkout(0x0FFFFFFF, "\xFF\xFF\xFF\x7F");
- checkout(0x10000000, "\x81\x80\x80\x80\x00");
- checkout(0x20000000, "\x82\x80\x80\x80\x00");
- checkout(0x1FFFFFFF, "\x81\xFF\xFF\xFF\x7F");
- checkout(0xFFFFFFFF, "\x8F\xFF\xFF\xFF\x7F");
-
- checkout(0x0000000100000000ull, "\x90\x80\x80\x80\x00");
- checkout(0x0000000200000000ull, "\xA0\x80\x80\x80\x00");
- checkout(0x0000000300000000ull, "\xB0\x80\x80\x80\x00");
- checkout(0x0000000700000000ull, "\xF0\x80\x80\x80\x00");
- checkout(0x00000007F0000000ull, "\xFF\x80\x80\x80\x00");
- checkout(0x00000007FFFFFFFFull, "\xFF\xFF\xFF\xFF\x7F");
- checkout(0x0000000800000000ull, "\x81\x80\x80\x80\x80\x00");
- checkout(0x1FFFFFFFFFFFFFFFull, "\x9F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
- checkout(0x7FFFFFFFFFFFFFFFull, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
- checkout(0xFFFFFFFFFFFFFFFFull, "\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_3) {
- // Test out the slow path with a TBufferedTransport.
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- shared_ptr<TBufferedTransport> buff_trans(new TBufferedTransport(buffer, 3));
-
- proto->setTypeSpec(HolyMoley::local_reflection);
- proto.reset(new TDenseProtocol(buff_trans));
-
- checkout(0x0000000100000000ull, "\x90\x80\x80\x80\x00");
- checkout(0x0000000200000000ull, "\xA0\x80\x80\x80\x00");
- checkout(0x0000000300000000ull, "\xB0\x80\x80\x80\x00");
- checkout(0x0000000700000000ull, "\xF0\x80\x80\x80\x00");
- checkout(0x00000007F0000000ull, "\xFF\x80\x80\x80\x00");
- checkout(0x00000007FFFFFFFFull, "\xFF\xFF\xFF\xFF\x7F");
- checkout(0x0000000800000000ull, "\x81\x80\x80\x80\x80\x00");
- checkout(0x1FFFFFFFFFFFFFFFull, "\x9F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
- checkout(0x7FFFFFFFFFFFFFFFull, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
- checkout(0xFFFFFFFFFFFFFFFFull, "\x81\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
-}
-#endif
-
-// Test optional stuff.
-BOOST_AUTO_TEST_CASE(test_dense_proto_4_1) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- proto.reset(new TDenseProtocol(buffer));
- proto->setTypeSpec(ManyOpt::local_reflection);
-
- ManyOpt mo1, mo2;
- mo1.opt1 = 923759347;
- mo1.opt2 = 392749274;
- mo1.opt3 = 395739402;
- mo1.def4 = 294730928;
- mo1.opt5 = 394309218;
- mo1.opt6 = 832194723;
- mo1.__isset.opt1 = true;
- mo1.__isset.opt2 = true;
- mo1.__isset.opt3 = true;
- mo1.__isset.def4 = true;
- mo1.__isset.opt5 = true;
- mo1.__isset.opt6 = true;
-
- mo1.write(proto.get());
- mo2.read(proto.get());
-
- BOOST_CHECK(mo2.__isset.opt1 == true);
- BOOST_CHECK(mo2.__isset.opt2 == true);
- BOOST_CHECK(mo2.__isset.opt3 == true);
- BOOST_CHECK(mo2.__isset.def4 == true);
- BOOST_CHECK(mo2.__isset.opt5 == true);
- BOOST_CHECK(mo2.__isset.opt6 == true);
-
- BOOST_CHECK(mo1 == mo2);
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_4_2) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- proto.reset(new TDenseProtocol(buffer));
- proto->setTypeSpec(ManyOpt::local_reflection);
-
- ManyOpt mo1, mo2;
- mo1.opt1 = 923759347;
- mo1.opt2 = 392749274;
- mo1.opt3 = 395739402;
- mo1.def4 = 294730928;
- mo1.opt5 = 394309218;
- mo1.opt6 = 832194723;
- mo1.__isset.opt1 = false;
- mo1.__isset.opt2 = true;
- mo1.__isset.opt3 = false;
- mo1.__isset.def4 = true;
- mo1.__isset.opt5 = false;
- mo1.__isset.opt6 = true;
-
- mo1.write(proto.get());
- mo2.read(proto.get());
-
- BOOST_CHECK(mo2.__isset.opt1 == false);
- BOOST_CHECK(mo2.__isset.opt2 == true);
- BOOST_CHECK(mo2.__isset.opt3 == false);
- BOOST_CHECK(mo2.__isset.def4 == true);
- BOOST_CHECK(mo2.__isset.opt5 == false);
- BOOST_CHECK(mo2.__isset.opt6 == true);
-
- BOOST_CHECK(mo1 == mo2);
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_4_3) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- proto.reset(new TDenseProtocol(buffer));
- proto->setTypeSpec(ManyOpt::local_reflection);
-
- ManyOpt mo1, mo2;
- mo1.opt1 = 923759347;
- mo1.opt2 = 392749274;
- mo1.opt3 = 395739402;
- mo1.def4 = 294730928;
- mo1.opt5 = 394309218;
- mo1.opt6 = 832194723;
- mo1.__isset.opt1 = true;
- mo1.__isset.opt2 = false;
- mo1.__isset.opt3 = true;
- mo1.__isset.def4 = true;
- mo1.__isset.opt5 = true;
- mo1.__isset.opt6 = false;
-
- mo1.write(proto.get());
- mo2.read(proto.get());
-
- BOOST_CHECK(mo2.__isset.opt1 == true);
- BOOST_CHECK(mo2.__isset.opt2 == false);
- BOOST_CHECK(mo2.__isset.opt3 == true);
- BOOST_CHECK(mo2.__isset.def4 == true);
- BOOST_CHECK(mo2.__isset.opt5 == true);
- BOOST_CHECK(mo2.__isset.opt6 == false);
-
- BOOST_CHECK(mo1 == mo2);
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_4_4) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- proto.reset(new TDenseProtocol(buffer));
- proto->setTypeSpec(ManyOpt::local_reflection);
-
- ManyOpt mo1, mo2;
- mo1.opt1 = 923759347;
- mo1.opt2 = 392749274;
- mo1.opt3 = 395739402;
- mo1.def4 = 294730928;
- mo1.opt5 = 394309218;
- mo1.opt6 = 832194723;
- mo1.__isset.opt1 = false;
- mo1.__isset.opt2 = false;
- mo1.__isset.opt3 = true;
- mo1.__isset.def4 = true;
- mo1.__isset.opt5 = false;
- mo1.__isset.opt6 = false;
-
- mo1.write(proto.get());
- mo2.read(proto.get());
-
- BOOST_CHECK(mo2.__isset.opt1 == false);
- BOOST_CHECK(mo2.__isset.opt2 == false);
- BOOST_CHECK(mo2.__isset.opt3 == true);
- BOOST_CHECK(mo2.__isset.def4 == true);
- BOOST_CHECK(mo2.__isset.opt5 == false);
- BOOST_CHECK(mo2.__isset.opt6 == false);
-
- BOOST_CHECK(mo1 == mo2);
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_4_5) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
- proto.reset(new TDenseProtocol(buffer));
- proto->setTypeSpec(ManyOpt::local_reflection);
-
- ManyOpt mo1, mo2;
- mo1.opt1 = 923759347;
- mo1.opt2 = 392749274;
- mo1.opt3 = 395739402;
- mo1.def4 = 294730928;
- mo1.opt5 = 394309218;
- mo1.opt6 = 832194723;
- mo1.__isset.opt1 = false;
- mo1.__isset.opt2 = false;
- mo1.__isset.opt3 = false;
- mo1.__isset.def4 = true;
- mo1.__isset.opt5 = false;
- mo1.__isset.opt6 = false;
-
- mo1.write(proto.get());
- mo2.read(proto.get());
-
- BOOST_CHECK(mo2.__isset.opt1 == false);
- BOOST_CHECK(mo2.__isset.opt2 == false);
- BOOST_CHECK(mo2.__isset.opt3 == false);
- BOOST_CHECK(mo2.__isset.def4 == true);
- BOOST_CHECK(mo2.__isset.opt5 == false);
- BOOST_CHECK(mo2.__isset.opt6 == false);
-
- BOOST_CHECK(mo1 == mo2);
-}
-
-// Test fingerprint checking stuff.
-BOOST_AUTO_TEST_CASE(test_dense_proto_5_1) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
-
- // Default and required have the same fingerprint.
- Tricky1 t1;
- Tricky3 t3;
- BOOST_CHECK(string(Tricky1::ascii_fingerprint) == Tricky3::ascii_fingerprint);
- proto->setTypeSpec(Tricky1::local_reflection);
- t1.im_default = 227;
- t1.write(proto.get());
- proto->setTypeSpec(Tricky3::local_reflection);
- t3.read(proto.get());
- BOOST_CHECK(t3.im_required == 227);
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_5_2) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
-
- // Optional changes things.
- Tricky1 t1;
- Tricky2 t2;
- BOOST_CHECK(string(Tricky1::ascii_fingerprint) != Tricky2::ascii_fingerprint);
- proto->setTypeSpec(Tricky1::local_reflection);
- t1.im_default = 227;
- t1.write(proto.get());
- try {
- proto->setTypeSpec(Tricky2::local_reflection);
- t2.read(proto.get());
- BOOST_CHECK(false);
- } catch (TProtocolException& ex) {
- buffer->resetBuffer();
- }
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_5_3) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
-
- // Holy cow. We can use the Tricky1 typespec with the Tricky2 structure.
- Tricky1 t1;
- Tricky2 t2;
- proto->setTypeSpec(Tricky1::local_reflection);
- t1.im_default = 227;
- t1.write(proto.get());
- t2.read(proto.get());
- BOOST_CHECK(t2.__isset.im_optional == true);
- BOOST_CHECK(t2.im_optional == 227);
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_5_4) {
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
-
- // And totally off the wall.
- Tricky1 t1;
- OneOfEach ooe2;
- BOOST_CHECK(string(Tricky1::ascii_fingerprint) != OneOfEach::ascii_fingerprint);
- proto->setTypeSpec(Tricky1::local_reflection);
- t1.im_default = 227;
- t1.write(proto.get());
- try {
- proto->setTypeSpec(OneOfEach::local_reflection);
- ooe2.read(proto.get());
- BOOST_CHECK(false);
- } catch (TProtocolException& ex) {
- buffer->resetBuffer();
- }
-}
-
-BOOST_AUTO_TEST_CASE(test_dense_proto_6) {
- // Okay, this is really off the wall.
- // Just don't crash.
- shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- shared_ptr<TDenseProtocol> proto(new TDenseProtocol(buffer));
-
- BOOST_TEST_MESSAGE("Starting fuzz test. This takes a while.");
- std::srand(12345);
- for (int i = 0; i < 2000; i++) {
- if (i % 100 == 0) {
- BOOST_TEST_MESSAGE("Do " << i / 100 << "/" << 2000 / 100);
- }
- buffer->resetBuffer();
- // Make sure the fingerprint prefix is right.
- buffer->write(Nesting::binary_fingerprint, 4);
- for (int j = 0; j < 1024 * 1024; j++) {
- uint8_t r = std::rand();
- buffer->write(&r, 1);
- }
- Nesting n;
- proto->setTypeSpec(OneOfEach::local_reflection);
- try {
- n.read(proto.get());
- } catch (TProtocolException& ex) {
- } catch (TTransportException& ex) {
- }
- }
-}
diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am
index 70efa6b..dadbe38 100755
--- a/lib/cpp/test/Makefile.am
+++ b/lib/cpp/test/Makefile.am
@@ -89,8 +89,7 @@
TFileTransportTest \
link_test \
OpenSSLManualInitTest \
- EnumTest \
- DenseProtoTest
+ EnumTest
if AMX_HAVE_LIBEVENT
noinst_PROGRAMS += \
@@ -276,16 +275,6 @@
$(BOOST_TEST_LDADD)
#
-# DenseProtoTest
-#
-DenseProtoTest_SOURCES = \
- DenseProtoTest.cpp
-
-DenseProtoTest_LDADD = \
- libtestgencpp.la \
- $(BOOST_TEST_LDADD)
-
-#
# SpecializationTest
#
SpecializationTest_SOURCES = \
@@ -337,7 +326,7 @@
THRIFT = $(top_builddir)/compiler/cpp/thrift
gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h: $(top_srcdir)/test/DebugProtoTest.thrift
- $(THRIFT) --gen cpp:dense $<
+ $(THRIFT) --gen cpp $<
gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h: $(top_srcdir)/test/EnumTest.thrift
$(THRIFT) --gen cpp $<
@@ -346,16 +335,16 @@
$(THRIFT) --gen cpp $<
gen-cpp/OptionalRequiredTest_types.cpp gen-cpp/OptionalRequiredTest_types.h: $(top_srcdir)/test/OptionalRequiredTest.thrift
- $(THRIFT) --gen cpp:dense $<
+ $(THRIFT) --gen cpp $<
gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h: $(top_srcdir)/test/Recursive.thrift
$(THRIFT) --gen cpp $<
gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp: $(top_srcdir)/test/StressTest.thrift
- $(THRIFT) --gen cpp:dense $<
+ $(THRIFT) --gen cpp $<
gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h: $(top_srcdir)/test/ThriftTest.thrift
- $(THRIFT) --gen cpp:dense $<
+ $(THRIFT) --gen cpp $<
gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h: processor/proc.thrift
$(THRIFT) --gen cpp:templates,cob_style $<