File indexing completed on 2025-01-30 09:44:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_IOSTREAMS_SKIP_HPP_INCLUDED
0011 #define BOOST_IOSTREAMS_SKIP_HPP_INCLUDED
0012
0013 #if defined(_MSC_VER)
0014 # pragma once
0015 #endif
0016
0017 #include <boost/iostreams/char_traits.hpp>
0018 #include <boost/iostreams/detail/ios.hpp> // failure.
0019 #include <boost/iostreams/operations.hpp>
0020 #include <boost/iostreams/seek.hpp>
0021 #include <boost/iostreams/traits.hpp>
0022 #include <boost/mpl/and.hpp>
0023 #include <boost/mpl/bool.hpp>
0024 #include <boost/mpl/or.hpp>
0025 #include <boost/throw_exception.hpp>
0026 #include <boost/type_traits/is_convertible.hpp>
0027
0028 namespace boost { namespace iostreams {
0029
0030 namespace detail {
0031
0032 template<typename Device>
0033 void skip(Device& dev, stream_offset off, mpl::true_)
0034 { iostreams::seek(dev, off, BOOST_IOS::cur); }
0035
0036 template<typename Device>
0037 void skip(Device& dev, stream_offset off, mpl::false_)
0038 {
0039 typedef typename char_type_of<Device>::type char_type;
0040 typedef iostreams::char_traits<char_type> traits_type;
0041 for (stream_offset z = 0; z < off; ) {
0042 typename traits_type::int_type c;
0043 if (traits_type::is_eof(c = iostreams::get(dev)))
0044 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad skip offset"));
0045 if (!traits_type::would_block(c))
0046 ++z;
0047 }
0048 }
0049
0050 template<typename Filter, typename Device>
0051 void skip( Filter& flt, Device& dev, stream_offset off,
0052 BOOST_IOS::openmode which, mpl::true_ )
0053 { boost::iostreams::seek(flt, dev, off, BOOST_IOS::cur, which); }
0054
0055 template<typename Filter, typename Device>
0056 void skip( Filter& flt, Device& dev, stream_offset off,
0057 BOOST_IOS::openmode, mpl::false_ )
0058 {
0059 typedef typename char_type_of<Device>::type char_type;
0060 char_type c;
0061 for (stream_offset z = 0; z < off; ) {
0062 std::streamsize amt;
0063 if ((amt = iostreams::read(flt, dev, &c, 1)) == -1)
0064 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad skip offset"));
0065 if (amt == 1)
0066 ++z;
0067 }
0068 }
0069
0070 }
0071
0072 template<typename Device>
0073 void skip(Device& dev, stream_offset off)
0074 {
0075 typedef typename mode_of<Device>::type mode;
0076 typedef mpl::or_<
0077 is_convertible<mode, input_seekable>,
0078 is_convertible<mode, output_seekable>
0079 > can_seek;
0080 BOOST_STATIC_ASSERT(
0081 (can_seek::value || is_convertible<mode, input>::value)
0082 );
0083 detail::skip(dev, off, can_seek());
0084 }
0085
0086 template<typename Filter, typename Device>
0087 void skip( Filter& flt, Device& dev, stream_offset off,
0088 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
0089 {
0090 typedef typename mode_of<Filter>::type filter_mode;
0091 typedef typename mode_of<Device>::type device_mode;
0092 typedef mpl::or_<
0093 mpl::and_<
0094 is_convertible<filter_mode, input_seekable>,
0095 is_convertible<device_mode, input_seekable>
0096 >,
0097 mpl::and_<
0098 is_convertible<filter_mode, output_seekable>,
0099 is_convertible<device_mode, output_seekable>
0100 >
0101 > can_seek;
0102 BOOST_STATIC_ASSERT(
0103 ( can_seek::value ||
0104 (is_convertible<filter_mode, input>::value &&
0105 is_convertible<device_mode, input>::value) )
0106 );
0107 detail::skip(flt, dev, off, which, can_seek());
0108 }
0109
0110 } }
0111
0112 #endif