1#ifndef BTLLIB_SEQ_READER_SAM_MODULE_HPP 
    2#define BTLLIB_SEQ_READER_SAM_MODULE_HPP 
    4#include "btllib/cstring.hpp" 
    5#include "btllib/process_pipeline.hpp" 
    6#include "btllib/seq.hpp" 
    7#include "btllib/status.hpp" 
   16class SeqReaderSamModule
 
   20  friend class SeqReader;
 
   31      loader_thread->join();
 
   35  std::unique_ptr<ProcessPipeline> samtools_process;
 
   36  std::unique_ptr<std::thread> loader_thread;
 
   38  static const size_t LOADER_BLOCK_SIZE = 4096;
 
   40  static bool buffer_valid(
const char* buffer, 
size_t size);
 
   41  template<
typename ReaderType, 
typename RecordType>
 
   42  bool read_buffer(ReaderType& reader, RecordType& record);
 
   43  template<
typename ReaderType, 
typename RecordType>
 
   44  bool read_transition(ReaderType& reader, RecordType& record);
 
   45  template<
typename ReaderType, 
typename RecordType>
 
   46  bool read_file(ReaderType& reader, RecordType& record);
 
   49template<
typename ReaderType, 
typename RecordType>
 
   51SeqReaderSamModule::read_buffer(ReaderType& reader, RecordType& record)
 
   56    const ProcessPipeline version_test(
 
   57      "samtools --version 2>/dev/stdout | head -n2");
 
   60    std::string version = 
"\n";
 
   62    check_error(getline(&line, &n, version_test.out) < 2,
 
   63                "Failed to get samtools version.");
 
   67    check_error(getline(&line, &n, version_test.out) < 2,
 
   68                "Failed to get samtools version.");
 
   75    std::unique_ptr<ProcessPipeline>( 
 
   76      new ProcessPipeline(
"samtools fastq"));
 
   78    std::unique_ptr<std::thread>(
new std::thread([
this, &reader]() {
 
   79      check_error(fwrite(reader.buffer.data.data() + reader.buffer.start,
 
   81                         reader.buffer.end - reader.buffer.start,
 
   82                         samtools_process->in) !=
 
   83                    reader.buffer.end - reader.buffer.start,
 
   84                  "SeqReader SAM module: fwrite failed.");
 
   85      reader.buffer.start = reader.buffer.end;
 
   86      if (std::ferror(reader.source) == 0 && std::feof(reader.source) == 0) {
 
   87        const auto p = std::fgetc(reader.source);
 
   89          const auto ret = std::ungetc(p, reader.source);
 
   90          check_error(ret == EOF, 
"SeqReaderSamModule: ungetc failed.");
 
   91          while (std::ferror(reader.source) == 0 &&
 
   92                 std::feof(reader.source) == 0) {
 
   93            const size_t bufsize = LOADER_BLOCK_SIZE;
 
   95            size_t bytes_read = fread(buf, 1, bufsize, reader.source);
 
   96            check_error(fwrite(buf, 1, bytes_read, samtools_process->in) !=
 
   98                        "SeqReader SAM module: fwrite failed.");
 
  102      samtools_process->close_in();
 
  107template<
typename ReaderType, 
typename RecordType>
 
  109SeqReaderSamModule::read_transition(ReaderType& reader, RecordType& record)
 
  116template<
typename ReaderType, 
typename RecordType>
 
  118SeqReaderSamModule::read_file(ReaderType& reader, RecordType& record)
 
  120  if (!reader.file_at_end(samtools_process->out)) {
 
  121    reader.readline_file(record.header, samtools_process->out);
 
  122    reader.readline_file(record.seq, samtools_process->out);
 
  123    reader.readline_file(tmp, samtools_process->out);
 
  124    reader.readline_file(record.qual, samtools_process->out);
 
void check_error(bool condition, const std::string &msg)
void log_info(const std::string &msg)