PageRenderTime 51ms CodeModel.GetById 37ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/archive/iterators/transform_width.hpp

http://hadesmem.googlecode.com/
C++ Header | 170 lines | 118 code | 22 blank | 30 comment | 10 complexity | 938012e31da627ba32264a55ce70badf MD5 | raw file
  1#ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
  2#define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
  3
  4// MS compatible compilers support #pragma once
  5#if defined(_MSC_VER) && (_MSC_VER >= 1020)
  6# pragma once
  7#endif
  8
  9/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 10// transform_width.hpp
 11
 12// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
 13// Use, modification and distribution is subject to the Boost Software
 14// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 15// http://www.boost.org/LICENSE_1_0.txt)
 16
 17//  See http://www.boost.org for updates, documentation, and revision history.
 18
 19// iterator which takes elements of x bits and returns elements of y bits.
 20// used to change streams of 8 bit characters into streams of 6 bit characters.
 21// and vice-versa for implementing base64 encodeing/decoding. Be very careful
 22// when using and end iterator.  end is only reliable detected when the input
 23// stream length is some common multiple of x and y.  E.G. Base64 6 bit
 24// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters
 25// or 3 8 bit characters
 26
 27#include <algorithm>
 28
 29#include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
 30#include <boost/serialization/pfto.hpp>
 31
 32#include <boost/iterator/iterator_adaptor.hpp>
 33#include <boost/iterator/iterator_traits.hpp>
 34
 35namespace boost { 
 36namespace archive {
 37namespace iterators {
 38
 39/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 40// class used by text archives to translate char strings to wchar_t
 41// strings of the currently selected locale
 42template<
 43    class Base, 
 44    int BitsOut, 
 45    int BitsIn, 
 46    class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type // output character
 47>
 48class transform_width : 
 49    public boost::iterator_adaptor<
 50        transform_width<Base, BitsOut, BitsIn, CharType>,
 51        Base,
 52        CharType,
 53        single_pass_traversal_tag,
 54        CharType
 55    >
 56{
 57    friend class boost::iterator_core_access;
 58    typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor<
 59        transform_width<Base, BitsOut, BitsIn, CharType>,
 60        Base,
 61        CharType,
 62        single_pass_traversal_tag,
 63        CharType
 64    > super_t;
 65
 66    typedef transform_width<Base, BitsOut, BitsIn, CharType> this_t;
 67    typedef BOOST_DEDUCED_TYPENAME iterator_value<Base>::type base_value_type;
 68
 69    CharType fill();
 70
 71    CharType dereference_impl(){
 72        if(! m_full){
 73            m_current_value = fill();
 74            m_full = true;
 75        }
 76        return m_current_value;
 77    }
 78
 79    CharType dereference() const {
 80        return const_cast<this_t *>(this)->dereference_impl();
 81    }
 82
 83    // test for iterator equality
 84    bool equal(const this_t & rhs) const {
 85        return
 86            this->base_reference() == rhs.base_reference();
 87        ;
 88    }
 89
 90    void increment(){
 91        m_displacement += BitsOut;
 92
 93        while(m_displacement >= BitsIn){
 94            m_displacement -= BitsIn;
 95            if(0 == m_displacement)
 96                m_bufferfull = false;
 97            if(! m_bufferfull){
 98                // note: suspect that this is not invoked for borland
 99                ++(this->base_reference());
100            }
101        }
102        m_full = false;
103    }
104
105    CharType m_current_value;
106    // number of bits left in current input character buffer
107    unsigned int m_displacement;
108    base_value_type m_buffer;
109    // flag to current output character is ready - just used to save time
110    bool m_full;
111    // flag to indicate that m_buffer has data
112    bool m_bufferfull;
113
114public:
115    // make composible buy using templated constructor
116    template<class T>
117    transform_width(BOOST_PFTO_WRAPPER(T) start) : 
118        super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
119        m_displacement(0),
120        m_full(false),
121        m_bufferfull(false)
122    {}
123    // intel 7.1 doesn't like default copy constructor
124    transform_width(const transform_width & rhs) : 
125        super_t(rhs.base_reference()),
126        m_current_value(rhs.m_current_value),
127        m_displacement(rhs.m_displacement),
128        m_buffer(rhs.m_buffer),
129        m_full(rhs.m_full),
130        m_bufferfull(rhs.m_bufferfull)
131    {}
132};
133
134template<class Base, int BitsOut, int BitsIn, class CharType>
135CharType transform_width<Base, BitsOut, BitsIn, CharType>::fill(){
136    CharType retval = 0;
137    unsigned int missing_bits = BitsOut;
138    for(;;){
139        unsigned int bcount;
140        if(! m_bufferfull){
141            m_buffer = * this->base_reference();
142            m_bufferfull = true;
143            bcount = BitsIn;
144        }
145        else
146            bcount = BitsIn - m_displacement;
147        unsigned int i = (std::min)(bcount, missing_bits);
148        // shift interesting bits to least significant position
149        unsigned int j = m_buffer >> (bcount - i);
150        // strip off uninteresting bits
151        // (note presumption of two's complement arithmetic)
152        j &= ~(-(1 << i));
153        // append then interesting bits to the output value
154        retval <<= i;
155        retval |= j;
156        missing_bits -= i;
157        if(0 == missing_bits)
158            break;
159        // note: suspect that this is not invoked for borland 5.51
160        ++(this->base_reference());
161        m_bufferfull = false;
162    }
163    return retval;
164}
165
166} // namespace iterators
167} // namespace archive
168} // namespace boost
169
170#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP