Boost logo

Boost Users :

From: Marc Viala Perso (marc.viala_at_[hidden])
Date: 2008-01-19 12:28:45


> Marc Viala Perso wrote:
> > Hello,
> >
> > I'm just wondering why zlib and bzip2 codec are "dual_use" filter but
not
> > gzip? Can anybody enlighten me on this restriction?
>
> Yeah, I'm probably the only one who can enlighten you. It was sheer
> laziness on my part, because the implementation looked like it would be
> pretty messy and I thought it would typically be used with input
> streams. There's no good excuse for this -- sorry. I've created a ticket
> to fix it for 1.36 (http://svn.boost.org/trac/boost/ticket/1579). It's
> too late for 1.35, but I may post a patch.

[Marc Viala]
Ok, thanks for this explanation — I'm pleased for hearing that I'm not the
only lazy developer ;-).
Right now, the patch is not necessary (see below) so I'll be able to wait
for Boost 1.36.

>
> > In fact, I have the following use case:
>
> ...
>
> > class gzfstream: public
> > boost::iostreams::filtering_stream<boost::iostreams::dual_use>
>
> You should never instantiate a
> filtering_stream<boost::iostreams::dual_use>. DualUse is not a real
> mode, it's a pseudo mode, provided as a convenience for filter
> implementors. I should put in a STATIC_ASSERT somewhere to prevent this.

[Marc Viala]
Oups, sorry but maybe it will be very valuable to add some explanations on
the Iostreams documentation to explain this type of restriction (and to add
also the STATIC_ASSERT). More generally, my feelings after some days diving
into the Iostream documentation, is that adding some use cases or examples
would be relevant. Your library is very important/great in my sense and I'm
sure that I'm not able to embrace all its features up to now, maybe due to
the documentation.

>
> If you need to use an external interface that expects an iostream, you
> could use a filtering_stream<bidirectional>, together with
> boost::iostreams::combination (http://tinyurl.com/24zwqy) to producing a
> bidirectional filter. Depending on your use case, which I don't fully
> understand, you could combine two compression filters to produce a
> bidirectional compression filter, or a compression filter with a dummy
> filter that always throws, to produce a bidirectional stream that at
> runtime can only be used for unidirectional i/o.

[Marc Viala]
Ok, I've implemented your suggestion and its works fine. Just to be sure
that I didn't miss anything, do you confirm the implementation hereafter?

class gzfstream:
  public boost::iostreams::filtering_stream<boost::iostreams::bidirectional>
{
public:
  template <class Path>
  gzfstream(const Path& file_path, std::ios_base::openmode mode):
    _file(file_path, mode)
  {
    namespace fs = boost::filesystem ;
    namespace io = boost::iostreams ;
    
    const typename Path::string_type& ext = fs::extension(file_path) ;
    if( gz_extension_exists(ext) )
      push(io::combine(io::gzip_decompressor(), io::gzip_compressor())) ;
    push(_file) ;
  }

  ~gzfstream()
  { reset() ; }
  
  static bool gz_extension_exists(const std::string& ext)
  { return ext.size() == 3 && ext == ".gz" ; }

  static bool gz_extension_exists(const std::wstring& ext)
  { return ext.size() == 3 && ext == L".gz" ; }

private:
  boost::filesystem::fstream _file ;
} ;

Jonathan thanks again for your library and your very quick help.

Best regards,

Marc VIALA


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net