summaryrefslogtreecommitdiff
path: root/boost/iostreams/detail/streambuf/indirect_streambuf.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/iostreams/detail/streambuf/indirect_streambuf.hpp')
-rw-r--r--boost/iostreams/detail/streambuf/indirect_streambuf.hpp39
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