const_buffers_iterator.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //
  2. // const_buffers_iterator.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 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. #ifndef BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
  11. #define BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <cstddef>
  18. #include <boost/config.hpp>
  19. #include <boost/iterator/iterator_facade.hpp>
  20. #include <boost/asio/detail/pop_options.hpp>
  21. #include <boost/asio/buffer.hpp>
  22. namespace boost {
  23. namespace asio {
  24. namespace detail {
  25. // A proxy iterator for a sub-range in a list of buffers.
  26. template <typename ConstBufferSequence>
  27. class const_buffers_iterator
  28. : public boost::iterator_facade<const_buffers_iterator<ConstBufferSequence>,
  29. const char, boost::bidirectional_traversal_tag>
  30. {
  31. public:
  32. // Default constructor creates an iterator in an undefined state.
  33. const_buffers_iterator()
  34. {
  35. }
  36. // Create an iterator for the specified position.
  37. const_buffers_iterator(const ConstBufferSequence& buffers,
  38. std::size_t position)
  39. : begin_(buffers.begin()),
  40. current_(buffers.begin()),
  41. end_(buffers.end()),
  42. position_(0)
  43. {
  44. while (current_ != end_)
  45. {
  46. current_buffer_ = *current_;
  47. std::size_t buffer_size = boost::asio::buffer_size(current_buffer_);
  48. if (position - position_ < buffer_size)
  49. {
  50. current_buffer_position_ = position - position_;
  51. position_ = position;
  52. return;
  53. }
  54. position_ += buffer_size;
  55. ++current_;
  56. }
  57. current_buffer_ = boost::asio::const_buffer();
  58. current_buffer_position_ = 0;
  59. }
  60. std::size_t position() const
  61. {
  62. return position_;
  63. }
  64. private:
  65. friend class boost::iterator_core_access;
  66. void increment()
  67. {
  68. if (current_ == end_)
  69. return;
  70. ++position_;
  71. ++current_buffer_position_;
  72. if (current_buffer_position_ != boost::asio::buffer_size(current_buffer_))
  73. return;
  74. ++current_;
  75. current_buffer_position_ = 0;
  76. while (current_ != end_)
  77. {
  78. current_buffer_ = *current_;
  79. if (boost::asio::buffer_size(current_buffer_) > 0)
  80. return;
  81. ++current_;
  82. }
  83. }
  84. void decrement()
  85. {
  86. if (position_ == 0)
  87. return;
  88. --position_;
  89. if (current_buffer_position_ != 0)
  90. {
  91. --current_buffer_position_;
  92. return;
  93. }
  94. typename ConstBufferSequence::const_iterator iter = current_;
  95. while (iter != begin_)
  96. {
  97. --iter;
  98. boost::asio::const_buffer buffer = *iter;
  99. std::size_t buffer_size = boost::asio::buffer_size(buffer);
  100. if (buffer_size > 0)
  101. {
  102. current_ = iter;
  103. current_buffer_ = buffer;
  104. current_buffer_position_ = buffer_size - 1;
  105. return;
  106. }
  107. }
  108. }
  109. bool equal(const const_buffers_iterator& other) const
  110. {
  111. return position_ == other.position_;
  112. }
  113. const char& dereference() const
  114. {
  115. return boost::asio::buffer_cast<const char*>(
  116. current_buffer_)[current_buffer_position_];
  117. }
  118. boost::asio::const_buffer current_buffer_;
  119. std::size_t current_buffer_position_;
  120. typename ConstBufferSequence::const_iterator begin_;
  121. typename ConstBufferSequence::const_iterator current_;
  122. typename ConstBufferSequence::const_iterator end_;
  123. std::size_t position_;
  124. };
  125. } // namespace detail
  126. } // namespace asio
  127. } // namespace boost
  128. #include <boost/asio/detail/pop_options.hpp>
  129. #endif // BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP