diff --git a/include/seqan3/io/sequence_file/format_embl.hpp b/include/seqan3/io/sequence_file/format_embl.hpp index 5137c3f4a8..79c46bad71 100644 --- a/include/seqan3/io/sequence_file/format_embl.hpp +++ b/include/seqan3/io/sequence_file/format_embl.hpp @@ -105,12 +105,14 @@ class format_embl id_type & id, qual_type & SEQAN3_DOXYGEN_ONLY(qualities)) { + // Store current position in buffer + // Must happen before construction the view. + // With libc++, tellg invalidates the I/O buffer. + position_buffer = stream.tellg(); + auto stream_view = detail::istreambuf(stream); auto stream_it = std::ranges::begin(stream_view); - // Store current position in buffer. - position_buffer = stream.tellg(); - std::string idbuffer; std::ranges::copy(stream_view | detail::take_until_or_throw(is_cntrl || is_blank), std::back_inserter(idbuffer)); diff --git a/include/seqan3/io/sequence_file/format_fasta.hpp b/include/seqan3/io/sequence_file/format_fasta.hpp index 98469ff02d..0f5e11e28e 100755 --- a/include/seqan3/io/sequence_file/format_fasta.hpp +++ b/include/seqan3/io/sequence_file/format_fasta.hpp @@ -117,11 +117,13 @@ class format_fasta id_type & id, qual_type & SEQAN3_DOXYGEN_ONLY(qualities)) { - auto stream_view = detail::istreambuf(stream); - // Store current position in buffer + // Must happen before construction the view. + // With libc++, tellg invalidates the I/O buffer. position_buffer = stream.tellg(); + auto stream_view = detail::istreambuf(stream); + // ID read_id(stream_view, options, id); diff --git a/include/seqan3/io/sequence_file/format_fastq.hpp b/include/seqan3/io/sequence_file/format_fastq.hpp index 4de369a3c4..063bc0031a 100644 --- a/include/seqan3/io/sequence_file/format_fastq.hpp +++ b/include/seqan3/io/sequence_file/format_fastq.hpp @@ -109,6 +109,11 @@ class format_fastq id_type & id, qual_type & qualities) { + // Store current position in buffer + // Must happen before construction the view. + // With libc++, tellg invalidates the I/O buffer. + position_buffer = stream.tellg(); + auto stream_view = detail::istreambuf(stream); auto stream_it = std::ranges::begin(stream_view); @@ -117,7 +122,6 @@ class format_fastq size_t sequence_size_after = 0; if constexpr (!detail::decays_to_ignore_v) sequence_size_before = size(sequence); - position_buffer = stream.tellg(); /* ID */ if (*stream_it != '@') // [[unlikely]] diff --git a/include/seqan3/io/sequence_file/format_genbank.hpp b/include/seqan3/io/sequence_file/format_genbank.hpp index ccfd7c6be1..de25a225b7 100644 --- a/include/seqan3/io/sequence_file/format_genbank.hpp +++ b/include/seqan3/io/sequence_file/format_genbank.hpp @@ -106,12 +106,14 @@ class format_genbank id_type & id, qual_type & SEQAN3_DOXYGEN_ONLY(qualities)) { + // Store current position in buffer + // Must happen before construction the view. + // With libc++, tellg invalidates the I/O buffer. + position_buffer = stream.tellg(); + auto stream_view = detail::istreambuf(stream); auto stream_it = std::ranges::begin(stream_view); - // Store current position in buffer. - position_buffer = stream.tellg(); - if (!(std::ranges::equal(stream_view | detail::take_until_or_throw(is_cntrl || is_blank), std::string{"LOCUS"}))) throw parse_error{"An entry has to start with the code word LOCUS."}; diff --git a/include/seqan3/io/stream/detail/fast_istreambuf_iterator.hpp b/include/seqan3/io/stream/detail/fast_istreambuf_iterator.hpp index 4b3b4fdfc0..be3b7bf87e 100644 --- a/include/seqan3/io/stream/detail/fast_istreambuf_iterator.hpp +++ b/include/seqan3/io/stream/detail/fast_istreambuf_iterator.hpp @@ -229,6 +229,7 @@ class fast_istreambuf_iterator reference operator*() const { assert(stream_buf != nullptr); + assert(stream_buf->gptr() != stream_buf->egptr()); return *stream_buf->gptr(); }