rippled
Loading...
Searching...
No Matches
ZeroCopyStream.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_OVERLAY_ZEROCOPYSTREAM_H_INCLUDED
21#define RIPPLE_OVERLAY_ZEROCOPYSTREAM_H_INCLUDED
22
23#include <xrpl/beast/utility/instrumentation.h>
24
25#include <boost/asio/buffer.hpp>
26
27#include <google/protobuf/io/zero_copy_stream.h>
28
29namespace ripple {
30
36template <class Buffers>
37class ZeroCopyInputStream : public ::google::protobuf::io::ZeroCopyInputStream
38{
39private:
40 using iterator = typename Buffers::const_iterator;
41 using const_buffer = boost::asio::const_buffer;
42
43 google::protobuf::int64 count_ = 0;
45 iterator first_; // Where pos_ comes from
46 const_buffer pos_; // What Next() will return
47
48public:
49 explicit ZeroCopyInputStream(Buffers const& buffers);
50
51 bool
52 Next(void const** data, int* size) override;
53
54 void
55 BackUp(int count) override;
56
57 bool
58 Skip(int count) override;
59
60 google::protobuf::int64
61 ByteCount() const override
62 {
63 return count_;
64 }
65};
66
67//------------------------------------------------------------------------------
68
69template <class Buffers>
71 : last_(buffers.end())
72 , first_(buffers.begin())
73 , pos_((first_ != last_) ? *first_ : const_buffer(nullptr, 0))
74{
75}
76
77template <class Buffers>
78bool
79ZeroCopyInputStream<Buffers>::Next(void const** data, int* size)
80{
81 *data = pos_.data();
82 *size = boost::asio::buffer_size(pos_);
83 if (first_ == last_)
84 return false;
85 count_ += *size;
86 pos_ = (++first_ != last_) ? *first_ : const_buffer(nullptr, 0);
87 return true;
88}
89
90template <class Buffers>
91void
93{
94 --first_;
95 pos_ = *first_ + (boost::asio::buffer_size(*first_) - count);
96 count_ -= count;
97}
98
99template <class Buffers>
100bool
102{
103 if (first_ == last_)
104 return false;
105 while (count > 0)
106 {
107 auto const size = boost::asio::buffer_size(pos_);
108 if (count < size)
109 {
110 pos_ = pos_ + count;
111 count_ += count;
112 return true;
113 }
114 count_ += size;
115 if (++first_ == last_)
116 return false;
117 count -= size;
118 pos_ = *first_;
119 }
120 return true;
121}
122
123//------------------------------------------------------------------------------
124
129template <class Streambuf>
130class ZeroCopyOutputStream : public ::google::protobuf::io::ZeroCopyOutputStream
131{
132private:
133 using buffers_type = typename Streambuf::mutable_buffers_type;
134 using iterator = typename buffers_type::const_iterator;
135 using mutable_buffer = boost::asio::mutable_buffer;
136
137 Streambuf& streambuf_;
139 google::protobuf::int64 count_ = 0;
143
144public:
145 explicit ZeroCopyOutputStream(Streambuf& streambuf, std::size_t blockSize);
146
148
149 bool
150 Next(void** data, int* size) override;
151
152 void
153 BackUp(int count) override;
154
155 google::protobuf::int64
156 ByteCount() const override
157 {
158 return count_;
159 }
160};
161
162//------------------------------------------------------------------------------
163
164template <class Streambuf>
166 Streambuf& streambuf,
167 std::size_t blockSize)
168 : streambuf_(streambuf)
169 , blockSize_(blockSize)
170 , buffers_(streambuf_.prepare(blockSize_))
171 , pos_(buffers_.begin())
172{
173}
174
175template <class Streambuf>
177{
178 if (commit_ != 0)
179 streambuf_.commit(commit_);
180}
181
182template <class Streambuf>
183bool
185{
186 if (commit_ != 0)
187 {
188 streambuf_.commit(commit_);
189 count_ += commit_;
190 }
191
192 if (pos_ == buffers_.end())
193 {
194 buffers_ = streambuf_.prepare(blockSize_);
195 pos_ = buffers_.begin();
196 }
197
198 *data = *pos_.data();
199 *size = boost::asio::buffer_size(*pos_);
200 commit_ = *size;
201 ++pos_;
202 return true;
203}
204
205template <class Streambuf>
206void
208{
209 XRPL_ASSERT(
210 count <= commit_, "ripple::ZeroCopyOutputStream::BackUp : valid input");
211 auto const n = commit_ - count;
212 streambuf_.commit(n);
213 count_ += n;
214 commit_ = 0;
215}
216
217} // namespace ripple
218
219#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:25