-// internal utility methods
-namespace BamTools {
-namespace Internal {
-
-/*! \fn bool IsValidSize(const string& tag, const string& type)
- \internal
-
- Checks that tag name & type strings are expected sizes.
- \a tag should have length
- \a type should have length 1
-
- \param tag BAM tag name
- \param type BAM tag type-code
-
- \return \c true if both \a tag and \a type are correct sizes
-*/
-bool IsValidSize(const string& tag, const string& type) {
- return (tag.size() == Constants::BAM_TAG_TAGSIZE) &&
- (type.size() == Constants::BAM_TAG_TYPESIZE);
-}
-
-/*! \fn bool SkipToNextTag(const char storageType, char* &pTagData, unsigned int& numBytesParsed)
- \internal
-
- Moves to next available tag in tag data string
-
- \param storageType BAM tag type-code that determines how far to move cursor
- \param pTagData pointer to current position (cursor) in tag string
- \param numBytesParsed report of how many bytes were parsed (cumulatively)
-
- \return \c if storageType was a recognized BAM tag type
- \post \a pTagData will point to the byte where the next tag data begins.
- \a numBytesParsed will correspond to the cursor's position in the full TagData string.
-*/
-bool SkipToNextTag(const char storageType, char* &pTagData, unsigned int& numBytesParsed) {
-
- switch (storageType) {
-
- case (Constants::BAM_TAG_TYPE_ASCII) :
- case (Constants::BAM_TAG_TYPE_INT8) :
- case (Constants::BAM_TAG_TYPE_UINT8) :
- ++numBytesParsed;
- ++pTagData;
- break;
-
- case (Constants::BAM_TAG_TYPE_INT16) :
- case (Constants::BAM_TAG_TYPE_UINT16) :
- numBytesParsed += 2;
- pTagData += 2;
- break;
-
- case (Constants::BAM_TAG_TYPE_FLOAT) :
- case (Constants::BAM_TAG_TYPE_INT32) :
- case (Constants::BAM_TAG_TYPE_UINT32) :
- numBytesParsed += 4;
- pTagData += 4;
- break;
-
- case (Constants::BAM_TAG_TYPE_STRING) :
- case (Constants::BAM_TAG_TYPE_HEX) :
- while(*pTagData) {
- ++numBytesParsed;
- ++pTagData;
- }
- // increment for null-terminator
- ++numBytesParsed;
- ++pTagData;
- break;
-
- default:
- // error case
- fprintf(stderr, "BamAlignment ERROR: unknown tag type encountered: [%c]\n", storageType);
- return false;
- }
-
- // return success
- return true;
-}
-
-/*! \fn bool FindTag(const std::string& tag, char* &pTagData, const unsigned int& tagDataLength, unsigned int& numBytesParsed)
- \internal
-
- Searches for requested tag in BAM tag data.
-
- \param tag requested 2-character tag name
- \param pTagData pointer to current position in BamAlignment::TagData
- \param tagDataLength length of BamAlignment::TagData
- \param numBytesParsed number of bytes parsed so far
-
- \return \c true if found
-
- \post If \a tag is found, \a pTagData will point to the byte where the tag data begins.
- \a numBytesParsed will correspond to the position in the full TagData string.
-
-*/
-bool FindTag(const std::string& tag,
- char* &pTagData,
- const unsigned int& tagDataLength,
- unsigned int& numBytesParsed)
-{
-
- while ( numBytesParsed < tagDataLength ) {
-
- const char* pTagType = pTagData;
- const char* pTagStorageType = pTagData + 2;
- pTagData += 3;
- numBytesParsed += 3;
-
- // check the current tag, return true on match
- if ( strncmp(pTagType, tag.c_str(), 2) == 0 )
- return true;
-
- // get the storage class and find the next tag
- if ( *pTagStorageType == '\0' ) return false;
- if ( !SkipToNextTag(*pTagStorageType, pTagData, numBytesParsed) ) return false;
- if ( *pTagData == '\0' ) return false;
- }
-
- // checked all tags, none match
- return false;
-}
-
-} // namespace Internal
-} // namespace BamTools
-