This class encapsulates the tag value pairs contained with a SAM Header line with accessors for getting and setting the tags within this header. More...
#include <SamHeaderRecord.h>
Public Types | |
enum | SamHeaderRecordType { HD, SQ, RG, PG } |
Specifies the Type for the sam header record (line). More... | |
Public Member Functions | |
SamHeaderRecord () | |
Constructor. | |
~SamHeaderRecord () | |
Destructor. | |
bool | setFields (const StringArray &tokens) |
Set the fields from the passed in line. | |
bool | isValid () |
Check to see if the record is valid. | |
const char * | getTagValue (const char *tag) const |
Return the value associated with the specified tag. | |
bool | setTag (const char *tag, const char *value) |
Set the value of the specified tag to the specified value, deletes the tag when value is NULL. | |
void | reset () |
Reset this header record to an empty state with no tags. | |
bool | appendString (std::string &header) |
Appends the string representation of this header record to the passed in string. | |
bool | addKey (const char *value) |
Add the key tag with the specified value (not for HD headers). | |
bool | isActiveHeaderRecord () |
This record is active (true) if there is at least one tag set. | |
const char * | getTypeString () |
Return the type of this header record (HD, SQ, RG, or PG) as a string. | |
SamHeaderRecordType | getType () |
Return the type of this header record (HD, SQ, RG, or PG) as an enum. | |
Protected Member Functions | |
void | addRequiredTag (const char *requiredTag) |
Protected Attributes | |
std::string | myTypeString |
SamHeaderRecordType | myType |
std::string | myKeyTag |
This class encapsulates the tag value pairs contained with a SAM Header line with accessors for getting and setting the tags within this header.
Definition at line 27 of file SamHeaderRecord.h.
bool SamHeaderRecord::appendString | ( | std::string & | header | ) |
Appends the string representation of this header record to the passed in string.
Definition at line 234 of file SamHeaderRecord.cpp.
References isActiveHeaderRecord(), and isValid().
00235 { 00236 // Track whether or not the header type has been written. 00237 // Only write the header type if at least one of the tags has 00238 // an associated value. 00239 bool writtenHeader = false; 00240 00241 if(isActiveHeaderRecord() && isValid()) 00242 { 00243 // Loop through all the entries in the tag vector. 00244 for(unsigned int vectorIndex = 0; 00245 vectorIndex < myTags.size(); 00246 vectorIndex++) 00247 { 00248 if(!writtenHeader && (myTags[vectorIndex]->hasValue())) 00249 { 00250 // The tag has a value and the header type has not yet been written, 00251 // so write it. 00252 header += "@"; 00253 header += myTypeString; 00254 writtenHeader = true; 00255 } 00256 myTags[vectorIndex]->getTagString(header); 00257 } 00258 00259 // If a header has been written, add a new line character. 00260 if(writtenHeader) 00261 { 00262 header += "\n"; 00263 return(true); 00264 } 00265 } 00266 00267 // Nothing was written, return false. 00268 return(false); 00269 }
bool SamHeaderRecord::setFields | ( | const StringArray & | tokens | ) |
Set the fields from the passed in line.
Return true if successfully set.
Definition at line 38 of file SamHeaderRecord.cpp.
References isValid(), and setTag().
00039 { 00040 bool status = true; 00041 00042 // Loop through the tags for this type. 00043 // The tags start in column 1 since column 0 contains the type. 00044 for(int columnIndex = 1; columnIndex < tokens.Length(); columnIndex++) 00045 { 00046 // Validate that the tag is at least 3 characters. Two for the token, 00047 // one for the ':'. 00048 if((tokens[columnIndex].Length() < 3) || 00049 (tokens[columnIndex][2] != ':')) 00050 { 00051 // Continue to the next tag, this one is too small/invalid. 00052 status = false; 00053 std::cerr << "ERROR: Poorly formatted tag in header: " 00054 << tokens[columnIndex] << std::endl; 00055 continue; 00056 } 00057 00058 // Get the tag from the token. 00059 char tag[3]; 00060 tag[0] = tokens[columnIndex][0]; 00061 tag[1] = tokens[columnIndex][1]; 00062 tag[2] = 0; 00063 00064 // The tag value is the rest of the substring. 00065 String tagValue = (tokens[columnIndex]).SubStr(3); 00066 00067 // Set the tag. 00068 status &= setTag(tag, tagValue.c_str()); 00069 } 00070 00071 status &= isValid(); 00072 00073 return(status); 00074 }
bool SamHeaderRecord::setTag | ( | const char * | tag, | |
const char * | value | |||
) |
Set the value of the specified tag to the specified value, deletes the tag when value is NULL.
Returns whether or not it was successful, fails if tag is the key tag and the key tag already exists.
Definition at line 119 of file SamHeaderRecord.cpp.
Referenced by addKey(), setFields(), SamFileHeader::setHDTag(), SamFileHeader::setPGTag(), SamFileHeader::setRGTag(), and SamFileHeader::setSQTag().
00120 { 00121 // Lookup the tag in the hash. 00122 int vectorIndex = myTagHash.Integer(tag); 00123 if(vectorIndex < 0) 00124 { 00125 // The tag was not found in the hash, so create a new one. 00126 SamHeaderTag* tagPtr = new SamHeaderTag(tag, value); 00127 00128 if(tagPtr == NULL) 00129 { 00130 // Failed to allocate the tag, return false. 00131 std::cerr << "Failed to allocate space (new) for a SamHeaderTag.\n"; 00132 return(false); 00133 } 00134 00135 // Add the new tag to the back of the tag values. 00136 vectorIndex = myTags.size(); 00137 myTags.push_back(tagPtr); 00138 00139 // If the value is not null, increment the number of active tags. 00140 if(value[0] != 0) 00141 { 00142 ++myNumActiveTags; 00143 } 00144 00145 // Add the tag to the hash. 00146 int hashIndex = myTagHash.Add(tag, vectorIndex); 00147 00148 if((myTagHash.Integer(hashIndex) != vectorIndex) || 00149 (myTagHash[hashIndex] != tag)) 00150 { 00151 // Failed to add the tag, so return false. 00152 std::cerr << "Failed to add tag, " << tag 00153 << ", to the hash." << std::endl; 00154 return(false); 00155 } 00156 return(true); 00157 } 00158 else if((unsigned int)vectorIndex < myTags.size()) 00159 { 00160 // Found the tag in the hash. So, update the tag if it 00161 // is not the key. 00162 if(myKeyTag != tag) 00163 { 00164 // Not the key, so update the tag. 00165 // If the new value is null and the old one is not, decrement the 00166 // number of active tags. 00167 if((value[0] == 0) && ((myTags[vectorIndex]->getValue())[0] != 0)) 00168 { 00169 // Tag was deleted since the new value is blank but the old 00170 // value was not. 00171 --myNumActiveTags; 00172 } 00173 else if((value[0] != 0) && 00174 ((myTags[vectorIndex]->getValue())[0] == 0)) 00175 { 00176 // Tag was added since the old value was blank and the new value 00177 // is not. 00178 ++myNumActiveTags; 00179 } 00180 00181 // Just modifying a tag, so this does not affect the number 00182 // of active tags. 00183 return(myTags[vectorIndex]->setValue(value)); 00184 } 00185 else if(strcmp(value, myTags[vectorIndex]->getValue()) == 0) 00186 { 00187 // The new key value is the same as the previous value, so 00188 // it is not a change, return true. 00189 return(true); 00190 } 00191 else 00192 { 00193 // Can't modify the key tag's value since that will 00194 // screw up the hash. 00195 std::cerr << "Can't modify the key tag, " << tag << " from " 00196 << myTags[vectorIndex]->getValue() << " to " 00197 << value << std::endl; 00198 return(false); 00199 } 00200 } 00201 00202 // Got an invalid index from the hash. This is not supposed to happen. 00203 // so return false. 00204 std::cerr << "Invalid tag index found: " << vectorIndex 00205 << ", but max index is " << myTags.size() << " for tag: " 00206 << tag << std::endl; 00207 return(false); 00208 }