#include "GDB.h" GDB::GDB() { VarsNumber = 0; ExVar = ""; ExVal = ""; plain_text = false; } GDB::GDB(const string &fileName) { GDBfileName = fileName; VarsNumber = 0; ExVar = ""; ExVal = ""; loadGDB(fileName); plain_text = false; } void GDB::loadGDB(const string &fileName) { GDBfileName = fileName; ifstream file(fileName.c_str()); if(! file.is_open() ){ cerr << "\tCan't open file " << fileName << " for reading" << endl; exit(0); } int entry_count=1; string str; bool DATA_START = false; while (! file.eof() ) { getline (file, str); if(str.empty() || str.size() == 0) continue; StringList fields = split(" ", str); if(fields.size() == 0) continue; //read entries if( DATA_START && VarsNumber > 0 && fields.size() == VarsNumber ) { for(int i = 0; i < VarsNumber; i++) { // if( ExVar == VARS[i] && ExVal.find(fields[i].ascii()) != 0 ) // { //cout << VARS[i] << " " << fields[i] << " " << ExVal.length() < 0) { string text1 = DATA[ fields[1] ]; text1 += " "; text1 += text; DATA[ fields[1] ] = text1; } } else if( fields[0] == "VARS" ) //read the VARS { string text; text = str.substr(fields[0].length(), str.length()); VARS_str = simplifyWhiteSpace(text); VARS_str_parser(VARS_str); } else if( fields[0].compare("FORMAT") == 0 )//read the FORMAT { FORMAT_str = str.substr(fields[0].length(), str.length()); FORMAT_str_parser(FORMAT_str); DATA_START = true; } } file.close(); //re-format the SEQUENCE if there exist SEQUENCE DATA if( !((DATA["SEQUENCE"]).empty()) ) { string seq = DATA["SEQUENCE"]; for(int i = 0; i < seq.length(); i++) { if( !(seq[i]>='A' && seq[i]<'Z') && seq[i]!='c' ) continue; residList[residList.size()+1] = seq.substr(i,1); // insert one-letter amino acid code } } } void GDB::loadGDB(const string &fileName, const string &eVar, const string &eVal) { setExclude(eVar, eVal); loadGDB(fileName); } void GDB::setExclude(const string &eVar, const string &eVal) { ExVar = eVar; ExVal = eVal; } void GDB::saveGDB(const string &fileName) { ofstream out(fileName.c_str(), ios::trunc); if( !out ){ cerr << "\tCan't save file " << fileName.c_str() << endl; } if(!plain_text) { map::iterator iterR; if (REMARKS.size() > 0) { out << "REMARK "; for ( iterR = REMARKS.begin(); iterR != REMARKS.end(); iterR++ ) out << iterR->second << endl; out << endl; } map::iterator itD; for ( itD = DATA.begin(); itD != DATA.end(); itD++ ) { if( itD->first == "SEQUENCE" ) { string seq = simplifyWhiteSpace(itD->second); int len = seq.length(); if(len <= 0) continue; for(int i = 0; i<= len/55; i++){ string temp = seq.substr(i*55, 55); out << "DATA " << itD->first.c_str() << " " << temp.c_str() << endl; } } else out << "DATA " << itD->first.c_str() << " " << itD->second.c_str() << endl; } out << endl; out << "VARS "; for ( iterR = VARS.begin(); iterR != VARS.end(); iterR++ ) out << iterR->second.c_str() << " "; out << endl; out << "FORMAT "; for ( iterR = FORMAT.begin(); iterR != FORMAT.end(); iterR++ ) out << iterR->second.c_str(); out << endl << endl; } // write the entries map< int, map >::iterator it; for ( it = Entries.begin(); it != Entries.end(); it++ ) { GDB_Entry ent = it->second; for(int i = 0; i < VARS.size(); i++) { if( contains(FORMAT[i],'s') == 1) { sprintf(buf, FORMAT[i].c_str(), ent[ VARS[i] ].c_str() ) ; out << buf; } else if( contains(FORMAT[i],'d') == 1) { sprintf(buf, FORMAT[i].c_str(), atoi(ent[ VARS[i] ].c_str() )) ; out << buf; } else if( contains(FORMAT[i],'f') == 1) { sprintf(buf, FORMAT[i].c_str(), atof(ent[ VARS[i] ].c_str() )) ; out << buf ; } } out << endl; } out.close(); } GDB_Entry GDB::getEntry(int number) { return Entries[number]; } // get the index-th entry with VName=VVal, default return the first satisfied entry GDB_Entry GDB::getEntry(const string &VName, const string &VVal, int index) { GDB_Entry ent; int count = 0; map< int, map >::iterator it; for ( it = Entries.begin(); it != Entries.end(); it++ ) { ent = it->second; if( ent[VName] == VVal ) count++; if( count == index && index > 0 ) return ent; } ent.clear(); return ent; } // get the index-th entry with VName1=VVal1 and VName2=VVal2, default return the first satisfied entry GDB_Entry GDB::getEntry(const string &VName1, const string &VVal1, const string &VName2, const string &VVal2, int index) { GDB_Entry ent; int count = 0; map< int, map >::iterator it; for ( it = Entries.begin(); it != Entries.end(); it++ ) { ent = it->second; if( ent[VName1] == VVal1 && ent[VName2] == VVal2 ) count++; if( count == index && index > 0 ) return ent; } ent.clear(); return ent; } string GDB::getResidName(int rNum) { return residList[rNum]; } int GDB::getEntryCount() // return size of current entries { return Entries.size(); } //set value to a variable of a given entry void GDB::setEntry(int index, const string &VarName, const string &VarVal) { map::iterator it_V; for( it_V = VARS.begin(); it_V != VARS.end(); it_V++ ) if( it_V->second == VarName ) break; if( it_V != VARS.end() ) (Entries[ index ])[VarName.c_str()] = VarVal.c_str(); else { cerr << "\tInvalid varible name '" << VarName << "'" << endl; exit(0); } } //add a new entry to the end of entries list void GDB::addEntry(const string &VarName, const string &VarVal) { setEntry( Entries.size()+1, VarName, VarVal); } //add a new REMARK entry void GDB::addRemark(const string &str) { REMARKS[REMARKS.size()] = str; } //add one VAR with given FORMAT to the end of VARS list void GDB::addVAR(const string &VAR_Name, const string &FORMAT_Name) { int size = VARS.size(); if( !checkFormat(FORMAT_Name) ) cerr << "\tBad format syntax '" << FORMAT_Name << "'" << endl; else if(contains(VAR_Name, ' ') > 0) cerr << "\tInvalid varible name '" << VAR_Name << "' (with space)" << endl; else { if(size == 0) { VARS[0] = VAR_Name; FORMAT[0] = FORMAT_Name; VarsNumber++; } else { int i; for(i=0; i< size; i++) if(VARS[i] == VAR_Name) break; VARS[i] = VAR_Name; FORMAT[i] = FORMAT_Name; if(i >= size) // VAR is not exist, add the VAR and its FORMAT VarsNumber++; } } } //re-set one VAR with given FORMAT, 'index' number starts from 1 and can't larger than current size + 1 //if 'index' equals to current VARS size + 1, add new VAR to the end of VARS list void GDB::setVAR(int index, const string &VAR_Name, const string &FORMAT_Name) { int size = VARS.size(); if( !checkFormat(FORMAT_Name) ) cerr << "\tBad format syntax '" << FORMAT_Name << "'" << endl; else if(contains(VAR_Name, ' ') > 0) cerr << "\tInvalid varible name '" << VAR_Name << "' (with space)" << endl; else { if(index > size+1 || index < 1) cerr << "\tPlease use number 1-" << size+1 << " as index for varible '" << VAR_Name << "' with format '" << FORMAT_Name << "'" << endl ; else { VARS[index-1] = VAR_Name; FORMAT[index-1] = FORMAT_Name; if(index == size+1) VarsNumber++; } } } void GDB::setData(const string &DataName, const string &DataVal) { DATA[DataName] = DataVal; } string GDB::getData(const string &DataName) { return DATA[DataName]; } bool GDB::isVarFloat(int index) { if(contains(FORMAT[index],'f') == 1) return true; return false; } bool GDB::isVarFloat(const string &VarName) { map::iterator it_V; for( it_V = VARS.begin(); it_V != VARS.end(); it_V++ ) { if( it_V->second == VarName ) return isVarFloat(it_V->first); } return false; } bool GDB::isVarInt(int index) { if(contains(FORMAT[index],'d') == 1) return true; return false; } bool GDB::isVarInt(const string &VarName) { map::iterator it_V; for( it_V = VARS.begin(); it_V != VARS.end(); it_V++ ) { if( it_V->second == VarName ) return isVarInt(it_V->first); } return false; } bool GDB::isVarString(int index) { if(contains(FORMAT[index],'s') == 1) return true; return false; } bool GDB::isVarString(const string &VarName) { map::iterator it_V; for( it_V = VARS.begin(); it_V != VARS.end(); it_V++ ) { if( it_V->second == VarName ) return isVarString(it_V->first); } return false; } // check if f is a valid FORMAT bool GDB::checkFormat(const string& f) { string str = simplifyWhiteSpace(f); int last = str.length()-1; if( contains(str, '%') != 1 || str[0] != '%') return false; if( contains(str, 's') != 1 && contains(str, 'd') != 1 && contains(str, 'f') != 1 ) return false; if( str[last] != 's' && str[last] != 'd' && str[last] != 'f' ) return false; for(int i=0; i= '0' && c <= '9') return true; return false; } bool GDB::isSpace( const char &c ) { if( (c >= 9 && c <= 13) || c == ' ' ) return true; return false; } StringList GDB::split(const char &sep, const string &str) { string sp = " "; sp[0] = sep; return split( sp, str ); } StringList GDB::split(const string &sep, const string &str) { StringList lst; int j = 0; int i = str.find( sep, j ); while ( i != -1 ) { if ( str.substr(j, i - j ).length() > 0 ) lst.push_back( str.substr( j, i - j ) ); j = i + sep.length(); i = str.find( sep, j ); } int l = str.length() - 1; if ( str.substr( j, l - j + 1 ).length() > 0 ) lst.push_back( str.substr( j, l - j + 1 ) ); return lst; } char *GDB::section( const string &str, const char &sep, char *buff, int start, int end ) { StringList fields = split(sep, str); string temp = ""; if( start < fields.size() ) for( int i = start; i <= end; i++) { if( i >= fields.size()) break; temp += fields[i]; if(i!=end) temp+=sep; } sprintf( buff, "%s", temp.c_str() ); return buff; } string GDB::simplifyWhiteSpace(const string &str) { if ( str.empty() ) // nothing to do return str; string result; result.resize(str.length()); //.setLength( length() ); const char *from = str.c_str(); const char *fromend = from+str.length(); int outc=0; char *to = &(result[0]); while ( true ) { while ( from!=fromend && isSpace(*from) ) from++; while ( from!=fromend && !isSpace(*from) ) to[outc++] = *from++; if ( from!=fromend ) to[outc++] = ' '; else break; } if ( outc > 0 && to[outc-1] == ' ' ) outc--; result.resize( outc ); return result; }