OdbDesignLib
OdbDesign ODB++ Parsing Library
 
Loading...
Searching...
No Matches
IProtoBuffable.h
1#pragma once
2
3#include <google/protobuf/message.h>
4#include <google/protobuf/util/json_util.h>
5#include "IJsonable.h"
6#include <absl/strings/string_view.h>
7#include <string>
8#include <memory>
9#include <type_traits>
10
11
12namespace 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::make_unique<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::make_unique<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::JsonPrintOptions 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 auto pMessage = std::make_unique<TPbMessage>();
93 auto status = google::protobuf::util::JsonStringToMessage(absl::string_view(json), pMessage.get());
94 if (!status.ok()) return;
95 from_protobuf(*pMessage);
96 }
97}