File indexing completed on 2025-01-30 09:44:33
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_READ_HPP_INCLUDED
0010
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif
0014
0015 #include <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/iostreams/char_traits.hpp>
0018 #include <boost/iostreams/detail/char_traits.hpp>
0019 #include <boost/iostreams/detail/dispatch.hpp>
0020 #include <boost/iostreams/detail/ios.hpp> // streamsize.
0021 #include <boost/iostreams/detail/streambuf.hpp>
0022 #include <boost/iostreams/detail/wrap_unwrap.hpp>
0023 #include <boost/iostreams/operations_fwd.hpp>
0024 #include <boost/mpl/if.hpp>
0025
0026
0027 #include <boost/iostreams/detail/config/disable_warnings.hpp>
0028
0029 namespace boost { namespace iostreams {
0030
0031 namespace detail {
0032
0033 template<typename T>
0034 struct read_device_impl;
0035
0036 template<typename T>
0037 struct read_filter_impl;
0038
0039 }
0040
0041 template<typename T>
0042 typename int_type_of<T>::type get(T& t)
0043 { return detail::read_device_impl<T>::get(detail::unwrap(t)); }
0044
0045 template<typename T>
0046 inline std::streamsize
0047 read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
0048 { return detail::read_device_impl<T>::read(detail::unwrap(t), s, n); }
0049
0050 template<typename T, typename Source>
0051 std::streamsize
0052 read(T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
0053 { return detail::read_filter_impl<T>::read(detail::unwrap(t), src, s, n); }
0054
0055 template<typename T>
0056 bool putback(T& t, typename char_type_of<T>::type c)
0057 { return detail::read_device_impl<T>::putback(detail::unwrap(t), c); }
0058
0059
0060
0061 namespace detail {
0062
0063
0064 inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; }
0065
0066
0067 template<bool IsLinked>
0068 struct true_eof_impl;
0069
0070 template<>
0071 struct true_eof_impl<true> {
0072 template<typename T>
0073 static bool true_eof(T& t) { return t.true_eof(); }
0074 };
0075
0076 template<>
0077 struct true_eof_impl<false> {
0078 template<typename T>
0079 static bool true_eof(T&) { return true; }
0080 };
0081
0082 template<typename T>
0083 inline bool true_eof(T& t)
0084 {
0085 const bool linked = is_linked<T>::value;
0086 return true_eof_impl<linked>::true_eof(t);
0087 }
0088
0089
0090
0091 template<typename T>
0092 struct read_device_impl
0093 : mpl::if_<
0094 detail::is_custom<T>,
0095 operations<T>,
0096 read_device_impl<
0097 BOOST_DEDUCED_TYPENAME
0098 detail::dispatch<
0099 T, istream_tag, streambuf_tag, input
0100 >::type
0101 >
0102 >::type
0103 { };
0104
0105 template<>
0106 struct read_device_impl<istream_tag> {
0107 template<typename T>
0108 static typename int_type_of<T>::type get(T& t)
0109 { return t.get(); }
0110
0111 template<typename T>
0112 static std::streamsize
0113 read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
0114 { return check_eof(t.rdbuf()->sgetn(s, n)); }
0115
0116 template<typename T>
0117 static bool putback(T& t, typename char_type_of<T>::type c)
0118 {
0119 typedef typename char_type_of<T>::type char_type;
0120 typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type;
0121 return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c),
0122 traits_type::eof() );
0123 }
0124 };
0125
0126 template<>
0127 struct read_device_impl<streambuf_tag> {
0128 template<typename T>
0129 static typename int_type_of<T>::type
0130 get(T& t)
0131 {
0132 typedef typename char_type_of<T>::type char_type;
0133 typedef iostreams::char_traits<char_type> traits_type;
0134 typename int_type_of<T>::type c;
0135 return !traits_type::is_eof(c = t.sbumpc()) ||
0136 detail::true_eof(t)
0137 ?
0138 c : traits_type::would_block();
0139 }
0140
0141 template<typename T>
0142 static std::streamsize
0143 read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
0144 {
0145 std::streamsize amt;
0146 return (amt = t.sgetn(s, n)) != 0 ?
0147 amt :
0148 detail::true_eof(t) ?
0149 -1 :
0150 0;
0151 }
0152
0153 template<typename T>
0154 static bool putback(T& t, typename char_type_of<T>::type c)
0155 {
0156 typedef typename char_type_of<T>::type char_type;
0157 typedef iostreams::char_traits<char_type> traits_type;
0158 return !traits_type::is_eof(t.sputbackc(c));
0159 }
0160 };
0161
0162 template<>
0163 struct read_device_impl<input> {
0164 template<typename T>
0165 static typename int_type_of<T>::type
0166 get(T& t)
0167 {
0168 typedef typename char_type_of<T>::type char_type;
0169 typedef iostreams::char_traits<char_type> traits_type;
0170 char_type c;
0171 std::streamsize amt;
0172 return (amt = t.read(&c, 1)) == 1 ?
0173 traits_type::to_int_type(c) :
0174 amt == -1 ?
0175 traits_type::eof() :
0176 traits_type::would_block();
0177 }
0178
0179 template<typename T>
0180 static std::streamsize
0181 read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
0182 { return t.read(s, n); }
0183
0184 template<typename T>
0185 static bool putback(T& t, typename char_type_of<T>::type c)
0186 {
0187 return t.putback(c);
0188 }
0189 };
0190
0191
0192
0193 template<typename T>
0194 struct read_filter_impl
0195 : mpl::if_<
0196 detail::is_custom<T>,
0197 operations<T>,
0198 read_filter_impl<
0199 BOOST_DEDUCED_TYPENAME
0200 detail::dispatch<
0201 T, multichar_tag, any_tag
0202 >::type
0203 >
0204 >::type
0205 { };
0206
0207 template<>
0208 struct read_filter_impl<multichar_tag> {
0209 template<typename T, typename Source>
0210 static std::streamsize read
0211 (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
0212 { return t.read(src, s, n); }
0213 };
0214
0215 template<>
0216 struct read_filter_impl<any_tag> {
0217 template<typename T, typename Source>
0218 static std::streamsize read
0219 (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
0220 {
0221 typedef typename char_type_of<T>::type char_type;
0222 typedef iostreams::char_traits<char_type> traits_type;
0223 for (std::streamsize off = 0; off < n; ++off) {
0224 typename traits_type::int_type c = t.get(src);
0225 if (traits_type::is_eof(c))
0226 return check_eof(off);
0227 if (traits_type::would_block(c))
0228 return off;
0229 s[off] = traits_type::to_char_type(c);
0230 }
0231 return n;
0232 }
0233 };
0234
0235 }
0236
0237 } }
0238
0239 #include <boost/iostreams/detail/config/enable_warnings.hpp>
0240
0241 #endif