Opened 13 years ago
Closed 13 years ago
#3723 closed Bugs (fixed)
gzip_docompressor error - basic_array_source no putback member
Reported by: | jose | Owned by: | Daniel James |
---|---|---|---|
Milestone: | Boost 1.43.0 | Component: | iostreams |
Version: | Boost 1.41.0 | Severity: | Showstopper |
Keywords: | Cc: |
Description
std::string decompress_gzip(const std::string& in) {
std::string res; bio::array_source src(in.data(),in.length()); bio::copy(bio::compose(bio::gzip_decompressor(), src),
bio::back_inserter(res));
return res;
}
I get this compile error with 1.41 (not with earlier releases):
home/code/boost_1_41_0/boost/iostreams/read.hpp:191: error: 'class boost::iostreams::detail::direct_adapter<boost::iostreams::basic_array_source<char>
' has no member named 'putback'
Attachments (1)
Change History (11)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Sorry for the mess. Reposting the patch.
$ svn diff -r HEAD Index: detail/adapter/direct_adapter.hpp =================================================================== --- detail/adapter/direct_adapter.hpp (revision 59992) +++ detail/adapter/direct_adapter.hpp (working copy) @@ -116,6 +116,7 @@ std::streamsize write(const char_type* s, std::streamsize n); std::streampos seek( stream_offset, BOOST_IOS::seekdir, BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out ); + bool putback(const char_type c); void close(); void close(BOOST_IOS::openmode which); #ifndef BOOST_IOSTREAMS_NO_LOCALE @@ -204,6 +205,18 @@ } template<typename Direct> +inline bool direct_adapter<Direct>::putback + (const char_type c) +{ + pointers& get = ptrs_.first(); + if( get.ptr == get.beg ) + throw bad_putback(); + get.ptr -= 1; + *get.ptr = c; + return true; +} + +template<typename Direct> inline std::streamsize direct_adapter<Direct>::write (const char_type* s, std::streamsize n) {
comment:3 by , 13 years ago
This looks wrong to me, I don't think you should be modifying the source array. IMO the correct solution is to remove the call to putback in basic_gzip_decompressor::peekable_source::putback
and change it so that it either throws an error or puts the character at the start of the buffer. The attached patch does the former, looking at the gzip implementation it only ever calls putback with a string or immediately after reading a character so it should never throw. Does it look okay to you?
by , 13 years ago
Attachment: | gzip.patch added |
---|
comment:4 by , 13 years ago
I see, I never even tried to understand the gzip code, just assumed that it *really* needs to putback in the source.
Does it look ok to you?
Of course. As long as it fixes my issue.
But I don't see why not have the array source peekable anyway(why is it wrong)? Aren't there other filters that require peekability?
Not trying to be pushy:) ...
follow-up: 8 comment:5 by , 13 years ago
Milestone: | Boost 1.42.0 → Boost 1.43.0 |
---|
The problem is that the 'peekable' interface doesn't just peek at a character, it lets you put back a different character, modifying the source array, which is read only according to the documentation (it probably should take a const
reference, but that's another matter). Did you test my patch with your code?
comment:6 by , 13 years ago
Sorry, bad link. Here's the correct link: http://www.boost.org/doc/libs/1_42_0/libs/iostreams/doc/classes/array.html#array_source
comment:7 by , 13 years ago
(In [60415]) Gzip filter shouldn't require its source to be peekable. Refs #3723.
In a recent version, the gzip filter stopped working for array sources, this is because it started to require them to be peekable, which they aren't and can't be because the peek interface modifies the source, which for an array source is immutable.
Looking at the implementation, gzip decompressor has an internal class to emulate a peekable source, which calls the putback member on the original source if it runs out of space (requiring the source to be peekable). It shouldn't really need to do that so I changed it to throw an exception instead.
If it does need to do that, we could change it to store the character that was put back at the beginning of the string instead.
comment:8 by , 13 years ago
Replying to danieljames:
Did you test my patch with your code?
Yes. It works for me. Thank you!
<teasing>
modifying the source array, which is read only
what about basic_array?
</teasing>
comment:9 by , 13 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:10 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(In [60666]) Merge iostreams.
Would you accept this patch? Or is it not general enough?
$ svn diff -r HEAD Index: detail/adapter/direct_adapter.hpp =================================================================== --- detail/adapter/direct_adapter.hpp (revision 59992) +++ detail/adapter/direct_adapter.hpp (working copy) @@ -116,6 +116,7 @@
+ bool putback(const char_type c);
@@ -204,6 +205,18 @@
+inline bool direct_adapter<Direct>::putback + (const char_type c) +{ + pointers& get = ptrs_.first(); + if( get.ptr == get.beg ) + throw bad_putback(); + get.ptr -= 1; + *get.ptr = c; + return true; +} + +template<typename Direct>