Imported Upstream version 17.22.0
[platform/upstream/libzypp.git] / zypp / base / GzStream.h
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                         (C) SuSE Linux Products GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       GzStream.h
14
15   Author:     Michael Andres <ma@suse.de>
16   Maintainer: Michael Andres <ma@suse.de>
17
18   Purpose: Streams reading and writing gzip files.
19
20 /-*/
21 #ifndef ZYPP_BASE_GZSTREAM_H
22 #define ZYPP_BASE_GZSTREAM_H
23
24 #include <iosfwd>
25 #include <streambuf>
26 #include <vector>
27 #include <zlib.h>
28
29 #include "zypp/base/SimpleStreambuf.h"
30 #include "zypp/base/fXstream.h"
31
32 ///////////////////////////////////////////////////////////////////
33 namespace zypp
34 { /////////////////////////////////////////////////////////////////
35
36   ///////////////////////////////////////////////////////////////////
37   namespace gzstream_detail
38   { /////////////////////////////////////////////////////////////////
39
40     ///////////////////////////////////////////////////////////////////
41     //
42     //  CLASS NAME : ZlibError
43     /**
44      * @short Helper class to ship zlib errors.
45      **/
46     struct ZlibError
47     {
48       /**
49        * The zlib error code
50        **/
51       int _zError;
52
53       /**
54        * errno, valid if zError is Z_ERRNO
55        **/
56       int _errno;
57
58       ZlibError()
59       : _zError( 0 ), _errno( 0 )
60       {}
61
62       /**
63        * Return string describing the zlib error code
64        **/
65       std::string
66       strerror() const;
67     };
68     ///////////////////////////////////////////////////////////////////
69
70     /** \relates ZlibError Stream output. */
71     inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
72     { return str << obj.strerror(); }
73
74
75     ///////////////////////////////////////////////////////////////////
76     //
77     //  CLASS NAME : gzstreambufimpl
78     /**
79      * @short Streambuffer reading or writing gzip files.
80      *
81      * Read and write mode are mutual exclusive. Seek is supported,
82      * but zlib restrictions appy (only forward seek in write mode;
83      * backward seek in read mode might be expensive).Putback is not
84      * supported.
85      *
86      * Reading plain (no gziped) files is possible as well.
87      *
88      * This streambuf is used in @ref ifgzstream and  @ref ofgzstream.
89      **/
90     class gzstreambufimpl {
91     public:
92
93       using error_type = ZlibError;
94
95       ~gzstreambufimpl()
96       { closeImpl(); }
97
98       bool
99       isOpen   () const
100       { return _file; }
101
102       bool
103       canRead  () const
104       { return( _mode == std::ios_base::in ); }
105
106       bool
107       canWrite () const
108       { return( _mode == std::ios_base::out ); }
109
110       bool
111       canSeek  ( std::ios_base::seekdir way_r ) const
112       { return ( way_r == std::ios_base::beg || way_r == std::ios_base::cur ); }
113
114     protected:
115       bool openImpl( const char * name_r, std::ios_base::openmode mode_r );
116       bool closeImpl ();
117
118       //! Tell the file position in the compressed file.
119       //! Analogous to tell(2), complementary to gztell.
120       off_t compressed_tell() const;
121
122     public:
123       /**
124          * The last error returned fron zlib.
125          **/
126       error_type
127       error() const
128       { return _error; }
129
130       std::streamsize readData ( char * buffer_r, std::streamsize maxcount_r  );
131       bool writeData( const char * buffer_r, std::streamsize count_r );
132       off_t seekTo( off_t off_r, std::ios_base::seekdir way_r, std::ios_base::openmode omode_r );
133       off_t tell() const;
134
135     private:
136
137       void
138       setZError() const
139       { gzerror( _file, &_error._zError ); }
140
141       //! file descriptor of the compressed file
142       int                        _fd = -1;
143
144       gzFile                   _file = nullptr;
145
146       std::ios_base::openmode  _mode = std::ios_base::openmode(0);
147
148       mutable ZlibError        _error;
149
150     };
151     using fgzstreambuf = detail::SimpleStreamBuf<gzstreambufimpl>;
152   } // namespace gzstream_detail
153
154   /**
155    * istream reading gzip files as well as plain files.
156    **/
157   typedef detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
158
159   /**
160    * ostream writing gzip files.
161    **/
162   typedef detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
163
164   /////////////////////////////////////////////////////////////////
165 } // namespace zypp
166 ///////////////////////////////////////////////////////////////////
167
168 #endif // ZYPP_BASE_GZSTREAM_H