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,
47 typename Tr = std::char_traits<Elem>,
48 typename ElemA = std::allocator<Elem>,
49 typename ByteT =
unsigned char,
50 typename ByteAT = std::allocator<ByteT>
52 class basic_gz_istreambuf :
53 public std::basic_streambuf<Elem, Tr>
56 typedef std::basic_istream<Elem, Tr> & istream_reference;
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;
64 typedef std::vector<byte_type, byte_allocator_type> byte_vector_type;
65 typedef std::vector<char_type, char_allocator_type> char_vector_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();
85 std::streamsize unzip_from_stream(char_type *, std::streamsize);
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,
158 static_cast<std::streamsize
>((m_buffer.size() - 4) *
sizeof(
char_type)));
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(
179 std::streamsize buffer_size_)
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);
200 std::streamsize n_read = buffer_size_ - m_zip_stream.avail_out /
sizeof(
char_type);
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])),
218 static_cast<std::streamsize
>(m_input_buffer.size() /
sizeof(
char_type)));
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,
245 typename Tr = std::char_traits<Elem>,
246 typename ElemA = std::allocator<Elem>,
247 typename ByteT =
unsigned char,
248 typename ByteAT = std::allocator<ByteT>
250 class basic_gz_istreambase :
251 virtual public std::basic_ios<Elem, Tr>
254 typedef std::basic_istream<Elem, Tr> & istream_reference;
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,
291 typename Tr = std::char_traits<Elem>,
292 typename ElemA = std::allocator<Elem>,
293 typename ByteT =
unsigned char,
294 typename ByteAT = std::allocator<ByteT>
296 class basic_gz_istream :
297 public basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT>,
298 public std::basic_istream<Elem, Tr>
301 typedef basic_gz_istreambase<Elem, Tr, ElemA, ByteT, ByteAT> zip_istreambase_type;
302 typedef std::basic_istream<Elem, Tr> istream_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;
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:169
typename stream::char_type char_type
Declares the associated char type.