diff options
Diffstat (limited to 'boost/iostreams/detail/streambuf/indirect_streambuf.hpp')
-rw-r--r-- | boost/iostreams/detail/streambuf/indirect_streambuf.hpp | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/boost/iostreams/detail/streambuf/indirect_streambuf.hpp b/boost/iostreams/detail/streambuf/indirect_streambuf.hpp index 8da5ef3c50..90e1e11531 100644 --- a/boost/iostreams/detail/streambuf/indirect_streambuf.hpp +++ b/boost/iostreams/detail/streambuf/indirect_streambuf.hpp @@ -107,7 +107,7 @@ private: bool can_read() const { return is_convertible<Mode, input>::value; } bool can_write() const { return is_convertible<Mode, output>::value; } bool output_buffered() const { return (flags_ & f_output_buffered) != 0; } - bool shared_buffer() const { return is_convertible<Mode, seekable>::value; } + bool shared_buffer() const { return is_convertible<Mode, seekable>::value || is_convertible<Mode, dual_seekable>::value; } void set_flags(int f) { flags_ = f; } //----------State changing functions--------------------------------------// @@ -169,16 +169,16 @@ void indirect_streambuf<T, Tr, Alloc, Mode>::open pback_size_ = (std::max)(std::streamsize(2), pback_size); // STLPort needs 2. std::streamsize size = pback_size_ + - ( buffer_size ? buffer_size: 1 ); - in().resize(size); + ( buffer_size ? buffer_size: std::streamsize(1) ); + in().resize(static_cast<int>(size)); if (!shared_buffer()) init_get_area(); } // Construct output buffer. if (can_write() && !shared_buffer()) { - if (buffer_size != 0) - out().resize(buffer_size); + if (buffer_size != std::streamsize(0)) + out().resize(static_cast<int>(buffer_size)); init_put_area(); } @@ -346,16 +346,31 @@ indirect_streambuf<T, Tr, Alloc, Mode>::seek_impl if ( gptr() != 0 && way == BOOST_IOS::cur && which == BOOST_IOS::in && eback() - gptr() <= off && off <= egptr() - gptr() ) { // Small seek optimization - gbump(off); - return obj().seek(0, BOOST_IOS::cur, BOOST_IOS::in, next_) - + gbump(static_cast<int>(off)); + return obj().seek(stream_offset(0), BOOST_IOS::cur, BOOST_IOS::in, next_) - static_cast<off_type>(egptr() - gptr()); } if (pptr() != 0) this->BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6. if (way == BOOST_IOS::cur && gptr()) off -= static_cast<off_type>(egptr() - gptr()); - setg(0, 0, 0); - setp(0, 0); + bool two_head = is_convertible<category, dual_seekable>::value || + is_convertible<category, bidirectional_seekable>::value; + if (two_head) { + BOOST_IOS::openmode both = BOOST_IOS::in | BOOST_IOS::out; + if ((which & both) == both) + boost::throw_exception(bad_seek()); + if (which & BOOST_IOS::in) { + setg(0, 0, 0); + } + if (which & BOOST_IOS::out) { + setp(0, 0); + } + } + else { + setg(0, 0, 0); + setp(0, 0); + } return obj().seek(off, way, which, next_); } @@ -394,7 +409,7 @@ void indirect_streambuf<T, Tr, Alloc, Mode>::sync_impl() else { const char_type* ptr = pptr(); setp(out().begin() + amt, out().end()); - pbump(ptr - pptr()); + pbump(static_cast<int>(ptr - pptr())); } } } @@ -413,8 +428,10 @@ template<typename T, typename Tr, typename Alloc, typename Mode> void indirect_streambuf<T, Tr, Alloc, Mode>::init_put_area() { using namespace std; - if (shared_buffer() && gptr() != 0) + if (shared_buffer() && gptr() != 0) { + obj().seek(static_cast<off_type>(gptr() - egptr()), BOOST_IOS::cur, BOOST_IOS::in, next_); setg(0, 0, 0); + } if (output_buffered()) setp(out().begin(), out().end()); else |