Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / archive / iterators / wchar_from_mb.hpp
1 #ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP
2 #define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP
3
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER)
6 # pragma once
7 #endif
8
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // wchar_from_mb.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 #include <boost/assert.hpp>
20 #include <cctype>
21 #include <cstddef> // size_t
22 #include <cstdlib> // mblen
23
24 #include <boost/config.hpp>
25 #if defined(BOOST_NO_STDC_NAMESPACE)
26 namespace std{ 
27     using ::mblen; 
28     using ::mbtowc; 
29 } // namespace std
30 #endif
31
32 #include <boost/serialization/throw_exception.hpp>
33 #include <boost/serialization/pfto.hpp>
34
35 #include <boost/iterator/iterator_adaptor.hpp>
36 #include <boost/archive/iterators/dataflow_exception.hpp>
37
38 namespace boost { 
39 namespace archive {
40 namespace iterators {
41
42 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
43 // class used by text archives to translate char strings to wchar_t
44 // strings of the currently selected locale
45 template<class Base>
46 class wchar_from_mb 
47     : public boost::iterator_adaptor<
48         wchar_from_mb<Base>, 
49         Base, 
50         wchar_t,
51         single_pass_traversal_tag,
52         wchar_t
53     >
54 {
55     friend class boost::iterator_core_access;
56     typedef typename boost::iterator_adaptor<
57         wchar_from_mb<Base>, 
58         Base, 
59         wchar_t,
60         single_pass_traversal_tag,
61         wchar_t
62     > super_t;
63
64     typedef wchar_from_mb<Base> this_t;
65
66     wchar_t drain();
67
68     wchar_t dereference_impl() {
69         if(! m_full){
70             m_current_value = drain();
71             m_full = true;
72         }
73         return m_current_value;
74     }
75
76     wchar_t dereference() const {
77         return const_cast<this_t *>(this)->dereference_impl();
78     }
79
80     void increment(){
81         dereference_impl();
82         m_full = false;
83         ++(this->base_reference());
84     };
85
86     wchar_t m_current_value;
87     bool m_full;
88
89 public:
90     // make composible buy using templated constructor
91     template<class T>
92     wchar_from_mb(BOOST_PFTO_WRAPPER(T) start) : 
93         super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
94         m_full(false)
95     {}
96     // intel 7.1 doesn't like default copy constructor
97     wchar_from_mb(const wchar_from_mb & rhs) : 
98         super_t(rhs.base_reference()),
99         m_full(rhs.m_full)
100     {}
101 };
102
103 template<class Base>
104 wchar_t wchar_from_mb<Base>::drain(){
105     char buffer[9];
106     char * bptr = buffer;
107     char val;
108     for(std::size_t i = 0; i++ < (unsigned)MB_CUR_MAX;){
109         val = * this->base_reference();
110         *bptr++ = val;
111         int result = std::mblen(buffer, i);
112         if(-1 != result)
113             break;
114         ++(this->base_reference());
115     }
116     wchar_t retval;
117     int result = std::mbtowc(& retval, buffer, MB_CUR_MAX);
118     if(0 >= result)
119         boost::serialization::throw_exception(iterators::dataflow_exception(
120             iterators::dataflow_exception::invalid_conversion
121         ));
122     return retval;
123 }
124
125 } // namespace iterators
126 } // namespace archive
127 } // namespace boost
128
129 #endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP