1#ifndef BTLLIB_SEQ_READER_MULTILINE_FASTA_MODULE_HPP
2#define BTLLIB_SEQ_READER_MULTILINE_FASTA_MODULE_HPP
4#include "btllib/cstring.hpp"
5#include "btllib/status.hpp"
12class SeqReaderMultilineFastaModule
16 friend class SeqReader;
25 Stage stage = Stage::HEADER;
27 static bool buffer_valid(
const char* buffer,
size_t size);
28 template<
typename ReaderType,
typename RecordType>
29 bool read_buffer(ReaderType& reader, RecordType& record);
30 template<
typename ReaderType,
typename RecordType>
31 bool read_transition(ReaderType& reader, RecordType& record);
32 template<
typename ReaderType,
typename RecordType>
33 bool read_file(ReaderType& reader, RecordType& record);
36template<
typename ReaderType,
typename RecordType>
38SeqReaderMultilineFastaModule::read_buffer(ReaderType& reader,
41 record.header.clear();
44 if (reader.buffer.start < reader.buffer.end) {
49 if (!reader.readline_buffer_append(record.header)) {
56 if (!reader.readline_buffer_append(record.seq)) {
60 stage = Stage::TRANSITION;
63 case Stage::TRANSITION: {
64 c = reader.getc_buffer();
68 reader.ungetc_buffer(c);
70 stage = Stage::HEADER;
77 log_error(
"SeqReader has entered an invalid state.");
78 std::exit(EXIT_FAILURE);
86template<
typename ReaderType,
typename RecordType>
88SeqReaderMultilineFastaModule::read_transition(ReaderType& reader,
91 if (std::ferror(reader.source) == 0 && std::feof(reader.source) == 0) {
92 const auto p = std::fgetc(reader.source);
94 const auto ret = std::ungetc(p, reader.source);
95 check_error(ret == EOF,
"SeqReaderMultilineFastaModule: ungetc failed.");
100 reader.readline_file_append(record.header, reader.source);
105 reader.readline_file_append(record.seq, reader.source);
107 stage = Stage::TRANSITION;
110 case Stage::TRANSITION: {
111 c = std::fgetc(reader.source);
115 const auto ret = std::ungetc(c, reader.source);
117 "SeqReaderMultilineFastaModule: ungetc failed.");
119 stage = Stage::HEADER;
126 log_error(
"SeqReader has entered an invalid state.");
127 std::exit(EXIT_FAILURE);
136template<
typename ReaderType,
typename RecordType>
138SeqReaderMultilineFastaModule::read_file(ReaderType& reader, RecordType& record)
140 if (!reader.file_at_end(reader.source)) {
141 reader.readline_file(record.header, reader.source);
143 reader.readline_file(record.seq, reader.source);
146 c = std::fgetc(reader.source);
150 const auto ret = std::ungetc(c, reader.source);
151 check_error(ret == EOF,
"SeqReaderMultilineFastaModule: ungetc failed.");
155 reader.readline_file_append(record.seq, reader.source);
void check_error(bool condition, const std::string &msg)
void rtrim(std::string &s)
void log_error(const std::string &msg)