SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
bz2_istream.hpp
1// SPDX-FileCopyrightText: 2003 Jonathan de Halleux
2// SPDX-License-Identifier: Zlib
3// bzip2stream Library License:
4// --------------------------
5//
6// The zlib/libpng License Copyright (c) 2003 Jonathan de Halleux.
7//
8// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
9//
10// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
11//
12// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
13//
14// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15//
16// 3. This notice may not be removed or altered from any source distribution
17//
18// Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003
19// Altered bzip2_stream header
20// Author: Hannes Hauswedell <hannes.hauswedell@fu-berlin.de>
21
22#pragma once
23
24#include <algorithm>
25#include <cstring>
26#include <iostream>
27#include <vector>
28
29#if !defined(SEQAN3_HAS_BZIP2) && !defined(SEQAN3_HEADER_TEST)
30#error "This file cannot be used when building without BZIP2-support."
31#endif // !defined(SEQAN3_HAS_BZIP2) && !defined(SEQAN3_HEADER_TEST)
32
33#if defined(SEQAN3_HAS_BZIP2)
34
35#define BZ_NO_STDIO
36#include <bzlib.h>
37
38namespace seqan3::contrib
39{
40
41// --------------------------------------------------------------------------
42// Class basic_bz2_istreambuf
43// --------------------------------------------------------------------------
44
45const size_t BZ2_INPUT_DEFAULT_BUFFER_SIZE = 4096;
46
47template<
48 typename Elem,
49 typename Tr = std::char_traits<Elem>,
50 typename ElemA = std::allocator<Elem>,
51 typename ByteT = char,
52 typename ByteAT = std::allocator<ByteT>
53>
54class basic_bz2_istreambuf :
55 public std::basic_streambuf<Elem, Tr>
56{
57public:
58 typedef std::basic_istream<Elem, Tr>& istream_reference;
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 typename Tr::char_type char_type;
64 typedef typename Tr::int_type int_type;
65 typedef std::vector<byte_type, byte_allocator_type > byte_vector_type;
66 typedef std::vector<char_type, char_allocator_type > char_vector_type;
67
68 basic_bz2_istreambuf(
69 istream_reference istream_,
70 size_t verbosity_,
71 bool small_,
72 size_t read_buffer_size_,
73 size_t input_buffer_size_
74 );
75
76 ~basic_bz2_istreambuf();
77
78 int_type underflow();
79
80 istream_reference get_istream() { return m_istream;};
81 bz_stream& get_bzip2_stream() { return m_bzip2_stream;};
82 int get_zerr() const { return m_err;};
83private:
84 std::streamsize unbzip2_from_stream( char_type*, std::streamsize);
85 void put_back_from_bzip2_stream();
86 size_t fill_input_buffer();
87
88 istream_reference m_istream;
89 bz_stream m_bzip2_stream;
90 int m_err;
91 byte_vector_type m_input_buffer;
92 char_vector_type m_buffer;
93};
94
95// --------------------------------------------------------------------------
96// Class basic_bz2_istreambuf implementation
97// --------------------------------------------------------------------------
98
99template<
100 typename Elem,
101 typename Tr,
102 typename ElemA,
103 typename ByteT,
104 typename ByteAT
105>
106basic_bz2_istreambuf<
107 Elem,Tr,ElemA,ByteT,ByteAT
108 >::basic_bz2_istreambuf(
109 istream_reference istream_,
110 size_t verbosity_,
111 bool small_,
112 size_t read_buffer_size_,
113 size_t input_buffer_size_
114)
115:
116 m_istream(istream_),
117 m_input_buffer(input_buffer_size_),
118 m_buffer(read_buffer_size_)
119{
120 // setting zalloc, zfree and opaque
121 m_bzip2_stream.bzalloc=NULL;
122 m_bzip2_stream.bzfree=NULL;
123
124 m_bzip2_stream.next_in=NULL;
125 m_bzip2_stream.avail_in=0;
126 m_bzip2_stream.avail_out=0;
127 m_bzip2_stream.next_out=NULL;
128
129
130 m_err=BZ2_bzDecompressInit (
131 &m_bzip2_stream,
132 std::min(4, static_cast<int>(verbosity_)),
133 static_cast<int>(small_)
134 );
135
136 this->setg(
137 &(m_buffer[0])+4, // beginning of putback area
138 &(m_buffer[0])+4, // read position
139 &(m_buffer[0])+4); // end position
140}
141
142template<
143 typename Elem,
144 typename Tr,
145 typename ElemA,
146 typename ByteT,
147 typename ByteAT
148>
149size_t basic_bz2_istreambuf<
150 Elem,Tr,ElemA,ByteT,ByteAT
151 >::fill_input_buffer()
152{
153 m_bzip2_stream.next_in=&(m_input_buffer[0]);
154 m_istream.read(
155 (char_type*)(&(m_input_buffer[0])),
156 static_cast<std::streamsize>(m_input_buffer.size()/sizeof(char_type))
157 );
158 return m_bzip2_stream.avail_in=m_istream.gcount()*sizeof(char_type);
159}
160
161template<
162 typename Elem,
163 typename Tr,
164 typename ElemA,
165 typename ByteT,
166 typename ByteAT
167>
168void basic_bz2_istreambuf<
169 Elem,Tr,ElemA,ByteT,ByteAT
170 >::put_back_from_bzip2_stream()
171{
172 if (m_bzip2_stream.avail_in==0)
173 return;
174
175 m_istream.clear( std::ios::goodbit );
176 m_istream.seekg(
177 -static_cast<int>(m_bzip2_stream.avail_in),
178 std::ios_base::cur
179 );
180
181 m_bzip2_stream.avail_in=0;
182}
183
184
185template<
186 typename Elem,
187 typename Tr,
188 typename ElemA,
189 typename ByteT,
190 typename ByteAT
191>
192basic_bz2_istreambuf<
193 Elem,Tr,ElemA,ByteT,ByteAT
194 >::~basic_bz2_istreambuf()
195{
196 BZ2_bzDecompressEnd(&m_bzip2_stream);
197}
198
199template<
200 typename Elem,
201 typename Tr,
202 typename ElemA,
203 typename ByteT,
204 typename ByteAT
205>
206typename basic_bz2_istreambuf<
207 Elem,Tr,ElemA,ByteT,ByteAT
208 >::int_type
209 basic_bz2_istreambuf<
210 Elem,Tr,ElemA,ByteT,ByteAT
211 >::underflow()
212{
213 if ( this->gptr() && ( this->gptr() < this->egptr()))
214 return * reinterpret_cast<unsigned char *>( this->gptr());
215
216 int n_putback = static_cast<int>(this->gptr() - this->eback());
217 if ( n_putback > 4)
218 n_putback = 4;
220 &(m_buffer[0]) + (4 - n_putback),
221 this->gptr() - n_putback,
222 n_putback*sizeof(char_type)
223 );
224
225 int num = unbzip2_from_stream(
226 &(m_buffer[0])+4,
227 static_cast<std::streamsize>((m_buffer.size()-4)*sizeof(char_type))
228 );
229 if (num <= 0) // ERROR or EOF
230 return EOF;
231
232 // reset buffer pointers
233 this->setg(
234 &(m_buffer[0]) + (4 - n_putback), // beginning of putback area
235 &(m_buffer[0]) + 4, // read position
236 &(m_buffer[0]) + 4 + num); // end of buffer
237
238 // return next character
239 return* reinterpret_cast<unsigned char *>( this->gptr());
240 }
241
242
243template<
244 typename Elem,
245 typename Tr,
246 typename ElemA,
247 typename ByteT,
248 typename ByteAT
249>
250std::streamsize basic_bz2_istreambuf<
251 Elem,Tr,ElemA,ByteT,ByteAT
252 >::unbzip2_from_stream(
253 char_type* buffer_,
254 std::streamsize buffer_size_
255 )
256{
257 m_bzip2_stream.next_out=(byte_buffer_type)buffer_;
258 m_bzip2_stream.avail_out=buffer_size_*sizeof(char_type);
259 size_t count =m_bzip2_stream.avail_in;
260
261 do
262 {
263 if (m_bzip2_stream.avail_in==0)
264 count=fill_input_buffer();
265
266 if (m_bzip2_stream.avail_in)
267 {
268 m_err = BZ2_bzDecompress( &m_bzip2_stream );
269 }
270 } while (m_err==BZ_OK && m_bzip2_stream.avail_out != 0 && count != 0);
271
272 if (m_err == BZ_STREAM_END)
273 put_back_from_bzip2_stream();
274
275 return buffer_size_ - m_bzip2_stream.avail_out/sizeof(char_type);
276}
277
278// --------------------------------------------------------------------------
279// Class basic_bz2_istreambase
280// --------------------------------------------------------------------------
281
282template<
283 typename Elem,
284 typename Tr = std::char_traits<Elem>,
285 typename ElemA = std::allocator<Elem>,
286 typename ByteT = char,
287 typename ByteAT = std::allocator<ByteT>
288>
289class basic_bz2_istreambase : virtual public std::basic_ios<Elem,Tr>
290{
291public:
292 typedef std::basic_istream<Elem, Tr>& istream_reference;
293 typedef basic_bz2_istreambuf<
294 Elem,Tr,ElemA,ByteT,ByteAT> unbzip2_streambuf_type;
295
296 basic_bz2_istreambase(
297 istream_reference ostream_,
298 size_t verbosity_,
299 bool small_,
300 size_t read_buffer_size_,
301 size_t input_buffer_size_
302 )
303 : m_buf(
304 ostream_,
305 verbosity_,
306 small_,
307 read_buffer_size_,
308 input_buffer_size_
309 )
310 {
311 this->init(&m_buf );
312 };
313
314 unbzip2_streambuf_type* rdbuf() { return &m_buf; };
315
316private:
317 unbzip2_streambuf_type m_buf;
318};
319
320// --------------------------------------------------------------------------
321// Class basic_bz2_istream
322// --------------------------------------------------------------------------
323
324template<
325 typename Elem,
326 typename Tr = std::char_traits<Elem>,
327 typename ElemA = std::allocator<Elem>,
328 typename ByteT = char,
329 typename ByteAT = std::allocator<ByteT>
330>
331class basic_bz2_istream :
332 public basic_bz2_istreambase<Elem,Tr,ElemA,ByteT,ByteAT>,
333 public std::basic_istream<Elem,Tr>
334{
335public:
336 typedef basic_bz2_istreambase<
337 Elem,Tr,ElemA,ByteT,ByteAT> bzip2_istreambase_type;
338 typedef std::basic_istream<Elem,Tr> istream_type;
339 typedef istream_type& istream_reference;
340 typedef unsigned char byte_type;
341
342 basic_bz2_istream(
343 istream_reference istream_,
344 size_t verbosity_ = 0,
345 bool small_ = false,
346 size_t read_buffer_size_ = BZ2_INPUT_DEFAULT_BUFFER_SIZE,
347 size_t input_buffer_size_ = BZ2_INPUT_DEFAULT_BUFFER_SIZE
348 )
349 :
350 bzip2_istreambase_type(istream_,verbosity_, small_, read_buffer_size_, input_buffer_size_),
351 istream_type(bzip2_istreambase_type::rdbuf())
352 {};
353#ifdef _WIN32
354private:
355 void _Add_vtordisp1() { } // Required to avoid VC++ warning C4250
356 void _Add_vtordisp2() { } // Required to avoid VC++ warning C4250
357#endif
358};
359
360// --------------------------------------------------------------------------
361// typedefs
362// --------------------------------------------------------------------------
363
364typedef basic_bz2_istream<char> bz2_istream;
365typedef basic_bz2_istream<wchar_t> bz2_wistream;
366
367} // namespace seqan3::contrib
368
369#endif // defined(SEQAN3_HAS_BZIP2)
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161
T init(T... args)
T memmove(T... args)
T min(T... args)
T rdbuf(T... args)
Hide me