diff --git a/src/api/internal/bam/BamReader_p.cpp b/src/api/internal/bam/BamReader_p.cpp index de430cfa..76faa636 100644 --- a/src/api/internal/bam/BamReader_p.cpp +++ b/src/api/internal/bam/BamReader_p.cpp @@ -248,28 +248,34 @@ void BamReaderPrivate::LoadHeaderData() static inline int bam_aux_type2size(int x) { - if (x == 'C' || x == 'c' || x == 'A') return 1; - else if (x == 'S' || x == 's') return 2; - else if (x == 'I' || x == 'i' || x == 'f') return 4; - else return 0; + if (x == 'C' || x == 'c' || x == 'A') + return 1; + else if (x == 'S' || x == 's') + return 2; + else if (x == 'I' || x == 'i' || x == 'f') + return 4; + else + return 0; } -static unsigned char *bam_aux_get(int aux_data_len, const unsigned char *aux_start, const char *tag) +static unsigned char* bam_aux_get(int aux_data_len, const unsigned char* aux_start, const char* tag) { - const unsigned char *p = aux_start; + const unsigned char* p = aux_start; while (p < aux_start + aux_data_len) { if (p[0] == tag[0] && p[1] == tag[1]) return (unsigned char*)(p + 2); - p += 2; // skip tag - int type = *p++; // read type + p += 2; // skip tag + int type = *p++; // read type if (type == 'B') { - int size = bam_aux_type2size(*p++); // read array type - unsigned len = (unsigned)p[0] | (unsigned)p[1]<<8 | (unsigned)p[2]<<16 | (unsigned)p[3]<<24; - p += 4; // skip the size field - p += len * size; // skip array + int size = bam_aux_type2size(*p++); // read array type + unsigned len = + (unsigned)p[0] | (unsigned)p[1] << 8 | (unsigned)p[2] << 16 | (unsigned)p[3] << 24; + p += 4; // skip the size field + p += len * size; // skip array } else if (type == 'Z' || type == 'H') { - while (*p++ != 0) {} // skip NULL terminated string + while (*p++ != 0) { + } // skip NULL terminated string } else { - p += bam_aux_type2size(type); // skip value + p += bam_aux_type2size(type); // skip value } } return NULL; @@ -277,28 +283,31 @@ static unsigned char *bam_aux_get(int aux_data_len, const unsigned char *aux_sta static inline int hts_reg2bin(int64_t beg, int64_t end, int min_shift, int n_lvls) { - int l, s = min_shift, t = ((1<<((n_lvls<<1) + n_lvls)) - 1) / 7; - for (--end, l = n_lvls; l > 0; --l, s += 3, t -= 1<<((l<<1)+l)) - if (beg>>s == end>>s) return t + (beg>>s); + int l, s = min_shift, t = ((1 << ((n_lvls << 1) + n_lvls)) - 1) / 7; + for (--end, l = n_lvls; l > 0; --l, s += 3, t -= 1 << ((l << 1) + l)) + if (beg >> s == end >> s) return t + (beg >> s); return 0; } -bool BamReaderPrivate::Tag2Cigar(BamAlignment &a, RaiiBuffer &buf) +bool BamReaderPrivate::Tag2Cigar(BamAlignment& a, RaiiBuffer& buf) { if (a.RefID < 0 || a.Position < 0 || a.SupportData.NumCigarOperations == 0) return false; - const unsigned char *data = (const unsigned char*)buf.Buffer; + const unsigned char* data = (const unsigned char*)buf.Buffer; const unsigned data_len = a.SupportData.BlockLength - Constants::BAM_CORE_SIZE; - const unsigned char *p = data + a.SupportData.QueryNameLength; // the original CIGAR - unsigned cigar1 = (unsigned)p[0] | (unsigned)p[1]<<8 | (unsigned)p[2]<<16 | (unsigned)p[3]<<24; - if ((cigar1&0xf) != 4 || cigar1>>4 != a.SupportData.QuerySequenceLength) return false; + const unsigned char* p = data + a.SupportData.QueryNameLength; // the original CIGAR + unsigned cigar1 = + (unsigned)p[0] | (unsigned)p[1] << 8 | (unsigned)p[2] << 16 | (unsigned)p[3] << 24; + if ((cigar1 & 0xf) != 4 || cigar1 >> 4 != a.SupportData.QuerySequenceLength) return false; const int seq_offset = a.SupportData.QueryNameLength + a.SupportData.NumCigarOperations * 4; - const int aux_offset = seq_offset + (a.SupportData.QuerySequenceLength + 1) / 2 + a.SupportData.QuerySequenceLength; - unsigned char *CG = bam_aux_get(data_len - aux_offset, data + aux_offset, "CG"); + const int aux_offset = seq_offset + (a.SupportData.QuerySequenceLength + 1) / 2 + + a.SupportData.QuerySequenceLength; + unsigned char* CG = bam_aux_get(data_len - aux_offset, data + aux_offset, "CG"); if (CG == NULL || CG[0] != 'B' || CG[1] != 'I') return false; - const unsigned tag_cigar_len = (unsigned)CG[2] | (unsigned)CG[3]<<8 | (unsigned)CG[4]<<16 | (unsigned)CG[5]<<24; + const unsigned tag_cigar_len = + (unsigned)CG[2] | (unsigned)CG[3] << 8 | (unsigned)CG[4] << 16 | (unsigned)CG[5] << 24; if (tag_cigar_len == 0) return false; // recalculate bin, as it may be incorrect if it was calculated by a tool unaware of the real CIGAR in tag @@ -306,10 +315,10 @@ bool BamReaderPrivate::Tag2Cigar(BamAlignment &a, RaiiBuffer &buf) unsigned alignment_end = a.Position; p = data + tag_cigar_offset; for (unsigned i = 0; i < tag_cigar_len * 4; i += 4, p += 4) { - unsigned cigar1 = (unsigned)p[0] | (unsigned)p[1]<<8 | (unsigned)p[2]<<16 | (unsigned)p[3]<<24; + unsigned cigar1 = + (unsigned)p[0] | (unsigned)p[1] << 8 | (unsigned)p[2] << 16 | (unsigned)p[3] << 24; int op = cigar1 & 0xf; - if (op == 0 || op == 2 || op == 3 || op == 7 || op == 8) - alignment_end += cigar1 >> 4; + if (op == 0 || op == 2 || op == 3 || op == 7 || op == 8) alignment_end += cigar1 >> 4; } a.Bin = hts_reg2bin(a.Position, alignment_end, 14, 5); @@ -317,11 +326,12 @@ bool BamReaderPrivate::Tag2Cigar(BamAlignment &a, RaiiBuffer &buf) int fake_bytes = a.SupportData.NumCigarOperations * 4; std::string new_data; new_data.reserve(data_len - 8 - fake_bytes + 1); - new_data.append((char*)data, a.SupportData.QueryNameLength); // query name - new_data.append((char*)data + tag_cigar_offset, tag_cigar_len * 4); // real CIGAR - new_data.append((char*)data + seq_offset, tag_cigar_offset - 8 - seq_offset); // seq, qual and tags before CG + new_data.append((char*)data, a.SupportData.QueryNameLength); // query name + new_data.append((char*)data + tag_cigar_offset, tag_cigar_len * 4); // real CIGAR + new_data.append((char*)data + seq_offset, + tag_cigar_offset - 8 - seq_offset); // seq, qual and tags before CG const unsigned tag_cigar_end_offset = tag_cigar_offset + tag_cigar_len * 4; - if (tag_cigar_end_offset < data_len) // tags after CG, if there is any + if (tag_cigar_end_offset < data_len) // tags after CG, if there is any new_data.append((char*)data + tag_cigar_end_offset, data_len - tag_cigar_end_offset); // update member variables @@ -382,8 +392,7 @@ bool BamReaderPrivate::LoadNextAlignment(BamAlignment& alignment) if (m_stream.Read(allCharData.Buffer, dataLength) == dataLength) { int OldNumCigarOperations = alignment.SupportData.NumCigarOperations; - if (Tag2Cigar(alignment, allCharData)) - dataLength -= 8 + OldNumCigarOperations * 4; + if (Tag2Cigar(alignment, allCharData)) dataLength -= 8 + OldNumCigarOperations * 4; // store 'allCharData' in supportData structure alignment.SupportData.AllCharData.assign((const char*)allCharData.Buffer, dataLength); diff --git a/src/api/internal/bam/BamReader_p.h b/src/api/internal/bam/BamReader_p.h index 655228be..48dea89e 100644 --- a/src/api/internal/bam/BamReader_p.h +++ b/src/api/internal/bam/BamReader_p.h @@ -53,7 +53,7 @@ class BamReaderPrivate // access alignment data bool GetNextAlignment(BamAlignment& alignment); bool GetNextAlignmentCore(BamAlignment& alignment); - bool Tag2Cigar(BamAlignment &alignment, RaiiBuffer &buf); + bool Tag2Cigar(BamAlignment& alignment, RaiiBuffer& buf); // access auxiliary data std::string GetHeaderText() const; diff --git a/src/api/internal/bam/BamWriter_p.cpp b/src/api/internal/bam/BamWriter_p.cpp index 978bde73..95097771 100644 --- a/src/api/internal/bam/BamWriter_p.cpp +++ b/src/api/internal/bam/BamWriter_p.cpp @@ -295,8 +295,7 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al) queryLength + // here referring to quality length tagDataLength; unsigned int blockSize = Constants::BAM_CORE_SIZE + dataBlockSize; - if (numCigarOperations >= 65536) - blockSize += 16; + if (numCigarOperations >= 65536) blockSize += 16; if (m_isBigEndian) BamTools::SwapEndian_32(blockSize); m_stream.Write((char*)&blockSize, Constants::BAM_SIZEOF_INT); @@ -305,7 +304,7 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al) buffer[0] = al.RefID; buffer[1] = al.Position; buffer[2] = (alignmentBin << 16) | (al.MapQuality << 8) | nameLength; - buffer[3] = (al.AlignmentFlag << 16) | (numCigarOperations < 65536? numCigarOperations : 2); + buffer[3] = (al.AlignmentFlag << 16) | (numCigarOperations < 65536 ? numCigarOperations : 2); buffer[4] = queryLength; buffer[5] = al.MateRefID; buffer[6] = al.MatePosition; @@ -333,9 +332,8 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al) BamTools::SwapEndian_32p(&cigarData[i]); } m_stream.Write(cigarData, packedCigarLength); - delete[] cigarData; // TODO: cleanup on Write exception thrown? - } - else + delete[] cigarData; // TODO: cleanup on Write exception thrown? + } else m_stream.Write(packedCigar.data(), packedCigarLength); } else { unsigned int cigar[2]; @@ -467,21 +465,21 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al) if (numCigarOperations >= 65536) { m_stream.Write("CGBI", 4); - if ( m_isBigEndian ) { + if (m_isBigEndian) { unsigned int cigar_len_buf = numCigarOperations; BamTools::SwapEndian_32(cigar_len_buf); m_stream.Write((char*)&cigar_len_buf, 4); char* cigarData = new char[packedCigarLength](); memcpy(cigarData, packedCigar.data(), packedCigarLength); - if ( m_isBigEndian ) { - for ( size_t i = 0; i < packedCigarLength; ++i ) // FIXME: similarly, this should be "i += 4", not "++i" + if (m_isBigEndian) { + for (size_t i = 0; i < packedCigarLength; + ++i) // FIXME: similarly, this should be "i += 4", not "++i" BamTools::SwapEndian_32p(&cigarData[i]); } m_stream.Write(cigarData, packedCigarLength); - delete[] cigarData; // TODO: cleanup on Write exception thrown? - } - else { + delete[] cigarData; // TODO: cleanup on Write exception thrown? + } else { m_stream.Write((char*)&numCigarOperations, 4); m_stream.Write(packedCigar.data(), packedCigarLength); } @@ -493,8 +491,7 @@ void BamWriterPrivate::WriteCoreAlignment(const BamAlignment& al) // write the block size unsigned int blockSize = al.SupportData.BlockLength; - if (al.SupportData.NumCigarOperations >= 65536) - blockSize += 16; + if (al.SupportData.NumCigarOperations >= 65536) blockSize += 16; if (m_isBigEndian) BamTools::SwapEndian_32(blockSize); m_stream.Write((char*)&blockSize, Constants::BAM_SIZEOF_INT); @@ -506,7 +503,8 @@ void BamWriterPrivate::WriteCoreAlignment(const BamAlignment& al) buffer[0] = al.RefID; buffer[1] = al.Position; buffer[2] = (alignmentBin << 16) | (al.MapQuality << 8) | al.SupportData.QueryNameLength; - buffer[3] = (al.AlignmentFlag << 16) | (al.SupportData.NumCigarOperations < 65536? al.SupportData.NumCigarOperations : 2); + buffer[3] = (al.AlignmentFlag << 16) | + (al.SupportData.NumCigarOperations < 65536 ? al.SupportData.NumCigarOperations : 2); buffer[4] = al.SupportData.QuerySequenceLength; buffer[5] = al.MateRefID; buffer[6] = al.MatePosition; @@ -526,7 +524,7 @@ void BamWriterPrivate::WriteCoreAlignment(const BamAlignment& al) m_stream.Write((char*)al.SupportData.AllCharData.data(), al.SupportData.BlockLength - Constants::BAM_CORE_SIZE); } else { - const char *data = al.SupportData.AllCharData.c_str(); + const char* data = al.SupportData.AllCharData.c_str(); const unsigned data_len = al.SupportData.BlockLength - Constants::BAM_CORE_SIZE; const unsigned cigar_offset = al.SupportData.QueryNameLength; const unsigned seq_offset = cigar_offset + al.SupportData.NumCigarOperations * 4;