-/*! \fn bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const std::string& value)
- \brief Adds a field with string data to the BAM tags.
-
- Does NOT modify an existing tag - use \link BamAlignment::EditTag() \endlink instead.
-
- \param tag 2-character tag name
- \param type 1-character tag type (must be "Z" or "H")
- \param value string data to store
-
- \return \c true if the \b new tag was added successfully
-
- \sa http://samtools.sourceforge.net/SAM-1.3.pdf
- for more details on reserved tag names, supported tag types, etc.
-*/
-bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const std::string& value) {
-
- // skip if core data not parsed
- if ( SupportData.HasCoreOnly ) return false;
-
- // validate tag/type size & that type is OK for string value
- if ( !Internal::IsValidSize(tag, type) ) return false;
- if ( type.at(0) != Constants::BAM_TAG_TYPE_STRING &&
- type.at(0) != Constants::BAM_TAG_TYPE_HEX )
- return false;
-
- // localize the tag data
- char* pTagData = (char*)TagData.data();
- const unsigned int tagDataLength = TagData.size();
- unsigned int numBytesParsed = 0;
-
- // if tag already exists, return false
- // use EditTag explicitly instead
- if ( Internal::FindTag(tag, pTagData, tagDataLength, numBytesParsed) )
- return false;
-
- // otherwise, copy tag data to temp buffer
- string newTag = tag + type + value;
- const int newTagDataLength = tagDataLength + newTag.size() + 1; // leave room for null-term
- char originalTagData[newTagDataLength];
- memcpy(originalTagData, TagData.c_str(), tagDataLength + 1); // '+1' for TagData null-term
-
- // append newTag
- strcat(originalTagData + tagDataLength, newTag.data()); // removes original null-term, appends newTag + null-term
-
- // store temp buffer back in TagData
- const char* newTagData = (const char*)originalTagData;
- TagData.assign(newTagData, newTagDataLength);
-
- // return success
- return true;
-}
-
-/*! \fn bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const uint32_t& value)
- \brief Adds a field with unsigned integer data to the BAM tags.
-
- Does NOT modify an existing tag - use \link BamAlignment::EditTag() \endlink instead.
-
- \param tag 2-character tag name
- \param type 1-character tag type (must NOT be "f", "Z", or "H")
- \param value unsigned int data to store
-
- \return \c true if the \b new tag was added successfully
- \sa http://samtools.sourceforge.net/SAM-1.3.pdf
- for more details on reserved tag names, supported tag types, etc.
-*/
-bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const uint32_t& value) {
-
- // skip if core data not parsed
- if ( SupportData.HasCoreOnly ) return false;
-
- // validate tag/type size & that type is OK for uint32_t value
- if ( !Internal::IsValidSize(tag, type) ) return false;
- if ( type.at(0) == Constants::BAM_TAG_TYPE_FLOAT ||
- type.at(0) == Constants::BAM_TAG_TYPE_STRING ||
- type.at(0) == Constants::BAM_TAG_TYPE_HEX )
- return false;
-
- // localize the tag data
- char* pTagData = (char*)TagData.data();
- const unsigned int tagDataLength = TagData.size();
- unsigned int numBytesParsed = 0;
-
- // if tag already exists, return false
- // use EditTag explicitly instead
- if ( Internal::FindTag(tag, pTagData, tagDataLength, numBytesParsed) )
- return false;
-
- // otherwise, convert value to string
- union { uint32_t value; char valueBuffer[sizeof(uint32_t)]; } un;
- un.value = value;
-
- // copy original tag data to temp buffer
- string newTag = tag + type;
- const int newTagDataLength = tagDataLength + newTag.size() + 4; // leave room for new integer
- char originalTagData[newTagDataLength];
- memcpy(originalTagData, TagData.c_str(), tagDataLength + 1); // '+1' for TagData null-term
-
- // append newTag
- strcat(originalTagData + tagDataLength, newTag.data());
- memcpy(originalTagData + tagDataLength + newTag.size(), un.valueBuffer, sizeof(uint32_t));
-
- // store temp buffer back in TagData
- const char* newTagData = (const char*)originalTagData;
- TagData.assign(newTagData, newTagDataLength);
-
- // return success
- return true;
-}
-
-/*! \fn bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const int32_t& value)
- \brief Adds a field with signed integer data to the BAM tags.
-
- Does NOT modify an existing tag - use \link BamAlignment::EditTag() \endlink instead.
-
- \param tag 2-character tag name
- \param type 1-character tag type (must NOT be "f", "Z", or "H")
- \param value signed int data to store
-
- \return \c true if the \b new tag was added successfully
-
- \sa http://samtools.sourceforge.net/SAM-1.3.pdf
- for more details on reserved tag names, supported tag types, etc.
-*/
-bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const int32_t& value) {
- return AddTag(tag, type, (const uint32_t&)value);
-}
-
-/*! \fn bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const float& value)
- \brief Adds a field with floating-point data to the BAM tags.
-
- Does NOT modify an existing tag - use \link BamAlignment::EditTag() \endlink instead.
-
- \param tag 2-character tag name
- \param type 1-character tag type (must NOT be "Z" or "H")
- \param value float data to store
-
- \return \c true if the \b new tag was added successfully
-
- \sa http://samtools.sourceforge.net/SAM-1.3.pdf
- for more details on reserved tag names, supported tag types, etc.
-*/
-bool BamAlignment::AddTag(const std::string& tag, const std::string& type, const float& value) {
-
- // skip if core data not parsed
- if ( SupportData.HasCoreOnly ) return false;
-
- // validate tag/type size & that type is OK for float value
- if ( !Internal::IsValidSize(tag, type) ) return false;
- if ( type.at(0) == Constants::BAM_TAG_TYPE_STRING ||
- type.at(0) == Constants::BAM_TAG_TYPE_HEX )
- return false;
-
- // localize the tag data
- char* pTagData = (char*)TagData.data();
- const unsigned int tagDataLength = TagData.size();
- unsigned int numBytesParsed = 0;
-
- // if tag already exists, return false
- // use EditTag explicitly instead
- if ( Internal::FindTag(tag, pTagData, tagDataLength, numBytesParsed) )
- return false;
-
- // otherwise, convert value to string
- union { float value; char valueBuffer[sizeof(float)]; } un;
- un.value = value;
-
- // copy original tag data to temp buffer
- string newTag = tag + type;
- const int newTagDataLength = tagDataLength + newTag.size() + 4; // leave room for new float
- char originalTagData[newTagDataLength];
- memcpy(originalTagData, TagData.c_str(), tagDataLength + 1); // '+1' for TagData null-term
-
- // append newTag
- strcat(originalTagData + tagDataLength, newTag.data());
- memcpy(originalTagData + tagDataLength + newTag.size(), un.valueBuffer, sizeof(float));
-
- // store temp buffer back in TagData
- const char* newTagData = (const char*)originalTagData;
- TagData.assign(newTagData, newTagDataLength);
-
- // return success
- return true;
-}
-