xrpld
Loading...
Searching...
No Matches
ZeroCopyStream.h
1#pragma once
2
3#include <xrpl/beast/utility/instrumentation.h>
4
5#include <boost/asio/buffer.hpp>
6
7#include <google/protobuf/io/zero_copy_stream.h>
8
9#include <cstddef>
10#include <cstdint>
11
12namespace xrpl {
13
20template <class Buffers>
21class ZeroCopyInputStream : public ::google::protobuf::io::ZeroCopyInputStream
22{
23private:
24 using iterator = Buffers::const_iterator;
25 using const_buffer = boost::asio::const_buffer;
26
29 iterator first_; // Where pos_ comes from
30 const_buffer pos_; // What Next() will return
31
32public:
33 explicit ZeroCopyInputStream(Buffers const& buffers);
34
35 bool
36 Next(void const** data, int* size) override;
37
38 void
39 BackUp(int count) override;
40
41 bool
42 Skip(int count) override;
43
44 [[nodiscard]] std::int64_t
45 ByteCount() const override
46 {
47 return count_;
48 }
49};
50
51//------------------------------------------------------------------------------
52
53template <class Buffers>
55 : last_(buffers.end())
56 , first_(buffers.begin())
57 , pos_((first_ != last_) ? *first_ : const_buffer(nullptr, 0))
58{
59}
60
61template <class Buffers>
62bool
63ZeroCopyInputStream<Buffers>::Next(void const** data, int* size)
64{
65 *data = pos_.data();
66 *size = boost::asio::buffer_size(pos_);
67 if (first_ == last_)
68 return false;
69 count_ += *size;
70 pos_ = (++first_ != last_) ? *first_ : const_buffer(nullptr, 0);
71 return true;
72}
73
74template <class Buffers>
75void
77{
78 --first_;
79 pos_ = *first_ + (boost::asio::buffer_size(*first_) - count);
80 count_ -= count;
81}
82
83template <class Buffers>
84bool
86{
87 if (first_ == last_)
88 return false;
89 while (count > 0)
90 {
91 auto const size = boost::asio::buffer_size(pos_);
92 if (count < size)
93 {
94 pos_ = pos_ + count;
95 count_ += count;
96 return true;
97 }
98 count_ += size;
99 if (++first_ == last_)
100 return false;
101 count -= size;
102 pos_ = *first_;
103 }
104 return true;
105}
106
107//------------------------------------------------------------------------------
108
114template <class Streambuf>
115class ZeroCopyOutputStream : public ::google::protobuf::io::ZeroCopyOutputStream
116{
117private:
118 using buffers_type = Streambuf::mutable_buffers_type;
119 using iterator = buffers_type::const_iterator;
120 using mutable_buffer = boost::asio::mutable_buffer;
121
122 Streambuf& streambuf_;
128
129public:
130 explicit ZeroCopyOutputStream(Streambuf& streambuf, std::size_t blockSize);
131
132 ~ZeroCopyOutputStream() override;
133
134 bool
135 Next(void** data, int* size) override;
136
137 void
138 BackUp(int count) override;
139
140 [[nodiscard]] std::int64_t
141 ByteCount() const override
142 {
143 return count_;
144 }
145};
146
147//------------------------------------------------------------------------------
148
149template <class Streambuf>
151 : streambuf_(streambuf)
152 , blockSize_(blockSize)
153 , buffers_(streambuf_.prepare(blockSize_))
154 , pos_(buffers_.begin())
155{
156}
157
158template <class Streambuf>
164
165template <class Streambuf>
166bool
168{
169 if (commit_ != 0)
170 {
171 streambuf_.commit(commit_);
172 count_ += commit_;
173 }
174
175 if (pos_ == buffers_.end())
176 {
177 buffers_ = streambuf_.prepare(blockSize_);
178 pos_ = buffers_.begin();
179 }
180
181 *data = *pos_.data();
182 *size = boost::asio::buffer_size(*pos_);
183 commit_ = *size;
184 ++pos_;
185 return true;
186}
187
188template <class Streambuf>
189void
191{
192 XRPL_ASSERT(count <= commit_, "xrpl::ZeroCopyOutputStream::BackUp : valid input");
193 auto const n = commit_ - count;
194 streambuf_.commit(n);
195 count_ += n;
196 commit_ = 0;
197}
198
199} // namespace xrpl
boost::asio::const_buffer const_buffer
bool Skip(int count) override
std::int64_t ByteCount() const override
bool Next(void const **data, int *size) override
ZeroCopyInputStream(Buffers const &buffers)
Buffers::const_iterator iterator
void BackUp(int count) override
std::int64_t ByteCount() const override
void BackUp(int count) override
boost::asio::mutable_buffer mutable_buffer
ZeroCopyOutputStream(Streambuf &streambuf, std::size_t blockSize)
buffers_type::const_iterator iterator
Streambuf::mutable_buffers_type buffers_type
bool Next(void **data, int *size) override
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5