//******************************************************************* // Project: Artificial Life // Title: Config Parser // Type: Utility // // Author: Alex Walker // Created: Nov. 8, 2006 // Modified: Nov. 11, 2006 // // Config Parser is a templated class allowing parsing of files that // adhere to a simple format. It utilitizes a map to store the // results, so it expects a pair of "key value." Either a space or // a new line will suffice as a delimiter between elements. // // Example file: // // WIDTH 640 // HEIGHT 480 // //******************************************************************* #ifndef _AL_CONFIGPARSER_H_ #define _AL_CONFIGPARSER_H_ #include using std::map; using std::make_pair; #include using std::vector; #include using std::string; #include using std::ifstream; using std::ofstream; template class ConfigParser { private: string filename; map * parsed; public: ConfigParser(const string & = ""); ConfigParser(const ConfigParser &); ConfigParser & operator=(const ConfigParser &); ~ConfigParser(); bool parse(const string & = ""); T get(const string & ); T getStr(const string & ); bool set(const string & , const T & ); bool exists(const string & ); bool write(); bool isParsed(){ return parsed->size() > 0; } vector * asVector(); }; template ConfigParser::ConfigParser(const string & fn) : filename(fn) { parsed = new map(); if( filename != "" ) parse(); } template ConfigParser::ConfigParser(const ConfigParser & rhs) { *this = rhs; } template ConfigParser & ConfigParser::operator=(const ConfigParser & rhs) { if( this != &rhs ) { delete parsed; parsed = new map( rhs.parsed->begin(), parsed->end() ); filename = rhs.filename; } return *this; } template ConfigParser::~ConfigParser() { filename.clear(); delete parsed; } template bool ConfigParser::parse(const string & fn) { if( fn != "" ) filename = fn; ifstream fin( filename.c_str() ); if( fin.is_open() ) { // erase previous data parsed->clear(); while( !fin.eof() ) { string attribute = ""; T value; if( fin >> attribute && attribute != "" ) { if( fin >> value ) { // dereference and assign attribute to value (*parsed)[attribute] = value; attribute.clear(); } } } fin.close(); return true; } return false; } template T ConfigParser::get(const string & attribute) { typename map::iterator i = parsed->find(attribute); // check success if( i != parsed->end() ) { return (*parsed)[attribute]; } return 0; } template T ConfigParser::getStr(const string & attribute) { typename map::iterator i = parsed->find(attribute); // check success if( i != parsed->end() ) { return (*parsed)[attribute]; } return ""; } template vector * ConfigParser::asVector() { vector * v = new vector(parsed->size()); typename map::iterator i = parsed->begin(); for(; i != parsed->end(); i++) { v->push_back( i->second ); } return v; } template bool ConfigParser::set(const string & attribute, const T & value) { // update value, return iterator to location and bool pair< typename map::iterator, bool > p = parsed->insert( make_pair(attribute, value) ); // p.second is a bool for success/fail return p.second; } template bool ConfigParser::exists(const string & attribute) { // find attribute, return iterator to location and bool pair< typename map::iterator, bool > p = parsed->find( attribute ); // p.second is a bool for success/fail return p.second; } template bool ConfigParser::write() { if( isParsed() ) { ofstream fout( filename.c_str(), std::ios::trunc ); if( fout.is_open() ) { typename map::iterator i = parsed->begin(); for(; i != parsed->end(); i++) { fout << i->first << ' ' << i->second << '\n'; } fout.close(); return true; } } return false; } #endif