proto_utils.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //
  2. //
  3. // Copyright 2015 gRPC authors.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. //
  18. #ifndef GRPCPP_IMPL_PROTO_UTILS_H
  19. #define GRPCPP_IMPL_PROTO_UTILS_H
  20. #include <type_traits>
  21. #include <grpc/byte_buffer_reader.h>
  22. #include <grpc/impl/grpc_types.h>
  23. #include <grpc/slice.h>
  24. #include <grpc/support/log.h>
  25. #include <grpcpp/impl/codegen/config_protobuf.h>
  26. #include <grpcpp/impl/serialization_traits.h>
  27. #include <grpcpp/support/byte_buffer.h>
  28. #include <grpcpp/support/proto_buffer_reader.h>
  29. #include <grpcpp/support/proto_buffer_writer.h>
  30. #include <grpcpp/support/slice.h>
  31. #include <grpcpp/support/status.h>
  32. /// This header provides serialization and deserialization between gRPC
  33. /// messages serialized using protobuf and the C++ objects they represent.
  34. namespace grpc {
  35. // ProtoBufferWriter must be a subclass of ::protobuf::io::ZeroCopyOutputStream.
  36. template <class ProtoBufferWriter, class T>
  37. Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb,
  38. bool* own_buffer) {
  39. static_assert(std::is_base_of<protobuf::io::ZeroCopyOutputStream,
  40. ProtoBufferWriter>::value,
  41. "ProtoBufferWriter must be a subclass of "
  42. "::protobuf::io::ZeroCopyOutputStream");
  43. *own_buffer = true;
  44. int byte_size = static_cast<int>(msg.ByteSizeLong());
  45. if (static_cast<size_t>(byte_size) <= GRPC_SLICE_INLINED_SIZE) {
  46. Slice slice(byte_size);
  47. // We serialize directly into the allocated slices memory
  48. GPR_ASSERT(slice.end() == msg.SerializeWithCachedSizesToArray(
  49. const_cast<uint8_t*>(slice.begin())));
  50. ByteBuffer tmp(&slice, 1);
  51. bb->Swap(&tmp);
  52. return grpc::Status::OK;
  53. }
  54. ProtoBufferWriter writer(bb, kProtoBufferWriterMaxBufferLength, byte_size);
  55. return msg.SerializeToZeroCopyStream(&writer)
  56. ? grpc::Status::OK
  57. : Status(StatusCode::INTERNAL, "Failed to serialize message");
  58. }
  59. // BufferReader must be a subclass of ::protobuf::io::ZeroCopyInputStream.
  60. template <class ProtoBufferReader, class T>
  61. Status GenericDeserialize(ByteBuffer* buffer,
  62. grpc::protobuf::MessageLite* msg) {
  63. static_assert(std::is_base_of<protobuf::io::ZeroCopyInputStream,
  64. ProtoBufferReader>::value,
  65. "ProtoBufferReader must be a subclass of "
  66. "::protobuf::io::ZeroCopyInputStream");
  67. if (buffer == nullptr) {
  68. return Status(StatusCode::INTERNAL, "No payload");
  69. }
  70. Status result = grpc::Status::OK;
  71. {
  72. ProtoBufferReader reader(buffer);
  73. if (!reader.status().ok()) {
  74. return reader.status();
  75. }
  76. if (!msg->ParseFromZeroCopyStream(&reader)) {
  77. result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
  78. }
  79. }
  80. buffer->Clear();
  81. return result;
  82. }
  83. // this is needed so the following class does not conflict with protobuf
  84. // serializers that utilize internal-only tools.
  85. #ifdef GRPC_OPEN_SOURCE_PROTO
  86. // This class provides a protobuf serializer. It translates between protobuf
  87. // objects and grpc_byte_buffers. More information about SerializationTraits can
  88. // be found in include/grpcpp/impl/codegen/serialization_traits.h.
  89. template <class T>
  90. class SerializationTraits<
  91. T, typename std::enable_if<
  92. std::is_base_of<grpc::protobuf::MessageLite, T>::value>::type> {
  93. public:
  94. static Status Serialize(const grpc::protobuf::MessageLite& msg,
  95. ByteBuffer* bb, bool* own_buffer) {
  96. return GenericSerialize<ProtoBufferWriter, T>(msg, bb, own_buffer);
  97. }
  98. static Status Deserialize(ByteBuffer* buffer,
  99. grpc::protobuf::MessageLite* msg) {
  100. return GenericDeserialize<ProtoBufferReader, T>(buffer, msg);
  101. }
  102. };
  103. #endif
  104. } // namespace grpc
  105. #endif // GRPCPP_IMPL_PROTO_UTILS_H