|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // A parser to retrieve information from a table with known column 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 00020 00021 // =========================================================================== 00022 // included modules 00023 // =========================================================================== 00024 #ifdef _MSC_VER 00025 #include <windows_config.h> 00026 #else 00027 #include <config.h> 00028 #endif 00029 00030 #include <map> 00031 #include <string> 00032 #include <utils/common/UtilExceptions.h> 00033 #include <utils/common/StringUtils.h> 00034 #include "NamedColumnsParser.h" 00035 00036 #ifdef CHECK_MEMORY_LEAKS 00037 #include <foreign/nvwa/debug_new.h> 00038 #endif // CHECK_MEMORY_LEAKS 00039 00040 00041 // =========================================================================== 00042 // method definitions 00043 // =========================================================================== 00044 NamedColumnsParser::NamedColumnsParser() throw() {} 00045 00046 00047 NamedColumnsParser::NamedColumnsParser(const std::string& def, 00048 const std::string& defDelim, 00049 const std::string& lineDelim, 00050 bool prune, bool ignoreCase) throw() 00051 : myLineDelimiter(lineDelim), myAmCaseInsensitive(ignoreCase) { 00052 reinitMap(def, defDelim, prune); 00053 } 00054 00055 00056 NamedColumnsParser::~NamedColumnsParser() throw() {} 00057 00058 00059 void 00060 NamedColumnsParser::reinit(const std::string& def, 00061 const std::string& defDelim, 00062 const std::string& lineDelim, 00063 bool prune, bool ignoreCase) throw() { 00064 myAmCaseInsensitive = ignoreCase; 00065 reinitMap(def, defDelim, prune); 00066 myLineDelimiter = lineDelim; 00067 } 00068 00069 00070 void 00071 NamedColumnsParser::parseLine(const std::string& line) throw() { 00072 myLineParser = StringTokenizer(line, myLineDelimiter); 00073 } 00074 00075 00076 std::string 00077 NamedColumnsParser::get(const std::string& name, bool prune) const throw(UnknownElement, OutOfBoundsException) { 00078 PosMap::const_iterator i = myDefinitionsMap.find(name); 00079 if (i==myDefinitionsMap.end()) { 00080 if (myAmCaseInsensitive) { 00081 i = myDefinitionsMap.find(StringUtils::to_lower_case(name)); 00082 } 00083 if (i==myDefinitionsMap.end()) { 00084 throw UnknownElement(name); 00085 } 00086 } 00087 size_t pos = (*i).second; 00088 if (myLineParser.size()<=pos) { 00089 throw OutOfBoundsException(); 00090 } 00091 std::string ret = myLineParser.get(pos); 00092 checkPrune(ret, prune); 00093 return ret; 00094 } 00095 00096 00097 bool 00098 NamedColumnsParser::know(const std::string& name) const throw() { 00099 PosMap::const_iterator i = myDefinitionsMap.find(name); 00100 if (i==myDefinitionsMap.end()) { 00101 if (myAmCaseInsensitive) { 00102 i = myDefinitionsMap.find(StringUtils::to_lower_case(name)); 00103 } 00104 } 00105 if (i==myDefinitionsMap.end()) { 00106 return false; 00107 } 00108 size_t pos = (*i).second; 00109 return myLineParser.size()>pos; 00110 } 00111 00112 00113 bool 00114 NamedColumnsParser::hasFullDefinition() const throw() { 00115 return myDefinitionsMap.size() == myLineParser.size(); 00116 } 00117 00118 00119 void 00120 NamedColumnsParser::reinitMap(std::string s, 00121 const std::string& delim, 00122 bool prune) throw() { 00123 if (myAmCaseInsensitive) { 00124 s = StringUtils::to_lower_case(s); 00125 } 00126 myDefinitionsMap.clear(); 00127 int pos = 0; 00128 StringTokenizer st(s, delim); 00129 while (st.hasNext()) { 00130 std::string next = st.next(); 00131 checkPrune(next, prune); 00132 myDefinitionsMap.insert(std::map<std::string, int>::value_type(next, pos++)); 00133 } 00134 } 00135 00136 00137 void 00138 NamedColumnsParser::checkPrune(std::string& str, bool prune) const throw() { 00139 if (!prune) { 00140 return; 00141 } 00142 size_t idx = str.find_first_not_of(" "); 00143 if (idx!=std::string::npos) { 00144 str = str.substr(idx); 00145 } 00146 idx = str.find_last_not_of(" "); 00147 if (idx!=std::string::npos&&idx!=str.length()-1) { 00148 str = str.substr(0, idx+1); 00149 } 00150 } 00151 00152 00153 00154 /****************************************************************************/ 00155