24 #ifdef SEQAN3_HAS_BZIP2
25 #include <seqan3/contrib/stream/bz2_istream.hpp>
27 #ifdef SEQAN3_HAS_ZLIB
28 #include <seqan3/contrib/stream/bgzf_istream.hpp>
30 #include <seqan3/contrib/stream/gz_istream.hpp>
36 namespace seqan3::detail
43 template <std::ranges::forward_range ref_t, std::ranges::forward_range query_t>
44 inline bool starts_with(ref_t && reference, query_t && query)
46 requires std::equality_comparable_with<std::ranges::range_reference_t<ref_t>,
47 std::ranges::range_reference_t<query_t>>
51 auto rend = std::ranges::end(reference);
54 auto qend = std::ranges::end(query);
78 template <builtin_
character
char_t>
82 assert(primary_stream.good());
91 std::array<char, bgzf_compression::magic_header.
size()> magic_number{};
92 size_t read_chars = 0;
93 for (; read_chars < magic_number.size(); ++read_chars)
98 magic_number[read_chars] = *it;
103 for (
size_t i = 0 ; i < read_chars; ++i)
104 primary_stream.unget();
107 if (filename.has_extension())
108 extension = filename.extension().
string().substr(1);
111 [[maybe_unused]]
auto contains_extension = [] (
auto compression_tag,
auto const & extension) constexpr
113 return std::ranges::find(decltype(compression_tag)::file_extensions, extension) !=
114 std::ranges::end(decltype(compression_tag)::file_extensions);
118 if (read_chars == magic_number.size() && bgzf_compression::validate_header(
std::span{magic_number}))
120 #ifdef SEQAN3_HAS_ZLIB
121 if (contains_extension(gz_compression{}, extension) || contains_extension(bgzf_compression{}, extension))
122 filename.replace_extension();
124 return {
new contrib::basic_bgzf_istream<char_t>{primary_stream},
125 stream_deleter_default};
127 throw file_open_error{
"Trying to read from a bgzf file, but no ZLIB available."};
130 else if (starts_with(magic_number, gz_compression::magic_header))
132 #ifdef SEQAN3_HAS_ZLIB
133 if (contains_extension(gz_compression{}, extension) || contains_extension(bgzf_compression{}, extension))
134 filename.replace_extension();
136 return {
new contrib::basic_gz_istream<char_t>{primary_stream}, stream_deleter_default};
138 throw file_open_error{
"Trying to read from a gzipped file, but no ZLIB available."};
141 else if (starts_with(magic_number, bz2_compression::magic_header))
143 #ifdef SEQAN3_HAS_BZIP2
144 if (contains_extension(bz2_compression{}, extension))
145 filename.replace_extension();
147 return {
new contrib::basic_bz2_istream<char_t>{primary_stream}, stream_deleter_default};
149 throw file_open_error{
"Trying to read from a bzipped file, but no libbz2 available."};
152 else if (starts_with(magic_number, zstd_compression::magic_header))
154 throw file_open_error{
"Trying to read from a zst'ed file, but SeqAn does not yet support this."};
157 return {&primary_stream, stream_deleter_noop};
161 template <builtin_
character
char_t>
165 return make_secondary_istream(primary_stream, p);
Adaptations of algorithms from the Ranges TS.
Provides stream compression utilities.
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
This header includes C++17 filesystem support and imports it into namespace std::filesystem (independ...
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition: traits.hpp:187
Provides exceptions used in the I/O module.
Adaptations of concepts from the Ranges TS.
Provides std::span from the C++20 standard library.