Skip to content

Commit

Permalink
thrift serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
chedeti committed Jul 31, 2016
1 parent 4d8283f commit bc618ee
Show file tree
Hide file tree
Showing 8 changed files with 452 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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))))

Expand Down
9 changes: 9 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1021,6 +1029,7 @@ libs:
- grpc++_codegen_base_src
- grpc++_codegen_proto
- grpc++_config_proto
- thrift_util
- name: grpc++_unsecure
build: all
language: c++
Expand Down
148 changes: 148 additions & 0 deletions include/grpc++/impl/codegen/thrift_serializer.h
Original file line number Diff line number Diff line change
@@ -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
169 changes: 169 additions & 0 deletions include/grpc++/impl/codegen/thrift_serializer_inl.h
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit bc618ee

Please sign in to comment.