Base the new SerializationTraits API on implicit type conversion rather than SFINAE

pull/12573/head
Vijay Pai 7 years ago
parent efce6e1e50
commit a44cffa11f
  1. 45
      include/grpc++/impl/codegen/byte_buffer.h
  2. 76
      include/grpc++/impl/codegen/call.h
  3. 8
      include/grpc++/impl/codegen/method_handler_impl.h
  4. 10
      include/grpc++/impl/codegen/serialization_traits.h
  5. 24
      src/cpp/util/byte_buffer_cc.cc

@ -34,10 +34,14 @@ namespace grpc {
template <class R> template <class R>
class CallOpRecvMessage; class CallOpRecvMessage;
class MethodHandler; class MethodHandler;
namespace internal { template <class ServiceType, class RequestType, class ResponseType>
template <class M, class T> class RpcMethodHandler;
class MessageDeserializer; template <class ServiceType, class RequestType, class ResponseType>
} class ServerStreamingHandler;
namespace CallOpGenericRecvMessageHelper {
template <class R>
class DeserializeFuncType;
} // namespace CallOpGenericRecvMessageHelper
/// A sequence of bytes. /// A sequence of bytes.
class ByteBuffer final { class ByteBuffer final {
@ -98,8 +102,14 @@ class ByteBuffer final {
friend class CallOpRecvMessage; friend class CallOpRecvMessage;
friend class CallOpGenericRecvMessage; friend class CallOpGenericRecvMessage;
friend class MethodHandler; friend class MethodHandler;
template <class M, class T> template <class ServiceType, class RequestType, class ResponseType>
friend class internal::MessageDeserializer; friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class R>
friend class CallOpGenericRecvMessageHelper::DeserializeFuncType;
grpc_byte_buffer* buffer_;
// takes ownership // takes ownership
void set_buffer(grpc_byte_buffer* buf) { void set_buffer(grpc_byte_buffer* buf) {
@ -112,20 +122,25 @@ class ByteBuffer final {
grpc_byte_buffer* c_buffer() { return buffer_; } grpc_byte_buffer* c_buffer() { return buffer_; }
grpc_byte_buffer** c_buffer_ptr() { return &buffer_; } grpc_byte_buffer** c_buffer_ptr() { return &buffer_; }
// DEPRECATED: Implicit conversion to transparently class ByteBufferPointer {
// support deprecated SerializationTraits API public:
// No need to inline since deprecated ByteBufferPointer(const ByteBuffer* b)
operator grpc_byte_buffer*(); : bbuf_(const_cast<ByteBuffer*>(b)) {}
operator const grpc_byte_buffer*() const; operator ByteBuffer*() { return bbuf_; }
operator grpc_byte_buffer*() { return bbuf_->buffer_; }
grpc_byte_buffer* buffer_; operator grpc_byte_buffer**() { return &bbuf_->buffer_; }
private:
ByteBuffer* bbuf_;
};
ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); }
}; };
template <> template <>
class SerializationTraits<ByteBuffer, void> { class SerializationTraits<ByteBuffer, void> {
public: public:
static Status Deserialize(const ByteBuffer& byte_buffer, ByteBuffer* dest) { static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) {
dest->set_buffer(byte_buffer.buffer_); dest->set_buffer(byte_buffer->buffer_);
return Status::OK; return Status::OK;
} }
static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer, static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer,

@ -305,9 +305,6 @@ class CallOpSendMessage {
void FinishOp(bool* status) { send_buf_.Clear(); } void FinishOp(bool* status) { send_buf_.Clear(); }
private: private:
template <class M, class T = void>
class MessageSerializer;
ByteBuffer send_buf_; ByteBuffer send_buf_;
WriteOptions write_options_; WriteOptions write_options_;
}; };
@ -317,41 +314,12 @@ template <class T>
T Example(); T Example();
} // namespace internal } // namespace internal
template <class M>
class CallOpSendMessage::MessageSerializer<
M, typename std::enable_if<std::is_same<
::grpc::Status, decltype(SerializationTraits<M>::Serialize(
internal::Example<const M&>(),
internal::Example<grpc_byte_buffer**>(),
internal::Example<bool*>()))>::value>::type> {
public:
static Status SendMessageInternal(const M& message, ByteBuffer* bbuf,
bool* own_buf) {
return SerializationTraits<M>::Serialize(message, bbuf->c_buffer_ptr(),
own_buf);
}
};
template <class M>
class CallOpSendMessage::MessageSerializer<
M, typename std::enable_if<std::is_same<
::grpc::Status, decltype(SerializationTraits<M>::Serialize(
internal::Example<const M&>(),
internal::Example<::grpc::ByteBuffer*>(),
internal::Example<bool*>()))>::value>::type> {
public:
static Status SendMessageInternal(const M& message, ByteBuffer* bbuf,
bool* own_buf) {
return SerializationTraits<M>::Serialize(message, bbuf, own_buf);
}
};
template <class M> template <class M>
Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) {
write_options_ = options; write_options_ = options;
bool own_buf; bool own_buf;
Status result = Status result = SerializationTraits<M>::Serialize(
MessageSerializer<M>::SendMessageInternal(message, &send_buf_, &own_buf); message, send_buf_.bbuf_ptr(), &own_buf);
if (!own_buf) { if (!own_buf) {
send_buf_.Duplicate(); send_buf_.Duplicate();
} }
@ -363,36 +331,6 @@ Status CallOpSendMessage::SendMessage(const M& message) {
return SendMessage(message, WriteOptions()); return SendMessage(message, WriteOptions());
} }
namespace internal {
template <class M, class T = void>
class MessageDeserializer;
template <class M>
class MessageDeserializer<
M, typename std::enable_if<std::is_same<
::grpc::Status, decltype(SerializationTraits<M>::Deserialize(
internal::Example<const ::grpc::ByteBuffer&>(),
internal::Example<M*>()))>::value>::type> {
public:
static Status Deserialize(const ByteBuffer& bbuf, M* message) {
return SerializationTraits<M>::Deserialize(bbuf, message);
}
};
template <class M>
class MessageDeserializer<
M, typename std::enable_if<std::is_same<
::grpc::Status, decltype(SerializationTraits<M>::Deserialize(
internal::Example<grpc_byte_buffer*>(),
internal::Example<M*>()))>::value>::type> {
public:
static Status Deserialize(const ByteBuffer& bbuf, M* message) {
return SerializationTraits<M>::Deserialize(
const_cast<ByteBuffer&>(bbuf).c_buffer(), message);
}
};
} // namespace internal
template <class R> template <class R>
class CallOpRecvMessage { class CallOpRecvMessage {
public: public:
@ -423,7 +361,7 @@ class CallOpRecvMessage {
if (recv_buf_.Valid()) { if (recv_buf_.Valid()) {
if (*status) { if (*status) {
got_message = *status = got_message = *status =
internal::MessageDeserializer<R>::Deserialize(recv_buf_, message_) SerializationTraits<R>::Deserialize(recv_buf_.bbuf_ptr(), message_)
.ok(); .ok();
recv_buf_.Release(); recv_buf_.Release();
} else { } else {
@ -448,7 +386,7 @@ class CallOpRecvMessage {
namespace CallOpGenericRecvMessageHelper { namespace CallOpGenericRecvMessageHelper {
class DeserializeFunc { class DeserializeFunc {
public: public:
virtual Status Deserialize(const ByteBuffer& buf) = 0; virtual Status Deserialize(ByteBuffer* buf) = 0;
virtual ~DeserializeFunc() {} virtual ~DeserializeFunc() {}
}; };
@ -456,8 +394,8 @@ template <class R>
class DeserializeFuncType final : public DeserializeFunc { class DeserializeFuncType final : public DeserializeFunc {
public: public:
DeserializeFuncType(R* message) : message_(message) {} DeserializeFuncType(R* message) : message_(message) {}
Status Deserialize(const ByteBuffer& buf) override { Status Deserialize(ByteBuffer* buf) override {
return grpc::internal::MessageDeserializer<R>::Deserialize(buf, message_); return SerializationTraits<R>::Deserialize(buf->bbuf_ptr(), message_);
} }
~DeserializeFuncType() override {} ~DeserializeFuncType() override {}
@ -501,7 +439,7 @@ class CallOpGenericRecvMessage {
if (recv_buf_.Valid()) { if (recv_buf_.Valid()) {
if (*status) { if (*status) {
got_message = true; got_message = true;
*status = deserialize_->Deserialize(recv_buf_).ok(); *status = deserialize_->Deserialize(&recv_buf_).ok();
recv_buf_.Release(); recv_buf_.Release();
} else { } else {
got_message = false; got_message = false;

@ -38,8 +38,8 @@ class RpcMethodHandler : public MethodHandler {
void RunHandler(const HandlerParameter& param) final { void RunHandler(const HandlerParameter& param) final {
RequestType req; RequestType req;
Status status = internal::MessageDeserializer<RequestType>::Deserialize( Status status = SerializationTraits<RequestType>::Deserialize(
param.request, &req); param.request.bbuf_ptr(), &req);
ResponseType rsp; ResponseType rsp;
if (status.ok()) { if (status.ok()) {
status = func_(service_, param.server_context, &req, &rsp); status = func_(service_, param.server_context, &req, &rsp);
@ -124,8 +124,8 @@ class ServerStreamingHandler : public MethodHandler {
void RunHandler(const HandlerParameter& param) final { void RunHandler(const HandlerParameter& param) final {
RequestType req; RequestType req;
Status status = internal::MessageDeserializer<RequestType>::Deserialize( Status status = SerializationTraits<RequestType>::Deserialize(
param.request, &req); param.request.bbuf_ptr(), &req);
if (status.ok()) { if (status.ok()) {
ServerWriter<ResponseType> writer(param.call, param.server_context); ServerWriter<ResponseType> writer(param.call, param.server_context);

@ -24,20 +24,20 @@ namespace grpc {
/// Defines how to serialize and deserialize some type. /// Defines how to serialize and deserialize some type.
/// ///
/// Used for hooking different message serialization API's into GRPC. /// Used for hooking different message serialization API's into GRPC.
/// Each SerializationTraits implementation must provide the following /// Each SerializationTraits<Message> implementation must provide the
/// functions: /// following functions:
/// 1. static Status Serialize(const Message& msg, /// 1. static Status Serialize(const Message& msg,
/// ByteBuffer* buffer, /// ByteBuffer* buffer,
/// bool* own_buffer); /// bool* own_buffer);
/// AND/OR /// OR
/// static Status Serialize(const Message& msg, /// static Status Serialize(const Message& msg,
/// grpc_byte_buffer** buffer, /// grpc_byte_buffer** buffer,
/// bool* own_buffer); /// bool* own_buffer);
/// The former is preferred; the latter is deprecated /// The former is preferred; the latter is deprecated
/// ///
/// 2. static Status Deserialize(const ByteBuffer& buffer, /// 2. static Status Deserialize(ByteBuffer* buffer,
/// Message* msg); /// Message* msg);
/// AND/OR /// OR
/// static Status Deserialize(grpc_byte_buffer* buffer, /// static Status Deserialize(grpc_byte_buffer* buffer,
/// Message* msg); /// Message* msg);
/// The former is preferred; the latter is deprecated /// The former is preferred; the latter is deprecated

@ -33,6 +33,15 @@ ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) {
"Slice must have same representation as grpc_slice"); "Slice must have same representation as grpc_slice");
static_assert(sizeof(Slice) == sizeof(grpc_slice), static_assert(sizeof(Slice) == sizeof(grpc_slice),
"Slice must have same representation as grpc_slice"); "Slice must have same representation as grpc_slice");
// The following assertions check that the representation of a ByteBuffer is
// identical to grpc_byte_buffer*: it has a grpc_byte_buffer* field,
// and nothing else.
static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value,
"ByteBuffer must have same representation as "
"grpc_byte_buffer*");
static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*),
"ByteBuffer must have same representation as "
"grpc_byte_buffer*");
g_gli_initializer.summon(); // Make sure that initializer linked in g_gli_initializer.summon(); // Make sure that initializer linked in
// The const_cast is legal if grpc_raw_byte_buffer_create() does no more // The const_cast is legal if grpc_raw_byte_buffer_create() does no more
// than its advertised side effect of increasing the reference count of the // than its advertised side effect of increasing the reference count of the
@ -87,19 +96,4 @@ void ByteBuffer::Swap(ByteBuffer* other) {
buffer_ = tmp; buffer_ = tmp;
} }
ByteBuffer::operator grpc_byte_buffer*() {
// The following assertions check that the representation of a ByteBuffer is
// identical to grpc_byte_buffer*: it has a grpc_byte_buffer* field,
// and nothing else.
static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value,
"ByteBuffer must have same representation as "
"grpc_byte_buffer*");
static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*),
"ByteBuffer must have same representation as "
"grpc_byte_buffer*");
return buffer_;
}
ByteBuffer::operator const grpc_byte_buffer*() const { return buffer_; }
} // namespace grpc } // namespace grpc

Loading…
Cancel
Save