31#if !defined(SEQAN3_HAS_ZLIB) && !defined(SEQAN3_HEADER_TEST)
32#error "This file cannot be used when building without ZLIB-support."
35#if defined(SEQAN3_HAS_ZLIB)
39namespace seqan3::contrib
43const size_t GZ_INPUT_DEFAULT_BUFFER_SIZE = 921600;
51template <
typename Elem,
54 typename ByteT =
unsigned char,
57class basic_gz_istreambuf :
62 typedef ElemA char_allocator_type;
63 typedef ByteT byte_type;
64 typedef ByteAT byte_allocator_type;
65 typedef byte_type * byte_buffer_type;
66 typedef Tr traits_type;
67 typedef typename Tr::char_type char_type;
68 typedef typename Tr::int_type int_type;
74 basic_gz_istreambuf(istream_reference istream_,
76 size_t read_buffer_size_,
77 size_t input_buffer_size_);
79 ~basic_gz_istreambuf();
84 istream_reference get_istream() {
return m_istream; }
86 z_stream & get_zip_stream() {
return m_zip_stream; }
89 void put_back_from_zip_stream();
91 size_t fill_input_buffer();
93 istream_reference m_istream;
94 z_stream m_zip_stream;
96 byte_vector_type m_input_buffer;
97 char_vector_type m_buffer;
104template <
typename Elem,
109basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::basic_gz_istreambuf(
110 istream_reference istream_,
112 size_t read_buffer_size_,
113 size_t input_buffer_size_
116 m_input_buffer(input_buffer_size_),
117 m_buffer(read_buffer_size_)
120 m_zip_stream.zalloc = (alloc_func)0;
121 m_zip_stream.zfree = (free_func)0;
123 m_zip_stream.next_in = NULL;
124 m_zip_stream.avail_in = 0;
125 m_zip_stream.avail_out = 0;
126 m_zip_stream.next_out = NULL;
128 m_err = inflateInit2(&m_zip_stream,
static_cast<int>(window_size_));
130 this->setg(&(m_buffer[0]) + 4,
135template <
typename Elem,
140basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::~basic_gz_istreambuf()
142 inflateEnd(&m_zip_stream);
145template <
typename Elem,
150typename basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::int_type
151basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::underflow()
153 if (this->gptr() && (this->gptr() < this->egptr()))
154 return *
reinterpret_cast<unsigned char *
>(this->gptr());
156 int n_putback =
static_cast<int>(this->gptr() - this->eback());
160 std::memmove(&(m_buffer[0]) + (4 - n_putback), this->gptr() - n_putback, n_putback *
sizeof(char_type));
162 int num = unzip_from_stream(&(m_buffer[0]) + 4,
163 static_cast<std::streamsize>((m_buffer.size() - 4) *
sizeof(char_type)));
166 return traits_type::eof();
169 this->setg(&(m_buffer[0]) + (4 - n_putback),
171 &(m_buffer[0]) + 4 + num);
174 return *
reinterpret_cast<unsigned char *
>(this->gptr());
177template <
typename Elem,
182std::streamsize basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::unzip_from_stream(
186 m_zip_stream.next_out = (byte_buffer_type)buffer_;
187 m_zip_stream.avail_out =
static_cast<uInt
>(buffer_size_ *
sizeof(char_type));
188 size_t count = m_zip_stream.avail_in;
192 if (m_zip_stream.avail_in == 0)
193 count = fill_input_buffer();
195 if (m_zip_stream.avail_in)
196 m_err = inflate(&m_zip_stream, Z_SYNC_FLUSH);
198 if (m_err == Z_STREAM_END)
199 inflateReset(&m_zip_stream);
203 while (m_zip_stream.avail_out > 0 && count > 0);
205 std::streamsize n_read = buffer_size_ - m_zip_stream.avail_out /
sizeof(char_type);
208 if (m_zip_stream.avail_out > 0 && m_err == Z_STREAM_END)
209 put_back_from_zip_stream();
214template <
typename Elem,
219size_t basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::fill_input_buffer()
221 m_zip_stream.next_in = &(m_input_buffer[0]);
222 m_istream.read((char_type *)(&(m_input_buffer[0])),
223 static_cast<std::streamsize>(m_input_buffer.size() /
sizeof(char_type)));
224 return m_zip_stream.avail_in = m_istream.gcount() *
sizeof(char_type);
227template <
typename Elem,
232void basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::put_back_from_zip_stream()
234 if (m_zip_stream.avail_in == 0)
237 m_istream.clear(std::ios::goodbit);
238 m_istream.seekg(-
static_cast<int>(m_zip_stream.avail_in), std::ios_base::cur);
240 m_zip_stream.avail_in = 0;
249template <
typename Elem,
252 typename ByteT =
unsigned char,
255class basic_gz_istreambase :
260 typedef basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT> unzip_streambuf_type;
262 basic_gz_istreambase(istream_reference ostream_,
264 size_t read_buffer_size_,
265 size_t input_buffer_size_) :
266 m_buf(ostream_, window_size_, read_buffer_size_, input_buffer_size_)
272 unzip_streambuf_type *
rdbuf() {
return &m_buf; }
275 unzip_streambuf_type m_buf;
295template <
typename Elem,
298 typename ByteT =
unsigned char,
301class basic_gz_istream :
302 public basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT>,
306 typedef basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT> zip_istreambase_type;
308 typedef istream_type & istream_reference;
309 typedef ByteT byte_type;
310 typedef Tr traits_type;
319 basic_gz_istream(istream_reference istream_,
320 size_t window_size_ = 31,
321 size_t read_buffer_size_ = GZ_INPUT_DEFAULT_BUFFER_SIZE,
322 size_t input_buffer_size_ = GZ_INPUT_DEFAULT_BUFFER_SIZE) :
323 zip_istreambase_type(istream_, window_size_, read_buffer_size_, input_buffer_size_),
324 istream_type(this->rdbuf())
329 void _Add_vtordisp1() {}
330 void _Add_vtordisp2() {}
339typedef basic_gz_istream<char> gz_istream;
341typedef basic_gz_istream<wchar_t> gz_wistream;
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161