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

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

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

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

Loading…
Cancel
Save