Skip to content

Commit

Permalink
update sam docu
Browse files Browse the repository at this point in the history
  • Loading branch information
smehringer committed Feb 22, 2022
1 parent e13c5c0 commit e6f581e
Showing 1 changed file with 89 additions and 36 deletions.
125 changes: 89 additions & 36 deletions include/bio/format/sam_input_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,75 @@
namespace bio
{

/*!\brief Format input handler for the SAM format (bio::sam).
* \ingroup format
* \details
*
* ### Attention
*
* Most users should not perform I/O through input/output handlers but should instead use the respective
* readers/writers. See the overview (TODO link) for more information.
*
* ### Options
*
* The following options are considered if the respective member variable is availabele in the object passed to
* the constructor:
*
* | Member | Type | Default | Description |
* |-----------------|---------|---------|------------------------------------------------------------------|
* |`print_warnings` |`bool` | `false` | Whether to print non-critical warnings to seqan3::debug_stream |
*
*/
template <>
class format_input_handler<sam> : public format_input_handler_base<format_input_handler<sam>>
{
private:
/* CRTP */
/*!\name CRTP related entities
* \{
*/
//!\brief The type of the CRTP base class.
using base_t = format_input_handler_base<format_input_handler<sam>>;
using base_t::parse_field;
using base_t::parse_field_aux;
using base_t::stream;

//!\brief Befriend the base class to enable CRTP.
friend base_t;
//!\}

//!\brief Default field handlers.
using base_t::parse_field;
using base_t::parse_field_aux;
/*!\name Options
* \{
*/
//!\brief Whether to print warnings or not.
bool print_warnings = true;
//!\}

//!\brief Throw a bio::format_error with an error message with current line number in diagnostic.
[[noreturn]] void error(auto const &... messages) const
{
std::string message = "[B.I.O sam format error in line " + detail::to_string(line) + "] ";
((message += detail::to_string(messages)), ...);

throw format_error{message};
}

//!\brief Print a B.I.O warning message with current line number in diagnostic.
/* [[noreturn]] compiler says this returns something...? */ void warning(auto const &... messages) const
{
if (print_warnings)
{
seqan3::debug_stream << "[B.I.O sam format warning in line " << line << "] ";
(seqan3::debug_stream << ... << messages);
seqan3::debug_stream << std::endl;
}
}

/* RAW RECORD HANDLING*/
/*!\name Raw record handling
* \{
*/
//!\brief The fields that this format supports [the base class accesses this type].
using format_fields = decltype(map_io::default_field_ids);
//!\brief Type of the raw record.
using raw_record_type = bio::record<format_fields,
seqan3::list_traits::repeat<format_fields::size, std::string_view>>;

Expand All @@ -69,27 +122,8 @@ class format_input_handler<sam> : public format_input_handler_base<format_input_
int32_t last_rname_idx = -1;
//!\brief Current line number in file.
size_t line = 0;
//!\brief Whether to print print_warnings or not.
bool print_warnings = true;

[[noreturn]] void error(auto const &... messages) const
{
std::string message = "[B.I.O sam format error in line " + detail::to_string(line) + "] ";
((message += detail::to_string(messages)), ...);

throw format_error{message};
}

/* [[noreturn]] compiler says this returns something...? */ void warning(auto const &... messages) const
{
if (print_warnings)
{
seqan3::debug_stream << "[B.I.O sam format warning in line " << line << "] ";
(seqan3::debug_stream << ... << messages);
seqan3::debug_stream << std::endl;
}
}

//!\brief Read the raw record [the base class invokes this function].
void read_raw_record()
{
++line;
Expand All @@ -116,9 +150,12 @@ class format_input_handler<sam> : public format_input_handler_base<format_input_
// SAM tags go from end of qual til end of line (possibly empty)
get<field::tags>(raw_record) = std::string_view{end_qual, static_cast<size_t>(end_line - end_qual)};
}
//!\}

/* PARSED RECORD HANDLING */

/*!\name Parsed record handling
* \brief This is mostly done via the defaults in the base class.
* \{
*/
//!\brief Overload for parsing QNAME.
template <typename parsed_field_t>
void parse_field(vtag_t<field::qname> const & /**/, parsed_field_t & parsed_field)
Expand Down Expand Up @@ -264,18 +301,29 @@ class format_input_handler<sam> : public format_input_handler_base<format_input_
{
parsed_field = map_io::record_private_data{.header_ptr = &header};
}
//!\}

public:
format_input_handler() = default;
format_input_handler(format_input_handler const &) = delete;
format_input_handler(format_input_handler &&) = default;
format_input_handler & operator=(format_input_handler const &) = delete;
format_input_handler & operator=(format_input_handler &&) = default;

/*!\name Constructors, destructor and assignment.
* \{
*/
format_input_handler() = default; //!< Defaulted.
format_input_handler(format_input_handler const &) = delete; //!< Deleted.
format_input_handler(format_input_handler &&) = default; //!< Defaulted.
~format_input_handler() = default; //!< Defaulted.
format_input_handler & operator=(format_input_handler const &) = delete; //!< Deleted.
format_input_handler & operator=(format_input_handler &&) = default; //!< Defaulted.

/*!\brief Construct with an options object.
* \param[in,out] str The input stream.
* \param[in] options An object with options for the input handler.
* \details
*
* The options argument is typically bio::map_io::reader_options, but any object with a subset of similarly named
* members is also accepted. See bio::format_input_handler<vcf> for the supported options and defaults.
*/
template <typename options_t>
format_input_handler(std::istream & str, options_t const & options) :
base_t{str},
file_it{str, false /*no_init!*/}
format_input_handler(std::istream & str, options_t const & options) : base_t{str}, file_it{str, false /*no_init!*/}
{
// extract options
if constexpr (requires { (bool)options.print_warnings; })
Expand All @@ -296,6 +344,11 @@ class format_input_handler<sam> : public format_input_handler_base<format_input_
header.read(header_string);
}

//!\brief Construct with only an input stream.
format_input_handler(std::istream & str) : format_input_handler{str, int{}} {}
//!\}

//!\brief Return a reference to the header contained in the input handler.
auto const & get_header() const { return header; }
};

Expand Down

0 comments on commit e6f581e

Please sign in to comment.