28 #ifndef SEQAN3_HAS_ZLIB
29 #error "This file cannot be used when building without ZLIB-support."
34 namespace seqan3::contrib
38 const size_t GZ_INPUT_DEFAULT_BUFFER_SIZE = 921600;
46 template <
typename Elem,
49 typename ByteT =
unsigned char,
52 class basic_gz_istreambuf :
57 typedef ElemA char_allocator_type;
58 typedef ByteT byte_type;
59 typedef ByteAT byte_allocator_type;
60 typedef byte_type * byte_buffer_type;
61 typedef Tr traits_type;
62 typedef typename Tr::char_type char_type;
63 typedef typename Tr::int_type int_type;
69 basic_gz_istreambuf(istream_reference istream_,
71 size_t read_buffer_size_,
72 size_t input_buffer_size_);
74 ~basic_gz_istreambuf();
79 istream_reference get_istream() {
return m_istream; }
81 z_stream & get_zip_stream() {
return m_zip_stream; }
84 void put_back_from_zip_stream();
86 size_t fill_input_buffer();
88 istream_reference m_istream;
89 z_stream m_zip_stream;
91 byte_vector_type m_input_buffer;
92 char_vector_type m_buffer;
99 template <
typename Elem,
104 basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::basic_gz_istreambuf(
105 istream_reference istream_,
107 size_t read_buffer_size_,
108 size_t input_buffer_size_
111 m_input_buffer(input_buffer_size_),
112 m_buffer(read_buffer_size_)
115 m_zip_stream.zalloc = (alloc_func)0;
116 m_zip_stream.zfree = (free_func)0;
118 m_zip_stream.next_in = NULL;
119 m_zip_stream.avail_in = 0;
120 m_zip_stream.avail_out = 0;
121 m_zip_stream.next_out = NULL;
123 m_err = inflateInit2(&m_zip_stream,
static_cast<int>(window_size_));
125 this->setg(&(m_buffer[0]) + 4,
130 template <
typename Elem,
135 basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::~basic_gz_istreambuf()
137 inflateEnd(&m_zip_stream);
140 template <
typename Elem,
145 typename basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::int_type
146 basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::underflow()
148 if (this->gptr() && (this->gptr() < this->egptr()))
149 return *
reinterpret_cast<unsigned char *
>(this->gptr());
151 int n_putback =
static_cast<int>(this->gptr() - this->eback());
155 std::memmove(&(m_buffer[0]) + (4 - n_putback), this->gptr() - n_putback, n_putback *
sizeof(
char_type));
157 int num = unzip_from_stream(&(m_buffer[0]) + 4,
161 return traits_type::eof();
164 this->setg(&(m_buffer[0]) + (4 - n_putback),
166 &(m_buffer[0]) + 4 + num);
169 return *
reinterpret_cast<unsigned char *
>(this->gptr());
172 template <
typename Elem,
177 std::streamsize basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::unzip_from_stream(
181 m_zip_stream.next_out = (byte_buffer_type)buffer_;
182 m_zip_stream.avail_out =
static_cast<uInt
>(buffer_size_ *
sizeof(
char_type));
183 size_t count = m_zip_stream.avail_in;
187 if (m_zip_stream.avail_in == 0)
188 count = fill_input_buffer();
190 if (m_zip_stream.avail_in)
191 m_err = inflate(&m_zip_stream, Z_SYNC_FLUSH);
193 if (m_err == Z_STREAM_END)
194 inflateReset(&m_zip_stream);
198 while (m_zip_stream.avail_out > 0 &&
count > 0);
203 if (m_zip_stream.avail_out > 0 && m_err == Z_STREAM_END)
204 put_back_from_zip_stream();
209 template <
typename Elem,
214 size_t basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::fill_input_buffer()
216 m_zip_stream.next_in = &(m_input_buffer[0]);
217 m_istream.read((
char_type *)(&(m_input_buffer[0])),
219 return m_zip_stream.avail_in = m_istream.gcount() *
sizeof(
char_type);
222 template <
typename Elem,
227 void basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT>::put_back_from_zip_stream()
229 if (m_zip_stream.avail_in == 0)
232 m_istream.clear(std::ios::goodbit);
233 m_istream.seekg(-
static_cast<int>(m_zip_stream.avail_in), std::ios_base::cur);
235 m_zip_stream.avail_in = 0;
244 template <
typename Elem,
247 typename ByteT =
unsigned char,
250 class basic_gz_istreambase :
255 typedef basic_gz_istreambuf<Elem, Tr, ElemA, ByteT, ByteAT> unzip_streambuf_type;
257 basic_gz_istreambase(istream_reference ostream_,
259 size_t read_buffer_size_,
260 size_t input_buffer_size_) :
261 m_buf(ostream_, window_size_, read_buffer_size_, input_buffer_size_)
267 unzip_streambuf_type *
rdbuf() {
return &m_buf; }
270 unzip_streambuf_type m_buf;
290 template <
typename Elem,
293 typename ByteT =
unsigned char,
296 class basic_gz_istream :
297 public basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT>,
301 typedef basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT> zip_istreambase_type;
303 typedef istream_type & istream_reference;
304 typedef ByteT byte_type;
305 typedef Tr traits_type;
314 basic_gz_istream(istream_reference istream_,
315 size_t window_size_ = 31,
316 size_t read_buffer_size_ = GZ_INPUT_DEFAULT_BUFFER_SIZE,
317 size_t input_buffer_size_ = GZ_INPUT_DEFAULT_BUFFER_SIZE) :
318 zip_istreambase_type(istream_, window_size_, read_buffer_size_, input_buffer_size_),
319 istream_type(this->rdbuf())
324 void _Add_vtordisp1() {}
325 void _Add_vtordisp2() {}
334 typedef basic_gz_istream<char> gz_istream;
336 typedef basic_gz_istream<wchar_t> gz_wistream;