//
// detail/consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP
#define BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/iterator.hpp>
#include <boost/limits.hpp>
#include <boost/asio/buffer.hpp>

#include <boost/asio/detail/push_options.hpp>

namespace boost {
namespace asio {
namespace detail {

// A proxy iterator for a sub-range in a list of buffers.
template <typename Buffer, typename Buffer_Iterator>
class consuming_buffers_iterator
  : public boost::iterator<std::forward_iterator_tag, const Buffer>
{
public:
  // Default constructor creates an end iterator.
  consuming_buffers_iterator()
    : at_end_(true)
  {
  }

  // Construct with a buffer for the first entry and an iterator
  // range for the remaining entries.
  consuming_buffers_iterator(bool at_end, const Buffer& first,
      Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder,
      std::size_t max_size)
    : at_end_(max_size > 0 ? at_end : true),
      first_(buffer(first, max_size)),
      begin_remainder_(begin_remainder),
      end_remainder_(end_remainder),
      offset_(0),
      max_size_(max_size)
  {
  }

  // Dereference an iterator.
  const Buffer& operator*() const
  {
    return dereference();
  }

  // Dereference an iterator.
  const Buffer* operator->() const
  {
    return &dereference();
  }

  // Increment operator (prefix).
  consuming_buffers_iterator& operator++()
  {
    increment();
    return *this;
  }

  // Increment operator (postfix).
  consuming_buffers_iterator operator++(int)
  {
    consuming_buffers_iterator tmp(*this);
    ++*this;
    return tmp;
  }

  // Test two iterators for equality.
  friend bool operator==(const consuming_buffers_iterator& a,
      const consuming_buffers_iterator& b)
  {
    return a.equal(b);
  }

  // Test two iterators for inequality.
  friend bool operator!=(const consuming_buffers_iterator& a,
      const consuming_buffers_iterator& b)
  {
    return !a.equal(b);
  }

private:
  void increment()
  {
    if (!at_end_)
    {
      if (begin_remainder_ == end_remainder_
          || offset_ + buffer_size(first_) >= max_size_)
      {
        at_end_ = true;
      }
      else
      {
        offset_ += buffer_size(first_);
        first_ = buffer(*begin_remainder_++, max_size_ - offset_);
      }
    }
  }

  bool equal(const consuming_buffers_iterator& other) const
  {
    if (at_end_ && other.at_end_)
      return true;
    return !at_end_ && !other.at_end_
      && buffer_cast<const void*>(first_)
        == buffer_cast<const void*>(other.first_)
      && buffer_size(first_) == buffer_size(other.first_)
      && begin_remainder_ == other.begin_remainder_
      && end_remainder_ == other.end_remainder_;
  }

  const Buffer& dereference() const
  {
    return first_;
  }

  bool at_end_;
  Buffer first_;
  Buffer_Iterator begin_remainder_;
  Buffer_Iterator end_remainder_;
  std::size_t offset_;
  std::size_t max_size_;
};

// A proxy for a sub-range in a list of buffers.
template <typename Buffer, typename Buffers>
class consuming_buffers
{
public:
  // The type for each element in the list of buffers.
  typedef Buffer value_type;

  // A forward-only iterator type that may be used to read elements.
  typedef consuming_buffers_iterator<Buffer, typename Buffers::const_iterator>
    const_iterator;

  // Construct to represent the entire list of buffers.
  consuming_buffers(const Buffers& buffers)
    : buffers_(buffers),
      at_end_(buffers_.begin() == buffers_.end()),
      begin_remainder_(buffers_.begin()),
      max_size_((std::numeric_limits<std::size_t>::max)())
  {
    if (!at_end_)
    {
      first_ = *buffers_.begin();
      ++begin_remainder_;
    }
  }

  // Copy constructor.
  consuming_buffers(const consuming_buffers& other)
    : buffers_(other.buffers_),
      at_end_(other.at_end_),
      first_(other.first_),
      begin_remainder_(buffers_.begin()),
      max_size_(other.max_size_)
  {
    typename Buffers::const_iterator first = other.buffers_.begin();
    typename Buffers::const_iterator second = other.begin_remainder_;
    std::advance(begin_remainder_, std::distance(first, second));
  }

  // Assignment operator.
  consuming_buffers& operator=(const consuming_buffers& other)
  {
    buffers_ = other.buffers_;
    at_end_ = other.at_end_;
    first_ = other.first_;
    begin_remainder_ = buffers_.begin();
    typename Buffers::const_iterator first = other.buffers_.begin();
    typename Buffers::const_iterator second = other.begin_remainder_;
    std::advance(begin_remainder_, std::distance(first, second));
    max_size_ = other.max_size_;
    return *this;
  }

  // Get a forward-only iterator to the first element.
  const_iterator begin() const
  {
    return const_iterator(at_end_, first_,
        begin_remainder_, buffers_.end(), max_size_);
  }

  // Get a forward-only iterator for one past the last element.
  const_iterator end() const
  {
    return const_iterator();
  }

  // Set the maximum size for a single transfer.
  void prepare(std::size_t max_size)
  {
    max_size_ = max_size;
  }

  // Consume the specified number of bytes from the buffers.
  void consume(std::size_t size)
  {
    // Remove buffers from the start until the specified size is reached.
    while (size > 0 && !at_end_)
    {
      if (buffer_size(first_) <= size)
      {
        size -= buffer_size(first_);
        if (begin_remainder_ == buffers_.end())
          at_end_ = true;
        else
          first_ = *begin_remainder_++;
      }
      else
      {
        first_ = first_ + size;
        size = 0;
      }
    }

    // Remove any more empty buffers at the start.
    while (!at_end_ && buffer_size(first_) == 0)
    {
      if (begin_remainder_ == buffers_.end())
        at_end_ = true;
      else
        first_ = *begin_remainder_++;
    }
  }

private:
  Buffers buffers_;
  bool at_end_;
  Buffer first_;
  typename Buffers::const_iterator begin_remainder_;
  std::size_t max_size_;
};

// Specialisation for null_buffers to ensure that the null_buffers type is
// always passed through to the underlying read or write operation.
template <typename Buffer>
class consuming_buffers<Buffer, boost::asio::null_buffers>
  : public boost::asio::null_buffers
{
public:
  consuming_buffers(const boost::asio::null_buffers&)
  {
    // No-op.
  }

  void prepare(std::size_t)
  {
    // No-op.
  }

  void consume(std::size_t)
  {
    // No-op.
  }
};

} // namespace detail
} // namespace asio
} // namespace boost

#include <boost/asio/detail/pop_options.hpp>

#endif // BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP
