thrift serializer

pull/7594/head
chedeti 9 years ago
parent 4d8283f93b
commit bc618eed71
  1. 3
      Makefile
  2. 9
      build.yaml
  3. 148
      include/grpc++/impl/codegen/thrift_serializer.h
  4. 169
      include/grpc++/impl/codegen/thrift_serializer_inl.h
  5. 90
      include/grpc++/impl/codegen/thrift_utils.h
  6. 22
      tools/run_tests/sources_and_headers.json
  7. 3
      vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
  8. 9
      vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters

@ -3923,6 +3923,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/time.h \
include/grpc++/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
include/grpc++/impl/codegen/thrift_serializer.h \
include/grpc++/impl/codegen/thrift_serializer_inl.h \
include/grpc++/impl/codegen/thrift_utils.h \
LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))

@ -780,6 +780,14 @@ filegroups:
- src/cpp/ext/reflection.pb.cc
uses:
- grpc++_codegen_proto
- name: thrift_util
language: c++
public_headers:
- include/grpc++/impl/codegen/thrift_serializer.h
- include/grpc++/impl/codegen/thrift_serializer_inl.h
- include/grpc++/impl/codegen/thrift_utils.h
uses:
- grpc++_codegen_base
libs:
- name: gpr
build: all
@ -1021,6 +1029,7 @@ libs:
- grpc++_codegen_base_src
- grpc++_codegen_proto
- grpc++_config_proto
- thrift_util
- name: grpc++_unsecure
build: all
language: c++

@ -0,0 +1,148 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
#include <memory>
#include <string>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TCompactProtocol.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TTransportUtils.h>
#include <grpc/impl/codegen/byte_buffer.h>
namespace apache {
namespace thrift {
namespace util {
using apache::thrift::protocol::TBinaryProtocolT;
using apache::thrift::protocol::TCompactProtocolT;
using apache::thrift::protocol::TNetworkBigEndian;
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::transport::TBufferBase;
using apache::thrift::transport::TTransport;
using std::shared_ptr;
template <typename Dummy, typename P>
class ThriftSerializer {
public:
ThriftSerializer()
: prepared_ (false)
, lastDeserialized_ (false)
, serializeVersion_ (false) {}
/**
* Serialize the passed type into the internal buffer
* and returns a pointer to internal buffer and its size
*
*/
template <typename T>
void serialize(const T& fields, const uint8_t** serializedBuffer,
size_t* serializedLen);
/**
* Serialize the passed type into the byte buffer
*/
template <typename T>
void serialize(const T& fields, grpc_byte_buffer** bp);
/**
* Deserialize the passed char array into the passed type, returns the number
* of bytes that have been consumed from the passed string.
*/
template <typename T>
uint32_t deserialize(const uint8_t* serializedBuffer, size_t length,
T* fields);
/**
* Deserialize the passed byte buffer to passed type, returns the number
* of bytes consumed from byte buffer
*/
template <typename T>
uint32_t deserialize(grpc_byte_buffer* buffer, T* msg);
void setSerializeVersion(bool value);
virtual ~ThriftSerializer() {}
/**
* Set the container size limit to deserialize
* This function should be called after buffer_ is initialized
*/
void setContainerSizeLimit(int32_t container_limit) {
if (!prepared_) {
prepare();
}
protocol_->setContainerSizeLimit(container_limit);
}
/**
* Set the string size limit to deserialize
* This function should be called after buffer_ is initialized
*/
void setStringSizeLimit(int32_t string_limit) {
if (!prepared_) {
prepare();
}
protocol_->setStringSizeLimit(string_limit);
}
private:
void prepare();
private:
typedef P Protocol;
bool prepared_;
bool lastDeserialized_;
boost::shared_ptr<TMemoryBuffer> buffer_;
shared_ptr<Protocol> protocol_;
bool serializeVersion_;
}; // ThriftSerializer
template <typename Dummy = void>
struct ThriftSerializerBinary : public ThriftSerializer<Dummy, TBinaryProtocolT<TBufferBase, TNetworkBigEndian> > {};
template <typename Dummy = void>
struct ThriftSerializerCompact : public ThriftSerializer<Dummy, TCompactProtocolT<TBufferBase> >{ };
}}} // namespace apache::thrift::util
#include <grpc++/impl/codegen/thrift_serializer_inl.h>
#endif

@ -0,0 +1,169 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H
#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H
#include <stdexcept>
#include <string>
#include <grpc++/impl/codegen/thrift_serializer.h>
#include <grpc/impl/codegen/byte_buffer_reader.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/slice_buffer.h>
#include <thrift/protocol/TProtocolException.h>
namespace apache {
namespace thrift {
namespace util {
using apache::thrift::protocol::TMessageType;
template <typename Dummy, typename P>
template <typename T>
void ThriftSerializer<Dummy, P>::serialize(const T& fields,
const uint8_t** serializedBuffer, size_t* serializedLen) {
// prepare or reset buffer
if (!prepared_ || lastDeserialized_) {
prepare();
} else {
buffer_->resetBuffer();
}
lastDeserialized_ = false;
// if required serialize protocol version
if (serializeVersion_) {
protocol_->writeMessageBegin("", TMessageType(0), 0);
}
// serilaize fields into buffer
fields.write(protocol_.get());
// write the end of message
if (serializeVersion_) {
protocol_->writeMessageEnd();
}
// assign buffer to string
uint8_t* byteBuffer;
uint32_t byteBufferSize;
buffer_->getBuffer(&byteBuffer, &byteBufferSize);
*serializedBuffer = byteBuffer;
*serializedLen = byteBufferSize;
}
template <typename Dummy, typename P>
template <typename T>
void ThriftSerializer<Dummy, P>::serialize(const T& fields, grpc_byte_buffer** bp) {
const uint8_t* byteBuffer;
size_t byteBufferSize;
serialize(fields, &byteBuffer, &byteBufferSize);
gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize);
*bp = grpc_raw_byte_buffer_create(&slice, 1);
gpr_slice_unref(slice);
}
template <typename Dummy, typename P>
template <typename T>
uint32_t ThriftSerializer<Dummy, P>::deserialize(const uint8_t* serializedBuffer,
size_t length, T* fields) {
// prepare buffer if necessary
if (!prepared_) {
prepare();
}
lastDeserialized_ = true;
//reset buffer transport
buffer_->resetBuffer((uint8_t*)serializedBuffer, length);
// read the protocol version if necessary
if (serializeVersion_) {
std::string name = "";
TMessageType mt = (TMessageType) 0;
int32_t seq_id = 0;
protocol_->readMessageBegin(name, mt, seq_id);
}
// deserialize buffer into fields
uint32_t len = fields->read(protocol_.get());
// read the end of message
if (serializeVersion_) {
protocol_->readMessageEnd();
}
return len;
}
template <typename Dummy, typename P>
template <typename T>
uint32_t ThriftSerializer<Dummy, P>::deserialize(grpc_byte_buffer* bp, T* fields) {
grpc_byte_buffer_reader reader;
grpc_byte_buffer_reader_init(&reader, bp);
gpr_slice slice = grpc_byte_buffer_reader_readall(&reader);
uint32_t len = deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), fields);
gpr_slice_unref(slice);
grpc_byte_buffer_reader_destroy(&reader);
return len;
}
template <typename Dummy, typename P>
void ThriftSerializer<Dummy, P>::setSerializeVersion(bool value) {
serializeVersion_ = value;
}
template <typename Dummy, typename P>
void
ThriftSerializer<Dummy, P>::prepare()
{
buffer_.reset(new TMemoryBuffer());
// create a protocol for the memory buffer transport
protocol_.reset(new Protocol(buffer_));
prepared_ = true;
}
}}} // namespace apache::thrift::util
#endif

@ -0,0 +1,90 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
#include <grpc/impl/codegen/byte_buffer.h>
#include <grpc/impl/codegen/byte_buffer_reader.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/slice_buffer.h>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/core_codegen_interface.h>
#include <grpc++/impl/codegen/serialization_traits.h>
#include <grpc++/impl/codegen/status.h>
#include <grpc++/impl/codegen/status_code_enum.h>
#include <grpc++/impl/codegen/thrift_serializer.h>
#include <cstdbool>
#include <cstdint>
#include <string>
#include <cstdlib>
namespace grpc {
using apache::thrift::util::ThriftSerializerCompact;
template <class T>
class SerializationTraits<T,typename std::enable_if<std::is_base_of<apache::thrift::TBase, T>::value>::type> {
public:
static Status Serialize(const T& msg,
grpc_byte_buffer** bp, bool* own_buffer) {
*own_buffer = true;
ThriftSerializerCompact<T> serializer;
serializer.serialize(msg, bp);
return Status(StatusCode::OK, "ok");
}
static Status Deserialize(grpc_byte_buffer* buffer,
T* msg,
int max_message_size) {
if (!buffer) {
return Status(StatusCode::INTERNAL, "No payload");
}
ThriftSerializerCompact<T> deserializer;
deserializer.deserialize(buffer, msg);
grpc_byte_buffer_destroy(buffer);
return Status(StatusCode::OK, "ok");
}
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H

@ -4411,7 +4411,8 @@
"grpc++_codegen_base_src",
"grpc++_codegen_proto",
"grpc++_config_proto",
"grpc_test_util"
"grpc_test_util",
"thrift_util"
],
"headers": [
"src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h",
@ -6784,5 +6785,24 @@
],
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"grpc++_codegen_base"
],
"headers": [
"include/grpc++/impl/codegen/thrift_serializer.h",
"include/grpc++/impl/codegen/thrift_serializer_inl.h",
"include/grpc++/impl/codegen/thrift_utils.h"
],
"language": "c++",
"name": "thrift_util",
"src": [
"include/grpc++/impl/codegen/thrift_serializer.h",
"include/grpc++/impl/codegen/thrift_serializer_inl.h",
"include/grpc++/impl/codegen/thrift_utils.h"
],
"third_party": false,
"type": "filegroup"
}
]

@ -200,6 +200,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer_inl.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_utils.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h" />

@ -192,6 +192,15 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer_inl.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_utils.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h">

Loading…
Cancel
Save