File indexing completed on 2025-01-18 09:28:38
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<BOOST_ASIO_MUTABLE_BUFFER>
0202 {
0203 public:
0204 explicit consuming_buffers(const mutable_buffer& buffer)
0205 : consuming_single_buffer<BOOST_ASIO_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<BOOST_ASIO_CONST_BUFFER>
0213 {
0214 public:
0215 explicit consuming_buffers(const mutable_buffer& buffer)
0216 : consuming_single_buffer<BOOST_ASIO_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<BOOST_ASIO_CONST_BUFFER>
0224 {
0225 public:
0226 explicit consuming_buffers(const const_buffer& buffer)
0227 : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
0228 {
0229 }
0230 };
0231
0232 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0233
0234 template <>
0235 class consuming_buffers<mutable_buffer,
0236 mutable_buffers_1, const mutable_buffer*>
0237 : public consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>
0238 {
0239 public:
0240 explicit consuming_buffers(const mutable_buffers_1& buffer)
0241 : consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>(buffer)
0242 {
0243 }
0244 };
0245
0246 template <>
0247 class consuming_buffers<const_buffer, mutable_buffers_1, const mutable_buffer*>
0248 : public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
0249 {
0250 public:
0251 explicit consuming_buffers(const mutable_buffers_1& buffer)
0252 : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
0253 {
0254 }
0255 };
0256
0257 template <>
0258 class consuming_buffers<const_buffer, const_buffers_1, const const_buffer*>
0259 : public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
0260 {
0261 public:
0262 explicit consuming_buffers(const const_buffers_1& buffer)
0263 : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
0264 {
0265 }
0266 };
0267
0268 #endif
0269
0270 template <>
0271 class consuming_buffers<mutable_buffer,
0272 mutable_registered_buffer, const mutable_buffer*>
0273 : public consuming_single_buffer<mutable_registered_buffer>
0274 {
0275 public:
0276 explicit consuming_buffers(const mutable_registered_buffer& buffer)
0277 : consuming_single_buffer<mutable_registered_buffer>(buffer)
0278 {
0279 }
0280 };
0281
0282 template <>
0283 class consuming_buffers<const_buffer,
0284 mutable_registered_buffer, const mutable_buffer*>
0285 : public consuming_single_buffer<mutable_registered_buffer>
0286 {
0287 public:
0288 explicit consuming_buffers(const mutable_registered_buffer& buffer)
0289 : consuming_single_buffer<mutable_registered_buffer>(buffer)
0290 {
0291 }
0292 };
0293
0294 template <>
0295 class consuming_buffers<const_buffer,
0296 const_registered_buffer, const const_buffer*>
0297 : public consuming_single_buffer<const_registered_buffer>
0298 {
0299 public:
0300 explicit consuming_buffers(const const_registered_buffer& buffer)
0301 : consuming_single_buffer<const_registered_buffer>(buffer)
0302 {
0303 }
0304 };
0305
0306 template <typename Buffer, typename Elem>
0307 class consuming_buffers<Buffer, boost::array<Elem, 2>,
0308 typename boost::array<Elem, 2>::const_iterator>
0309 {
0310 public:
0311
0312 explicit consuming_buffers(const boost::array<Elem, 2>& buffers)
0313 : buffers_(buffers),
0314 total_consumed_(0)
0315 {
0316 }
0317
0318
0319 bool empty() const
0320 {
0321 return total_consumed_ >=
0322 Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
0323 }
0324
0325
0326 boost::array<Buffer, 2> prepare(std::size_t max_size)
0327 {
0328 boost::array<Buffer, 2> result = {{
0329 Buffer(buffers_[0]), Buffer(buffers_[1]) }};
0330 std::size_t buffer0_size = result[0].size();
0331 result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
0332 result[1] = boost::asio::buffer(
0333 result[1] + (total_consumed_ < buffer0_size
0334 ? 0 : total_consumed_ - buffer0_size),
0335 max_size - result[0].size());
0336 return result;
0337 }
0338
0339
0340 void consume(std::size_t size)
0341 {
0342 total_consumed_ += size;
0343 }
0344
0345
0346 std::size_t total_consumed() const
0347 {
0348 return total_consumed_;
0349 }
0350
0351 private:
0352 boost::array<Elem, 2> buffers_;
0353 std::size_t total_consumed_;
0354 };
0355
0356 template <typename Buffer, typename Elem>
0357 class consuming_buffers<Buffer, std::array<Elem, 2>,
0358 typename std::array<Elem, 2>::const_iterator>
0359 {
0360 public:
0361
0362 explicit consuming_buffers(const std::array<Elem, 2>& buffers)
0363 : buffers_(buffers),
0364 total_consumed_(0)
0365 {
0366 }
0367
0368
0369 bool empty() const
0370 {
0371 return total_consumed_ >=
0372 Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
0373 }
0374
0375
0376 std::array<Buffer, 2> prepare(std::size_t max_size)
0377 {
0378 std::array<Buffer, 2> result = {{
0379 Buffer(buffers_[0]), Buffer(buffers_[1]) }};
0380 std::size_t buffer0_size = result[0].size();
0381 result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
0382 result[1] = boost::asio::buffer(
0383 result[1] + (total_consumed_ < buffer0_size
0384 ? 0 : total_consumed_ - buffer0_size),
0385 max_size - result[0].size());
0386 return result;
0387 }
0388
0389
0390 void consume(std::size_t size)
0391 {
0392 total_consumed_ += size;
0393 }
0394
0395
0396 std::size_t total_consumed() const
0397 {
0398 return total_consumed_;
0399 }
0400
0401 private:
0402 std::array<Elem, 2> buffers_;
0403 std::size_t total_consumed_;
0404 };
0405
0406
0407
0408 template <typename Buffer>
0409 class consuming_buffers<Buffer, null_buffers, const mutable_buffer*>
0410 : public boost::asio::null_buffers
0411 {
0412 public:
0413 consuming_buffers(const null_buffers&)
0414 {
0415
0416 }
0417
0418 bool empty()
0419 {
0420 return false;
0421 }
0422
0423 null_buffers prepare(std::size_t)
0424 {
0425 return null_buffers();
0426 }
0427
0428 void consume(std::size_t)
0429 {
0430
0431 }
0432
0433 std::size_t total_consumed() const
0434 {
0435 return 0;
0436 }
0437 };
0438
0439 }
0440 }
0441 }
0442
0443 #include <boost/asio/detail/pop_options.hpp>
0444
0445 #endif