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