/*!
* @class BamStream
*
* @headerfile <seqan/bam_io.h>
*
* @brief Class that provides an easy to use interface for reading and writing
* SAM and BAM files.
*
* @signature class BamStream;
*
* @section Example
*
* Read and write SAM or BAM files.
*
* @include demos/bam_io/bam_stream.cpp
*
* The output is as follows:
*
* @include demos/bam_io/bam_stream.cpp.stdout
*
* @see BamStream::Format
* @see BamStream::OperationMode
*
* @fn BamStream::BamStream
*
* @brief Constructor
*
* @signature BamStream::BamStream([fileName[, mode[, format]]]);
*
* @param[in] fileName The path to the SAM or BAM file to load, <tt>char const
* *</tt>.
* @param[in] mode The open mode, of type @link BamStream::OperationMode
* @endlink, defaults to <tt>READ</tt>.
* @param[in] format The format, of type @link BamStream::Format @endlink,
* defaults to <tt>AUTO</tt>.
*
* @var THeader BamStream::header;
*
* @brief The @link BamHeader @endlink of the @link BamStream @endlink object.
*
* SAM and BAM files have a header. When writing SAM or BAM files, you have to
* fill this member before writing @link BamAlignmentRecord @endlinks. Upon
* writing the first record, the header will be written out.
*
* When reading BAM files, the header will be read upon opening the file. When
* reading SAM files, any header will be read upon opening the file.
*
* Note that there is a special case when reading SAM records: If there is no
* header, or records refer to reference sequences that are previously unknown
* when reading SAM then a new entry is added to @link BamHeader::sequenceInfos
* @endlink.
*
* @var TBamIOContext BamStream::bamIOContext;
*
* @brief The @link BamIOContext @endlink object to use for reading and writing
* @link BamAlignmentRecord @endlinks.
*
* When reading, the <tt>bamIOContext</tt> will be updated automatically. When
* reading SAM, new reference sequences can be introduced "on the fly" when a
* new sequence appears. When writing, the <tt>bamIOContext</tt> is
* automatically filled/reset when the first record is written.
*
* @fn BamStream#open
*
* @brief Open a @link BamStream @endlink object for reading/writing.
*
* @signature int open(bamIO, fileName[, mode[, format]]);
*
* @param[in,out] bamIO The @link BamStream @endlink object to open. Types:
* BamStream
* @param[in] fileName The path to the file to open, <tt>char const *</tt>.
* @param[in] mode The mode to open the file in, optional, of type @link
* BamStream::OperationMode @endlink, defaults to
* <tt>BamStream::READ</tt>.
* @param[in] format The format to use, inferred from file contents (reading) or
* file name (writing) by default. the path to the file to
* open, of type @link BamStream::Format @endlink, defaults to
* <tt>AUTO</tt>.
*
* @return int A status code, 0 on success, a value <tt>!= 0</tt> on errors.
*
* @fn BamStream#flush
*
* @brief Flush output when writing.
*
* @signature int flush(stream);
*
* @param[in,out] stream The @link BamStream @endlink object to flush.
*
* @return int A status code, 0 on success, <tt>!= 0</tt> on errors.
*
* @section Remarks
*
* This will write out the header if no record has been written out yet.
*
* @fn BamStream#close
*
* @brief Close BamStream object's underlying file.
*
* @signature int close(stream);
*
* @param[in,out] stream The @link BamStream @endlink object to close.
*
* @return int A status code, 0 on success, <tt>!= 0</tt> on error.
*
* @fn BamStream#atEnd
*
* @brief Check whether a @link BamStream @endlink object is at end when
* reading.
*
* @signature bool atEnd(stream);
*
* @param[in] stream The @link BamStream @endlink object to query.
*
* @return bool true in case of the stream being at the end, false otherwise.
*
* @section Remarks
*
* The stream will only be guaranteed at the end after trying to read
* <b>after</b> the last character.
*
* @fn BamStream#isGood
*
* @brief Check whether the @link BamStream @endlink object has is in the
* failure state.
*
* @signature bool isGood(stream);
*
* @param[in] stream The @link BamStream @endlink object to query.
*
* @return bool true if the stream is not in an error state and false otherwise.
*
* @fn BamStream#readRecord
*
* @brief Read one @link BamAlignmentRecord @endlink from a @link BamStream
* @endlink.
*
* @signature int readRecord(record, stream);
*
* @param[out] record The @link BamAlignmentRecord @endlink to read the next
* alignment record into. Of type @link BamAlignmentRecord
* @endlink.
* @param[in,out] stream The @link BamStream @endlink object to read from.
*
* @return int A status code, 0 on success.
*
* @fn BamStream#writeRecord
*
* @brief Write one @link BamAlignmentRecord @endlink to a @link BamStream
* @endlink.
*
* @signature int writeRecord(stream, record);
*
* @param[in,out] bamIO The @link BamStream @endlink object to write to.
* @param[in] record The @link BamAlignmentRecord @endlink to write out.
*
* @return int A status code, 0 on success.
*
* @fn BamStream#fileSize
*
* @brief Returns the size of the file in bytes as stored on the disk.
*
* @signature __int64 fileSize(stream);
*
* @param[in] stream The @link BamStream @endlink to query.
*
* @return __int64 The size of the file on the disk.
*
* @section Remarks
*
* This only works when reading.
*
* @fn BamStream#positionInFile
*
* @brief Approximate byte position in file, to be used for progress display,
* not for seeking.
*
* @signature __int64 positionInFile(stream);
*
* @param[in] stream The @link BamStream @endlink to query for its position in
* the file.
*
* @return __int64 The position in the file.
*
* @section Remarks
*
* This function returns the "approximate" position in the file and only works
* when the file is opened in BAM format. It is meant for progress display in
* connection with @link BamStream#fileSize @endlink and not for jumping within
* the file. The position is approximate in the sense that it points between the
* block boundaries of the BGZ file.
*
* @fn BamStream#jumpToRegion
*
* @brief Seek in BamStream using an index.
*
* @signature bool jumpToRegion(stream, hasAlignments, bamIOContext, refID, pos,
* posEnd, index);
*
* @param[in,out] stream The @link BamStream @endlink to jump with.
* @param[out] hasAlignments A <tt>bool</tt> that is set true if the region
* <tt>[pos, posEnd)</tt> has any alignments.
* @param[in] refID The reference id to jump to (<tt>__int32</tt>).
* @param[in] pos The begin of the region to jump to (<tt>__int32</tt>).
* @param[in] posEnd The end of the region to jump to (<tt>__int32</tt>).
* @param[in] index The @link BamIndex @endlink to use for the jumping.
*
* @return bool true if seeking was successful, false if not.
*
* You provide a region <tt>[pos, posEnd)</tt> on the reference <tt>refID</tt>
* that you want to jump to and the function jumps to the first alignment in
* this region, if any.
*
* @section Remarks
*
* This function fails if <tt>refID</tt>/<tt>pos</tt> are invalid.
*
* @see BamIndex#jumpToRegion
*
* @fn BamStream#jumpToOrphans
*
* @brief Seek to orphans block in BamStream using an index.
*
* @signature bool jumpToOrphans(stream, hasAlignments, index);
*
* @param[in,out] stream The @link BgzfStream @endlink object to jump with.
* @param[out] hasAlignments A <tt>bool</tt> that is set to true if there are
* any orphans.
* @param[in] index The index to use for jumping.
*
* @see BamIndex#jumpToOrphans
*/