Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others. 4 : // This program and the accompanying materials are made available under the 5 : // terms of the Eclipse Public License 2.0 which is available at 6 : // https://www.eclipse.org/legal/epl-2.0/ 7 : // This Source Code may also be made available under the following Secondary 8 : // Licenses when the conditions for such availability set forth in the Eclipse 9 : // Public License 2.0 are satisfied: GNU General Public License, version 2 10 : // or later which is available at 11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html 12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later 13 : /****************************************************************************/ 14 : /// @file NamedColumnsParser.cpp 15 : /// @author Daniel Krajzewicz 16 : /// @author Michael Behrisch 17 : /// @date Fri, 19 Jul 2002 18 : /// 19 : // A parser to retrieve information from a table with known column 20 : /****************************************************************************/ 21 : #include <config.h> 22 : 23 : #include <map> 24 : #include <string> 25 : #include <utils/common/UtilExceptions.h> 26 : #include <utils/common/StringUtils.h> 27 : #include "NamedColumnsParser.h" 28 : 29 : 30 : // =========================================================================== 31 : // method definitions 32 : // =========================================================================== 33 118 : NamedColumnsParser::NamedColumnsParser() {} 34 : 35 : 36 0 : NamedColumnsParser::NamedColumnsParser(const std::string& def, 37 : const std::string& defDelim, 38 : const std::string& lineDelim, 39 0 : bool prune, bool ignoreCase) 40 0 : : myLineDelimiter(lineDelim), myAmCaseInsensitive(ignoreCase) { 41 0 : reinitMap(def, defDelim, prune); 42 0 : } 43 : 44 : 45 118 : NamedColumnsParser::~NamedColumnsParser() {} 46 : 47 : 48 : void 49 269 : NamedColumnsParser::reinit(const std::string& def, 50 : const std::string& defDelim, 51 : const std::string& lineDelim, 52 : bool prune, bool ignoreCase) { 53 269 : myAmCaseInsensitive = ignoreCase; 54 269 : reinitMap(def, defDelim, prune); 55 269 : myLineDelimiter = lineDelim; 56 269 : } 57 : 58 : 59 : void 60 13171 : NamedColumnsParser::parseLine(const std::string& line) { 61 19249 : myLineParser = StringTokenizer(line, myLineDelimiter); 62 13171 : } 63 : 64 : 65 : std::string 66 74332 : NamedColumnsParser::get(const std::string& name, bool prune) const { 67 : PosMap::const_iterator i = myDefinitionsMap.find(name); 68 74332 : if (i == myDefinitionsMap.end()) { 69 23109 : if (myAmCaseInsensitive) { 70 46218 : i = myDefinitionsMap.find(StringUtils::to_lower_case(name)); 71 : } 72 23109 : if (i == myDefinitionsMap.end()) { 73 1744 : throw UnknownElement("Element '" + name + "' is missing"); 74 : } 75 : } 76 73460 : int pos = (*i).second; 77 73460 : if (myLineParser.size() <= pos) { 78 0 : throw OutOfBoundsException(); 79 : } 80 73460 : std::string ret = myLineParser.get(pos); 81 73460 : checkPrune(ret, prune); 82 73460 : return ret; 83 : } 84 : 85 : 86 : bool 87 35643 : NamedColumnsParser::know(const std::string& name) const { 88 : PosMap::const_iterator i = myDefinitionsMap.find(name); 89 35643 : if (i == myDefinitionsMap.end()) { 90 35643 : if (myAmCaseInsensitive) { 91 71286 : i = myDefinitionsMap.find(StringUtils::to_lower_case(name)); 92 : } 93 : } 94 35643 : if (i == myDefinitionsMap.end()) { 95 : return false; 96 : } 97 27013 : int pos = (*i).second; 98 27013 : return myLineParser.size() > pos; 99 : } 100 : 101 : 102 : bool 103 8043 : NamedColumnsParser::hasFullDefinition() const { 104 8043 : return (int)myDefinitionsMap.size() == myLineParser.size(); 105 : } 106 : 107 : 108 : void 109 269 : NamedColumnsParser::reinitMap(std::string s, 110 : const std::string& delim, 111 : bool prune) { 112 269 : if (myAmCaseInsensitive) { 113 538 : s = StringUtils::to_lower_case(s); 114 : } 115 : myDefinitionsMap.clear(); 116 : int pos = 0; 117 538 : StringTokenizer st(s, delim); 118 3279 : while (st.hasNext()) { 119 3010 : std::string next = st.next(); 120 3010 : checkPrune(next, prune); 121 6020 : myDefinitionsMap.insert(std::map<std::string, int>::value_type(next, pos++)); 122 : } 123 269 : } 124 : 125 : 126 : void 127 76470 : NamedColumnsParser::checkPrune(std::string& str, bool prune) const { 128 76470 : if (!prune) { 129 : return; 130 : } 131 : std::string::size_type idx = str.find_first_not_of(" "); 132 651 : if (idx != std::string::npos) { 133 1302 : str = str.substr(idx); 134 : } 135 : idx = str.find_last_not_of(" "); 136 651 : if (idx != std::string::npos && idx != str.length() - 1) { 137 0 : str = str.substr(0, idx + 1); 138 : } 139 : } 140 : 141 : 142 : /****************************************************************************/