/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file NamedColumnsParser.h14/// @author Daniel Krajzewicz15/// @author Michael Behrisch16/// @date Fri, 19 Jul 200217///18// A parser to retrieve information from a table with known columns19/****************************************************************************/20#pragma once21#include <config.h>2223#include <map>24#include <string>25#include <utils/common/StringTokenizer.h>262728// ===========================================================================29// class definitions30// ===========================================================================31/**32* @class NamedColumnsParser33* @brief A parser to retrieve information from a table with known columns34*35* When initialised, this parser stores the given information about the36* order of the named elements and allows the retrieval of lines using the37* names of these elements.38* Use it like this:39* @arg Initialise with "Name;PositionX;PositionY"40* (defDelim=default=";")41* (lineDelim=default=";")42* @arg Parse each line of a table using "parseLine" (parseLine("Dummy;0;0"))43* @arg get values using operations like: string posX = get("PositionX");44*45* @todo What happens if an uninitialised NamedColumnsParser is used? exceptions?46*/47class NamedColumnsParser {48public:49/** @brief Constructor50*51* Does nothing, a later call to reinit is necessary52*/53NamedColumnsParser();545556/** @brief Constructor57*58* Initialises the parser (mainly using "reinitMap", only "ignoreCase" and59* "lineDelim" are saved directly into member variables - "reinit"60* does the same).61*62* @param[in] def The line that describes (names) the entries63* @param[in] defDelim Delimiter for the entry names64* @param[in] lineDelim Delimiter used within data lines65* @param[in] chomp Whether the lines shall be trimmed (white spaces shall be removed)66* @param[in] ignoreCase Whether the case shall be ignored when parsing the definitions67*/68NamedColumnsParser(const std::string& def, const std::string& defDelim = ";",69const std::string& lineDelim = ";", bool chomp = false,70bool ignoreCase = true);717273/// @brief Destructor74~NamedColumnsParser();757677/** @brief Reinitialises the parser78*79* Initialises the parser (mainly using "reinitMap", only "ignoreCase" and80* "lineDelim" are saved directly into member variables81*82* @param[in] def The line that describes (names) the entries83* @param[in] defDelim Delimiter for the entry names84* @param[in] lineDelim Delimiter used within data lines85* @param[in] chomp Whether the lines shall be trimmed (white spaces shall be removed)86* @param[in] ignoreCase Whether the case shall be ignored when parsing the definitions87*/88void reinit(const std::string& def, const std::string& defDelim = ";",89const std::string& lineDelim = ";", bool chomp = false,90bool ignoreCase = true);919293/** @brief Parses the contents of the line94*95* Parses the line by tokenizing it using a StringTokenizer and the set96* line delimiter ("myLineDelimiter"). Stores the tokenized line into97* "myLineParser"98*99* @param[in] line The line to parse100*/101void parseLine(const std::string& line);102103104/** @brief Returns the named information105*106* Tries to find the given variable name within the parsed definition line107* ("myDefinitionsMap"). If the value was not within the definition, an108* UnknownElement exception is thrown. Otherwise, the method tries to return109* the element from the parsed value line that is at the obtained position.110* If the value line had less tokens than the position assumes, an OutOfBoundsException111* is thrown, otherwise the value at the position returned (optionally prunned).112*113* @param[in] name The name of the value to retrieve114* @param[in] prune Whether the returned value shall be trimmed (leading/trainling spaces removed)115* @return The obtained value116* @exception UnknownElement when the element was not named during the initialisation117* @exception OutOfBoundsException when the line was too short and did not contain the item */118std::string get(const std::string& name,119bool prune = false) const;120121122/** @brief Returns the information whether the named column is known123*124* @param[in] name The name of the value to check125* @return Whether the named value is stored in the parsed line126*/127bool know(const std::string& name) const;128129130/** @brief Returns whether the number of named columns matches the actual number131*132* @return Whether the number of named columns matches the actual number133*/134bool hasFullDefinition() const;135136137private:138/** @brief Rebuilds the map of attribute names to their positions in a table139*140* The given definition string is split using the given delimiter. The obtained141* tokens are stired in "" together with their positions within the tokenized142* string.143* If wished (myAmCaseInsensitive==true), the definition string is converted144* into lower case, first. Also, if chomp==true, each token ist prunned.145*146* @param[in] def The definition string147* @param[in] delim The delimiter string148* @param[in] chomp Whether the tokens shall be prunned149*/150void reinitMap(std::string def, const std::string& delim = ";",151bool chomp = false);152153154/** @brief Prunes the given string if it shall be done155*156* If prune==true, the given string is prunned (all leading/trailing spaces157* are removed).158*159* @param[in, out] str The string to prune (optionally)160* @param[in] prune Whether the string shall be prunned161*/162void checkPrune(std::string& str, bool prune) const;163164165private:166/** @brief The map's definition of column item names to their positions within the table */167typedef std::map<std::string, int> PosMap;168169/// @brief The map of column item names to their positions within the table170PosMap myDefinitionsMap;171172/// @brief The delimiter to split the column items on173std::string myLineDelimiter;174175/// @brief The contents of the current line176StringTokenizer myLineParser;177178/// @brief Information whether case insensitive match shall be done179bool myAmCaseInsensitive;180181};182183184