btllib
seq_reader_fasta_module.hpp
1#ifndef BTLLIB_SEQ_READER_FASTA_MODULE_HPP
2#define BTLLIB_SEQ_READER_FASTA_MODULE_HPP
3
4#include "btllib/status.hpp"
5
6#include <cstdlib>
7
8namespace btllib {
9
11class SeqReaderFastaModule
12{
13
14private:
15 friend class SeqReader;
16
17 enum class Stage
18 {
19 HEADER,
20 SEQ
21 };
22
23 Stage stage = Stage::HEADER;
24
25 static bool buffer_valid(const char* buffer, size_t size);
26 template<typename ReaderType, typename RecordType>
27 bool read_buffer(ReaderType& reader, RecordType& record);
28 template<typename ReaderType, typename RecordType>
29 bool read_transition(ReaderType& reader, RecordType& record);
30 template<typename ReaderType, typename RecordType>
31 bool read_file(ReaderType& reader, RecordType& record);
32};
33
34template<typename ReaderType, typename RecordType>
35inline bool
36SeqReaderFastaModule::read_buffer(ReaderType& reader, RecordType& record)
37{
38 record.header.clear();
39 record.seq.clear();
40 record.qual.clear();
41 if (reader.buffer.start < reader.buffer.end) {
42 switch (stage) {
43 case Stage::HEADER: {
44 if (!reader.readline_buffer_append(record.header)) {
45 return false;
46 }
47 stage = Stage::SEQ;
48 }
49 // fall through
50 case Stage::SEQ: {
51 if (!reader.readline_buffer_append(record.seq)) {
52 return false;
53 }
54 stage = Stage::HEADER;
55 return true;
56 }
57 default: {
58 log_error("SeqReader has entered an invalid state.");
59 std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe)
60 }
61 }
62 }
63 return false;
64}
65
66template<typename ReaderType, typename RecordType>
67inline bool
68SeqReaderFastaModule::read_transition(ReaderType& reader, RecordType& record)
69{
70 if (std::ferror(reader.source) == 0 && std::feof(reader.source) == 0) {
71 const auto p = std::fgetc(reader.source);
72 if (p != EOF) {
73 std::ungetc(p, reader.source);
74 switch (stage) {
75 case Stage::HEADER: {
76 reader.readline_file_append(record.header, reader.source);
77 stage = Stage::SEQ;
78 }
79 // fall through
80 case Stage::SEQ: {
81 reader.readline_file_append(record.seq, reader.source);
82 stage = Stage::HEADER;
83 return true;
84 }
85 default: {
86 log_error("SeqReader has entered an invalid state.");
87 std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe)
88 }
89 }
90 }
91 }
92 return false;
93}
94
95template<typename ReaderType, typename RecordType>
96inline bool
97SeqReaderFastaModule::read_file(ReaderType& reader, RecordType& record)
98{
99 if (!reader.file_at_end(reader.source)) {
100 reader.readline_file(record.header, reader.source);
101 reader.readline_file(record.seq, reader.source);
102 return true;
103 }
104 return false;
105}
107
108} // namespace btllib
109
110#endif
Definition: bloom_filter.hpp:16
void log_error(const std::string &msg)