rippled
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
9namespace xrpl {
10
16template <class Buffers>
17class ZeroCopyInputStream : public ::google::protobuf::io::ZeroCopyInputStream
18{
19private:
20 using iterator = typename Buffers::const_iterator;
21 using const_buffer = boost::asio::const_buffer;
22
23 google::protobuf::int64 count_ = 0;
25 iterator first_; // Where pos_ comes from
26 const_buffer pos_; // What Next() will return
27
28public:
29 explicit ZeroCopyInputStream(Buffers const& buffers);
30
31 bool
32 Next(void const** data, int* size) override;
33
34 void
35 BackUp(int count) override;
36
37 bool
38 Skip(int count) override;
39
40 google::protobuf::int64
41 ByteCount() const override
42 {
43 return count_;
44 }
45};
46
47//------------------------------------------------------------------------------
48
49template <class Buffers>
51 : last_(buffers.end())
52 , first_(buffers.begin())
53 , pos_((first_ != last_) ? *first_ : const_buffer(nullptr, 0))
54{
55}
56
57template <class Buffers>
58bool
59ZeroCopyInputStream<Buffers>::Next(void const** data, int* size)
60{
61 *data = pos_.data();
62 *size = boost::asio::buffer_size(pos_);
63 if (first_ == last_)
64 return false;
65 count_ += *size;
66 pos_ = (++first_ != last_) ? *first_ : const_buffer(nullptr, 0);
67 return true;
68}
69
70template <class Buffers>
71void
73{
74 --first_;
75 pos_ = *first_ + (boost::asio::buffer_size(*first_) - count);
76 count_ -= count;
77}
78
79template <class Buffers>
80bool
82{
83 if (first_ == last_)
84 return false;
85 while (count > 0)
86 {
87 auto const size = boost::asio::buffer_size(pos_);
88 if (count < size)
89 {
90 pos_ = pos_ + count;
91 count_ += count;
92 return true;
93 }
94 count_ += size;
95 if (++first_ == last_)
96 return false;
97 count -= size;
98 pos_ = *first_;
99 }
100 return true;
101}
102
103//------------------------------------------------------------------------------
104
109template <class Streambuf>
110class ZeroCopyOutputStream : public ::google::protobuf::io::ZeroCopyOutputStream
111{
112private:
113 using buffers_type = typename Streambuf::mutable_buffers_type;
114 using iterator = typename buffers_type::const_iterator;
115 using mutable_buffer = boost::asio::mutable_buffer;
116
117 Streambuf& streambuf_;
119 google::protobuf::int64 count_ = 0;
123
124public:
125 explicit ZeroCopyOutputStream(Streambuf& streambuf, std::size_t blockSize);
126
128
129 bool
130 Next(void** data, int* size) override;
131
132 void
133 BackUp(int count) override;
134
135 google::protobuf::int64
136 ByteCount() const override
137 {
138 return count_;
139 }
140};
141
142//------------------------------------------------------------------------------
143
144template <class Streambuf>
146 : streambuf_(streambuf)
147 , blockSize_(blockSize)
148 , buffers_(streambuf_.prepare(blockSize_))
149 , pos_(buffers_.begin())
150{
151}
152
153template <class Streambuf>
155{
156 if (commit_ != 0)
157 streambuf_.commit(commit_);
158}
159
160template <class Streambuf>
161bool
163{
164 if (commit_ != 0)
165 {
166 streambuf_.commit(commit_);
167 count_ += commit_;
168 }
169
170 if (pos_ == buffers_.end())
171 {
172 buffers_ = streambuf_.prepare(blockSize_);
173 pos_ = buffers_.begin();
174 }
175
176 *data = *pos_.data();
177 *size = boost::asio::buffer_size(*pos_);
178 commit_ = *size;
179 ++pos_;
180 return true;
181}
182
183template <class Streambuf>
184void
186{
187 XRPL_ASSERT(count <= commit_, "xrpl::ZeroCopyOutputStream::BackUp : valid input");
188 auto const n = commit_ - count;
189 streambuf_.commit(n);
190 count_ += n;
191 commit_ = 0;
192}
193
194} // namespace xrpl
Implements ZeroCopyInputStream around a buffer sequence.
boost::asio::const_buffer const_buffer
google::protobuf::int64 count_
typename Buffers::const_iterator iterator
bool Skip(int count) override
bool Next(void const **data, int *size) override
ZeroCopyInputStream(Buffers const &buffers)
google::protobuf::int64 ByteCount() const override
void BackUp(int count) override
Implements ZeroCopyOutputStream around a Streambuf.
typename Streambuf::mutable_buffers_type buffers_type
void BackUp(int count) override
google::protobuf::int64 count_
boost::asio::mutable_buffer mutable_buffer
ZeroCopyOutputStream(Streambuf &streambuf, std::size_t blockSize)
google::protobuf::int64 ByteCount() const override
typename buffers_type::const_iterator iterator
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