mcpack2pb.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. 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,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. // mcpack2pb - Make protobuf be front-end of mcpack/compack
  18. // Date: Mon Oct 19 17:17:36 CST 2015
  19. #ifndef MCPACK2PB_MCPACK_MCPACK2PB_H
  20. #define MCPACK2PB_MCPACK_MCPACK2PB_H
  21. #include <google/protobuf/message.h>
  22. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  23. #include "butil/containers/flat_map.h"
  24. #include "butil/iobuf.h"
  25. #include "mcpack2pb/parser.h"
  26. #include "mcpack2pb/serializer.h"
  27. namespace mcpack2pb {
  28. typedef bool (*SetFieldFn)(::google::protobuf::Message* msg,
  29. UnparsedValue& value);
  30. // Mapping from filed name to its parsing&setting function.
  31. typedef butil::FlatMap<butil::StringPiece, SetFieldFn> FieldMap;
  32. enum SerializationFormat {
  33. FORMAT_COMPACK,
  34. FORMAT_MCPACK_V2
  35. };
  36. struct MessageHandler {
  37. // Parse `msg' from `input' as a mcpack_v2 or compack object.
  38. // Returns number of bytes consumed.
  39. size_t (*parse)(::google::protobuf::Message* msg,
  40. ::google::protobuf::io::ZeroCopyInputStream* input);
  41. // Parse `msg' from `input' as a mcpack_v2 or compack object removed with header.
  42. // Returns true on success.
  43. bool (*parse_body)(::google::protobuf::Message* msg,
  44. ::google::protobuf::io::ZeroCopyInputStream* input,
  45. size_t size);
  46. // Serialize `msg' as a mcpack_v2 or compack object into `output'.
  47. // The serialization format is decided by `format'.
  48. // Returns true on success.
  49. bool (*serialize)(const ::google::protobuf::Message& msg,
  50. ::google::protobuf::io::ZeroCopyOutputStream* output,
  51. SerializationFormat format);
  52. // Serialize `msg' as a mcpack_v2 or compack object without header into
  53. // `serializer'. The serialization format is decided by `format'.
  54. // Returns true on success.
  55. void (*serialize_body)(const ::google::protobuf::Message& msg,
  56. Serializer& serializer,
  57. SerializationFormat format);
  58. // -------------------
  59. // Helper functions
  60. // -------------------
  61. // Parse `msg' from IOBuf or array which may contain more data than just
  62. // the message.
  63. // Returns bytes parsed, 0 on error.
  64. size_t parse_from_iobuf_prefix(::google::protobuf::Message* msg,
  65. const ::butil::IOBuf& buf);
  66. size_t parse_from_array_prefix(::google::protobuf::Message* msg,
  67. const void* data, int size);
  68. // Parse `msg' from IOBuf or array which may just contain the message.
  69. // Returns true on success.
  70. bool parse_from_iobuf(::google::protobuf::Message* msg,
  71. const ::butil::IOBuf& buf);
  72. bool parse_from_array(::google::protobuf::Message* msg,
  73. const void* data, int size);
  74. // Serialize `msg' to IOBuf or string.
  75. // Returns true on success.
  76. bool serialize_to_iobuf(const ::google::protobuf::Message& msg,
  77. ::butil::IOBuf* buf, SerializationFormat format);
  78. // TODO(gejun): serialize_to_string is not supported because OutputStream
  79. // requires the embedded zero-copy stream to return permanent memory blocks
  80. // to support reserve() however the string inside StringOutputStream may
  81. // be resized and invalidates previous returned memory blocks.
  82. };
  83. static const MessageHandler INVALID_MESSAGE_HANDLER = {NULL, NULL, NULL, NULL};
  84. // if the *.pb.cc and *.pb.h was generated by mcpack2pb. This function will be
  85. // called with the mcpack/compack parser and serializer BEFORE main().
  86. void register_message_handler_or_die(const std::string& full_name,
  87. const MessageHandler& handler);
  88. // Find the registered parser/serializer by `full_name'
  89. // e.g. "example.SampleMessage".
  90. // If the handler was not registered, function pointers inside are NULL.
  91. MessageHandler find_message_handler(const std::string& full_name);
  92. // inline impl.
  93. inline size_t MessageHandler::parse_from_iobuf_prefix(
  94. ::google::protobuf::Message* msg, const ::butil::IOBuf& buf) {
  95. if (parse == NULL) {
  96. LOG(ERROR) << "`parse' is NULL";
  97. return 0;
  98. }
  99. ::butil::IOBufAsZeroCopyInputStream zc_stream(buf);
  100. return parse(msg, &zc_stream);
  101. }
  102. inline bool MessageHandler::parse_from_iobuf(
  103. ::google::protobuf::Message* msg, const ::butil::IOBuf& buf) {
  104. if (parse == NULL) {
  105. LOG(ERROR) << "`parse' is NULL";
  106. return 0;
  107. }
  108. ::butil::IOBufAsZeroCopyInputStream zc_stream(buf);
  109. return parse(msg, &zc_stream) == buf.size();
  110. }
  111. inline size_t MessageHandler::parse_from_array_prefix(
  112. ::google::protobuf::Message* msg, const void* data, int size) {
  113. if (parse == NULL) {
  114. LOG(ERROR) << "`parse' is NULL";
  115. return 0;
  116. }
  117. ::google::protobuf::io::ArrayInputStream zc_stream(data, size);
  118. return parse(msg, &zc_stream);
  119. }
  120. inline bool MessageHandler::parse_from_array(
  121. ::google::protobuf::Message* msg, const void* data, int size) {
  122. if (parse == NULL) {
  123. LOG(ERROR) << "`parse' is NULL";
  124. return 0;
  125. }
  126. ::google::protobuf::io::ArrayInputStream zc_stream(data, size);
  127. return (int)parse(msg, &zc_stream) == size;
  128. }
  129. inline bool MessageHandler::serialize_to_iobuf(
  130. const ::google::protobuf::Message& msg,
  131. ::butil::IOBuf* buf, SerializationFormat format) {
  132. if (serialize == NULL) {
  133. LOG(ERROR) << "`serialize' is NULL";
  134. return false;
  135. }
  136. ::butil::IOBufAsZeroCopyOutputStream zc_stream(buf);
  137. return serialize(msg, &zc_stream, format);
  138. }
  139. } // namespace mcpack2pb
  140. #endif // MCPACK2PB_MCPACK_MCPACK2PB_H