Boost C++ Libraries: Ticket #3723: gzip_docompressor error - basic_array_source no putback member https://svn.boost.org/trac10/ticket/3723 <p> std::string decompress_gzip(const std::string&amp; in) { </p> <blockquote> <p> std::string res; bio::array_source src(in.data(),in.length()); bio::copy(bio::compose(bio::gzip_decompressor(), src), </p> </blockquote> <p> bio::back_inserter(res)); </p> <blockquote> <p> return res; </p> </blockquote> <p> } </p> <p> I get this compile error with 1.41 (not with earlier releases): </p> <p> home/code/boost_1_41_0/boost/iostreams/read.hpp:191: error: 'class boost::iostreams::detail::direct_adapter&lt;boost::iostreams::basic_array_source&lt;char&gt; </p> <blockquote class="citation"> <p> ' has no member named 'putback' </p> </blockquote> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3723 Trac 1.4.3 Nikolay Mladenov Mon, 01 Mar 2010 02:26:14 GMT <link>https://svn.boost.org/trac10/ticket/3723#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:1</guid> <description> <p> Would you accept this patch? Or is it not general enough? </p> <p> $ 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 @@ </p> <blockquote> <p> std::streamsize write(const char_type* s, std::streamsize n); std::streampos seek( stream_offset, BOOST_IOS::seekdir, </p> <blockquote> <p> BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out ); </p> </blockquote> </blockquote> <p> + bool putback(const char_type c); </p> <blockquote> <p> void close(); void close(BOOST_IOS::openmode which); </p> </blockquote> <blockquote> <p> #ifndef BOOST_IOSTREAMS_NO_LOCALE </p> </blockquote> <p> @@ -204,6 +205,18 @@ </p> <blockquote> <p> } </p> </blockquote> <blockquote> <p> template&lt;typename Direct&gt; </p> </blockquote> <p> +inline bool direct_adapter&lt;Direct&gt;::putback + (const char_type c) +{ + pointers&amp; get = ptrs_.first(); + if( get.ptr == get.beg ) + throw bad_putback(); + get.ptr -= 1; + *get.ptr = c; + return true; +} + +template&lt;typename Direct&gt; </p> <blockquote> <p> inline std::streamsize direct_adapter&lt;Direct&gt;::write </p> <blockquote> <p> (const char_type* s, std::streamsize n) </p> </blockquote> <p> { </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>Nikolay Mladenov</dc:creator> <pubDate>Mon, 01 Mar 2010 02:28:47 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3723#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:2</guid> <description> <p> Sorry for the mess. Reposting the patch. </p> <pre class="wiki">$ 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&lt;typename Direct&gt; +inline bool direct_adapter&lt;Direct&gt;::putback + (const char_type c) +{ + pointers&amp; get = ptrs_.first(); + if( get.ptr == get.beg ) + throw bad_putback(); + get.ptr -= 1; + *get.ptr = c; + return true; +} + +template&lt;typename Direct&gt; inline std::streamsize direct_adapter&lt;Direct&gt;::write (const char_type* s, std::streamsize n) { </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Daniel James</dc:creator> <pubDate>Sat, 06 Mar 2010 14:15:48 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3723#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:3</guid> <description> <p> 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 <code>basic_gzip_decompressor::peekable_source::putback</code> 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? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Daniel James</dc:creator> <pubDate>Sat, 06 Mar 2010 14:16:51 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3723 https://svn.boost.org/trac10/ticket/3723 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">gzip.patch</span> </li> </ul> Ticket anonymous Mon, 08 Mar 2010 18:59:47 GMT <link>https://svn.boost.org/trac10/ticket/3723#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:4</guid> <description> <p> I see, I never even tried to understand the gzip code, just assumed that it *really* needs to putback in the source. </p> <blockquote class="citation"> <p> Does it look ok to you? </p> </blockquote> <p> Of course. As long as it fixes my issue. </p> <p> 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? </p> <p> Not trying to be pushy:) ... </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Daniel James</dc:creator> <pubDate>Mon, 08 Mar 2010 19:28:29 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/3723#comment:5 https://svn.boost.org/trac10/ticket/3723#comment:5 <ul> <li><strong>milestone</strong> <span class="trac-field-old">Boost 1.42.0</span> → <span class="trac-field-new">Boost 1.43.0</span> </li> </ul> <p> 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 <a href="http://www.boost.org/doc/libs/1_42_0/libs/iostreams/doc/index.html">the documentation</a> (it probably should take a <code>const</code> reference, but that's another matter). Did you test my patch with your code? </p> Ticket Daniel James Mon, 08 Mar 2010 19:32:06 GMT <link>https://svn.boost.org/trac10/ticket/3723#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:6</guid> <description> <p> Sorry, bad link. Here's the correct link: <a href="http://www.boost.org/doc/libs/1_42_0/libs/iostreams/doc/classes/array.html#array_source">http://www.boost.org/doc/libs/1_42_0/libs/iostreams/doc/classes/array.html#array_source</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Daniel James</dc:creator> <pubDate>Wed, 10 Mar 2010 07:29:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3723#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:7</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/60415" title="Gzip filter shouldn't require its source to be peekable. Refs #3723. ...">[60415]</a>) Gzip filter shouldn't require its source to be peekable. Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3723" title="#3723: Bugs: gzip_docompressor error - basic_array_source no putback member (closed: fixed)">#3723</a>. </p> <p> 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. </p> <p> 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. </p> <p> 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. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Nikolay Mladenov</dc:creator> <pubDate>Wed, 10 Mar 2010 18:02:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3723#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3723#comment:8</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3723#comment:5" title="Comment 5">danieljames</a>: </p> <blockquote class="citation"> <p> Did you test my patch with your code? </p> </blockquote> <p> Yes. It works for me. Thank you! </p> <p> &lt;teasing&gt; </p> <blockquote class="citation"> <p> modifying the source array, which is read only </p> </blockquote> <p> what about basic_array? </p> <p> &lt;/teasing&gt; </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Daniel James</dc:creator> <pubDate>Fri, 12 Mar 2010 19:36:49 GMT</pubDate> <title>owner, status changed https://svn.boost.org/trac10/ticket/3723#comment:9 https://svn.boost.org/trac10/ticket/3723#comment:9 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Jonathan Turkanis</span> to <span class="trac-author">Daniel James</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket Daniel James Wed, 17 Mar 2010 00:23:34 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3723#comment:10 https://svn.boost.org/trac10/ticket/3723#comment:10 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/60666" title="Merge iostreams. - Fix write_device_impl&lt;ostream_tag&gt;. Fixes #3839 ...">[60666]</a>) Merge iostreams. </p> <ul><li>Fix write_device_impl&lt;ostream_tag&gt;. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3839" title="#3839: Bugs: [iostreams]write.hpp:write_device_impl&lt;ostream_tag&gt; tries access ... (closed: fixed)">#3839</a> </li><li>Fix error checks after calling <a class="missing wiki">SetFilePointer</a>. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3953" title="#3953: Bugs: [boost][iostreams] mapped_file bug on Win32? (closed: fixed)">#3953</a> </li><li>Gzip filter shouldn't require its source to be peekable. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3723" title="#3723: Bugs: gzip_docompressor error - basic_array_source no putback member (closed: fixed)">#3723</a>. </li><li>In <code>position_to_offset</code>, only cast to <code>stream_offset</code> after calculating <code>_Myoff</code>. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3969" title="#3969: Patches: position_to_offset() is broken for Microsoft Visual C++/Dinkumware (closed: fixed)">#3969</a>. </li><li>ptrdiff_t is in std. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/2505" title="#2505: Bugs: iostreams/test/grep_test.cpp assumes that ptrdiff_t is in the global ... (closed: fixed)">#2505</a>. </li></ul> Ticket