source: NonGTP/Boost/boost/archive/iterators/transform_width.hpp @ 857

Revision 857, 5.4 KB checked in by igarcia, 18 years ago (diff)
Line 
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 <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
28#include <boost/pfto.hpp>
29
30#include <boost/iterator/iterator_adaptor.hpp>
31#include <boost/iterator/iterator_traits.hpp>
32
33namespace boost {
34namespace archive {
35namespace iterators {
36
37/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
38// class used by text archives to translate char strings to wchar_t
39// strings of the currently selected locale
40template<
41    class Base,
42    int BitsOut,
43    int BitsIn,
44    class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type // output character
45>
46class transform_width :
47    public boost::iterator_adaptor<
48        transform_width<Base, BitsOut, BitsIn, CharType>,
49        Base,
50        CharType,
51        single_pass_traversal_tag,
52        CharType
53    >
54{
55    friend class boost::iterator_core_access;
56    typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor<
57        transform_width<Base, BitsOut, BitsIn, CharType>,
58        Base,
59        CharType,
60        single_pass_traversal_tag,
61        CharType
62    > super_t;
63
64    typedef transform_width<Base, BitsOut, BitsIn, CharType> this_t;
65    typedef BOOST_DEDUCED_TYPENAME iterator_value<Base>::type base_value_type;
66
67    CharType fill();
68
69    CharType dereference_impl(){
70        if(! m_full){
71            m_current_value = fill();
72            m_full = true;
73        }
74        return m_current_value;
75    }
76
77    CharType dereference() const {
78        return const_cast<this_t *>(this)->dereference_impl();
79    }
80
81    // test for iterator equality
82    bool equal(const this_t & rhs) const {
83        return
84            this->base_reference() == rhs.base_reference();
85        ;
86    }
87
88    void increment(){
89        m_displacement += BitsOut;
90
91        while(m_displacement >= BitsIn){
92            m_displacement -= BitsIn;
93            if(0 == m_displacement)
94                m_bufferfull = false;
95            if(! m_bufferfull){
96                // note: suspect that this is not invoked for borland
97                ++(this->base_reference());
98            }
99        }
100        m_full = false;
101    }
102
103    CharType m_current_value;
104    // number of bits left in current input character buffer
105    unsigned int m_displacement;
106    base_value_type m_buffer;
107    // flag to current output character is ready - just used to save time
108    bool m_full;
109    // flag to indicate that m_buffer has data
110    bool m_bufferfull;
111
112public:
113    // make composible buy using templated constructor
114    template<class T>
115    transform_width(BOOST_PFTO_WRAPPER(T) start) :
116        super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast<T>(start)))),
117        m_displacement(0),
118        m_full(false),
119        m_bufferfull(false)
120    {}
121    // intel 7.1 doesn't like default copy constructor
122    transform_width(const transform_width & rhs) :
123        super_t(rhs.base_reference()),
124        m_current_value(rhs.m_current_value),
125        m_displacement(rhs.m_displacement),
126        m_buffer(rhs.m_buffer),
127        m_full(rhs.m_full),
128        m_bufferfull(rhs.m_bufferfull)
129    {}
130};
131
132template<class Base, int BitsOut, int BitsIn, class CharType>
133CharType transform_width<Base, BitsOut, BitsIn, CharType>::fill(){
134    CharType retval = 0;
135    unsigned int missing_bits = BitsOut;
136    for(;;){
137        unsigned int bcount;
138        if(! m_bufferfull){
139            m_buffer = * this->base_reference();
140            m_bufferfull = true;
141            bcount = BitsIn;
142        }
143        else
144            bcount = BitsIn - m_displacement;
145        unsigned int i = (std::min)(bcount, missing_bits);
146        // shift interesting bits to least significant position
147        unsigned int j = m_buffer >> (bcount - i);
148        // strip off uninteresting bits
149        // (note presumption of two's complement arithmetic)
150        j &= ~(-(1 << i));
151        // append then interesting bits to the output value
152        retval <<= i;
153        retval |= j;
154        missing_bits -= i;
155        if(0 == missing_bits)
156            break;
157        // note: suspect that this is not invoked for borland 5.51
158        ++(this->base_reference());
159        m_bufferfull = false;
160    }
161    return retval;
162}
163
164} // namespace iterators
165} // namespace archive
166} // namespace boost
167
168#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
Note: See TracBrowser for help on using the repository browser.