Opened 10 years ago
Last modified 9 years ago
#8203 new Bugs
filtering_ostream fails to write 0xFF characters with XCode
Reported by: | Owned by: | Jonathan Turkanis | |
---|---|---|---|
Milestone: | To Be Determined | Component: | iostreams |
Version: | Boost 1.51.0 | Severity: | Problem |
Keywords: | eof rdbuf filtering_ostream write xcode | Cc: |
Description
I originally found the problem using the zlib_compressor to write to an ofstream. It worked correctly on Windows but in Xcode 4.6 occasionally a 0xFF character was not written to the stream.
I managed to reduce the code required to reproduce it down to:
filtering stream fails to write 0xFF chars to ostream. Have reproduced with ofstream too std::ostringstream ostm(std::ios_base::out | std::ios_base::binary);
Use empty filtering stream. Problem was originally found with zlib_compressor boost::iostreams::filtering_ostream filterStream; filterStream.push( ostm );
const unsigned fileSize = 30000;
for( unsigned nWritten = 0; nWritten < fileSize; ++nWritten) {
const char eofTest = -1; Only fails with 0xFF character any other value fine
filterStream.write( &eofTest, sizeof eofTest);
} filterStream.flush();
This assert fails with Xcode 4.6 assert( ostm.str().size() == fileSize);
The number of missing characters is equal to the number of times overflow gets called. I suspect it's something to do with EOF character detection as the problem doesn't happen with other character values.
I was unable to find the exact reason for the problem but was able to get it work by changing this code in write.hpp:
static std::streamsize write(T& t, const typename char_type_of<T>::type* s, std::streamsize n) {
return t.rdbuf()->sputn(s, n);
}
to:
static std::streamsize write(T& t, const typename char_type_of<T>::type* s, std::streamsize n) {
t.write(s, n); return n;
}
It looks like bypassing the ofstream in Xcode and going to the lower level rdbuf::sputn causes the issue.
Attachments (1)
Change History (4)
by , 10 years ago
Attachment: | iostream_filter_issue.cpp added |
---|
comment:1 by , 10 years ago
I also had to change the use of sputn in write_device_impl::write by using sputc instead that doesn't seem to have a problem:
static std::streamsize write
(T& t, const typename char_type_of<T>::type* s, std::streamsize n)
{
typedef typename char_type_of<T>::type char_type; typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; const char_type* pNext = s; while( pNext < s + n ) {
if ( traits_type::eq_int_type( t.sputc(*pNext), traits_type::eof() ) ) {
break;
} ++pNext;
} return pNext - s;
}
comment:2 by , 9 years ago
I'm pretty sure this is a duplicate of #8150:
https://svn.boost.org/trac/boost/ticket/8203
The fix is to update libc++.
comment:3 by , 9 years ago
Thanks. That looks like it. The streambuf header in Xcode 4.6 was updated in January 2013 and includes the fix.
Please close the bug.
Demonstrates issue writing 0xFF through filtering_ostream on XCode