btllib
Loading...
Searching...
No Matches
seq_reader_fastq_module.hpp
1#ifndef BTLLIB_SEQ_READER_FASTQ_MODULE_HPP
2#define BTLLIB_SEQ_READER_FASTQ_MODULE_HPP
3
4#include "btllib/cstring.hpp"
5#include "btllib/status.hpp"
6
7#include <cstdlib>
8
9namespace btllib {
10
12class SeqReaderFastqModule
13{
14
15private:
16 friend class SeqReader;
17
18 enum class Stage
19 {
20 HEADER,
21 SEQ,
22 SEP,
23 QUAL
24 };
25
26 Stage stage = Stage::HEADER;
27 CString tmp;
28
29 static bool buffer_valid(const char* buffer, size_t size);
30 template<typename ReaderType, typename RecordType>
31 bool read_buffer(ReaderType& reader, RecordType& record);
32 template<typename ReaderType, typename RecordType>
33 bool read_transition(ReaderType& reader, RecordType& record);
34 template<typename ReaderType, typename RecordType>
35 bool read_file(ReaderType& reader, RecordType& record);
36};
37
38template<typename ReaderType, typename RecordType>
39inline bool
40SeqReaderFastqModule::read_buffer(ReaderType& reader, RecordType& record)
41{
42 record.header.clear();
43 record.seq.clear();
44 record.qual.clear();
45 if (reader.buffer.start < reader.buffer.end) {
46 switch (stage) {
47 case Stage::HEADER: {
48 if (!reader.readline_buffer_append(record.header)) {
49 return false;
50 }
51 stage = Stage::SEQ;
52 }
53 // fall through
54 case Stage::SEQ: {
55 if (!reader.readline_buffer_append(record.seq)) {
56 return false;
57 }
58 stage = Stage::SEP;
59 }
60 // fall through
61 case Stage::SEP: {
62 if (!reader.readline_buffer_append(tmp)) {
63 return false;
64 }
65 stage = Stage::QUAL;
66 tmp.clear();
67 }
68 // fall through
69 case Stage::QUAL: {
70 if (!reader.readline_buffer_append(record.qual)) {
71 return false;
72 }
73 stage = Stage::HEADER;
74 return true;
75 }
76 default: {
77 log_error("SeqReader has entered an invalid state.");
78 std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe)
79 }
80 }
81 }
82 return false;
83}
84
85template<typename ReaderType, typename RecordType>
86inline bool
87SeqReaderFastqModule::read_transition(ReaderType& reader, RecordType& record)
88{
89 if (std::ferror(reader.source) == 0 && std::feof(reader.source) == 0) {
90 const auto p = std::fgetc(reader.source);
91 if (p != EOF) {
92 const auto ret = std::ungetc(p, reader.source);
93 check_error(ret == EOF, "SeqReaderFastqModule: ungetc failed.");
94 switch (stage) {
95 case Stage::HEADER: {
96 reader.readline_file_append(record.header, reader.source);
97 stage = Stage::SEQ;
98 }
99 // fall through
100 case Stage::SEQ: {
101 reader.readline_file_append(record.seq, reader.source);
102 stage = Stage::SEP;
103 }
104 // fall through
105 case Stage::SEP: {
106 reader.readline_file_append(tmp, reader.source);
107 stage = Stage::QUAL;
108 tmp.clear();
109 }
110 // fall through
111 case Stage::QUAL: {
112 reader.readline_file_append(record.qual, reader.source);
113 stage = Stage::HEADER;
114 return true;
115 }
116 default: {
117 log_error("SeqReader has entered an invalid state.");
118 std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe)
119 }
120 }
121 }
122 }
123 return false;
124}
125
126template<typename ReaderType, typename RecordType>
127inline bool
128SeqReaderFastqModule::read_file(ReaderType& reader, RecordType& record)
129{
130 if (!reader.file_at_end(reader.source)) {
131 reader.readline_file(record.header, reader.source);
132 reader.readline_file(record.seq, reader.source);
133 reader.readline_file(tmp, reader.source);
134 reader.readline_file(record.qual, reader.source);
135 return true;
136 }
137 return false;
138}
140
141} // namespace btllib
142
143#endif
Definition aahash.hpp:12
void check_error(bool condition, const std::string &msg)
void log_error(const std::string &msg)