File indexing completed on 2025-09-16 08:28:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP
0012 #define BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstddef>
0020 #include <boost/asio/buffer.hpp>
0021 #include <boost/asio/detail/buffer_sequence_adapter.hpp>
0022 #include <boost/asio/detail/limits.hpp>
0023 #include <boost/asio/registered_buffer.hpp>
0024
0025 #include <boost/asio/detail/push_options.hpp>
0026
0027 namespace boost {
0028 namespace asio {
0029 namespace detail {
0030
0031
0032 template <typename Buffers>
0033 struct prepared_buffers_max
0034 {
0035 enum { value = buffer_sequence_adapter_base::max_buffers };
0036 };
0037
0038 template <typename Elem, std::size_t N>
0039 struct prepared_buffers_max<boost::array<Elem, N>>
0040 {
0041 enum { value = N };
0042 };
0043
0044 template <typename Elem, std::size_t N>
0045 struct prepared_buffers_max<std::array<Elem, N>>
0046 {
0047 enum { value = N };
0048 };
0049
0050
0051 template <typename Buffer, std::size_t MaxBuffers>
0052 struct prepared_buffers
0053 {
0054 typedef Buffer value_type;
0055 typedef const Buffer* const_iterator;
0056
0057 enum { max_buffers = MaxBuffers < 16 ? MaxBuffers : 16 };
0058
0059 prepared_buffers() : count(0) {}
0060 const_iterator begin() const { return elems; }
0061 const_iterator end() const { return elems + count; }
0062
0063 Buffer elems[max_buffers];
0064 std::size_t count;
0065 };
0066
0067
0068 template <typename Buffer, typename Buffers, typename Buffer_Iterator>
0069 class consuming_buffers
0070 {
0071 public:
0072 typedef prepared_buffers<Buffer, prepared_buffers_max<Buffers>::value>
0073 prepared_buffers_type;
0074
0075
0076 explicit consuming_buffers(const Buffers& buffers)
0077 : buffers_(buffers),
0078 total_consumed_(0),
0079 next_elem_(0),
0080 next_elem_offset_(0)
0081 {
0082 using boost::asio::buffer_size;
0083 total_size_ = buffer_size(buffers);
0084 }
0085
0086
0087 bool empty() const
0088 {
0089 return total_consumed_ >= total_size_;
0090 }
0091
0092
0093 prepared_buffers_type prepare(std::size_t max_size)
0094 {
0095 prepared_buffers_type result;
0096
0097 Buffer_Iterator next = boost::asio::buffer_sequence_begin(buffers_);
0098 Buffer_Iterator end = boost::asio::buffer_sequence_end(buffers_);
0099
0100 std::advance(next, next_elem_);
0101 std::size_t elem_offset = next_elem_offset_;
0102 while (next != end && max_size > 0 && (result.count) < result.max_buffers)
0103 {
0104 Buffer next_buf = Buffer(*next) + elem_offset;
0105 result.elems[result.count] = boost::asio::buffer(next_buf, max_size);
0106 max_size -= result.elems[result.count].size();
0107 elem_offset = 0;
0108 if (result.elems[result.count].size() > 0)
0109 ++result.count;
0110 ++next;
0111 }
0112
0113 return result;
0114 }
0115
0116
0117 void consume(std::size_t size)
0118 {
0119 total_consumed_ += size;
0120
0121 Buffer_Iterator next = boost::asio::buffer_sequence_begin(buffers_);
0122 Buffer_Iterator end = boost::asio::buffer_sequence_end(buffers_);
0123
0124 std::advance(next, next_elem_);
0125 while (next != end && size > 0)
0126 {
0127 Buffer next_buf = Buffer(*next) + next_elem_offset_;
0128 if (size < next_buf.size())
0129 {
0130 next_elem_offset_ += size;
0131 size = 0;
0132 }
0133 else
0134 {
0135 size -= next_buf.size();
0136 next_elem_offset_ = 0;
0137 ++next_elem_;
0138 ++next;
0139 }
0140 }
0141 }
0142
0143
0144 std::size_t total_consumed() const
0145 {
0146 return total_consumed_;
0147 }
0148
0149 private:
0150 Buffers buffers_;
0151 std::size_t total_size_;
0152 std::size_t total_consumed_;
0153 std::size_t next_elem_;
0154 std::size_t next_elem_offset_;
0155 };
0156
0157
0158 template <typename Buffer>
0159 class consuming_single_buffer
0160 {
0161 public:
0162
0163 template <typename Buffer1>
0164 explicit consuming_single_buffer(const Buffer1& buffer)
0165 : buffer_(buffer),
0166 total_consumed_(0)
0167 {
0168 }
0169
0170
0171 bool empty() const
0172 {
0173 return total_consumed_ >= buffer_.size();
0174 }
0175
0176
0177 Buffer prepare(std::size_t max_size)
0178 {
0179 return boost::asio::buffer(buffer_ + total_consumed_, max_size);
0180 }
0181
0182
0183 void consume(std::size_t size)
0184 {
0185 total_consumed_ += size;
0186 }
0187
0188
0189 std::size_t total_consumed() const
0190 {
0191 return total_consumed_;
0192 }
0193
0194 private:
0195 Buffer buffer_;
0196 std::size_t total_consumed_;
0197 };
0198
0199 template <>
0200 class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>
0201 : public consuming_single_buffer<mutable_buffer>
0202 {
0203 public:
0204 explicit consuming_buffers(const mutable_buffer& buffer)
0205 : consuming_single_buffer<mutable_buffer>(buffer)
0206 {
0207 }
0208 };
0209
0210 template <>
0211 class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>
0212 : public consuming_single_buffer<const_buffer>
0213 {
0214 public:
0215 explicit consuming_buffers(const mutable_buffer& buffer)
0216 : consuming_single_buffer<const_buffer>(buffer)
0217 {
0218 }
0219 };
0220
0221 template <>
0222 class consuming_buffers<const_buffer, const_buffer, const const_buffer*>
0223 : public consuming_single_buffer<const_buffer>
0224 {
0225 public:
0226 explicit consuming_buffers(const const_buffer& buffer)
0227 : consuming_single_buffer<const_buffer>(buffer)
0228 {
0229 }
0230 };
0231
0232 template <>
0233 class consuming_buffers<mutable_buffer,
0234 mutable_registered_buffer, const mutable_buffer*>
0235 : public consuming_single_buffer<mutable_registered_buffer>
0236 {
0237 public:
0238 explicit consuming_buffers(const mutable_registered_buffer& buffer)
0239 : consuming_single_buffer<mutable_registered_buffer>(buffer)
0240 {
0241 }
0242 };
0243
0244 template <>
0245 class consuming_buffers<const_buffer,
0246 mutable_registered_buffer, const mutable_buffer*>
0247 : public consuming_single_buffer<mutable_registered_buffer>
0248 {
0249 public:
0250 explicit consuming_buffers(const mutable_registered_buffer& buffer)
0251 : consuming_single_buffer<mutable_registered_buffer>(buffer)
0252 {
0253 }
0254 };
0255
0256 template <>
0257 class consuming_buffers<const_buffer,
0258 const_registered_buffer, const const_buffer*>
0259 : public consuming_single_buffer<const_registered_buffer>
0260 {
0261 public:
0262 explicit consuming_buffers(const const_registered_buffer& buffer)
0263 : consuming_single_buffer<const_registered_buffer>(buffer)
0264 {
0265 }
0266 };
0267
0268 template <typename Buffer, typename Elem>
0269 class consuming_buffers<Buffer, boost::array<Elem, 2>,
0270 typename boost::array<Elem, 2>::const_iterator>
0271 {
0272 public:
0273
0274 explicit consuming_buffers(const boost::array<Elem, 2>& buffers)
0275 : buffers_(buffers),
0276 total_consumed_(0)
0277 {
0278 }
0279
0280
0281 bool empty() const
0282 {
0283 return total_consumed_ >=
0284 Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
0285 }
0286
0287
0288 boost::array<Buffer, 2> prepare(std::size_t max_size)
0289 {
0290 boost::array<Buffer, 2> result = {{
0291 Buffer(buffers_[0]), Buffer(buffers_[1]) }};
0292 std::size_t buffer0_size = result[0].size();
0293 result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
0294 result[1] = boost::asio::buffer(
0295 result[1] + (total_consumed_ < buffer0_size
0296 ? 0 : total_consumed_ - buffer0_size),
0297 max_size - result[0].size());
0298 return result;
0299 }
0300
0301
0302 void consume(std::size_t size)
0303 {
0304 total_consumed_ += size;
0305 }
0306
0307
0308 std::size_t total_consumed() const
0309 {
0310 return total_consumed_;
0311 }
0312
0313 private:
0314 boost::array<Elem, 2> buffers_;
0315 std::size_t total_consumed_;
0316 };
0317
0318 template <typename Buffer, typename Elem>
0319 class consuming_buffers<Buffer, std::array<Elem, 2>,
0320 typename std::array<Elem, 2>::const_iterator>
0321 {
0322 public:
0323
0324 explicit consuming_buffers(const std::array<Elem, 2>& buffers)
0325 : buffers_(buffers),
0326 total_consumed_(0)
0327 {
0328 }
0329
0330
0331 bool empty() const
0332 {
0333 return total_consumed_ >=
0334 Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
0335 }
0336
0337
0338 std::array<Buffer, 2> prepare(std::size_t max_size)
0339 {
0340 std::array<Buffer, 2> result = {{
0341 Buffer(buffers_[0]), Buffer(buffers_[1]) }};
0342 std::size_t buffer0_size = result[0].size();
0343 result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
0344 result[1] = boost::asio::buffer(
0345 result[1] + (total_consumed_ < buffer0_size
0346 ? 0 : total_consumed_ - buffer0_size),
0347 max_size - result[0].size());
0348 return result;
0349 }
0350
0351
0352 void consume(std::size_t size)
0353 {
0354 total_consumed_ += size;
0355 }
0356
0357
0358 std::size_t total_consumed() const
0359 {
0360 return total_consumed_;
0361 }
0362
0363 private:
0364 std::array<Elem, 2> buffers_;
0365 std::size_t total_consumed_;
0366 };
0367
0368
0369
0370 template <typename Buffer>
0371 class consuming_buffers<Buffer, null_buffers, const mutable_buffer*>
0372 : public boost::asio::null_buffers
0373 {
0374 public:
0375 consuming_buffers(const null_buffers&)
0376 {
0377
0378 }
0379
0380 bool empty()
0381 {
0382 return false;
0383 }
0384
0385 null_buffers prepare(std::size_t)
0386 {
0387 return null_buffers();
0388 }
0389
0390 void consume(std::size_t)
0391 {
0392
0393 }
0394
0395 std::size_t total_consumed() const
0396 {
0397 return 0;
0398 }
0399 };
0400
0401 }
0402 }
0403 }
0404
0405 #include <boost/asio/detail/pop_options.hpp>
0406
0407 #endif