Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / detail / consuming_buffers.hpp @ 2486

History | View | Annotate | Download (7.3 kB)

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