OdbDesignLib
OdbDesign ODB++ Parsing Library
IProtoBuffable.h
1 #pragma once
2 
3 #include <google/protobuf/message.h>
4 #include <google/protobuf/util/json_util.h>
5 #include "crow_win.h"
6 #include "IJsonable.h"
7 #include "odbdesign_export.h"
8 #include <ostream>
9 #include <istream>
10 
11 
12 namespace Odb::Lib
13 {
14  template<typename TPbMessage>
15  class IProtoBuffable : public Utils::IJsonable
16  {
17  public:
18  // to and from Protocol Buffer messages
19  virtual std::unique_ptr<TPbMessage> to_protobuf() const = 0;
20  virtual void from_protobuf(const TPbMessage& message) = 0;
21 
22  // to and from Protocol Buffer string
23  bool to_pbstring(std::string& pb_string) const;
24  bool from_pbstring(const std::string& pb_string);
25 
26  // to and from output and input streams
27  bool to_stream(std::ostream& outputStream) const;
28  bool from_stream(std::istream& inputStream);
29 
30  // Inherited via IJsonConvertable
31  std::string to_json() const override;
32  void from_json(const std::string& json) override;
33 
34  protected:
35  // abstract class
36  IProtoBuffable() = default;
37 
38  // TMessage MUST derive from Message (must use this until template type contraints support is added)
39  static_assert(std::is_base_of<google::protobuf::Message, TPbMessage>::value, "template parameter type TPbMessage must derive from Protobuf Message class");
40 
41  };
42 
43  template<typename TPbMessage>
44  inline bool IProtoBuffable<TPbMessage>::to_pbstring(std::string& pb_string) const
45  {
46  auto pMessage = to_protobuf();
47  if (pMessage == nullptr) return false;
48  return pMessage->SerializeToString(&pb_string);
49  }
50 
51  template<typename TPbMessage>
52  inline bool IProtoBuffable<TPbMessage>::from_pbstring(const std::string& pb_string)
53  {
54  auto pMessage = std::unique_ptr<TPbMessage>();
55  if (!pMessage->ParseFromString(pb_string)) return false;
56  from_protobuf(*pMessage);
57  return true;
58  }
59 
60  template<typename TPbMessage>
61  inline bool IProtoBuffable<TPbMessage>::to_stream(std::ostream& outputStream) const
62  {
63  auto pMessage = to_protobuf();
64  if (pMessage == nullptr) return false;
65  return pMessage->SerializeToOstream(&outputStream);
66  }
67 
68  template<typename TPbMessage>
69  inline bool IProtoBuffable<TPbMessage>::from_stream(std::istream& inputStream)
70  {
71  auto pMessage = std::unique_ptr<TPbMessage>();
72  if (!pMessage->ParseFromIstream(&inputStream)) return false;
73  from_protobuf(*pMessage);
74  return true;
75  }
76 
77  template<typename TPbMessage>
78  std::string IProtoBuffable<TPbMessage>::to_json() const
79  {
80  // use default options
81  google::protobuf::util::JsonOptions jsonOptions;
82 
83  std::string json;
84  auto status = google::protobuf::util::MessageToJsonString(*to_protobuf(), &json, jsonOptions);
85  if (!status.ok()) json.clear();
86  return json;
87  }
88 
89  template<typename TPbMessage>
90  inline void IProtoBuffable<TPbMessage>::from_json(const std::string& json)
91  {
92  google::protobuf::StringPiece sp_json(json);
93  // use default options
94  google::protobuf::util::JsonOptions jsonOptions;
95 
96  auto pMessage = std::unique_ptr<TPbMessage>();
97  auto status = google::protobuf::util::JsonStringToMessage(sp_json, pMessage.get());
98  if (!status.ok()) return;
99  from_protobuf(*pMessage);
100  }
101 }