LCOV - code coverage report
Current view: top level - src/utils/xml - SUMOSAXAttributes.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 38 38
Test Date: 2024-11-20 15:55:46 Functions: 92.9 % 28 26

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2007-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    SUMOSAXAttributes.h
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Fri, 30 Mar 2007
      19              : ///
      20              : // Encapsulated SAX-Attributes
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <vector>
      27              : #include <set>
      28              : 
      29              : #include <utils/common/StringUtils.h>
      30              : #include <utils/common/SUMOTime.h>
      31              : #include <utils/common/ToString.h>
      32              : #include <utils/common/UtilExceptions.h>
      33              : #include "SUMOXMLDefinitions.h"
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // class declarations
      38              : // ===========================================================================
      39              : class Position;
      40              : class PositionVector;
      41              : class Boundary;
      42              : class RGBColor;
      43              : 
      44              : 
      45              : // ===========================================================================
      46              : // class definitions
      47              : // ===========================================================================
      48              : /**
      49              :  * @class SUMOSAXAttributes
      50              :  * @brief Encapsulated SAX-Attributes
      51              :  *
      52              :  * This class is an interface for using encapsulated SAX-attributes.
      53              :  * Encapsulation is done to allow a common access without the need to
      54              :  *  import all the Xerces-definitions.
      55              :  */
      56              : class SUMOSAXAttributes {
      57              : public:
      58              :     /* @brief Constructor
      59              :      * @param[in] tagName The name of the parsed object type; used for error message generation
      60              :      */
      61              :     SUMOSAXAttributes(const std::string& objectType);
      62              : 
      63              : 
      64              :     /// @brief Destructor
      65     16705362 :     virtual ~SUMOSAXAttributes() { }
      66              : 
      67              : 
      68              :     /** @brief Tries to read given attribute assuming it is an int
      69              :      *
      70              :      * If an error occurs (the attribute is not there, it is not numeric), "ok" is
      71              :      *  set to false. If report is true an error message is written to MsgHandler::getErrorInstance.
      72              :      *
      73              :      * If the value could be read, "ok" is not changed, and the value is returned.
      74              :      *
      75              :      * @param[in] attr The id of the attribute to read
      76              :      * @param[in] objectid The name of the parsed object; used for error message generation
      77              :      * @param[out] ok Whether the value could be read
      78              :      * @param[in] report Whether errors shall be written to msg handler's error instance
      79              :      * @return The read value if given and correct; -1 if an error occurred
      80              :      */
      81              :     template <typename T>
      82              :     T get(int attr, const char* objectid, bool& ok, bool report = true) const;
      83              : 
      84              : 
      85              :     /** @brief Tries to read given attribute assuming it is an int
      86              :      *
      87              :      * If the attribute is not existing in the current element, the default value is returned.
      88              :      * If an error occurs on parsing (the attribute is empty, it is not numeric), "ok" is
      89              :      *  set to false. If report is true an error message is written to MsgHandler::getErrorInstance.
      90              :      *
      91              :      * If the value could be read, "ok" is not changed, and the value is returned.
      92              :      *
      93              :      * @param[in] attr The id of the attribute to read
      94              :      * @param[in] objectid The name of the parsed object; used for error message generation
      95              :      * @param[out] ok Whether the value could be read
      96              :      * @param[in] defaultValue The value to return if the attribute is not within the element
      97              :      * @param[in] report Whether errors shall be written to msg handler's error instance
      98              :      * @return The read value if given and correct; the default value if the attribute does not exist;  -1 if an error occurred
      99              :      */
     100              :     template <typename T>
     101              :     T getOpt(int attr, const char* objectid, bool& ok, T defaultValue = T(), bool report = true) const;
     102              : 
     103              : 
     104              :     /** @brief Tries to read given attribute assuming it is a SUMOTime
     105              :      *
     106              :      * If an error occurs (the attribute is not there, it is not numeric), "ok" is
     107              :      *  set to false and an error message is written to MsgHandler::getErrorInstance.
     108              :      *
     109              :      * Otherwise, "ok" is not changed.
     110              :      *
     111              :      * In dependence to the used time representation, either get<int> or get<double>
     112              :      *  is used.
     113              :      *
     114              :      * @param[in] attr The id of the attribute to read
     115              :      * @param[in] objectid The name of the parsed object; used for error message generation
     116              :      * @param[out] ok Whether the value could be read
     117              :      * @param[in] report Whether errors shall be written to msg handler's error instance
     118              :      * @return The read value if given and correct; -1 if an error occurred
     119              :      */
     120              :     SUMOTime getSUMOTimeReporting(int attr, const char* objectid, bool& ok,
     121              :                                   bool report = true) const;
     122              : 
     123              : 
     124              :     /** @brief Tries to read the SUMOTime 'period' attribute
     125              :      *
     126              :      * If 'period' cannot be found, tries 'freq' as an alias.
     127              :      *
     128              :      * If an error occurs (the attribute is not there, it is not numeric), "ok" is
     129              :      *  set to false and an error message is written to MsgHandler::getErrorInstance.
     130              :      *
     131              :      * Otherwise, "ok" is not changed.
     132              :      *
     133              :      * In dependence to the used time representation, either get<int> or get<double>
     134              :      *  is used.
     135              :      *
     136              :      * @param[in] objectid The name of the parsed object; used for error message generation
     137              :      * @param[out] ok Whether the value could be read
     138              :      * @param[in] report Whether errors shall be written to msg handler's error instance
     139              :      * @return The read value if given and correct; -1 if an error occurred
     140              :      */
     141              :     SUMOTime getPeriod(const char* objectid, bool& ok, bool report = true) const;
     142              : 
     143              : 
     144              :     /** @brief Tries to read given attribute assuming it is a SUMOTime
     145              :      *
     146              :      * If the attribute is not existing in the current element, the default value is returned.
     147              :      * If an error occurs on parsing (the attribute is empty, it is not numeric), "ok" is
     148              :      *  set to false. If report is true an error message is written to MsgHandler::getErrorInstance.
     149              :      *
     150              :      * Otherwise, "ok" is not changed.
     151              :      *
     152              :      * In dependence to the used time representation, either get<int> or get<double>
     153              :      *  is used.
     154              :      *
     155              :      * @param[in] attr The id of the attribute to read
     156              :      * @param[in] objectid The name of the parsed object; used for error message generation
     157              :      * @param[out] ok Whether the value could be read
     158              :      * @param[in] defaultValue The value to return if the attribute is not within the element
     159              :      * @param[in] report Whether errors shall be written to msg handler's error instance
     160              :      * @return The read value if given and correct; the default value if the attribute does not exist;  -1 if an error occurred
     161              :      */
     162              :     SUMOTime getOptSUMOTimeReporting(int attr, const char* objectid, bool& ok,
     163              :                                      SUMOTime defaultValue, bool report = true) const;
     164              : 
     165              :     /** @brief Tries to read given attribute assuming it is a tls offset
     166              :      * (SUMOTime or "begin")
     167              :      *
     168              :      * If the attribute is not existing in the current element, the default value is returned.
     169              :      * If an error occurs on parsing (the attribute is empty, it is not numeric), "ok" is
     170              :      *  set to false. If report is true an error message is written to MsgHandler::getErrorInstance.
     171              :      *
     172              :      * Otherwise, "ok" is not changed.
     173              :      *
     174              :      * In dependence to the used time representation, either get<int> or get<double>
     175              :      *  is used.
     176              :      *
     177              :      * @param[in] attr The id of the attribute to read
     178              :      * @param[in] objectid The name of the parsed object; used for error message generation
     179              :      * @param[out] ok Whether the value could be read
     180              :      * @param[in] defaultValue The value to return if the attribute is not within the element
     181              :      * @param[in] report Whether errors shall be written to msg handler's error instance
     182              :      * @return The read value if given and correct; the default value if the attribute does not exist;  -1 if an error occurred
     183              :      */
     184              :     SUMOTime getOptOffsetReporting(int attr, const char* objectid, bool& ok,
     185              :                                      SUMOTime defaultValue, bool report = true) const;
     186              : 
     187              :     /** @brief Tries to read the SUMOTime 'period' attribute
     188              :      *
     189              :      * If 'period' cannot be found, tries 'freq' as an alias.
     190              :      *
     191              :      * If both attributes do not exist in the current element, the default value is returned.
     192              :      * If an error occurs on parsing (the attribute is empty, it is not numeric), "ok" is
     193              :      *  set to false. If report is true an error message is written to MsgHandler::getErrorInstance.
     194              :      *
     195              :      * Otherwise, "ok" is not changed.
     196              :      *
     197              :      * In dependence to the used time representation, either get<int> or get<double>
     198              :      *  is used.
     199              :      *
     200              :      * @param[in] objectid The name of the parsed object; used for error message generation
     201              :      * @param[out] ok Whether the value could be read
     202              :      * @param[in] defaultValue The value to return if the attribute is not within the element
     203              :      * @param[in] report Whether errors shall be written to msg handler's error instance
     204              :      * @return The read value if given and correct; the default value if the attribute does not exist;  -1 if an error occurred
     205              :      */
     206              :     SUMOTime getOptPeriod(const char* objectid, bool& ok, SUMOTime defaultValue, bool report = true) const;
     207              : 
     208              : 
     209              : 
     210              :     /// @name virtual methods for retrieving attribute values
     211              :     /// @{
     212              : 
     213              :     /** @brief Returns the information whether the named (by its enum-value) attribute is within the current list
     214              :      *
     215              :      * @param[in] id The id of the attribute to search for
     216              :      * @return Whether the attribute is within the attributes
     217              :      */
     218              :     virtual bool hasAttribute(int id) const = 0;
     219              : 
     220              : 
     221              :     /** @brief Returns the information whether the named attribute is within the current list
     222              :      *
     223              :      * @param[in] id The name of the attribute to search for
     224              :      * @return Whether the named attribute is within the attributes
     225              :      */
     226              :     virtual bool hasAttribute(const std::string& id) const = 0;
     227              : 
     228              : 
     229              :     /**
     230              :      * @brief Returns the bool-value of the named (by its enum-value) attribute
     231              :      *
     232              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     233              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2bool.
     234              :      *  If the attribute is empty or ==0, TplConvert<XMLCh>::_2bool throws an
     235              :      *  EmptyData-exception which is passed.
     236              :      * If the value can not be parsed to a bool, TplConvert<XMLCh>::_2bool throws a
     237              :      *  BoolFormatException-exception which is passed.
     238              :      *
     239              :      * @param[in] id The id of the attribute to return the value of
     240              :      * @return The attribute's value as a bool, if it could be read and parsed
     241              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     242              :      * @exception BoolFormatException If the attribute value can not be parsed to a bool
     243              :      */
     244              :     inline bool getBool(int id) const {
     245              :         return StringUtils::toBool(getString(id));
     246              :     }
     247              : 
     248              :     /**
     249              :      * @brief Returns the int-value of the named (by its enum-value) attribute
     250              :      *
     251              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     252              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2int.
     253              :      *  If the attribute is empty or ==0, TplConvert<XMLCh>::_2int throws an
     254              :      *  EmptyData-exception which is passed.
     255              :      * If the value can not be parsed to an int, TplConvert<XMLCh>::_2int throws a
     256              :      *  NumberFormatException-exception which is passed.
     257              :      *
     258              :      * @param[in] id The id of the attribute to return the value of
     259              :      * @return The attribute's value as an int, if it could be read and parsed
     260              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     261              :      * @exception NumberFormatException If the attribute value can not be parsed to an int
     262              :      */
     263         2056 :     inline int getInt(int id) const {
     264         4112 :         return StringUtils::toInt(getString(id));
     265              :     }
     266              : 
     267              : 
     268              :     /**
     269              :      * @brief Returns the long-value of the named (by its enum-value) attribute
     270              :      *
     271              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     272              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2long.
     273              :      *  If the attribute is empty or ==0, TplConvert<XMLCh>::_2long throws an
     274              :      *  EmptyData-exception which is passed.
     275              :      * If the value can not be parsed to a long, TplConvert<XMLCh>::_2long throws a
     276              :      *  NumberFormatException-exception which is passed.
     277              :      *
     278              :      * @param[in] id The id of the attribute to return the value of
     279              :      * @return The attribute's value as an int, if it could be read and parsed
     280              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     281              :      * @exception NumberFormatException If the attribute value can not be parsed to an int
     282              :      */
     283          185 :     virtual long long int getLong(int id) const {
     284          370 :         return StringUtils::toLong(getString(id));
     285              :     }
     286              : 
     287              : 
     288              :     /**
     289              :      * @brief Returns the string-value of the named (by its enum-value) attribute
     290              :      *
     291              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     292              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2str.
     293              :      *  If the attribute is ==0, TplConvert<XMLCh>::_2str throws an
     294              :      *  EmptyData-exception which is passed.
     295              :      *
     296              :      * @param[in] id The id of the attribute to return the value of
     297              :      * @return The attribute's value as a string, if it could be read and parsed
     298              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     299              :      */
     300              :     virtual std::string getString(int id, bool* isPresent = nullptr) const = 0;
     301              : 
     302              : 
     303              :     /**
     304              :      * @brief Returns the string-value of the named (by its enum-value) attribute
     305              :      *
     306              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     307              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2strSec.
     308              :      *  If the attribute is ==0, TplConvert<XMLCh>::_2strSec returns the default value.
     309              :      *
     310              :      * @param[in] id The id of the attribute to return the value of
     311              :      * @param[in] def The default value to return if the attribute is not in attributes
     312              :      * @return The attribute's value as a string, if it could be read and parsed
     313              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     314              :      */
     315              :     virtual std::string getStringSecure(int id, const std::string& def) const = 0;
     316              : 
     317              : 
     318              :     /**
     319              :      * @brief Returns the double-value of the named (by its enum-value) attribute
     320              :      *
     321              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     322              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2double.
     323              :      *  If the attribute is empty or ==0, TplConvert<XMLCh>::_2double throws an
     324              :      *  EmptyData-exception which is passed.
     325              :      * If the value can not be parsed to a double, TplConvert<XMLCh>::_2double throws a
     326              :      *  NumberFormatException-exception which is passed.
     327              :      *
     328              :      * @param[in] id The id of the attribute to return the value of
     329              :      * @return The attribute's value as a float, if it could be read and parsed
     330              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     331              :      * @exception NumberFormatException If the attribute value can not be parsed to an double
     332              :      */
     333        13980 :     inline double getFloat(int id) const {
     334        27960 :         return StringUtils::toDouble(getString(id));
     335              :     }
     336              : 
     337              : 
     338              :     /**
     339              :      * @brief Returns the double-value of the named attribute
     340              :      *
     341              :      * Tries to retrieve the attribute from the attribute list. The retrieved
     342              :      *  attribute  (which may be 0) is then parsed using TplConvert<XMLCh>::_2double.
     343              :      *  If the attribute is empty or ==0, TplConvert<XMLCh>::_2double throws an
     344              :      *  EmptyData-exception which is passed.
     345              :      * If the value can not be parsed to a double, TplConvert<XMLCh>::_2double throws a
     346              :      *  NumberFormatException-exception which is passed.
     347              :      *
     348              :      * @param[in] id The name of the attribute to return the value of
     349              :      * @return The attribute's value as a float, if it could be read and parsed
     350              :      * @exception EmptyData If the attribute is not known or the attribute value is an empty string
     351              :      * @exception NumberFormatException If the attribute value can not be parsed to an double
     352              :      */
     353              :     virtual double getFloat(const std::string& id) const = 0;
     354              : 
     355              : 
     356              :     /**
     357              :      * @brief Returns the string-value of the named (by its enum-value) attribute
     358              :      *
     359              :      * Tries to retrieve the attribute from the attribute list.
     360              :      *  If the attribute is ==0, TplConvert<XMLCh>::_2strSec returns the default value.
     361              :      * @param[in] id The name of the attribute to return the value of
     362              :      * @param[in] def The default value to return if the attribute is not in attributes
     363              :      * @return The attribute's value as a string, if it could be read and parsed
     364              :      */
     365              :     virtual std::string getStringSecure(const std::string& id,
     366              :                                         const std::string& def) const = 0;
     367              :     //}
     368              : 
     369              : 
     370              :     /** @brief Converts the given attribute id into a man readable string
     371              :      *
     372              :      * @param[in] attr The id of the attribute to return the name of
     373              :      * @return The name of the described attribute
     374              :      */
     375              :     virtual std::string getName(int attr) const = 0;
     376              : 
     377              :     /** @brief Prints all attribute names and values into the given stream
     378              :      *
     379              :      * @param[in] os The stream to use
     380              :      */
     381              :     virtual void serialize(std::ostream& os) const = 0;
     382              : 
     383              :     /** @brief Retrieves all attribute names
     384              :      */
     385              :     virtual std::vector<std::string> getAttributeNames() const = 0;
     386              : 
     387              :     /// @brief return the objecttype to which these attributes belong
     388              :     const std::string& getObjectType() const {
     389        10228 :         return myObjectType;
     390              :     }
     391              : 
     392              :     friend std::ostream& operator<<(std::ostream& os, const SUMOSAXAttributes& src);
     393              : 
     394              :     /// @brief return a new deep-copy attributes object
     395              :     virtual SUMOSAXAttributes* clone() const = 0;
     396              : 
     397              :     /** @brief The encoding of parsed strings */
     398              :     static const std::string ENCODING;
     399              : 
     400              : 
     401              : protected:
     402              :     template <typename T> T fromString(const std::string& value) const;
     403              :     void emitUngivenError(const std::string& attrname, const char* objectid) const;
     404              :     void emitEmptyError(const std::string& attrname, const char* objectid) const;
     405              :     void emitFormatError(const std::string& attrname, const std::string& type, const char* objectid) const;
     406              : 
     407              : private:
     408              :     /// @brief Invalidated copy constructor.
     409              :     SUMOSAXAttributes(const SUMOSAXAttributes& src) = delete;
     410              : 
     411              :     /// @brief Invalidated assignment operator.
     412              :     SUMOSAXAttributes& operator=(const SUMOSAXAttributes& src) = delete;
     413              : 
     414              :     /// @brief the object type to use in error reporting
     415              :     std::string myObjectType;
     416              : 
     417              : };
     418              : 
     419              : 
     420              : inline std::ostream& operator<<(std::ostream& os, const SUMOSAXAttributes& src) {
     421          136 :     src.serialize(os);
     422              :     return os;
     423              : }
     424              : 
     425              : 
     426              : template<typename X> struct invalid_return {
     427              :     static const X value;
     428              : };
     429              : 
     430              : #define INVALID_RETURN(TYPE) \
     431              : template<> struct invalid_return<TYPE> { \
     432              :     static const TYPE value; \
     433              : }
     434              : INVALID_RETURN(std::string);
     435              : INVALID_RETURN(int);
     436              : INVALID_RETURN(long long int);
     437              : INVALID_RETURN(double);
     438              : INVALID_RETURN(bool);
     439              : INVALID_RETURN(RGBColor);
     440              : INVALID_RETURN(Position);
     441              : INVALID_RETURN(PositionVector);
     442              : INVALID_RETURN(Boundary);
     443              : INVALID_RETURN(SumoXMLEdgeFunc);
     444              : INVALID_RETURN(SumoXMLNodeType);
     445              : INVALID_RETURN(RightOfWay);
     446              : INVALID_RETURN(FringeType);
     447              : INVALID_RETURN(ParkingType);
     448              : INVALID_RETURN(std::vector<std::string>);
     449              : INVALID_RETURN(std::vector<int>);
     450              : INVALID_RETURN(std::vector<double>);
     451              : 
     452              : 
     453              : template <typename T>
     454     54791471 : T SUMOSAXAttributes::get(int attr, const char* objectid,
     455              :                          bool& ok, bool report) const {
     456              :     try {
     457     54791471 :         bool isPresent = true;
     458     54791471 :         const std::string& strAttr = getString(attr, &isPresent);
     459     54791471 :         if (isPresent) {
     460     54791171 :             return fromString<T>(strAttr);
     461              :         }
     462          300 :         if (report) {
     463         9894 :             emitUngivenError(getName(attr), objectid);
     464              :         }
     465         9580 :     } catch (const FormatException& e) {
     466          244 :         if (report) {
     467          352 :             emitFormatError(getName(attr), e.what(), objectid);
     468              :         }
     469        18184 :     } catch (EmptyData&) {
     470         9092 :         if (report) {
     471          868 :             emitEmptyError(getName(attr), objectid);
     472              :         }
     473              :     }
     474         9636 :     ok = false;
     475         8877 :     return invalid_return<T>::value;
     476              : }
     477              : 
     478              : 
     479              : template <typename T>
     480     61050862 : T SUMOSAXAttributes::getOpt(int attr, const char* objectid,
     481              :                             bool& ok, T defaultValue, bool report) const {
     482              :     try {
     483     61050862 :         bool isPresent = true;
     484     61050862 :         const std::string& strAttr = getString(attr, &isPresent);
     485     61050862 :         if (isPresent) {
     486      8815004 :             return fromString<T>(strAttr);
     487              :         }
     488     27199246 :         return defaultValue;
     489          417 :     } catch (const FormatException& e) {
     490           58 :         if (report) {
     491          116 :             emitFormatError(getName(attr), e.what(), objectid);
     492              :         }
     493          602 :     } catch (EmptyData&) {
     494          301 :         if (report) {
     495          168 :             emitEmptyError(getName(attr), objectid);
     496              :         }
     497              :     }
     498          359 :     ok = false;
     499           84 :     return invalid_return<T>::value;
     500              : }
        

Generated by: LCOV version 2.0-1