Realistic 3D camera system
3D camera system components
consuming_buffers.hpp
Go to the documentation of this file.
1 //
2 // detail/consuming_buffers.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_DETAIL_CONSUMING_BUFFERS_HPP
12 #define ASIO_DETAIL_CONSUMING_BUFFERS_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include <cstddef>
20 #include <iterator>
21 #include "asio/buffer.hpp"
22 #include "asio/detail/limits.hpp"
23 
25 
26 namespace asio {
27 namespace detail {
28 
29 // A proxy iterator for a sub-range in a list of buffers.
30 template <typename Buffer, typename Buffer_Iterator>
32 {
33 public:
35  typedef std::ptrdiff_t difference_type;
36 
38  typedef Buffer value_type;
39 
41  typedef const Buffer* pointer;
42 
44  typedef const Buffer& reference;
45 
47  typedef std::forward_iterator_tag iterator_category;
48 
49  // Default constructor creates an end iterator.
51  : at_end_(true)
52  {
53  }
54 
55  // Construct with a buffer for the first entry and an iterator
56  // range for the remaining entries.
57  consuming_buffers_iterator(bool at_end, const Buffer& first,
58  Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder,
59  std::size_t max_size)
60  : at_end_(max_size > 0 ? at_end : true),
61  first_(buffer(first, max_size)),
62  begin_remainder_(begin_remainder),
63  end_remainder_(end_remainder),
64  offset_(0),
65  max_size_(max_size)
66  {
67  }
68 
69  // Dereference an iterator.
70  const Buffer& operator*() const
71  {
72  return dereference();
73  }
74 
75  // Dereference an iterator.
76  const Buffer* operator->() const
77  {
78  return &dereference();
79  }
80 
81  // Increment operator (prefix).
83  {
84  increment();
85  return *this;
86  }
87 
88  // Increment operator (postfix).
90  {
91  consuming_buffers_iterator tmp(*this);
92  ++*this;
93  return tmp;
94  }
95 
96  // Test two iterators for equality.
97  friend bool operator==(const consuming_buffers_iterator& a,
99  {
100  return a.equal(b);
101  }
102 
103  // Test two iterators for inequality.
106  {
107  return !a.equal(b);
108  }
109 
110 private:
111  void increment()
112  {
113  if (!at_end_)
114  {
115  if (begin_remainder_ == end_remainder_
116  || offset_ + buffer_size(first_) >= max_size_)
117  {
118  at_end_ = true;
119  }
120  else
121  {
122  offset_ += buffer_size(first_);
123  first_ = buffer(*begin_remainder_++, max_size_ - offset_);
124  }
125  }
126  }
127 
128  bool equal(const consuming_buffers_iterator& other) const
129  {
130  if (at_end_ && other.at_end_)
131  return true;
132  return !at_end_ && !other.at_end_
133  && buffer_cast<const void*>(first_)
134  == buffer_cast<const void*>(other.first_)
135  && buffer_size(first_) == buffer_size(other.first_)
136  && begin_remainder_ == other.begin_remainder_
137  && end_remainder_ == other.end_remainder_;
138  }
139 
140  const Buffer& dereference() const
141  {
142  return first_;
143  }
144 
145  bool at_end_;
146  Buffer first_;
147  Buffer_Iterator begin_remainder_;
148  Buffer_Iterator end_remainder_;
149  std::size_t offset_;
150  std::size_t max_size_;
151 };
152 
153 // A proxy for a sub-range in a list of buffers.
154 template <typename Buffer, typename Buffers>
156 {
157 public:
158  // The type for each element in the list of buffers.
159  typedef Buffer value_type;
160 
161  // A forward-only iterator type that may be used to read elements.
164 
165  // Construct to represent the entire list of buffers.
166  consuming_buffers(const Buffers& buffers)
167  : buffers_(buffers),
168  at_end_(buffers_.begin() == buffers_.end()),
169  begin_remainder_(buffers_.begin()),
170  max_size_((std::numeric_limits<std::size_t>::max)())
171  {
172  if (!at_end_)
173  {
174  first_ = *buffers_.begin();
175  ++begin_remainder_;
176  }
177  }
178 
179  // Copy constructor.
181  : buffers_(other.buffers_),
182  at_end_(other.at_end_),
183  first_(other.first_),
184  begin_remainder_(buffers_.begin()),
185  max_size_(other.max_size_)
186  {
187  typename Buffers::const_iterator first = other.buffers_.begin();
188  typename Buffers::const_iterator second = other.begin_remainder_;
189  std::advance(begin_remainder_, std::distance(first, second));
190  }
191 
192  // Assignment operator.
194  {
195  buffers_ = other.buffers_;
196  at_end_ = other.at_end_;
197  first_ = other.first_;
198  begin_remainder_ = buffers_.begin();
199  typename Buffers::const_iterator first = other.buffers_.begin();
200  typename Buffers::const_iterator second = other.begin_remainder_;
201  std::advance(begin_remainder_, std::distance(first, second));
202  max_size_ = other.max_size_;
203  return *this;
204  }
205 
206  // Get a forward-only iterator to the first element.
208  {
209  return const_iterator(at_end_, first_,
210  begin_remainder_, buffers_.end(), max_size_);
211  }
212 
213  // Get a forward-only iterator for one past the last element.
215  {
216  return const_iterator();
217  }
218 
219  // Set the maximum size for a single transfer.
220  void prepare(std::size_t max_size)
221  {
222  max_size_ = max_size;
223  }
224 
225  // Consume the specified number of bytes from the buffers.
226  void consume(std::size_t size)
227  {
228  // Remove buffers from the start until the specified size is reached.
229  while (size > 0 && !at_end_)
230  {
231  if (buffer_size(first_) <= size)
232  {
233  size -= buffer_size(first_);
234  if (begin_remainder_ == buffers_.end())
235  at_end_ = true;
236  else
237  first_ = *begin_remainder_++;
238  }
239  else
240  {
241  first_ = first_ + size;
242  size = 0;
243  }
244  }
245 
246  // Remove any more empty buffers at the start.
247  while (!at_end_ && buffer_size(first_) == 0)
248  {
249  if (begin_remainder_ == buffers_.end())
250  at_end_ = true;
251  else
252  first_ = *begin_remainder_++;
253  }
254  }
255 
256 private:
257  Buffers buffers_;
258  bool at_end_;
259  Buffer first_;
260  typename Buffers::const_iterator begin_remainder_;
261  std::size_t max_size_;
262 };
263 
264 // Specialisation for null_buffers to ensure that the null_buffers type is
265 // always passed through to the underlying read or write operation.
266 template <typename Buffer>
268  : public asio::null_buffers
269 {
270 public:
272  {
273  // No-op.
274  }
275 
276  void prepare(std::size_t)
277  {
278  // No-op.
279  }
280 
281  void consume(std::size_t)
282  {
283  // No-op.
284  }
285 };
286 
287 } // namespace detail
288 } // namespace asio
289 
291 
292 #endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP
SocketService Iterator begin
Definition: connect.hpp:521
friend bool operator==(const consuming_buffers_iterator &a, const consuming_buffers_iterator &b)
STL namespace.
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Definition: buffer.hpp:706
asio::basic_streambuf< Allocator > & b
Definition: read.hpp:702
std::size_t buffer_size(const mutable_buffer &b)
Get the number of bytes in a modifiable buffer.
Definition: buffer.hpp:357
PointerToPodType buffer_cast(const mutable_buffer &b)
Cast a non-modifiable buffer to a specified pointer to POD type.
Definition: buffer.hpp:424
void prepare(std::size_t max_size)
const MutableBufferSequence & buffers
Definition: read.hpp:521
consuming_buffers(const consuming_buffers &other)
consuming_buffers_iterator operator++(int)
friend bool operator!=(const consuming_buffers_iterator &a, const consuming_buffers_iterator &b)
consuming_buffers_iterator & operator++()
consuming_buffers_iterator< Buffer, typename Buffers::const_iterator > const_iterator
consuming_buffers & operator=(const consuming_buffers &other)
std::forward_iterator_tag iterator_category
The iterator category.
std::ptrdiff_t difference_type
The type used for the distance between two iterators.
Buffer value_type
The type of the value pointed to by the iterator.
SocketService Iterator Iterator end
Definition: connect.hpp:592
consuming_buffers(const Buffers &buffers)
const Buffer & reference
The type of the result of applying operator*() to the iterator.
consuming_buffers_iterator(bool at_end, const Buffer &first, Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder, std::size_t max_size)
const Buffer * pointer
The type of the result of applying operator->() to the iterator.