28#if !defined(SEQAN3_HAS_ZLIB) && !defined(SEQAN3_HEADER_TEST)
29#error "This file cannot be used when building without ZLIB-support."
32#if defined(SEQAN3_HAS_ZLIB)
36namespace seqan3::contrib
40const size_t GZ_INPUT_DEFAULT_BUFFER_SIZE = 921600;
48template <
typename Elem,
51 typename ByteT =
unsigned char,
54class basic_gz_istreambuf :
59 typedef ElemA char_allocator_type;
60 typedef ByteT byte_type;
61 typedef ByteAT byte_allocator_type;
62 typedef byte_type * byte_buffer_type;
63 typedef Tr traits_type;
64 typedef typename Tr::char_type char_type;
65 typedef typename Tr::int_type int_type;
71 basic_gz_istreambuf(istream_reference istream_,
73 size_t read_buffer_size_,
74 size_t input_buffer_size_);
76 ~basic_gz_istreambuf();
81 istream_reference get_istream() {
return m_istream; }
83 z_stream & get_zip_stream() {
return m_zip_stream; }
86 void put_back_from_zip_stream();
88 size_t fill_input_buffer();
90 istream_reference m_istream;
91 z_stream m_zip_stream;
93 byte_vector_type m_input_buffer;
94 char_vector_type m_buffer;
101template <
typename Elem,
106basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::basic_gz_istreambuf(
107 istream_reference istream_,
109 size_t read_buffer_size_,
110 size_t input_buffer_size_
113 m_input_buffer(input_buffer_size_),
114 m_buffer(read_buffer_size_)
117 m_zip_stream.zalloc = (alloc_func)0;
118 m_zip_stream.zfree = (free_func)0;
120 m_zip_stream.next_in = NULL;
121 m_zip_stream.avail_in = 0;
122 m_zip_stream.avail_out = 0;
123 m_zip_stream.next_out = NULL;
125 m_err = inflateInit2(&m_zip_stream,
static_cast<int>(window_size_));
127 this->setg(&(m_buffer[0]) + 4,
132template <
typename Elem,
137basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::~basic_gz_istreambuf()
139 inflateEnd(&m_zip_stream);
142template <
typename Elem,
147typename basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::int_type
148basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::underflow()
150 if (this->gptr() && (this->gptr() < this->egptr()))
151 return *
reinterpret_cast<unsigned char *
>(this->gptr());
153 int n_putback =
static_cast<int>(this->gptr() - this->eback());
157 std::memmove(&(m_buffer[0]) + (4 - n_putback), this->gptr() - n_putback, n_putback *
sizeof(
char_type));
159 int num = unzip_from_stream(&(m_buffer[0]) + 4,
163 return traits_type::eof();
166 this->setg(&(m_buffer[0]) + (4 - n_putback),
168 &(m_buffer[0]) + 4 + num);
171 return *
reinterpret_cast<unsigned char *
>(this->gptr());
174template <
typename Elem,
179std::streamsize basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::unzip_from_stream(
183 m_zip_stream.next_out = (byte_buffer_type)buffer_;
184 m_zip_stream.avail_out =
static_cast<uInt
>(buffer_size_ *
sizeof(
char_type));
185 size_t count = m_zip_stream.avail_in;
189 if (m_zip_stream.avail_in == 0)
190 count = fill_input_buffer();
192 if (m_zip_stream.avail_in)
193 m_err = inflate(&m_zip_stream, Z_SYNC_FLUSH);
195 if (m_err == Z_STREAM_END)
196 inflateReset(&m_zip_stream);
200 while (m_zip_stream.avail_out > 0 &&
count > 0);
205 if (m_zip_stream.avail_out > 0 && m_err == Z_STREAM_END)
206 put_back_from_zip_stream();
211template <
typename Elem,
216size_t basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::fill_input_buffer()
218 m_zip_stream.next_in = &(m_input_buffer[0]);
219 m_istream.read((
char_type *)(&(m_input_buffer[0])),
221 return m_zip_stream.avail_in = m_istream.gcount() *
sizeof(
char_type);
224template <
typename Elem,
229void basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::put_back_from_zip_stream()
231 if (m_zip_stream.avail_in == 0)
234 m_istream.clear(std::ios::goodbit);
235 m_istream.seekg(-
static_cast<int>(m_zip_stream.avail_in), std::ios_base::cur);
237 m_zip_stream.avail_in = 0;
246template <
typename Elem,
249 typename ByteT =
unsigned char,
252class basic_gz_istreambase :
257 typedef basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT> unzip_streambuf_type;
259 basic_gz_istreambase(istream_reference ostream_,
261 size_t read_buffer_size_,
262 size_t input_buffer_size_) :
263 m_buf(ostream_, window_size_, read_buffer_size_, input_buffer_size_)
269 unzip_streambuf_type *
rdbuf() {
return &m_buf; }
272 unzip_streambuf_type m_buf;
292template <
typename Elem,
295 typename ByteT =
unsigned char,
298class basic_gz_istream :
299 public basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT>,
303 typedef basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT> zip_istreambase_type;
305 typedef istream_type & istream_reference;
306 typedef ByteT byte_type;
307 typedef Tr traits_type;
316 basic_gz_istream(istream_reference istream_,
317 size_t window_size_ = 31,
318 size_t read_buffer_size_ = GZ_INPUT_DEFAULT_BUFFER_SIZE,
319 size_t input_buffer_size_ = GZ_INPUT_DEFAULT_BUFFER_SIZE) :
320 zip_istreambase_type(istream_, window_size_, read_buffer_size_, input_buffer_size_),
321 istream_type(this->rdbuf())
326 void _Add_vtordisp1() {}
327 void _Add_vtordisp2() {}
336typedef basic_gz_istream<char> gz_istream;
338typedef basic_gz_istream<wchar_t> gz_wistream;
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:164
typename stream::char_type char_type
Declares the associated char type.