LCOV - code coverage report
Current view: top level - src/utils/common - Parameterised.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 50 98 51.0 %
Date: 2024-05-02 15:31:40 Functions: 15 21 71.4 %

          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    Parameterised.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @date    Sept 2002
      17             : ///
      18             : // A super class for objects with additional parameters
      19             : /****************************************************************************/
      20             : #include <config.h>
      21             : #include <utils/common/MsgHandler.h>
      22             : #include <utils/common/StringUtils.h>
      23             : #include <utils/common/StringTokenizer.h>
      24             : #include <utils/iodevices/OutputDevice.h>
      25             : 
      26             : #include "Parameterised.h"
      27             : 
      28             : 
      29             : // ===========================================================================
      30             : // method definitions
      31             : // ===========================================================================
      32             : 
      33    10781442 : Parameterised::Parameterised() {}
      34             : 
      35             : 
      36      228475 : Parameterised::Parameterised(const Parameterised::Map& mapArg) :
      37      228475 :     myMap(mapArg) {
      38      228475 : }
      39             : 
      40             : 
      41    33955429 : Parameterised::~Parameterised() {}
      42             : 
      43             : 
      44             : void
      45    12273634 : Parameterised::setParameter(const std::string& key, const std::string& value) {
      46    12273634 :     myMap[key] = value;
      47    12273634 : }
      48             : 
      49             : 
      50             : void
      51       99316 : Parameterised::unsetParameter(const std::string& key) {
      52             :     myMap.erase(key);
      53       99316 : }
      54             : 
      55             : 
      56             : void
      57     2102361 : Parameterised::updateParameters(const Parameterised::Map& mapArg) {
      58     2141312 :     for (const auto& keyValue : mapArg) {
      59       38951 :         setParameter(keyValue.first, keyValue.second);
      60             :     }
      61     2102361 : }
      62             : 
      63             : 
      64             : void
      65        9354 : Parameterised::mergeParameters(const Parameterised::Map& mapArg, const std::string separator, bool uniqueValues) {
      66       12259 :     for (const auto& keyValue : mapArg) {
      67        2905 :         if (hasParameter(keyValue.first)) {
      68             :             bool append = true;
      69        1335 :             if (uniqueValues) {
      70        1342 :                 if (getParameter(keyValue.first) == keyValue.second) {
      71             :                     append = false;
      72             :                 }
      73             :             }
      74             :             if (append) {
      75          24 :                 setParameter(keyValue.first, getParameter(keyValue.first) + separator + keyValue.second);
      76             :             }
      77             :         } else {
      78        1570 :             setParameter(keyValue.first, keyValue.second);
      79             :         }
      80             :     }
      81        9354 : }
      82             : 
      83             : bool
      84   313225760 : Parameterised::hasParameter(const std::string& key) const {
      85   313225760 :     return myMap.find(key) != myMap.end();
      86             : }
      87             : 
      88             : 
      89             : const std::string
      90     9649147 : Parameterised::getParameter(const std::string& key, const std::string defaultValue) const {
      91             :     const auto i = myMap.find(key);
      92     9649147 :     if (i != myMap.end()) {
      93             :         return i->second;
      94             :     }
      95             :     return defaultValue;
      96             : }
      97             : 
      98             : 
      99             : double
     100     8251795 : Parameterised::getDouble(const std::string& key, const double defaultValue) const {
     101             :     const auto i = myMap.find(key);
     102     8251795 :     if (i != myMap.end()) {
     103             :         try {
     104        4059 :             return StringUtils::toDouble(i->second);
     105           0 :         } catch (NumberFormatException&) {
     106           0 :             WRITE_WARNINGF(TL("Invalid conversion from string to double (%)"), i->second);
     107             :             return defaultValue;
     108           0 :         } catch (EmptyData&) {
     109           0 :             WRITE_WARNING(TL("Invalid conversion from string to double (empty value)"));
     110             :             return defaultValue;
     111           0 :         }
     112             :     }
     113             :     return defaultValue;
     114             : }
     115             : 
     116             : 
     117             : std::vector<double>
     118           0 : Parameterised::getDoubles(const std::string& key, std::vector<double> defaultValue) const {
     119             :     const auto i = myMap.find(key);
     120           0 :     if (i != myMap.end()) {
     121             :         try {
     122             :             std::vector<double> result;
     123           0 :             for (const std::string& s : StringTokenizer(i->second).getVector()) {
     124           0 :                 result.push_back(StringUtils::toDouble(s));
     125           0 :             }
     126             :             return result;
     127           0 :         } catch (NumberFormatException&) {
     128           0 :             WRITE_WARNINGF(TL("Invalid conversion from string to doubles (%)"), i->second);
     129             :             return defaultValue;
     130           0 :         } catch (EmptyData&) {
     131           0 :             WRITE_WARNING(TL("Invalid conversion from string to doubles (empty value)"));
     132             :             return defaultValue;
     133           0 :         }
     134             :     }
     135             :     return defaultValue;
     136             : }
     137             : 
     138             : void
     139     1439612 : Parameterised::clearParameter() {
     140             :     myMap.clear();
     141     1439612 : }
     142             : 
     143             : 
     144             : const Parameterised::Map&
     145     7485405 : Parameterised::getParametersMap() const {
     146     7485405 :     return myMap;
     147             : }
     148             : 
     149             : 
     150             : std::string
     151           0 : Parameterised::getParametersStr(const std::string kvsep, const std::string sep) const {
     152             :     std::string result;
     153             :     // Generate an string using configurable seperatrs, default: "key1=value1|key2=value2|...|keyN=valueN"
     154             :     bool addSep = false;
     155           0 :     for (const auto& keyValue : myMap) {
     156           0 :         if (addSep) {
     157             :             result += sep;
     158             :         }
     159           0 :         result += keyValue.first + kvsep + keyValue.second;
     160             :         addSep = true;
     161             :     }
     162           0 :     return result;
     163             : }
     164             : 
     165             : 
     166             : void
     167     1077446 : Parameterised::setParameters(const Parameterised& params) {
     168     1077446 :     myMap = params.getParametersMap();
     169     1077446 : }
     170             : 
     171             : 
     172             : void
     173         606 : Parameterised::setParametersStr(const std::string& paramsString, const std::string kvsep, const std::string sep) {
     174             :     // clear parameters
     175             :     myMap.clear();
     176             :     // separate value in a vector of string using | as separator
     177        1218 :     std::vector<std::string> parameters = StringTokenizer(paramsString, sep).getVector();
     178             :     // iterate over all values
     179         612 :     for (const auto& keyValue : parameters) {
     180             :         // obtain key and value and save it in myParameters
     181          18 :         std::vector<std::string> keyValueStr = StringTokenizer(keyValue, kvsep).getVector();
     182           6 :         setParameter(keyValueStr.front(), keyValueStr.back());
     183           6 :     }
     184         606 : }
     185             : 
     186             : 
     187             : void
     188     1385436 : Parameterised::writeParams(OutputDevice& device) const {
     189             :     // iterate over all parameters and write it
     190     1479601 :     for (const auto& keyValue : myMap) {
     191       94165 :         device.openTag(SUMO_TAG_PARAM);
     192       94165 :         device.writeAttr(SUMO_ATTR_KEY, StringUtils::escapeXML(keyValue.first));
     193       94165 :         device.writeAttr(SUMO_ATTR_VALUE, StringUtils::escapeXML(keyValue.second));
     194      188330 :         device.closeTag();
     195             :     }
     196     1385436 : }
     197             : 
     198             : 
     199             : bool
     200           0 : Parameterised::areParametersValid(const std::string& value, bool report, const std::string kvsep, const std::string sep) {
     201           0 :     std::vector<std::string> parameters = StringTokenizer(value, sep).getVector();
     202             :     // first check if parsed parameters are valid
     203           0 :     for (const auto& keyValueStr : parameters) {
     204             :         // check if parameter is valid
     205           0 :         if (!isParameterValid(keyValueStr, kvsep, sep)) {
     206             :             // report depending of flag
     207           0 :             if (report) {
     208           0 :                 WRITE_WARNINGF(TL("Invalid format of parameter (%)"), keyValueStr);
     209             :             }
     210             :             return false;
     211             :         }
     212             :     }
     213             :     // all ok, then return true
     214             :     return true;
     215           0 : }
     216             : 
     217             : 
     218             : bool
     219           0 : Parameterised::areAttributesValid(const std::string& value, bool report, const std::string kvsep, const std::string sep) {
     220           0 :     std::vector<std::string> parameters = StringTokenizer(value, sep).getVector();
     221             :     // first check if parsed parameters are valid
     222           0 :     for (const auto& keyValueStr : parameters) {
     223             :         // check if parameter is valid
     224           0 :         if (isParameterValid(keyValueStr, kvsep, sep)) {
     225             :             // separate key and value
     226           0 :             const auto attr = StringTokenizer(value, kvsep).getVector().front();
     227             :             // get first letter
     228           0 :             const auto letter = StringTokenizer(value, kvsep).getVector().front().front();
     229             :             // check key
     230           0 :             if (!((letter >= 'a') && (letter <= 'z')) && !((letter >= 'A') && (letter <= 'Z'))) {
     231             :                 // report depending of flag
     232           0 :                 if (report) {
     233           0 :                     WRITE_WARNINGF(TL("Invalid format of attribute '%'. Attribute must start with a letter"), attr);
     234             :                 }
     235             :                 return false;
     236             :             }
     237             :         } else {
     238             :             // report depending of flag
     239           0 :             if (report) {
     240           0 :                 WRITE_WARNINGF(TL("Invalid format of attribute (%)"), keyValueStr);
     241             :             }
     242           0 :             return false;
     243             :         }
     244             :     }
     245             :     // all ok, then return true
     246             :     return true;
     247           0 : }
     248             : 
     249             : // ===========================================================================
     250             : // private
     251             : // ===========================================================================
     252             : 
     253             : bool
     254           0 : Parameterised::isParameterValid(const std::string& value, const std::string& kvsep, const std::string& sep) {
     255           0 :     if (value.find(sep) != std::string::npos || value.find(kvsep) == std::string::npos) {
     256           0 :         return false;
     257             :     }
     258             :     // separate key and value
     259           0 :     std::vector<std::string> keyValueStr = StringTokenizer(value, kvsep).getVector();
     260             :     // Check that keyValue size is exactly 2 (key, value)
     261           0 :     if (keyValueStr.size() == 2) {
     262             :         // check if key and value contains valid characters
     263           0 :         if (SUMOXMLDefinitions::isValidParameterKey(keyValueStr.front()) == false) {
     264             :             return false;
     265             :         } else {
     266             :             // key=value valid, then return true
     267           0 :             return true;
     268             :         }
     269             :     } else {
     270             :         // invalid format
     271             :         return false;
     272             :     }
     273           0 : }
     274             : 
     275             : /****************************************************************************/

Generated by: LCOV version 1.14