X-Git-Url: https://git.donarmstrong.com/?p=bamtools.git;a=blobdiff_plain;f=src%2Fapi%2Finternal%2FBamHeader_p.cpp;fp=src%2Fapi%2Finternal%2FBamHeader_p.cpp;h=7ec1181703a07c8e7ad48bd4c2cf5b3c1f12d6f6;hp=45dc379f52327c6cc9a77d232e1b53a9b83bd56e;hb=8a90b7aefffaf186053ef4da96c8663bf528274a;hpb=c1fc1c5423ca73a1b5bcbe790650821d73e5959c diff --git a/src/api/internal/BamHeader_p.cpp b/src/api/internal/BamHeader_p.cpp index 45dc379..7ec1181 100644 --- a/src/api/internal/BamHeader_p.cpp +++ b/src/api/internal/BamHeader_p.cpp @@ -2,24 +2,37 @@ // BamHeader_p.cpp (c) 2010 Derek Barnett // Marth Lab, Department of Biology, Boston College // --------------------------------------------------------------------------- -// Last modified: 21 March 2011 (DB) +// Last modified: 7 October 2011 (DB) // --------------------------------------------------------------------------- // Provides the basic functionality for handling BAM headers. // *************************************************************************** #include #include +#include #include #include using namespace BamTools; using namespace BamTools::Internal; -#include #include #include -#include using namespace std; +// ------------------------ +// static utility methods +// ------------------------ + +static inline +bool isValidMagicNumber(const char* buffer) { + return ( strncmp(buffer, Constants::BAM_HEADER_MAGIC, + Constants::BAM_HEADER_MAGIC_LENGTH) == 0 ); +} + +// -------------------------- +// BamHeader implementation +// -------------------------- + // ctor BamHeader::BamHeader(void) { } @@ -27,23 +40,17 @@ BamHeader::BamHeader(void) { } BamHeader::~BamHeader(void) { } // reads magic number from BGZF stream, returns true if valid -bool BamHeader::CheckMagicNumber(BgzfStream* stream) { +void BamHeader::CheckMagicNumber(BgzfStream* stream) { // try to read magic number char buffer[Constants::BAM_HEADER_MAGIC_LENGTH]; - if ( stream->Read(buffer, Constants::BAM_HEADER_MAGIC_LENGTH) != Constants::BAM_HEADER_MAGIC_LENGTH ) { - fprintf(stderr, "BamHeader ERROR: could not read magic number\n"); - return false; - } + const size_t numBytesRead = stream->Read(buffer, Constants::BAM_HEADER_MAGIC_LENGTH); + if ( numBytesRead != (int)Constants::BAM_HEADER_MAGIC_LENGTH ) + throw BamException("BamHeader::CheckMagicNumber", "could not read magic number"); // validate magic number - if ( strncmp(buffer, Constants::BAM_HEADER_MAGIC, Constants::BAM_HEADER_MAGIC_LENGTH) != 0 ) { - fprintf(stderr, "BamHeader ERROR: invalid magic number\n"); - return false; - } - - // all checks out - return true; + if ( !isValidMagicNumber(buffer) ) + throw BamException("BamHeader::CheckMagicNumber", "invalid magic number"); } // clear SamHeader data @@ -57,68 +64,49 @@ bool BamHeader::IsValid(void) const { } // load BAM header ('magic number' and SAM header text) from BGZF stream -// returns true if all OK -bool BamHeader::Load(BgzfStream* stream) { +void BamHeader::Load(BgzfStream* stream) { - // cannot load if invalid stream - if ( stream == 0 ) - return false; + // read & check magic number + CheckMagicNumber(stream); - // cannot load if magic number is invalid - if ( !CheckMagicNumber(stream) ) - return false; - - // cannot load header if cannot read header length + // read header (length, then actual text) uint32_t length(0); - if ( !ReadHeaderLength(stream, length) ) - return false; - - // cannot load header if cannot read header text - if ( !ReadHeaderText(stream, length) ) - return false; - - // otherwise, everything OK - return true; + ReadHeaderLength(stream, length); + ReadHeaderText(stream, length); } // reads SAM header text length from BGZF stream, stores it in @length -// returns read success/fail status -bool BamHeader::ReadHeaderLength(BgzfStream* stream, uint32_t& length) { +void BamHeader::ReadHeaderLength(BgzfStream* stream, uint32_t& length) { - // attempt to read BAM header text length + // read BAM header text length char buffer[sizeof(uint32_t)]; - if ( stream->Read(buffer, sizeof(uint32_t)) != sizeof(uint32_t) ) { - fprintf(stderr, "BamHeader ERROR: could not read header length\n"); - return false; - } + const size_t numBytesRead = stream->Read(buffer, sizeof(uint32_t)); + if ( numBytesRead != sizeof(uint32_t) ) + throw BamException("BamHeader::ReadHeaderLength", "could not read header length"); - // convert char buffer to length, return success + // convert char buffer to length length = BamTools::UnpackUnsignedInt(buffer); if ( BamTools::SystemIsBigEndian() ) BamTools::SwapEndian_32(length); - return true; } // reads SAM header text from BGZF stream, stores in SamHeader object -// returns read success/fail status -bool BamHeader::ReadHeaderText(BgzfStream* stream, const uint32_t& length) { +void BamHeader::ReadHeaderText(BgzfStream* stream, const uint32_t& length) { - // set up destination buffer + // read header text char* headerText = (char*)calloc(length + 1, 1); + const size_t bytesRead = stream->Read(headerText, length); - // attempt to read header text - const unsigned bytesRead = stream->Read(headerText, length); - const bool readOk = ( bytesRead == length ); - if ( readOk ) - m_header.SetHeaderText( (string)((const char*)headerText) ); - else - fprintf(stderr, "BamHeader ERROR: could not read header text\n"); + // if error reading, clean up buffer & throw + if ( bytesRead != length ) { + free(headerText); + throw BamException("BamHeader::ReadHeaderText", "could not read header text"); + } - // clean up calloc-ed temp variable (on success or fail) + // otherwise, text was read OK + // store & cleanup + m_header.SetHeaderText( (string)((const char*)headerText) ); free(headerText); - - // return read success - return readOk; } // returns *copy* of SamHeader data object