Chris@16: // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) Chris@16: // (C) Copyright 2005-2007 Jonathan Turkanis Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) Chris@16: Chris@16: // See http://www.boost.org/libs/iostreams for documentation. Chris@16: Chris@16: #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED Chris@16: #define BOOST_IOSTREAMS_READ_HPP_INCLUDED Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1020) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include // DEDUCED_TYPENAME, MSVC. Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include // streamsize. Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Must come last. Chris@16: #include Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------// Chris@16: # include Chris@16: #else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------// Chris@16: Chris@16: namespace boost { namespace iostreams { Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: template Chris@16: struct read_device_impl; Chris@16: Chris@16: template Chris@16: struct read_filter_impl; Chris@16: Chris@16: } // End namespace detail. Chris@16: Chris@16: template Chris@16: typename int_type_of::type get(T& t) Chris@16: { return detail::read_device_impl::get(detail::unwrap(t)); } Chris@16: Chris@16: template Chris@16: inline std::streamsize Chris@16: read(T& t, typename char_type_of::type* s, std::streamsize n) Chris@16: { return detail::read_device_impl::read(detail::unwrap(t), s, n); } Chris@16: Chris@16: template Chris@16: std::streamsize Chris@16: read(T& t, Source& src, typename char_type_of::type* s, std::streamsize n) Chris@16: { return detail::read_filter_impl::read(detail::unwrap(t), src, s, n); } Chris@16: Chris@16: template Chris@16: bool putback(T& t, typename char_type_of::type c) Chris@16: { return detail::read_device_impl::putback(detail::unwrap(t), c); } Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: // Helper function for adding -1 as EOF indicator. Chris@16: inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; } Chris@16: Chris@16: // Helper templates for reading from streambufs. Chris@16: template Chris@16: struct true_eof_impl; Chris@16: Chris@16: template<> Chris@16: struct true_eof_impl { Chris@16: template Chris@16: static bool true_eof(T& t) { return t.true_eof(); } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct true_eof_impl { Chris@16: template Chris@16: static bool true_eof(T&) { return true; } Chris@16: }; Chris@16: Chris@16: template Chris@16: inline bool true_eof(T& t) Chris@16: { Chris@16: const bool linked = is_linked::value; Chris@16: return true_eof_impl::true_eof(t); Chris@16: } Chris@16: Chris@16: //------------------Definition of read_device_impl----------------------------// Chris@16: Chris@16: template Chris@16: struct read_device_impl Chris@16: : mpl::if_< Chris@16: detail::is_custom, Chris@16: operations, Chris@16: read_device_impl< Chris@16: BOOST_DEDUCED_TYPENAME Chris@16: detail::dispatch< Chris@16: T, istream_tag, streambuf_tag, input Chris@16: >::type Chris@16: > Chris@16: >::type Chris@16: { }; Chris@16: Chris@16: template<> Chris@16: struct read_device_impl { Chris@16: template Chris@16: static typename int_type_of::type get(T& t) Chris@16: { return t.get(); } Chris@16: Chris@16: template Chris@16: static std::streamsize Chris@16: read(T& t, typename char_type_of::type* s, std::streamsize n) Chris@16: { return check_eof(t.rdbuf()->sgetn(s, n)); } Chris@16: Chris@16: template Chris@16: static bool putback(T& t, typename char_type_of::type c) Chris@16: { Chris@16: typedef typename char_type_of::type char_type; Chris@16: typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; Chris@16: return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c), Chris@16: traits_type::eof() ); Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct read_device_impl { Chris@16: template Chris@16: static typename int_type_of::type Chris@16: get(T& t) Chris@16: { // gcc 2.95 needs namespace qualification for char_traits. Chris@16: typedef typename char_type_of::type char_type; Chris@16: typedef iostreams::char_traits traits_type; Chris@16: typename int_type_of::type c; Chris@16: return !traits_type::is_eof(c = t.sbumpc()) || Chris@16: detail::true_eof(t) Chris@16: ? Chris@16: c : traits_type::would_block(); Chris@16: } Chris@16: Chris@16: template Chris@16: static std::streamsize Chris@16: read(T& t, typename char_type_of::type* s, std::streamsize n) Chris@16: { Chris@16: std::streamsize amt; Chris@16: return (amt = t.sgetn(s, n)) != 0 ? Chris@16: amt : Chris@16: detail::true_eof(t) ? Chris@16: -1 : Chris@16: 0; Chris@16: } Chris@16: Chris@16: template Chris@16: static bool putback(T& t, typename char_type_of::type c) Chris@16: { // gcc 2.95 needs namespace qualification for char_traits. Chris@16: typedef typename char_type_of::type char_type; Chris@16: typedef iostreams::char_traits traits_type; Chris@16: return !traits_type::is_eof(t.sputbackc(c)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct read_device_impl { Chris@16: template Chris@16: static typename int_type_of::type Chris@16: get(T& t) Chris@16: { // gcc 2.95 needs namespace qualification for char_traits. Chris@16: typedef typename char_type_of::type char_type; Chris@16: typedef iostreams::char_traits traits_type; Chris@16: char_type c; Chris@16: std::streamsize amt; Chris@16: return (amt = t.read(&c, 1)) == 1 ? Chris@16: traits_type::to_int_type(c) : Chris@16: amt == -1 ? Chris@16: traits_type::eof() : Chris@16: traits_type::would_block(); Chris@16: } Chris@16: Chris@16: template Chris@16: static std::streamsize Chris@16: read(T& t, typename char_type_of::type* s, std::streamsize n) Chris@16: { return t.read(s, n); } Chris@16: Chris@16: template Chris@16: static bool putback(T& t, typename char_type_of::type c) Chris@16: { // T must be Peekable. Chris@16: return t.putback(c); Chris@16: } Chris@16: }; Chris@16: Chris@16: //------------------Definition of read_filter_impl----------------------------// Chris@16: Chris@16: template Chris@16: struct read_filter_impl Chris@16: : mpl::if_< Chris@16: detail::is_custom, Chris@16: operations, Chris@16: read_filter_impl< Chris@16: BOOST_DEDUCED_TYPENAME Chris@16: detail::dispatch< Chris@16: T, multichar_tag, any_tag Chris@16: >::type Chris@16: > Chris@16: >::type Chris@16: { }; Chris@16: Chris@16: template<> Chris@16: struct read_filter_impl { Chris@16: template Chris@16: static std::streamsize read Chris@16: (T& t, Source& src, typename char_type_of::type* s, std::streamsize n) Chris@16: { return t.read(src, s, n); } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct read_filter_impl { Chris@16: template Chris@16: static std::streamsize read Chris@16: (T& t, Source& src, typename char_type_of::type* s, std::streamsize n) Chris@16: { // gcc 2.95 needs namespace qualification for char_traits. Chris@16: typedef typename char_type_of::type char_type; Chris@16: typedef iostreams::char_traits traits_type; Chris@16: for (std::streamsize off = 0; off < n; ++off) { Chris@16: typename traits_type::int_type c = t.get(src); Chris@16: if (traits_type::is_eof(c)) Chris@16: return check_eof(off); Chris@16: if (traits_type::would_block(c)) Chris@16: return off; Chris@16: s[off] = traits_type::to_char_type(c); Chris@16: } Chris@16: return n; Chris@16: } Chris@16: }; Chris@16: Chris@16: } // End namespace detail. Chris@16: Chris@16: } } // End namespaces iostreams, boost. Chris@16: Chris@16: #endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------// Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED