rippled
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 <google/protobuf/io/zero_copy_stream.h>
24 #include <boost/asio/buffer.hpp>
25 #include <cstdint>
26 
27 namespace ripple {
28 
33 template <class Buffers>
35  : public ::google::protobuf::io::ZeroCopyInputStream
36 {
37 private:
38  using iterator = typename Buffers::const_iterator;
39  using const_buffer = boost::asio::const_buffer;
40 
41  google::protobuf::int64 count_ = 0;
43  iterator first_; // Where pos_ comes from
44  const_buffer pos_; // What Next() will return
45 
46 public:
47  explicit
48  ZeroCopyInputStream (Buffers const& buffers);
49 
50  bool
51  Next (const void** data, int* size) override;
52 
53  void
54  BackUp (int count) override;
55 
56  bool
57  Skip (int count) override;
58 
59  google::protobuf::int64
60  ByteCount() const override
61  {
62  return count_;
63  }
64 };
65 
66 //------------------------------------------------------------------------------
67 
68 template <class Buffers>
70  Buffers const& buffers)
71  : last_ (buffers.end())
72  , first_ (buffers.begin())
73  , pos_ ((first_ != last_) ?
74  *first_ : const_buffer(nullptr, 0))
75 {
76 }
77 
78 template <class Buffers>
79 bool
81  const void** data, int* size)
82 {
83  *data = boost::asio::buffer_cast<void const*>(pos_);
84  *size = boost::asio::buffer_size(pos_);
85  if (first_ == last_)
86  return false;
87  count_ += *size;
88  pos_ = (++first_ != last_) ? *first_ :
89  const_buffer(nullptr, 0);
90  return true;
91 }
92 
93 template <class Buffers>
94 void
96 {
97  --first_;
98  pos_ = *first_ +
99  (boost::asio::buffer_size(*first_) - count);
100  count_ -= count;
101 }
102 
103 template <class Buffers>
104 bool
106 {
107  if (first_ == last_)
108  return false;
109  while (count > 0)
110  {
111  auto const size =
112  boost::asio::buffer_size(pos_);
113  if (count < size)
114  {
115  pos_ = pos_ + count;
116  count_ += count;
117  return true;
118  }
119  count_ += size;
120  if (++first_ == last_)
121  return false;
122  count -= size;
123  pos_ = *first_;
124  }
125  return true;
126 }
127 
128 //------------------------------------------------------------------------------
129 
134 template <class Streambuf>
136  : public ::google::protobuf::io::ZeroCopyOutputStream
137 {
138 private:
139  using buffers_type = typename Streambuf::mutable_buffers_type;
140  using iterator = typename buffers_type::const_iterator;
141  using mutable_buffer = boost::asio::mutable_buffer;
142 
143  Streambuf& streambuf_;
145  google::protobuf::int64 count_ = 0;
149 
150 public:
151  explicit
152  ZeroCopyOutputStream (Streambuf& streambuf,
153  std::size_t blockSize);
154 
156 
157  bool
158  Next (void** data, int* size) override;
159 
160  void
161  BackUp (int count) override;
162 
163  google::protobuf::int64
164  ByteCount() const override
165  {
166  return count_;
167  }
168 };
169 
170 //------------------------------------------------------------------------------
171 
172 template <class Streambuf>
174  Streambuf& streambuf, std::size_t blockSize)
175  : streambuf_ (streambuf)
176  , blockSize_ (blockSize)
177  , buffers_ (streambuf_.prepare(blockSize_))
178  , pos_ (buffers_.begin())
179 {
180 }
181 
182 template <class Streambuf>
184 {
185  if (commit_ != 0)
186  streambuf_.commit(commit_);
187 }
188 
189 template <class Streambuf>
190 bool
192  void** data, int* size)
193 {
194  if (commit_ != 0)
195  {
196  streambuf_.commit(commit_);
197  count_ += commit_;
198  }
199 
200  if (pos_ == buffers_.end())
201  {
202  buffers_ = streambuf_.prepare (blockSize_);
203  pos_ = buffers_.begin();
204  }
205 
206  *data = boost::asio::buffer_cast<void*>(*pos_);
207  *size = boost::asio::buffer_size(*pos_);
208  commit_ = *size;
209  ++pos_;
210  return true;
211 }
212 
213 template <class Streambuf>
214 void
216 {
217  assert(count <= commit_);
218  auto const n = commit_ - count;
219  streambuf_.commit(n);
220  count_ += n;
221  commit_ = 0;
222 }
223 
224 } // ripple
225 
226 #endif
ripple::ZeroCopyOutputStream
Implements ZeroCopyOutputStream around a Streambuf.
Definition: ZeroCopyStream.h:135
ripple::ZeroCopyOutputStream::ByteCount
google::protobuf::int64 ByteCount() const override
Definition: ZeroCopyStream.h:164
ripple::ZeroCopyOutputStream::~ZeroCopyOutputStream
~ZeroCopyOutputStream()
Definition: ZeroCopyStream.h:183
ripple::ZeroCopyInputStream::count_
google::protobuf::int64 count_
Definition: ZeroCopyStream.h:41
ripple::ZeroCopyInputStream::last_
iterator last_
Definition: ZeroCopyStream.h:42
ripple::ZeroCopyInputStream::BackUp
void BackUp(int count) override
Definition: ZeroCopyStream.h:95
ripple::ZeroCopyInputStream::ByteCount
google::protobuf::int64 ByteCount() const override
Definition: ZeroCopyStream.h:60
ripple::ZeroCopyInputStream
Implements ZeroCopyInputStream around a buffer sequence.
Definition: ZeroCopyStream.h:34
ripple::ZeroCopyOutputStream::streambuf_
Streambuf & streambuf_
Definition: ZeroCopyStream.h:143
ripple::ZeroCopyOutputStream::Next
bool Next(void **data, int *size) override
Definition: ZeroCopyStream.h:191
ripple::ZeroCopyOutputStream::iterator
typename buffers_type::const_iterator iterator
Definition: ZeroCopyStream.h:140
ripple::ZeroCopyOutputStream::commit_
std::size_t commit_
Definition: ZeroCopyStream.h:146
ripple::ZeroCopyOutputStream::blockSize_
std::size_t blockSize_
Definition: ZeroCopyStream.h:144
ripple::ZeroCopyInputStream::const_buffer
boost::asio::const_buffer const_buffer
Definition: ZeroCopyStream.h:39
ripple::ZeroCopyOutputStream::count_
google::protobuf::int64 count_
Definition: ZeroCopyStream.h:145
ripple::ZeroCopyInputStream::iterator
typename Buffers::const_iterator iterator
Definition: ZeroCopyStream.h:38
cstdint
ripple::ZeroCopyOutputStream::mutable_buffer
boost::asio::mutable_buffer mutable_buffer
Definition: ZeroCopyStream.h:141
ripple::ZeroCopyInputStream::Skip
bool Skip(int count) override
Definition: ZeroCopyStream.h:105
ripple::ZeroCopyInputStream::pos_
const_buffer pos_
Definition: ZeroCopyStream.h:44
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ZeroCopyOutputStream::buffers_type
typename Streambuf::mutable_buffers_type buffers_type
Definition: ZeroCopyStream.h:139
ripple::ZeroCopyInputStream::Next
bool Next(const void **data, int *size) override
Definition: ZeroCopyStream.h:80
std::size_t
ripple::ZeroCopyOutputStream::buffers_
buffers_type buffers_
Definition: ZeroCopyStream.h:147
ripple::ZeroCopyOutputStream::BackUp
void BackUp(int count) override
Definition: ZeroCopyStream.h:215
ripple::ZeroCopyOutputStream::pos_
iterator pos_
Definition: ZeroCopyStream.h:148
ripple::ZeroCopyInputStream::first_
iterator first_
Definition: ZeroCopyStream.h:43
ripple::ZeroCopyOutputStream::ZeroCopyOutputStream
ZeroCopyOutputStream(Streambuf &streambuf, std::size_t blockSize)
Definition: ZeroCopyStream.h:173
ripple::ZeroCopyInputStream::ZeroCopyInputStream
ZeroCopyInputStream(Buffers const &buffers)
Definition: ZeroCopyStream.h:69