#ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
#define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// transform_width.hpp

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
// Use, modification and distribution is subject to 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 for updates, documentation, and revision history.

// iterator which takes elements of x bits and returns elements of y bits.
// used to change streams of 8 bit characters into streams of 6 bit characters.
// and vice-versa for implementing base64 encodeing/decoding. Be very careful
// when using and end iterator.  end is only reliable detected when the input
// stream length is some common multiple of x and y.  E.G. Base64 6 bit
// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters
// or 3 8 bit characters

#include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
#include <boost/serialization/pfto.hpp>

#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_traits.hpp>

namespace boost { 
namespace archive {
namespace iterators {

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// class used by text archives to translate char strings to wchar_t
// strings of the currently selected locale
template<
    class Base, 
    int BitsOut, 
    int BitsIn, 
    class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type // output character
>
class transform_width : 
    public boost::iterator_adaptor<
        transform_width<Base, BitsOut, BitsIn, CharType>,
        Base,
        CharType,
        single_pass_traversal_tag,
        CharType
    >
{
    friend class boost::iterator_core_access;
    typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor<
        transform_width<Base, BitsOut, BitsIn, CharType>,
        Base,
        CharType,
        single_pass_traversal_tag,
        CharType
    > super_t;

    typedef transform_width<Base, BitsOut, BitsIn, CharType> this_t;
    typedef BOOST_DEDUCED_TYPENAME iterator_value<Base>::type base_value_type;

    CharType fill();

    CharType dereference_impl(){
        if(! m_full){
            m_current_value = fill();
            m_full = true;
        }
        return m_current_value;
    }

    CharType dereference() const {
        return const_cast<this_t *>(this)->dereference_impl();
    }

    // test for iterator equality
    bool equal(const this_t & rhs) const {
        return
            this->base_reference() == rhs.base_reference();
        ;
    }

    void increment(){
        m_displacement += BitsOut;

        while(m_displacement >= BitsIn){
            m_displacement -= BitsIn;
            if(0 == m_displacement)
                m_bufferfull = false;
            if(! m_bufferfull){
                // note: suspect that this is not invoked for borland
                ++(this->base_reference());
            }
        }
        m_full = false;
    }

    CharType m_current_value;
    // number of bits left in current input character buffer
    unsigned int m_displacement;
    base_value_type m_buffer;
    // flag to current output character is ready - just used to save time
    bool m_full;
    // flag to indicate that m_buffer has data
    bool m_bufferfull;

public:
    // make composible buy using templated constructor
    template<class T>
    transform_width(BOOST_PFTO_WRAPPER(T) start) : 
        super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
        m_displacement(0),
        m_full(false),
        m_bufferfull(false)
    {}
    // intel 7.1 doesn't like default copy constructor
    transform_width(const transform_width & rhs) : 
        super_t(rhs.base_reference()),
        m_current_value(rhs.m_current_value),
        m_displacement(rhs.m_displacement),
        m_buffer(rhs.m_buffer),
        m_full(rhs.m_full),
        m_bufferfull(rhs.m_bufferfull)
    {}
};

template<class Base, int BitsOut, int BitsIn, class CharType>
CharType transform_width<Base, BitsOut, BitsIn, CharType>::fill(){
    CharType retval = 0;
    unsigned int missing_bits = BitsOut;
    for(;;){
        unsigned int bcount;
        if(! m_bufferfull){
            m_buffer = * this->base_reference();
            m_bufferfull = true;
            bcount = BitsIn;
        }
        else
            bcount = BitsIn - m_displacement;
        unsigned int i = (std::min)(bcount, missing_bits);
        // shift interesting bits to least significant position
        unsigned int j = m_buffer >> (bcount - i);
        // strip off uninteresting bits
        // (note presumption of two's complement arithmetic)
        j &= ~(-(1 << i));
        // append then interesting bits to the output value
        retval <<= i;
        retval |= j;
        missing_bits -= i;
        if(0 == missing_bits)
            break;
        // note: suspect that this is not invoked for borland 5.51
        ++(this->base_reference());
        m_bufferfull = false;
    }
    return retval;
}

} // namespace iterators
} // namespace archive
} // namespace boost

#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
