#ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP #define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // wchar_from_mb.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. #include #include #include // size_t #ifndef BOOST_NO_CWCHAR #include // mbstate_t #endif #include // copy #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::mbstate_t; } // namespace std #endif #include #include #include #include #include #include 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 wchar_from_mb : public boost::iterator_adaptor< wchar_from_mb, Base, wchar_t, single_pass_traversal_tag, wchar_t > { friend class boost::iterator_core_access; typedef typename boost::iterator_adaptor< wchar_from_mb, Base, wchar_t, single_pass_traversal_tag, wchar_t > super_t; typedef wchar_from_mb this_t; void drain(); wchar_t dereference() const { if(m_output.m_next == m_output.m_next_available) return static_cast(0); return * m_output.m_next; } void increment(){ if(m_output.m_next == m_output.m_next_available) return; if(++m_output.m_next == m_output.m_next_available){ if(m_input.m_done) return; drain(); } } bool equal(this_t const & rhs) const { return dereference() == rhs.dereference(); } boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; std::mbstate_t m_mbs; template struct sliding_buffer { boost::array m_buffer; typename boost::array::const_iterator m_next_available; typename boost::array::iterator m_next; bool m_done; // default ctor sliding_buffer() : m_next_available(m_buffer.begin()), m_next(m_buffer.begin()), m_done(false) {} // copy ctor sliding_buffer(const sliding_buffer & rhs) : m_next_available( std::copy( rhs.m_buffer.begin(), rhs.m_next_available, m_buffer.begin() ) ), m_next( m_buffer.begin() + (rhs.m_next - rhs.m_buffer.begin()) ), m_done(rhs.m_done) {} }; sliding_buffer::type> m_input; sliding_buffer::type> m_output; public: // make composible buy using templated constructor template wchar_from_mb(T start) : super_t(Base(static_cast< T >(start))), m_mbs(std::mbstate_t()) { BOOST_ASSERT(std::mbsinit(&m_mbs)); drain(); } // default constructor used as an end iterator wchar_from_mb(){} // copy ctor wchar_from_mb(const wchar_from_mb & rhs) : super_t(rhs.base_reference()), m_mbs(rhs.m_mbs), m_input(rhs.m_input), m_output(rhs.m_output) {} }; template void wchar_from_mb::drain(){ BOOST_ASSERT(! m_input.m_done); for(;;){ typename boost::iterators::iterator_reference::type c = *(this->base_reference()); // a null character in a multibyte stream is takes as end of string if(0 == c){ m_input.m_done = true; break; } ++(this->base_reference()); * const_cast::type *>( (m_input.m_next_available++) ) = c; // if input buffer is full - we're done for now if(m_input.m_buffer.end() == m_input.m_next_available) break; } const typename boost::iterators::iterator_value::type * input_new_start; typename iterator_value::type * next_available; std::codecvt_base::result r = m_codecvt_facet.in( m_mbs, m_input.m_buffer.begin(), m_input.m_next_available, input_new_start, m_output.m_buffer.begin(), m_output.m_buffer.end(), next_available ); BOOST_ASSERT(std::codecvt_base::ok == r); m_output.m_next_available = next_available; m_output.m_next = m_output.m_buffer.begin(); // we're done with some of the input so shift left. m_input.m_next_available = std::copy( input_new_start, m_input.m_next_available, m_input.m_buffer.begin() ); m_input.m_next = m_input.m_buffer.begin(); } } // namespace iterators } // namespace archive } // namespace boost #endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP