source: NonGTP/Boost/boost/iostreams/read.hpp @ 857

Revision 857, 7.6 KB checked in by igarcia, 18 years ago (diff)
Line 
1// (C) Copyright Jonathan Turkanis 2005.
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5// See http://www.boost.org/libs/iostreams for documentation.
6
7#ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED
8#define BOOST_IOSTREAMS_READ_HPP_INCLUDED
9
10#if defined(_MSC_VER) && (_MSC_VER >= 1020)
11# pragma once
12#endif
13
14#include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
15#include <boost/detail/workaround.hpp>
16#include <boost/iostreams/char_traits.hpp>
17#include <boost/iostreams/detail/char_traits.hpp>
18#include <boost/iostreams/detail/dispatch.hpp>
19#include <boost/iostreams/detail/ios.hpp>  // streamsize.
20#include <boost/iostreams/detail/streambuf.hpp>
21#include <boost/iostreams/detail/wrap_unwrap.hpp>
22#include <boost/iostreams/operations_fwd.hpp>
23#include <boost/mpl/if.hpp>
24
25// Must come last.
26#include <boost/iostreams/detail/config/disable_warnings.hpp>
27
28#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------//
29# include <boost/iostreams/detail/vc6/read.hpp>
30#else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------//
31
32namespace boost { namespace iostreams {
33
34namespace detail {
35
36template<typename T>
37struct read_device_impl;
38
39template<typename T>
40struct read_filter_impl;
41
42} // End namespace detail.
43
44template<typename T>
45typename int_type_of<T>::type get(T& t)
46{ return detail::read_device_impl<T>::get(detail::unwrap(t)); }
47
48template<typename T>
49inline std::streamsize
50read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
51{ return detail::read_device_impl<T>::read(detail::unwrap(t), s, n); }
52
53template<typename T, typename Source>
54std::streamsize
55read(T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
56{ return detail::read_filter_impl<T>::read(detail::unwrap(t), src, s, n); }
57
58template<typename T>
59bool putback(T& t, typename char_type_of<T>::type c)
60{ return detail::read_device_impl<T>::putback(detail::unwrap(t), c); }
61
62//----------------------------------------------------------------------------//
63
64namespace detail {
65
66// Helper function for adding -1 as EOF indicator.
67inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; }
68
69// Helper templates for reading from streambufs.
70template<bool IsLinked>
71struct true_eof_impl;
72
73template<>
74struct true_eof_impl<true> {
75    template<typename T>
76    static bool true_eof(T& t) { return t.true_eof(); }
77};
78
79template<>
80struct true_eof_impl<false> {
81    template<typename T>
82    static bool true_eof(T& t) { return true; }
83};
84
85template<typename T>
86inline bool true_eof(T& t)
87{
88    const bool linked = is_linked<T>::value;
89    return true_eof_impl<linked>::true_eof(t);
90}
91
92//------------------Definition of read_device_impl----------------------------//
93
94template<typename T>
95struct read_device_impl
96    : mpl::if_<
97          detail::is_custom<T>,
98          operations<T>,
99          read_device_impl<
100              BOOST_DEDUCED_TYPENAME
101              detail::dispatch<
102                  T, istream_tag, streambuf_tag, input
103              >::type
104          >
105      >::type
106    { };
107
108template<>
109struct read_device_impl<istream_tag> {
110    template<typename T>
111    static typename int_type_of<T>::type get(T& t)
112    { return t.get(); }
113
114    template<typename T>
115    static std::streamsize
116    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
117    { return check_eof(t.rdbuf()->sgetn(s, n)); }
118
119    template<typename T>
120    static bool putback(T& t, typename char_type_of<T>::type c)
121    {
122        typedef typename char_type_of<T>::type          char_type;
123        typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
124        return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c),
125                                          traits_type::eof() );
126    }
127};
128
129template<>
130struct read_device_impl<streambuf_tag> {
131    template<typename T>
132    static typename int_type_of<T>::type
133    get(T& t)
134    {   // gcc 2.95 needs namespace qualification for char_traits.
135        typedef typename char_type_of<T>::type     char_type;
136        typedef iostreams::char_traits<char_type>  traits_type;
137        typename int_type_of<T>::type c;
138        return !traits_type::is_eof(c = t.sbumpc()) ||
139                detail::true_eof(t)
140                    ?
141                c : traits_type::would_block();
142    }
143
144    template<typename T>
145    static std::streamsize
146    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
147    {
148        std::streamsize amt;
149        return (amt = t.sgetn(s, n)) != 0 ?
150            amt :
151            detail::true_eof(t) ?
152                -1 :
153                0;
154    }
155
156    template<typename T>
157    static bool putback(T& t, typename char_type_of<T>::type c)
158    {   // gcc 2.95 needs namespace qualification for char_traits.
159        typedef typename char_type_of<T>::type     char_type;
160        typedef iostreams::char_traits<char_type>  traits_type;
161        return !traits_type::is_eof(t.sputbackc(c));
162    }
163};
164
165template<>
166struct read_device_impl<input> {
167    template<typename T>
168    static typename int_type_of<T>::type
169    get(T& t)
170    {   // gcc 2.95 needs namespace qualification for char_traits.
171        typedef typename char_type_of<T>::type     char_type;
172        typedef iostreams::char_traits<char_type>  traits_type;
173        char_type c;
174        std::streamsize amt;
175        return (amt = t.read(&c, 1)) == 1 ?
176            traits_type::to_int_type(c) :
177            amt == -1 ?
178                traits_type::eof() :
179                traits_type::would_block();
180    }
181
182    template<typename T>
183    static std::streamsize
184    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
185    { return t.read(s, n); }
186
187    template<typename T>
188    static bool putback(T& t, typename char_type_of<T>::type c)
189    {   // T must be Peekable.
190        return t.putback(c);
191    }
192};
193
194//------------------Definition of read_filter_impl----------------------------//
195
196template<typename T>
197struct read_filter_impl
198    : mpl::if_<
199          detail::is_custom<T>,
200          operations<T>,
201          read_filter_impl<
202              BOOST_DEDUCED_TYPENAME
203              detail::dispatch<
204                  T, multichar_tag, any_tag
205              >::type
206          >
207      >::type
208    { };
209
210template<>
211struct read_filter_impl<multichar_tag> {
212    template<typename T, typename Source>
213    static std::streamsize read
214       (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
215    { return t.read(src, s, n); }
216};
217
218template<>
219struct read_filter_impl<any_tag> {
220    template<typename T, typename Source>
221    static std::streamsize read
222       (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
223    {   // gcc 2.95 needs namespace qualification for char_traits.
224        typedef typename char_type_of<T>::type     char_type;
225        typedef iostreams::char_traits<char_type>  traits_type;
226        for (std::streamsize off = 0; off < n; ++off) {
227            typename traits_type::int_type c = t.get(src);
228            if (traits_type::is_eof(c))
229                return check_eof(off);
230            if (traits_type::would_block(c))
231                return off;
232            s[off] = traits_type::to_char_type(c);
233        }
234        return n;
235    }
236};
237
238} // End namespace detail.
239
240} } // End namespaces iostreams, boost.
241
242#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------//
243
244#include <boost/iostreams/detail/config/enable_warnings.hpp>
245
246#endif // #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.