btllib
Loading...
Searching...
No Matches
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 const auto ret = std::ungetc(p, reader.source);
74 check_error(ret == EOF, "SeqReaderFastaModule: ungetc failed.");
75 switch (stage) {
76 case Stage::HEADER: {
77 reader.readline_file_append(record.header, reader.source);
78 stage = Stage::SEQ;
79 }
80 // fall through
81 case Stage::SEQ: {
82 reader.readline_file_append(record.seq, reader.source);
83 stage = Stage::HEADER;
84 return true;
85 }
86 default: {
87 log_error("SeqReader has entered an invalid state.");
88 std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe)
89 }
90 }
91 }
92 }
93 return false;
94}
95
96template<typename ReaderType, typename RecordType>
97inline bool
98SeqReaderFastaModule::read_file(ReaderType& reader, RecordType& record)
99{
100 if (!reader.file_at_end(reader.source)) {
101 reader.readline_file(record.header, reader.source);
102 reader.readline_file(record.seq, reader.source);
103 return true;
104 }
105 return false;
106}
108
109} // namespace btllib
110
111#endif
Definition aahash.hpp:12
void check_error(bool condition, const std::string &msg)
void log_error(const std::string &msg)