diff options
author | 2016-07-31 15:35:51 -0700 | |
---|---|---|
committer | 2016-07-31 15:35:51 -0700 | |
commit | bc618eed71f1c2a2b69351a6aa60e8bb460773b9 (patch) | |
tree | f1a2681e249121f6a88ec5b85f93502d80aa4956 /include/grpc++/impl/codegen | |
parent | 4d8283f93bed3b9d35362cad2c4fb38474b547d6 (diff) |
thrift serializer
Diffstat (limited to 'include/grpc++/impl/codegen')
-rw-r--r-- | include/grpc++/impl/codegen/thrift_serializer.h | 148 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/thrift_serializer_inl.h | 169 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/thrift_utils.h | 90 |
3 files changed, 407 insertions, 0 deletions
diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h new file mode 100644 index 0000000000..315d76cf2a --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -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 diff --git a/include/grpc++/impl/codegen/thrift_serializer_inl.h b/include/grpc++/impl/codegen/thrift_serializer_inl.h new file mode 100644 index 0000000000..866ecf6312 --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer_inl.h @@ -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 diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h new file mode 100644 index 0000000000..629441149f --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -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 |