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

Revision 857, 7.0 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
7namespace boost { namespace iostreams {
8
9namespace detail {
10
11template<typename T>
12struct read_device_impl;
13
14template<typename T>
15struct read_filter_impl;
16
17} // End namespace detail.
18
19template<typename T>
20typename int_type_of<T>::type get(T& t)
21{
22    typedef typename detail::unwrapped_type<T>::type unwrapped;
23    return detail::read_device_impl<T>::inner<unwrapped>::get(detail::unwrap(t));
24}
25
26template<typename T>
27inline std::streamsize
28read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
29{
30    typedef typename detail::unwrapped_type<T>::type unwrapped;
31    return detail::read_device_impl<T>::inner<unwrapped>::read(detail::unwrap(t), s, n);
32}
33
34template<typename T, typename Source>
35std::streamsize
36read(T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
37{
38    typedef typename detail::unwrapped_type<T>::type unwrapped;
39    return detail::read_filter_impl<T>::inner<unwrapped>::read(detail::unwrap(t), src, s, n);
40}
41
42template<typename T>
43bool putback(T& t, typename char_type_of<T>::type c)
44{
45    typedef typename detail::unwrapped_type<T>::type unwrapped;
46    return detail::read_device_impl<T>::inner<unwrapped>::putback(detail::unwrap(t), c);
47}
48
49//----------------------------------------------------------------------------//
50
51namespace detail {
52
53// Helper function for adding -1 as EOF indicator.
54inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; }
55
56// Helper templates for reading from streambufs.
57template<bool IsLinked>
58struct true_eof_impl;
59
60template<>
61struct true_eof_impl<true> {
62    template<typename T>
63    static bool true_eof(T& t) { return t.true_eof(); }
64};
65
66template<>
67struct true_eof_impl<false> {
68    template<typename T>
69    static bool true_eof(T& t) { return true; }
70};
71
72template<typename T>
73inline bool true_eof(T& t)
74{
75    const bool linked = is_linked<T>::value;
76    return true_eof_impl<linked>::true_eof(t);
77}
78                   
79//------------------Definition of read_device_impl----------------------------//
80
81template<typename T>
82struct read_device_impl
83    : mpl::if_<
84          detail::is_custom<T>,
85          operations<T>,
86          read_device_impl<
87              BOOST_DEDUCED_TYPENAME
88              detail::dispatch<
89                  T, istream_tag, streambuf_tag, input
90              >::type
91          >
92      >::type
93    { };
94
95template<>
96struct read_device_impl<istream_tag> {
97    template<typename T>
98    struct inner {
99        static typename int_type_of<T>::type get(T& t)
100        { return t.get(); }
101
102        static std::streamsize
103        read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
104        { return check_eof(t.rdbuf()->sgetn(s, n)); }
105
106        static bool putback(T& t, typename char_type_of<T>::type c)
107        {
108            typedef typename char_type_of<T>::type          char_type;
109            typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
110            return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c),
111                                              traits_type::eof() );
112        }
113    };
114};
115
116template<>
117struct read_device_impl<streambuf_tag> {
118    template<typename T>
119    struct inner {
120        static typename int_type_of<T>::type
121        get(T& t)
122        {
123            typedef typename char_type_of<T>::type  char_type;
124            typedef char_traits<char_type>          traits_type;
125            typename int_type_of<T>::type c;
126            return !traits_type::is_eof(c = t.sbumpc()) ||
127                    detail::true_eof(t)
128                        ?
129                    c : traits_type::would_block();
130        }
131
132        static std::streamsize
133        read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
134        {
135            std::streamsize amt;
136            return (amt = t.sgetn(s, n)) != 0 ?
137                amt :
138                detail::true_eof(t) ?
139                    -1 :
140                    0;
141        }
142
143        static bool putback(T& t, typename char_type_of<T>::type c)
144        {
145            typedef typename char_type_of<T>::type  char_type;
146            typedef char_traits<char_type>          traits_type;
147            return !traits_type::is_eof(t.sputbackc(c));
148        }
149    };
150};
151
152template<>
153struct read_device_impl<input> {
154    template<typename T>
155    struct inner {
156        static typename int_type_of<T>::type
157        get(T& t)
158        {
159            typedef typename char_type_of<T>::type  char_type;
160            typedef char_traits<char_type>          traits_type;
161            char_type c;
162            std::streamsize amt;
163            return (amt = t.read(&c, 1)) == 1 ?
164                traits_type::to_int_type(c) :
165                amt == -1 ?
166                    traits_type::eof() :
167                    traits_type::would_block();
168        }
169
170        template<typename T>
171        static std::streamsize
172        read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
173        { return t.read(s, n); }
174
175        template<typename T>
176        static bool putback(T& t, typename char_type_of<T>::type c)
177        {   // T must be Peekable.
178            return t.putback(c);
179        }
180    };
181};
182
183//------------------Definition of read_filter_impl----------------------------//
184
185template<typename T>
186struct read_filter_impl
187    : mpl::if_<
188          detail::is_custom<T>,
189          operations<T>,
190          read_filter_impl<
191              BOOST_DEDUCED_TYPENAME
192              detail::dispatch<
193                  T, multichar_tag, any_tag
194              >::type
195          >
196      >::type
197    { };
198
199template<>
200struct read_filter_impl<multichar_tag> {
201    template<typename T>
202    struct inner {
203        template<typename Source>
204        static std::streamsize read
205            ( T& t, Source& src, typename char_type_of<T>::type* s,   
206              std::streamsize n )
207        { return t.read(src, s, n); }
208    };
209};
210
211template<>
212struct read_filter_impl<any_tag> {
213    template<typename T>
214    struct inner {
215        template<typename Source>
216        static std::streamsize read
217            ( T& t, Source& src, typename char_type_of<T>::type* s,
218              std::streamsize n )
219        {
220            typedef typename char_type_of<T>::type  char_type;
221            typedef char_traits<char_type>          traits_type;
222            for (std::streamsize off = 0; off < n; ++off) {
223                typename traits_type::int_type c = t.get(src);
224                if (traits_type::is_eof(c))
225                    return check_eof(off);
226                if (traits_type::would_block(c))
227                    return off;
228                s[off] = traits_type::to_char_type(c);
229            }
230            return n;
231        }
232    };
233};
234
235} // End namespace detail.
236
237} } // End namespaces iostreams, boost.
Note: See TracBrowser for help on using the repository browser.