X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2Fapi%2Finternal%2FBamWriter_p.cpp;h=8f6c30d5558780240c9b65f0d363d8de3be0081a;hb=cdf4bbcb19025398d429035fe672661a8c8d1a80;hp=7147a33ff654918e720cd4ea9acf0036083a5213;hpb=9cf50963514decd5c272f52a0a019c6289d43c63;p=bamtools.git diff --git a/src/api/internal/BamWriter_p.cpp b/src/api/internal/BamWriter_p.cpp index 7147a33..8f6c30d 100644 --- a/src/api/internal/BamWriter_p.cpp +++ b/src/api/internal/BamWriter_p.cpp @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 21 March 2011 (DB) +// Last modified: 19 April 2011 (DB) // --------------------------------------------------------------------------- // Provides the basic functionality for producing BAM files // *************************************************************************** @@ -70,6 +70,8 @@ void BamWriterPrivate::CreatePackedCigar(const vector& cigarOperations, case (Constants::BAM_CIGAR_SOFTCLIP_CHAR) : cigarOp = Constants::BAM_CIGAR_SOFTCLIP; break; case (Constants::BAM_CIGAR_HARDCLIP_CHAR) : cigarOp = Constants::BAM_CIGAR_HARDCLIP; break; case (Constants::BAM_CIGAR_PAD_CHAR) : cigarOp = Constants::BAM_CIGAR_PAD; break; + case (Constants::BAM_CIGAR_SEQMATCH_CHAR) : cigarOp = Constants::BAM_CIGAR_SEQMATCH; break; + case (Constants::BAM_CIGAR_MISMATCH_CHAR) : cigarOp = Constants::BAM_CIGAR_MISMATCH; break; default: fprintf(stderr, "BamWriter ERROR: unknown cigar operation found: %c\n", coIter->Type); exit(1); @@ -241,8 +243,10 @@ void BamWriterPrivate::SaveAlignment(const BamAlignment& al) { if ( m_isBigEndian ) { char* cigarData = (char*)calloc(sizeof(char), packedCigarLength); memcpy(cigarData, packedCigar.data(), packedCigarLength); - for (unsigned int i = 0; i < packedCigarLength; ++i) - if (m_isBigEndian) BamTools::SwapEndian_32p(&cigarData[i]); + if ( m_isBigEndian ) { + for ( unsigned int i = 0; i < packedCigarLength; ++i ) + BamTools::SwapEndian_32p(&cigarData[i]); + } m_stream.Write(cigarData, packedCigarLength); free(cigarData); } @@ -254,7 +258,7 @@ void BamWriterPrivate::SaveAlignment(const BamAlignment& al) { // write the base qualities char* pBaseQualities = (char*)al.Qualities.data(); - for(unsigned int i = 0; i < queryLength; i++) + for ( unsigned int i = 0; i < queryLength; i++ ) pBaseQualities[i] -= 33; // FASTQ conversion m_stream.Write(pBaseQualities, queryLength); @@ -295,11 +299,56 @@ void BamWriterPrivate::SaveAlignment(const BamAlignment& al) { case(Constants::BAM_TAG_TYPE_HEX) : case(Constants::BAM_TAG_TYPE_STRING) : // no endian swapping necessary for hex-string/string data - while (tagData[i]) { ++i; } + while ( tagData[i] ) + ++i; // increment one more for null terminator ++i; break; + case(Constants::BAM_TAG_TYPE_ARRAY) : + + { + // read array type + const char arrayType = tagData[i]; + ++i; + + // swap endian-ness of number of elements in place, then retrieve for loop + BamTools::SwapEndian_32p(&tagData[i]); + int32_t numElements; + memcpy(&numElements, &tagData[i], sizeof(uint32_t)); + i += sizeof(uint32_t); + + // swap endian-ness of array elements + for ( int j = 0; j < numElements; ++j ) { + switch (arrayType) { + case (Constants::BAM_TAG_TYPE_INT8) : + case (Constants::BAM_TAG_TYPE_UINT8) : + // no endian-swapping necessary + ++i; + break; + case (Constants::BAM_TAG_TYPE_INT16) : + case (Constants::BAM_TAG_TYPE_UINT16) : + BamTools::SwapEndian_16p(&tagData[i]); + i += sizeof(uint16_t); + break; + case (Constants::BAM_TAG_TYPE_FLOAT) : + case (Constants::BAM_TAG_TYPE_INT32) : + case (Constants::BAM_TAG_TYPE_UINT32) : + BamTools::SwapEndian_32p(&tagData[i]); + i += sizeof(uint32_t); + break; + default: + // error case + fprintf(stderr, + "BamWriter ERROR: unknown binary array type encountered: [%c]\n", + arrayType); + exit(1); + } + } + + break; + } + default : fprintf(stderr, "BamWriter ERROR: invalid tag value type\n"); // shouldn't get here free(tagData); @@ -368,6 +417,6 @@ void BamWriterPrivate::WriteSamHeaderText(const std::string& samHeaderText) { m_stream.Write((char*)&samHeaderLen, Constants::BAM_SIZEOF_INT); // write the SAM header text - if (samHeaderLen > 0) + if ( samHeaderLen > 0 ) m_stream.Write(samHeaderText.data(), samHeaderLen); }