SamHeaderRecord.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "SamHeaderRecord.h"
00019
00020
00021 SamHeaderRecord::SamHeaderRecord()
00022 : myTagHash(),
00023 myTags(),
00024 myNumActiveTags(0)
00025 {
00026 }
00027
00028
00029
00030 SamHeaderRecord::~SamHeaderRecord()
00031 {
00032 reset();
00033 }
00034
00035
00036
00037
00038 bool SamHeaderRecord::setFields(const StringArray& tokens)
00039 {
00040 bool status = true;
00041
00042
00043
00044 for(int columnIndex = 1; columnIndex < tokens.Length(); columnIndex++)
00045 {
00046
00047
00048 if((tokens[columnIndex].Length() < 3) ||
00049 (tokens[columnIndex][2] != ':'))
00050 {
00051
00052 status = false;
00053 std::cerr << "ERROR: Poorly formatted tag in header: "
00054 << tokens[columnIndex] << std::endl;
00055 continue;
00056 }
00057
00058
00059 char tag[3];
00060 tag[0] = tokens[columnIndex][0];
00061 tag[1] = tokens[columnIndex][1];
00062 tag[2] = 0;
00063
00064
00065 String tagValue = (tokens[columnIndex]).SubStr(3);
00066
00067
00068 status &= setTag(tag, tagValue.c_str());
00069 }
00070
00071 status &= isValid();
00072
00073 return(status);
00074 }
00075
00076
00077
00078 bool SamHeaderRecord::isValid()
00079 {
00080 bool status = true;
00081
00082 for(unsigned int reqIndex = 0; reqIndex < myRequiredTags.size(); reqIndex++)
00083 {
00084
00085
00086 int index = myTagHash.Integer(myRequiredTags[reqIndex].c_str());
00087 if((index < 0) || !(myTags[index]->hasValue()))
00088 {
00089
00090 std::cerr << "ERROR: Missing required tag: "
00091 << myRequiredTags[reqIndex] << "." << std::endl;
00092 status = false;
00093 }
00094 }
00095 return(status);
00096 }
00097
00098
00099
00100 const char* SamHeaderRecord::getTagValue(const char* tag) const
00101 {
00102
00103 int index = myTagHash.Integer(tag);
00104 if(index < 0)
00105 {
00106
00107 return("");
00108 }
00109
00110
00111
00112 return(myTags[index]->getValue());
00113 }
00114
00115
00116
00117
00118
00119 bool SamHeaderRecord::setTag(const char* tag, const char* value)
00120 {
00121
00122 int vectorIndex = myTagHash.Integer(tag);
00123 if(vectorIndex < 0)
00124 {
00125
00126 SamHeaderTag* tagPtr = new SamHeaderTag(tag, value);
00127
00128 if(tagPtr == NULL)
00129 {
00130
00131 std::cerr << "Failed to allocate space (new) for a SamHeaderTag.\n";
00132 return(false);
00133 }
00134
00135
00136 vectorIndex = myTags.size();
00137 myTags.push_back(tagPtr);
00138
00139
00140 if(value[0] != 0)
00141 {
00142 ++myNumActiveTags;
00143 }
00144
00145
00146 int hashIndex = myTagHash.Add(tag, vectorIndex);
00147
00148 if((myTagHash.Integer(hashIndex) != vectorIndex) ||
00149 (myTagHash[hashIndex] != tag))
00150 {
00151
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
00161
00162 if(myKeyTag != tag)
00163 {
00164
00165
00166
00167 if((value[0] == 0) && ((myTags[vectorIndex]->getValue())[0] != 0))
00168 {
00169
00170
00171 --myNumActiveTags;
00172 }
00173 else if((value[0] != 0) &&
00174 ((myTags[vectorIndex]->getValue())[0] == 0))
00175 {
00176
00177
00178 ++myNumActiveTags;
00179 }
00180
00181
00182
00183 return(myTags[vectorIndex]->setValue(value));
00184 }
00185 else if(strcmp(value, myTags[vectorIndex]->getValue()) == 0)
00186 {
00187
00188
00189 return(true);
00190 }
00191 else
00192 {
00193
00194
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
00203
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 }
00209
00210
00211
00212 void SamHeaderRecord::reset()
00213 {
00214
00215 myTagHash.Clear();
00216
00217
00218 for(unsigned int vectorIndex = 0;
00219 vectorIndex < myTags.size();
00220 vectorIndex++)
00221 {
00222 delete myTags[vectorIndex];
00223 myTags[vectorIndex] = NULL;
00224 }
00225
00226 myTags.clear();
00227
00228 myNumActiveTags = 0;
00229 }
00230
00231
00232
00233
00234 bool SamHeaderRecord::appendString(std::string& header)
00235 {
00236
00237
00238
00239 bool writtenHeader = false;
00240
00241 if(isActiveHeaderRecord() && isValid())
00242 {
00243
00244 for(unsigned int vectorIndex = 0;
00245 vectorIndex < myTags.size();
00246 vectorIndex++)
00247 {
00248 if(!writtenHeader && (myTags[vectorIndex]->hasValue()))
00249 {
00250
00251
00252 header += "@";
00253 header += myTypeString;
00254 writtenHeader = true;
00255 }
00256 myTags[vectorIndex]->getTagString(header);
00257 }
00258
00259
00260 if(writtenHeader)
00261 {
00262 header += "\n";
00263 return(true);
00264 }
00265 }
00266
00267
00268 return(false);
00269 }
00270
00271
00272
00273 bool SamHeaderRecord::addKey(const char* value)
00274 {
00275 if(myKeyTag.size() == 0)
00276 {
00277 return(false);
00278 }
00279 return(setTag(myKeyTag.data(), value));
00280 }
00281
00282
00283
00284 bool SamHeaderRecord::isActiveHeaderRecord()
00285 {
00286 return(myNumActiveTags != 0);
00287 }
00288
00289
00290
00291 const char* SamHeaderRecord::getTypeString()
00292 {
00293 return(myTypeString.c_str());
00294 }
00295
00296
00297
00298 SamHeaderRecord::SamHeaderRecordType SamHeaderRecord::getType()
00299 {
00300 return(myType);
00301 }
00302
00303
00304 void SamHeaderRecord::addRequiredTag(const char* requiredTag)
00305 {
00306 myRequiredTags.push_back(requiredTag);
00307 }