// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2003-2007 Jonathan Turkanis
// 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.)

// See http://www.boost.org/libs/iostreams for documentation.

#ifndef NDNBOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED
#define NDNBOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED

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

#include <algorithm>                             // min.
#include <ndnboost/assert.hpp>
#include <cstddef>                               // ptrdiff_t.
#include <iosfwd>                                // streamsize, streamoff.
#include <ndnboost/detail/iterator.hpp>             // ndnboost::iterator_traits.
#include <ndnboost/iostreams/categories.hpp>
#include <ndnboost/iostreams/detail/error.hpp>
#include <ndnboost/iostreams/positioning.hpp>
#include <ndnboost/mpl/if.hpp>
#include <ndnboost/throw_exception.hpp>
#include <ndnboost/type_traits/is_convertible.hpp>
#include <ndnboost/utility/enable_if.hpp>

// Must come last.
#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.

namespace ndnboost { namespace iostreams { namespace detail {

// Used for simulated tag dispatch.
template<typename Traversal> struct range_adapter_impl;

//
// Template name: range_adapter
// Description: Device based on an instance of ndnboost::iterator_range.
// Template parameters:
//     Mode - A mode tag.
//     Range - An instance of iterator_range.
//
template<typename Mode, typename Range>
class range_adapter {
private:
    typedef typename Range::iterator                  iterator;
    typedef ndnboost::detail::iterator_traits<iterator>  iter_traits;
    typedef typename iter_traits::iterator_category   iter_cat;
public:
    typedef typename Range::value_type                char_type;
    struct category : Mode, device_tag { };
    typedef typename
            mpl::if_<
                is_convertible<
                    iter_cat,
                    std::random_access_iterator_tag
                >,
                std::random_access_iterator_tag,
                std::forward_iterator_tag
            >::type                                   tag;
    typedef range_adapter_impl<tag>                   impl;

    explicit range_adapter(const Range& rng);
    range_adapter(iterator first, iterator last);
    std::streamsize read(char_type* s, std::streamsize n);
    std::streamsize write(const char_type* s, std::streamsize n);
    std::streampos seek(stream_offset off, NDNBOOST_IOS::seekdir way);
private:
    iterator first_, cur_, last_;
};

//------------------Implementation of range_adapter---------------------------//

template<typename Mode, typename Range>
range_adapter<Mode, Range>::range_adapter(const Range& rng)
    : first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { }

template<typename Mode, typename Range>
range_adapter<Mode, Range>::range_adapter(iterator first, iterator last)
    : first_(first), cur_(first), last_(last) { }

template<typename Mode, typename Range>
inline std::streamsize range_adapter<Mode, Range>::read
    (char_type* s, std::streamsize n)
{ return impl::read(cur_, last_, s, n); }

template<typename Mode, typename Range>
inline std::streamsize range_adapter<Mode, Range>::write
    (const char_type* s, std::streamsize n)
{ return impl::write(cur_, last_, s, n); }


template<typename Mode, typename Range>
std::streampos range_adapter<Mode, Range>::seek
    (stream_offset off, NDNBOOST_IOS::seekdir way)
{ 
    impl::seek(first_, cur_, last_, off, way); 
    return offset_to_position(cur_ - first_);
}

//------------------Implementation of range_adapter_impl----------------------//

template<>
struct range_adapter_impl<std::forward_iterator_tag> {
    template<typename Iter, typename Ch>
    static std::streamsize read
        (Iter& cur, Iter& last, Ch* s,std::streamsize n)
    {
        std::streamsize rem = n; // No. of chars remaining.
        while (cur != last && rem-- > 0) *s++ = *cur++;
        return n - rem != 0 ? n - rem : -1;
    }

    template<typename Iter, typename Ch>
    static std::streamsize write
        (Iter& cur, Iter& last, const Ch* s, std::streamsize n)
    {
        while (cur != last && n-- > 0) *cur++ = *s++;
        if (cur == last && n > 0)
            ndnboost::throw_exception(write_area_exhausted());
        return n;
    }
};

template<>
struct range_adapter_impl<std::random_access_iterator_tag> {
    template<typename Iter, typename Ch>
    static std::streamsize read
        (Iter& cur, Iter& last, Ch* s,std::streamsize n)
    {
        std::streamsize result = 
            (std::min)(static_cast<std::streamsize>(last - cur), n);
        if (result)
            std::copy(cur, cur + result, s);
        cur += result;
        return result != 0 ? result : -1;
    }

    template<typename Iter, typename Ch>
    static std::streamsize write
        (Iter& cur, Iter& last, const Ch* s, std::streamsize n)
    {
        std::streamsize count =
            (std::min)(static_cast<std::streamsize>(last - cur), n);
        std::copy(s, s + count, cur);
        cur += count;
        if (count < n) 
            ndnboost::throw_exception(write_area_exhausted());
        return n;
    }

    template<typename Iter>
    static void seek
        ( Iter& first, Iter& cur, Iter& last, stream_offset off,
          NDNBOOST_IOS::seekdir way )
    {
        using namespace std;
        switch (way) {
        case NDNBOOST_IOS::beg:
            if (off > last - first || off < 0)
                ndnboost::throw_exception(bad_seek());
            cur = first + off;
            break;
        case NDNBOOST_IOS::cur:
            {
                std::ptrdiff_t newoff = cur - first + off;
                if (newoff > last - first || newoff < 0)
                    ndnboost::throw_exception(bad_seek());
                cur += off;
                break;
            }
        case NDNBOOST_IOS::end:
            if (last - first + off < 0 || off > 0)
                ndnboost::throw_exception(bad_seek());
            cur = last + off;
            break;
        default:
            NDNBOOST_ASSERT(0);
        }
    }
};

} } } // End namespaces detail, iostreams, boost.

#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.

#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------//
