1 // ***************************************************************************
2 // BamHeader_p.cpp (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 21 March 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides the basic functionality for handling BAM headers.
8 // ***************************************************************************
10 #include <api/BamAux.h>
11 #include <api/BamConstants.h>
12 #include <api/internal/BamHeader_p.h>
13 #include <api/internal/BgzfStream_p.h>
14 using namespace BamTools;
15 using namespace BamTools::Internal;
24 BamHeader::BamHeader(void) { }
27 BamHeader::~BamHeader(void) { }
29 // reads magic number from BGZF stream, returns true if valid
30 bool BamHeader::CheckMagicNumber(BgzfStream* stream) {
32 // try to read magic number
33 char buffer[Constants::BAM_HEADER_MAGIC_LENGTH];
34 if ( stream->Read(buffer, Constants::BAM_HEADER_MAGIC_LENGTH) != (int)Constants::BAM_HEADER_MAGIC_LENGTH ) {
35 fprintf(stderr, "BamHeader ERROR: could not read magic number\n");
39 // validate magic number
40 if ( strncmp(buffer, Constants::BAM_HEADER_MAGIC, Constants::BAM_HEADER_MAGIC_LENGTH) != 0 ) {
41 fprintf(stderr, "BamHeader ERROR: invalid magic number\n");
49 // clear SamHeader data
50 void BamHeader::Clear(void) {
54 // return true if SamHeader data is valid
55 bool BamHeader::IsValid(void) const {
56 return m_header.IsValid();
59 // load BAM header ('magic number' and SAM header text) from BGZF stream
60 // returns true if all OK
61 bool BamHeader::Load(BgzfStream* stream) {
63 // cannot load if invalid stream
67 // cannot load if magic number is invalid
68 if ( !CheckMagicNumber(stream) )
71 // cannot load header if cannot read header length
73 if ( !ReadHeaderLength(stream, length) )
76 // cannot load header if cannot read header text
77 if ( !ReadHeaderText(stream, length) )
80 // otherwise, everything OK
84 // reads SAM header text length from BGZF stream, stores it in @length
85 // returns read success/fail status
86 bool BamHeader::ReadHeaderLength(BgzfStream* stream, uint32_t& length) {
88 // attempt to read BAM header text length
89 char buffer[sizeof(uint32_t)];
90 if ( stream->Read(buffer, sizeof(uint32_t)) != sizeof(uint32_t) ) {
91 fprintf(stderr, "BamHeader ERROR: could not read header length\n");
95 // convert char buffer to length, return success
96 length = BamTools::UnpackUnsignedInt(buffer);
97 if ( BamTools::SystemIsBigEndian() )
98 BamTools::SwapEndian_32(length);
102 // reads SAM header text from BGZF stream, stores in SamHeader object
103 // returns read success/fail status
104 bool BamHeader::ReadHeaderText(BgzfStream* stream, const uint32_t& length) {
106 // set up destination buffer
107 char* headerText = (char*)calloc(length + 1, 1);
109 // attempt to read header text
110 const unsigned bytesRead = stream->Read(headerText, length);
111 const bool readOk = ( bytesRead == length );
113 m_header.SetHeaderText( (string)((const char*)headerText) );
115 fprintf(stderr, "BamHeader ERROR: could not read header text\n");
117 // clean up calloc-ed temp variable (on success or fail)
120 // return read success
124 // returns *copy* of SamHeader data object
125 SamHeader BamHeader::ToSamHeader(void) const {
129 // returns SAM-formatted string of header data
130 string BamHeader::ToString(void) const {
131 return m_header.ToString();