Kagome
Polkadot Runtime Engine in C++17
message_read_writer.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_MESSAGE_READ_WRITER_HPP
7 #define KAGOME_MESSAGE_READ_WRITER_HPP
8 
9 #include <boost/assert.hpp>
10 #include <boost/system/error_code.hpp>
11 #include <functional>
12 #include <gsl/span>
13 #include <memory>
14 #include <vector>
15 
16 #include "outcome/outcome.hpp"
17 
18 namespace kagome::network {
22  struct NoSink {};
23 
27  template <typename Adapter, typename Ancestor>
28  struct MessageReadWriter final {
29  using AncestorType = Ancestor;
30  using AdapterType = Adapter;
31  using BufferContainer = std::vector<uint8_t>;
33 
34  public:
35  MessageReadWriter() = default;
36  ~MessageReadWriter() = default;
37 
38  MessageReadWriter(MessageReadWriter &&) noexcept = default;
39  MessageReadWriter &operator=(MessageReadWriter &&) noexcept = default;
40 
41  MessageReadWriter(const MessageReadWriter &) = delete;
42  MessageReadWriter &operator=(const MessageReadWriter &) = delete;
43 
44  public:
45  template <typename T>
46  static size_t need_to_reserve(const T &t) {
47  return AdapterType::size(t) + AncestorType::need_to_reserve(t);
48  }
49 
50  template <typename T>
51  static BufferContainer::iterator write(const T &t,
52  BufferContainer &out,
53  size_t reserved = 0ull) {
54  const auto need_to_reserve = SelfType::need_to_reserve(t);
55  if (need_to_reserve > out.size()) out.resize(need_to_reserve);
56 
57  const size_t r = AdapterType::size(t) + reserved;
58  auto loaded = AncestorType::write(t, out, r);
59 
60  BOOST_ASSERT(std::distance(out.begin(), loaded) >= 0);
61  BOOST_ASSERT(static_cast<size_t>(std::distance(out.begin(), loaded))
62  >= r);
63  return AdapterType::write(t, out, loaded);
64  }
65 
66  template <typename T>
67  static outcome::result<BufferContainer::const_iterator> read(
68  T &out,
69  const BufferContainer &src,
70  BufferContainer::const_iterator from) {
71  if (from == src.end())
72  return outcome::failure(boost::system::error_code{});
73 
74  OUTCOME_TRY(it, AdapterType::read(out, src, from));
75  return AncestorType::read(out, src, it);
76  }
77  };
78 
79  template <typename Adapter>
80  struct MessageReadWriter<Adapter, NoSink> final {
81  using AdapterType = Adapter;
82  using BufferContainer = std::vector<uint8_t>;
84 
85  public:
86  MessageReadWriter() = default;
87  ~MessageReadWriter() = default;
88 
89  MessageReadWriter(MessageReadWriter &&) noexcept = default;
90  MessageReadWriter &operator=(MessageReadWriter &&) noexcept = default;
91 
92  MessageReadWriter(const MessageReadWriter &) = delete;
93  MessageReadWriter &operator=(const MessageReadWriter &) = delete;
94 
95  public:
96  template <typename T>
97  static BufferContainer::iterator write(const T &t,
98  BufferContainer &out,
99  size_t reserved = 0) {
100  const auto need_to_reserve = SelfType::need_to_reserve(t);
101  if (need_to_reserve > out.size()) out.resize(need_to_reserve);
102 
103  BOOST_ASSERT(std::distance(out.begin(), out.end()) >= 0);
104  BOOST_ASSERT(static_cast<size_t>(std::distance(out.begin(), out.end()))
105  >= AdapterType::size(t) + reserved);
106  return AdapterType::write(t, out, out.end());
107  }
108 
109  template <typename T>
110  static outcome::result<BufferContainer::const_iterator> read(
111  T &out,
112  const BufferContainer &src,
113  BufferContainer::const_iterator from) {
114  if (from == src.end())
115  return outcome::failure(boost::system::error_code{});
116 
117  return AdapterType::read(out, src, from);
118  }
119 
120  template <typename T>
121  static size_t need_to_reserve(const T &t) {
122  return AdapterType::size(t);
123  }
124  };
125 
126 } // namespace kagome::network
127 
128 #endif // KAGOME_SCALE_MESSAGE_READ_WRITER_HPP
static outcome::result< BufferContainer::const_iterator > read(T &out, const BufferContainer &src, BufferContainer::const_iterator from)
static outcome::result< BufferContainer::const_iterator > read(T &out, const BufferContainer &src, BufferContainer::const_iterator from)
static BufferContainer::iterator write(const T &t, BufferContainer &out, size_t reserved=0ull)