Opened 10 years ago

Last modified 9 years ago

#8203 new Bugs

filtering_ostream fails to write 0xFF characters with XCode

Reported by: support@… 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)

iostream_filter_issue.cpp (828 bytes ) - added by anonymous 10 years ago.
Demonstrates issue writing 0xFF through filtering_ostream on XCode

Download all attachments as: .zip

Change History (4)

by anonymous, 10 years ago

Attachment: iostream_filter_issue.cpp added

Demonstrates issue writing 0xFF through filtering_ostream on XCode

comment:1 by support@…, 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 anonymous, 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 anonymous, 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.

Note: See TracTickets for help on using tickets.