Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:50

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.(See accompanying 
0003  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
0004  * 
0005  * See http://www.boost.org/libs/iostreams for documentation.
0006 
0007  * File:        boost/iostreams/detail/restrict_impl.hpp
0008  * Date:        Sun Jan 06 12:57:30 MST 2008
0009  * Copyright:   2007-2008 CodeRage, LLC
0010  * Author:      Jonathan Turkanis
0011  * Contact:     turkanis at coderage dot com
0012  *
0013  * If included with the macro BOOST_IOSTREAMS_RESTRICT undefined, defines the 
0014  * class template boost::iostreams::restriction. If included with the macro
0015  * BOOST_IOSTREAMS_RESTRICT defined as an identifier, defines the overloaded
0016  * function template boost::iostreams::BOOST_IOSTREAMS_RESTRICT, and object 
0017  * generator for boost::iostreams::restriction.
0018  *
0019  * This design allows <boost/iostreams/restrict.hpp> and 
0020  * <boost/iostreams/slice.hpp> to share an implementation.
0021  */
0022 
0023 #if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) && \
0024     !defined(BOOST_IOSTREAMS_RESTRICT)
0025 # define BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED
0026                     
0027 //------------------Implementation of restriction-----------------------------//
0028 
0029 # include <algorithm>          // min.
0030 # include <utility>            // pair.
0031 # include <boost/cstdint.hpp>  // intmax_t.
0032 # include <boost/config.hpp>   // DEDUCED_TYPENAME.
0033 # include <boost/iostreams/categories.hpp>
0034 # include <boost/iostreams/char_traits.hpp>
0035 # include <boost/iostreams/detail/adapter/device_adapter.hpp>
0036 # include <boost/iostreams/detail/adapter/filter_adapter.hpp>
0037 # include <boost/iostreams/detail/call_traits.hpp>
0038 # include <boost/iostreams/detail/enable_if_stream.hpp>
0039 # include <boost/iostreams/detail/error.hpp>
0040 # include <boost/iostreams/detail/ios.hpp>     // failure.
0041 # include <boost/iostreams/detail/select.hpp>
0042 # include <boost/iostreams/operations.hpp>
0043 # include <boost/iostreams/skip.hpp>
0044 # include <boost/iostreams/traits.hpp>         // mode_of, is_direct.
0045 # include <boost/mpl/bool.hpp>
0046 # include <boost/static_assert.hpp>
0047 # include <boost/throw_exception.hpp>
0048 # include <boost/type_traits/is_convertible.hpp>
0049 
0050 # include <boost/iostreams/detail/config/disable_warnings.hpp>
0051 
0052 namespace boost { namespace iostreams {
0053 
0054 namespace detail {
0055 
0056 //
0057 // Template name: restricted_indirect_device.
0058 // Description: Provides an restricted view of an indirect Device.
0059 // Template parameters:
0060 //      Device - An indirect model of Device that models either Source or
0061 //          SeekableDevice.
0062 //
0063 template<typename Device>
0064 class restricted_indirect_device : public device_adapter<Device> {
0065 private:
0066     typedef typename detail::param_type<Device>::type  param_type;
0067 public:
0068     typedef typename char_type_of<Device>::type  char_type;
0069     typedef typename mode_of<Device>::type       mode;
0070     BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
0071     struct category
0072         : mode,
0073           device_tag,
0074           closable_tag,
0075           flushable_tag,
0076           localizable_tag,
0077           optimally_buffered_tag
0078         { };
0079     restricted_indirect_device( param_type dev, stream_offset off,
0080                                 stream_offset len = -1 );
0081     std::streamsize read(char_type* s, std::streamsize n);
0082     std::streamsize write(const char_type* s, std::streamsize n);
0083     std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
0084 private:
0085     stream_offset beg_, pos_, end_;
0086 };
0087 
0088 //
0089 // Template name: restricted_direct_device.
0090 // Description: Provides an restricted view of a Direct Device.
0091 // Template parameters:
0092 //      Device - A model of Direct and Device.
0093 //
0094 template<typename Device>
0095 class restricted_direct_device : public device_adapter<Device> {
0096 public:
0097     typedef typename char_type_of<Device>::type  char_type;
0098     typedef std::pair<char_type*, char_type*>    pair_type;
0099     typedef typename mode_of<Device>::type       mode;
0100     BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
0101     struct category
0102         : mode_of<Device>::type,
0103           device_tag,
0104           direct_tag,
0105           closable_tag,
0106           localizable_tag
0107         { };
0108     restricted_direct_device( const Device& dev, stream_offset off,
0109                               stream_offset len = -1 );
0110     pair_type input_sequence();
0111     pair_type output_sequence();
0112 private:
0113     pair_type sequence(mpl::true_);
0114     pair_type sequence(mpl::false_);
0115     char_type *beg_, *end_;
0116 };
0117 
0118 //
0119 // Template name: restricted_filter.
0120 // Description: Provides an restricted view of a Filter.
0121 // Template parameters:
0122 //      Filter - An indirect model of Filter.
0123 //
0124 template<typename Filter>
0125 class restricted_filter : public filter_adapter<Filter> {
0126 public:
0127     typedef typename char_type_of<Filter>::type char_type;
0128     typedef typename mode_of<Filter>::type      mode;
0129     BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
0130     struct category
0131         : mode,
0132           filter_tag,
0133           multichar_tag,
0134           closable_tag,
0135           localizable_tag,
0136           optimally_buffered_tag
0137         { };
0138     restricted_filter( const Filter& flt, stream_offset off, 
0139                        stream_offset len = -1 );
0140 
0141     template<typename Source>
0142     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0143     {
0144         using namespace std;
0145         if (!open_)
0146             open(src, BOOST_IOS::in);
0147         std::streamsize amt =
0148             end_ != -1 ?
0149                 (std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
0150                 n;
0151         std::streamsize result = 
0152             iostreams::read(this->component(), src, s, amt);
0153         if (result != -1)
0154             pos_ += result;
0155         return result;
0156     }
0157 
0158     template<typename Sink>
0159     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
0160     {
0161         if (!open_)
0162             open(snk, BOOST_IOS::out);
0163         if (end_ != -1 && pos_ + n >= end_) {
0164             if(pos_ < end_)
0165                 pos_ += iostreams::write(this->component(),
0166                     snk, s, end_ - pos_);
0167             boost::throw_exception(bad_write());
0168         }
0169         std::streamsize result = 
0170             iostreams::write(this->component(), snk, s, n);
0171         pos_ += result;
0172         return result;
0173     }
0174 
0175     template<typename Device>
0176     std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way)
0177     {
0178         stream_offset next;
0179         if (way == BOOST_IOS::beg) {
0180             next = beg_ + off;
0181         } else if (way == BOOST_IOS::cur) {
0182             next = pos_ + off;
0183         } else if (end_ != -1) {
0184             next = end_ + off;
0185         } else {
0186             // Restriction is half-open; seek relative to the actual end.
0187             pos_ = this->component().seek(dev, off, BOOST_IOS::end);
0188             if (pos_ < beg_)
0189                 boost::throw_exception(bad_seek());
0190             return offset_to_position(pos_ - beg_);
0191         }
0192         if (next < beg_ || (end_ != -1 && next >= end_))
0193             boost::throw_exception(bad_seek());
0194         pos_ = this->component().seek(dev, next, BOOST_IOS::cur);
0195         return offset_to_position(pos_ - beg_);
0196     }
0197 
0198     template<typename Device>
0199     void close(Device& dev) 
0200     { 
0201         open_ = false;
0202         detail::close_all(this->component(), dev); 
0203     }
0204 
0205     template<typename Device>
0206     void close(Device& dev, BOOST_IOS::openmode which) 
0207     { 
0208         open_ = false;
0209         iostreams::close(this->component(), dev, which); 
0210     }
0211 private:
0212     template<typename Device>
0213     void open(Device& dev, BOOST_IOS::openmode which)
0214     {
0215         typedef typename is_convertible<mode, dual_use>::type is_dual_use;
0216         open_ = true;
0217         which = is_dual_use() ? which : (BOOST_IOS::in | BOOST_IOS::out);
0218         iostreams::skip(this->component(), dev, beg_, which);
0219     }
0220 
0221     stream_offset  beg_, pos_, end_;
0222     bool           open_;
0223 };
0224 
0225 template<typename T>
0226 struct restriction_traits
0227     : iostreams::select<  // Disambiguation for Tru64.
0228           is_filter<T>,  restricted_filter<T>,
0229           is_direct<T>,  restricted_direct_device<T>,
0230           else_,         restricted_indirect_device<T>
0231       >
0232     { };
0233 
0234 } // End namespace detail.
0235 
0236 template<typename T>
0237 struct restriction : public detail::restriction_traits<T>::type {
0238     typedef typename detail::param_type<T>::type          param_type;
0239     typedef typename detail::restriction_traits<T>::type  base_type;
0240     restriction(param_type t, stream_offset off, stream_offset len = -1)
0241         : base_type(t, off, len)
0242         { }
0243 };
0244 
0245 namespace detail {
0246 
0247 //--------------Implementation of restricted_indirect_device------------------//
0248 
0249 template<typename Device>
0250 restricted_indirect_device<Device>::restricted_indirect_device
0251     (param_type dev, stream_offset off, stream_offset len)
0252     : device_adapter<Device>(dev), beg_(off), pos_(off), 
0253       end_(len != -1 ? off + len : -1)
0254 {
0255     if (len < -1 || off < 0)
0256         boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset"));
0257     iostreams::skip(this->component(), off);
0258 }
0259 
0260 template<typename Device>
0261 inline std::streamsize restricted_indirect_device<Device>::read
0262     (char_type* s, std::streamsize n)
0263 {
0264     using namespace std;
0265     std::streamsize amt =
0266         end_ != -1 ?
0267             (std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
0268             n;
0269     std::streamsize result = iostreams::read(this->component(), s, amt);
0270     if (result != -1)
0271         pos_ += result;
0272     return result;
0273 }
0274 
0275 template<typename Device>
0276 inline std::streamsize restricted_indirect_device<Device>::write
0277     (const char_type* s, std::streamsize n)
0278 {
0279     if (end_ != -1 && pos_ + n >= end_) {
0280         if(pos_ < end_)
0281             pos_ += iostreams::write(this->component(), s, end_ - pos_);
0282         boost::throw_exception(bad_write());
0283     }
0284     std::streamsize result = iostreams::write(this->component(), s, n);
0285     pos_ += result;
0286     return result;
0287 }
0288 
0289 template<typename Device>
0290 std::streampos restricted_indirect_device<Device>::seek
0291     (stream_offset off, BOOST_IOS::seekdir way)
0292 {
0293     stream_offset next;
0294     if (way == BOOST_IOS::beg) {
0295         next = beg_ + off;
0296     } else if (way == BOOST_IOS::cur) {
0297         next = pos_ + off;
0298     } else if (end_ != -1) {
0299         next = end_ + off;
0300     } else {
0301         // Restriction is half-open; seek relative to the actual end.
0302         pos_ = iostreams::seek(this->component(), off, BOOST_IOS::end);
0303         if (pos_ < beg_)
0304             boost::throw_exception(bad_seek());
0305         return offset_to_position(pos_ - beg_);
0306     }
0307     if (next < beg_ || (end_ != -1 && next > end_))
0308         boost::throw_exception(bad_seek());
0309     pos_ = iostreams::seek(this->component(), next - pos_, BOOST_IOS::cur);
0310     return offset_to_position(pos_ - beg_);
0311 }
0312 
0313 //--------------Implementation of restricted_direct_device--------------------//
0314 
0315 template<typename Device>
0316 restricted_direct_device<Device>::restricted_direct_device
0317     (const Device& dev, stream_offset off, stream_offset len)
0318     : device_adapter<Device>(dev), beg_(0), end_(0)
0319 {
0320     std::pair<char_type*, char_type*> seq =
0321         sequence(is_convertible<category, input>());
0322     if ( off < 0 || len < -1 || 
0323          (len != -1 && off + len > seq.second - seq.first) )
0324     {
0325         boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset"));
0326     }
0327     beg_ = seq.first + off;
0328     end_ = len != -1 ? 
0329         seq.first + off + len :
0330         seq.second;
0331 }
0332 
0333 template<typename Device>
0334 typename restricted_direct_device<Device>::pair_type
0335 restricted_direct_device<Device>::input_sequence()
0336 {
0337     BOOST_STATIC_ASSERT((is_convertible<category, input>::value));
0338     return std::make_pair(beg_, end_);
0339 }
0340 
0341 template<typename Device>
0342 typename restricted_direct_device<Device>::pair_type
0343 restricted_direct_device<Device>::output_sequence()
0344 {
0345     BOOST_STATIC_ASSERT((is_convertible<category, output>::value));
0346     return std::make_pair(beg_, end_);
0347 }
0348 
0349 template<typename Device>
0350 typename restricted_direct_device<Device>::pair_type
0351 restricted_direct_device<Device>::sequence(mpl::true_)
0352 { return iostreams::input_sequence(this->component()); }
0353 
0354 template<typename Device>
0355 typename restricted_direct_device<Device>::pair_type
0356 restricted_direct_device<Device>::sequence(mpl::false_)
0357 { return iostreams::output_sequence(this->component()); }
0358 
0359 //--------------Implementation of restricted_filter---------------------------//
0360 
0361 template<typename Filter>
0362 restricted_filter<Filter>::restricted_filter
0363     (const Filter& flt, stream_offset off, stream_offset len)
0364     : filter_adapter<Filter>(flt), beg_(off),
0365       pos_(off), end_(len != -1 ? off + len : -1), open_(false)
0366 {
0367     if (len < -1 || off < 0)
0368         boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset"));
0369 }
0370 
0371 } // End namespace detail.
0372 
0373 } } // End namespaces iostreams, boost.
0374 
0375 #elif defined(BOOST_IOSTREAMS_RESTRICT)
0376 
0377 namespace boost { namespace iostreams {
0378 
0379 //--------------Implementation of restrict/slice------------------------------//
0380 
0381 // Note: The following workarounds are patterned after resolve.hpp. It has not
0382 // yet been confirmed that they are necessary.
0383 
0384 # ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //------------------------//
0385 #  ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //------------------------------//
0386 
0387 template<typename T>
0388 restriction<T> 
0389 BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
0390                           BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
0391 { return restriction<T>(t, off, len); }
0392 
0393 template<typename Ch, typename Tr>
0394 restriction< std::basic_streambuf<Ch, Tr> >
0395 BOOST_IOSTREAMS_RESTRICT( std::basic_streambuf<Ch, Tr>& sb, stream_offset off, 
0396                           stream_offset len = -1 )
0397 { return restriction< std::basic_streambuf<Ch, Tr> >(sb, off, len); }
0398 
0399 template<typename Ch, typename Tr>
0400 restriction< std::basic_istream<Ch, Tr> >
0401 BOOST_IOSTREAMS_RESTRICT
0402     (std::basic_istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
0403 { return restriction< std::basic_istream<Ch, Tr> >(is, off, len); }
0404 
0405 template<typename Ch, typename Tr>
0406 restriction< std::basic_ostream<Ch, Tr> >
0407 BOOST_IOSTREAMS_RESTRICT
0408     (std::basic_ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
0409 { return restriction< std::basic_ostream<Ch, Tr> >(os, off, len); }
0410 
0411 template<typename Ch, typename Tr>
0412 restriction< std::basic_iostream<Ch, Tr> >
0413 BOOST_IOSTREAMS_RESTRICT
0414     (std::basic_iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
0415 { return restriction< std::basic_iostream<Ch, Tr> >(io, off, len); }
0416 
0417 #  else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
0418 
0419 template<typename T>
0420 restriction<T> 
0421 BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
0422                           BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
0423 { return restriction<T>(t, off, len); }
0424 
0425 restriction<std::streambuf> 
0426 BOOST_IOSTREAMS_RESTRICT
0427     (std::streambuf& sb, stream_offset off, stream_offset len = -1)
0428 { return restriction<std::streambuf>(sb, off, len); }
0429 
0430 restriction<std::istream> 
0431 BOOST_IOSTREAMS_RESTRICT
0432     (std::istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
0433 { return restriction<std::istream>(is, off, len); }
0434 
0435 restriction<std::ostream> 
0436 BOOST_IOSTREAMS_RESTRICT
0437     (std::ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
0438 { return restriction<std::ostream>(os, off, len); }
0439 
0440 restriction<std::iostream> 
0441 BOOST_IOSTREAMS_RESTRICT
0442     (std::iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
0443 { return restriction<std::iostream>(io, off, len); }
0444 
0445 #  endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------//
0446 # else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
0447 
0448 template<typename T>
0449 restriction<T> 
0450 BOOST_IOSTREAMS_RESTRICT
0451     (const T& t, stream_offset off, stream_offset len, mpl::true_)
0452 {   // Bad overload resolution.
0453     return restriction<T>(const_cast<T&>(t, off, len));
0454 }
0455 
0456 template<typename T>
0457 restriction<T> 
0458 BOOST_IOSTREAMS_RESTRICT
0459     (const T& t, stream_offset off, stream_offset len, mpl::false_)
0460 { return restriction<T>(t, off, len); }
0461 
0462 template<typename T>
0463 restriction<T> 
0464 BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
0465                           BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
0466 { return BOOST_IOSTREAMS_RESTRICT(t, off, len, is_std_io<T>()); }
0467 
0468 # if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \
0469      !defined(__GNUC__) // ---------------------------------------------------//
0470 
0471 template<typename T>
0472 restriction<T>
0473 BOOST_IOSTREAMS_RESTRICT(T& t, stream_offset off, stream_offset len = -1)
0474 { return restriction<T>(t, off, len); }
0475 
0476 #  endif // Borland 5.x or GCC //-------------------------------//
0477 # endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //--------------//
0478 
0479 } } // End namespaces iostreams, boost.
0480 
0481 # include <boost/iostreams/detail/config/enable_warnings.hpp>
0482 
0483 #endif // #if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) ...