Chris@16
|
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
|
Chris@16
|
2 // (C) Copyright 2003-2007 Jonathan Turkanis
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
Chris@16
|
5
|
Chris@16
|
6 // See http://www.boost.org/libs/iostreams for documentation.
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
|
Chris@16
|
9 #define BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
|
Chris@16
|
10
|
Chris@16
|
11 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
Chris@16
|
12 # pragma once
|
Chris@16
|
13 #endif
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
|
Chris@16
|
16 #include <boost/integer_traits.hpp>
|
Chris@16
|
17 #include <boost/iostreams/categories.hpp>
|
Chris@16
|
18 #include <boost/iostreams/detail/dispatch.hpp>
|
Chris@16
|
19 #include <boost/iostreams/detail/ios.hpp> // streamsize, seekdir, openmode.
|
Chris@16
|
20 #include <boost/iostreams/detail/streambuf.hpp>
|
Chris@16
|
21 #include <boost/iostreams/detail/wrap_unwrap.hpp>
|
Chris@16
|
22 #include <boost/iostreams/operations_fwd.hpp>
|
Chris@16
|
23 #include <boost/iostreams/positioning.hpp>
|
Chris@16
|
24 #include <boost/mpl/if.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 // Must come last.
|
Chris@16
|
27 #include <boost/iostreams/detail/config/disable_warnings.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 namespace boost { namespace iostreams {
|
Chris@16
|
30
|
Chris@16
|
31 namespace detail {
|
Chris@16
|
32
|
Chris@16
|
33 template<typename T>
|
Chris@16
|
34 struct seek_device_impl;
|
Chris@16
|
35
|
Chris@16
|
36 template<typename T>
|
Chris@16
|
37 struct seek_filter_impl;
|
Chris@16
|
38
|
Chris@16
|
39 } // End namespace detail.
|
Chris@16
|
40
|
Chris@16
|
41 template<typename T>
|
Chris@16
|
42 inline std::streampos
|
Chris@16
|
43 seek( T& t, stream_offset off, BOOST_IOS::seekdir way,
|
Chris@16
|
44 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
|
Chris@16
|
45 {
|
Chris@16
|
46 using namespace detail;
|
Chris@16
|
47 return seek_device_impl<T>::seek(detail::unwrap(t), off, way, which);
|
Chris@16
|
48 }
|
Chris@16
|
49
|
Chris@16
|
50 template<typename T, typename Device>
|
Chris@16
|
51 inline std::streampos
|
Chris@16
|
52 seek( T& t, Device& dev, stream_offset off, BOOST_IOS::seekdir way,
|
Chris@16
|
53 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
|
Chris@16
|
54 {
|
Chris@16
|
55 using namespace detail;
|
Chris@16
|
56 return seek_filter_impl<T>::seek(detail::unwrap(t), dev, off, way, which);
|
Chris@16
|
57 }
|
Chris@16
|
58
|
Chris@16
|
59 namespace detail {
|
Chris@16
|
60
|
Chris@16
|
61 //------------------Definition of seek_device_impl----------------------------//
|
Chris@16
|
62
|
Chris@16
|
63 template<typename T>
|
Chris@16
|
64 struct seek_device_impl
|
Chris@16
|
65 : mpl::if_<
|
Chris@16
|
66 is_custom<T>,
|
Chris@16
|
67 operations<T>,
|
Chris@16
|
68 seek_device_impl<
|
Chris@16
|
69 BOOST_DEDUCED_TYPENAME
|
Chris@16
|
70 dispatch<
|
Chris@16
|
71 T, iostream_tag, istream_tag, ostream_tag,
|
Chris@16
|
72 streambuf_tag, two_head, any_tag
|
Chris@16
|
73 >::type
|
Chris@16
|
74 >
|
Chris@16
|
75 >::type
|
Chris@16
|
76 { };
|
Chris@16
|
77
|
Chris@16
|
78 struct seek_impl_basic_ios {
|
Chris@16
|
79 template<typename T>
|
Chris@16
|
80 static std::streampos seek( T& t, stream_offset off,
|
Chris@16
|
81 BOOST_IOS::seekdir way,
|
Chris@16
|
82 BOOST_IOS::openmode which )
|
Chris@16
|
83 {
|
Chris@16
|
84 if ( way == BOOST_IOS::beg &&
|
Chris@16
|
85 ( off < integer_traits<std::streamoff>::const_min ||
|
Chris@16
|
86 off > integer_traits<std::streamoff>::const_max ) )
|
Chris@16
|
87 {
|
Chris@16
|
88 return t.rdbuf()->pubseekpos(offset_to_position(off));
|
Chris@16
|
89 } else {
|
Chris@16
|
90 return t.rdbuf()->pubseekoff(off, way, which);
|
Chris@16
|
91 }
|
Chris@16
|
92 }
|
Chris@16
|
93 };
|
Chris@16
|
94
|
Chris@16
|
95 template<>
|
Chris@16
|
96 struct seek_device_impl<iostream_tag> : seek_impl_basic_ios { };
|
Chris@16
|
97
|
Chris@16
|
98 template<>
|
Chris@16
|
99 struct seek_device_impl<istream_tag> : seek_impl_basic_ios { };
|
Chris@16
|
100
|
Chris@16
|
101 template<>
|
Chris@16
|
102 struct seek_device_impl<ostream_tag> : seek_impl_basic_ios { };
|
Chris@16
|
103
|
Chris@16
|
104 template<>
|
Chris@16
|
105 struct seek_device_impl<streambuf_tag> {
|
Chris@16
|
106 template<typename T>
|
Chris@16
|
107 static std::streampos seek( T& t, stream_offset off,
|
Chris@16
|
108 BOOST_IOS::seekdir way,
|
Chris@16
|
109 BOOST_IOS::openmode which )
|
Chris@16
|
110 {
|
Chris@16
|
111 if ( way == BOOST_IOS::beg &&
|
Chris@16
|
112 ( off < integer_traits<std::streamoff>::const_min ||
|
Chris@16
|
113 off > integer_traits<std::streamoff>::const_max ) )
|
Chris@16
|
114 {
|
Chris@16
|
115 return t.BOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off));
|
Chris@16
|
116 } else {
|
Chris@16
|
117 return t.BOOST_IOSTREAMS_PUBSEEKOFF(off, way, which);
|
Chris@16
|
118 }
|
Chris@16
|
119 }
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 template<>
|
Chris@16
|
123 struct seek_device_impl<two_head> {
|
Chris@16
|
124 template<typename T>
|
Chris@16
|
125 static std::streampos seek( T& t, stream_offset off,
|
Chris@16
|
126 BOOST_IOS::seekdir way,
|
Chris@16
|
127 BOOST_IOS::openmode which )
|
Chris@16
|
128 { return t.seek(off, way, which); }
|
Chris@16
|
129 };
|
Chris@16
|
130
|
Chris@16
|
131 template<>
|
Chris@16
|
132 struct seek_device_impl<any_tag> {
|
Chris@16
|
133 template<typename T>
|
Chris@16
|
134 static std::streampos seek( T& t, stream_offset off,
|
Chris@16
|
135 BOOST_IOS::seekdir way,
|
Chris@16
|
136 BOOST_IOS::openmode )
|
Chris@16
|
137 { return t.seek(off, way); }
|
Chris@16
|
138 };
|
Chris@16
|
139
|
Chris@16
|
140 //------------------Definition of seek_filter_impl----------------------------//
|
Chris@16
|
141
|
Chris@16
|
142 template<typename T>
|
Chris@16
|
143 struct seek_filter_impl
|
Chris@16
|
144 : mpl::if_<
|
Chris@16
|
145 is_custom<T>,
|
Chris@16
|
146 operations<T>,
|
Chris@16
|
147 seek_filter_impl<
|
Chris@16
|
148 BOOST_DEDUCED_TYPENAME
|
Chris@16
|
149 dispatch<T, two_head, any_tag>::type
|
Chris@16
|
150 >
|
Chris@16
|
151 >::type
|
Chris@16
|
152 { };
|
Chris@16
|
153
|
Chris@16
|
154 template<>
|
Chris@16
|
155 struct seek_filter_impl<two_head> {
|
Chris@16
|
156 template<typename T, typename Device>
|
Chris@16
|
157 static std::streampos seek( T& t, Device& d,
|
Chris@16
|
158 stream_offset off,
|
Chris@16
|
159 BOOST_IOS::seekdir way,
|
Chris@16
|
160 BOOST_IOS::openmode which )
|
Chris@16
|
161 { return t.seek(d, off, way, which); }
|
Chris@16
|
162 };
|
Chris@16
|
163
|
Chris@16
|
164 template<>
|
Chris@16
|
165 struct seek_filter_impl<any_tag> {
|
Chris@16
|
166 template<typename T, typename Device>
|
Chris@16
|
167 static std::streampos seek( T& t, Device& d,
|
Chris@16
|
168 stream_offset off,
|
Chris@16
|
169 BOOST_IOS::seekdir way,
|
Chris@16
|
170 BOOST_IOS::openmode )
|
Chris@16
|
171 { return t.seek(d, off, way); }
|
Chris@16
|
172 };
|
Chris@16
|
173
|
Chris@16
|
174 } // End namespace detail.
|
Chris@16
|
175
|
Chris@16
|
176 } } // End namespaces iostreams, boost.
|
Chris@16
|
177
|
Chris@16
|
178 #include <boost/iostreams/detail/config/enable_warnings.hpp>
|
Chris@16
|
179
|
Chris@16
|
180 #endif // #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
|