cuSBF
Loading...
Searching...
No Matches
Public Member Functions | List of all members
cusbf::detail::FastxBufferReader Class Reference

FASTA/FASTQ parser over a contiguous in-memory buffer. More...

#include <fastx_buffer_reader.hpp>

Public Member Functions

 FastxBufferReader (std::string_view data, std::string_view source_name="<buffer>")
 Constructs a reader over a contiguous in-memory FASTA/FASTQ buffer.
 
Result< boolnextRecord (FastxRecord &record)
 Reads the next record into record.
 
std::string_view buffer () const noexcept
 Entire mmap or owned buffer backing this reader.
 
Result< std::optional< RecordRange > > appendNextRecord (FastxRecord &record, std::string &sequence, std::string_view &buffer)
 Parses one record with optional zero-copy sequence views for single-line FASTA.
 

Detailed Description

FASTA/FASTQ parser over a contiguous in-memory buffer.

Definition at line 112 of file fastx_buffer_reader.hpp.

Constructor & Destructor Documentation

◆ FastxBufferReader()

cusbf::detail::FastxBufferReader::FastxBufferReader ( std::string_view  data,
std::string_view  source_name = "<buffer>" 
)
inlineexplicit

Constructs a reader over a contiguous in-memory FASTA/FASTQ buffer.

Parameters
dataEntire file or chunk payload.
source_nameLabel used in parse error messages.

Definition at line 120 of file fastx_buffer_reader.hpp.

121 : data_(data), source_name_(source_name) {}
consteval bool separatorPositionAlwaysEncodesInvalid(char *input, uint64_t separatorPosition, uint64_t index)
Recursively tests whether placing the separator byte at any position in an input of valid bytes alway...
Definition Alphabet.cuh:37

Member Function Documentation

◆ appendNextRecord()

Result< std::optional< RecordRange > > cusbf::detail::FastxBufferReader::appendNextRecord ( FastxRecord record,
std::string &  sequence,
std::string_view &  buffer 
)
inline

Parses one record with optional zero-copy sequence views for single-line FASTA.

When the sequence fits one mmap line, returns a RecordRange into buffer instead of appending to sequence. Otherwise appends sequence bytes to sequence and returns an owned range offset.

Parameters
recordOutput header (sequence may stay empty on zero-copy path).
sequenceGrowing buffer for multi-line or owned FASTA sequence data.
bufferSet to the full mmap view on first zero-copy record.
Returns
Record byte range, std::nullopt at end-of-buffer, or an error.

Definition at line 188 of file fastx_buffer_reader.hpp.

188 {
189 record.header.clear();
190 record.sequence.clear();
191
192 const auto header = readHeaderLine();
193 if (!header) {
194 return Err(header.error());
195 }
196 if (header->empty()) {
197 return std::nullopt;
198 }
199
200 const char header_tag = header->front();
201 if (format_ == FastxFormat::unknown) {
202 if (header_tag == '>') {
203 format_ = FastxFormat::fasta;
204 } else if (header_tag == '@') {
205 format_ = FastxFormat::fastq;
206 } else {
207 return Err(
208 parseError("expected FASTA or FASTQ header", fastx_column_at(*header, 0))
209 );
210 }
211 }
212
213 const char expected_header = format_ == FastxFormat::fasta ? '>' : '@';
215 return Err(parseError(
216 "mixed FASTA and FASTQ records are not supported", fastx_column_at(*header, 0)
217 ));
218 }
219
220 record.header.assign(header->substr(1));
221 if (format_ == FastxFormat::fasta) {
222 const auto sequence_offset = static_cast<uint64_t>(position_);
223 const std::string_view line = readLine();
224 if (line.empty()) {
225 return Err(parseError("FASTA record missing sequence", fastx_column_at(line, 0)));
226 }
227 if (!line.empty() && line.front() == '>') {
228 return Err(parseError("FASTA record missing sequence", fastx_column_at(line, 0)));
229 }
230
231 if (position_ < data_.size() && data_[position_] != '>') {
232 const auto owned_offset = static_cast<uint64_t>(sequence.size());
233 sequence.append(line.data(), line.size());
234 CUSBF_TRY(readFastaSequence(sequence));
235 return RecordRange{
237 static_cast<uint64_t>(sequence.size()) - owned_offset,
238 };
239 }
240
241 if (buffer.empty()) {
242 buffer = data_;
243 }
244 return RecordRange{sequence_offset, static_cast<uint64_t>(line.size())};
245 }
246
247 const auto sequence_offset = static_cast<uint64_t>(sequence.size());
248 CUSBF_TRY(readFastqSequence(sequence, sequence.size()));
249 return RecordRange{
251 static_cast<uint64_t>(sequence.size()) - sequence_offset,
252 };
253 }
std::string_view buffer() const noexcept
Entire mmap or owned buffer backing this reader.
#define CUSBF_TRY(expr)
Propagates a cusbf::Result failure from the enclosing function (GNU statement expression).
Definition error.hpp:246
uint32_t fastx_column_at(std::string_view line, size_t byte_index)
1-based column at byte_index within line (clamped to the line end).
Definition Fastx.hpp:268
@ fasta
FASTA (> headers).
@ fastq
FASTQ (@ headers).
@ unknown
Format not yet determined from the first header.
cuda::std::unexpected< Error > Err(Error error)
Failure return; converts to any Result<T> via cuda::std::unexpected.
Definition error.hpp:219
Here is the call graph for this function:

◆ buffer()

std::string_view cusbf::detail::FastxBufferReader::buffer ( ) const
inlinenoexcept

Entire mmap or owned buffer backing this reader.

Definition at line 171 of file fastx_buffer_reader.hpp.

171 {
172 return data_;
173 }
Here is the caller graph for this function:

◆ nextRecord()

Result< bool > cusbf::detail::FastxBufferReader::nextRecord ( FastxRecord record)
inline

Reads the next record into record.

Parameters
recordOutput record, cleared before fill.
Returns
false at end-of-buffer, true when a record was read, or an error.

Definition at line 129 of file fastx_buffer_reader.hpp.

129 {
130 record.header.clear();
131 record.sequence.clear();
132
133 const auto header = readHeaderLine();
134 if (!header) {
135 return Err(header.error());
136 }
137 if (header->empty()) {
138 return false;
139 }
140
141 const char header_tag = header->front();
142 if (format_ == FastxFormat::unknown) {
143 if (header_tag == '>') {
144 format_ = FastxFormat::fasta;
145 } else if (header_tag == '@') {
146 format_ = FastxFormat::fastq;
147 } else {
148 return Err(
149 parseError("expected FASTA or FASTQ header", fastx_column_at(*header, 0))
150 );
151 }
152 }
153
154 const char expected_header = format_ == FastxFormat::fasta ? '>' : '@';
156 return Err(parseError(
157 "mixed FASTA and FASTQ records are not supported", fastx_column_at(*header, 0)
158 ));
159 }
160
161 record.header.assign(header->substr(1));
162 if (format_ == FastxFormat::fasta) {
163 CUSBF_TRY(readFastaSequence(record.sequence));
164 } else {
165 CUSBF_TRY(readFastqSequence(record.sequence));
166 }
167 return true;
168 }
Here is the call graph for this function:

The documentation for this class was generated from the following file: