LCOV - code coverage report
Current view: top level - src/utils/common - Parameterised.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 51.5 % 97 50
Test Date: 2024-11-22 15:46:21 Functions: 71.4 % 21 15

            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     11619770 : Parameterised::Parameterised() {}
      34              : 
      35              : 
      36       231784 : Parameterised::Parameterised(const Parameterised::Map& mapArg) :
      37       231784 :     myMap(mapArg) {
      38       231784 : }
      39              : 
      40              : 
      41     30364164 : Parameterised::~Parameterised() {}
      42              : 
      43              : 
      44              : void
      45      4921504 : Parameterised::setParameter(const std::string& key, const std::string& value) {
      46      4921504 :     myMap[key] = value;
      47      4921504 : }
      48              : 
      49              : 
      50              : void
      51        72125 : Parameterised::unsetParameter(const std::string& key) {
      52              :     myMap.erase(key);
      53        72125 : }
      54              : 
      55              : 
      56              : void
      57      2410808 : Parameterised::updateParameters(const Parameterised::Map& mapArg) {
      58      2445672 :     for (const auto& keyValue : mapArg) {
      59        34864 :         setParameter(keyValue.first, keyValue.second);
      60              :     }
      61      2410808 : }
      62              : 
      63              : 
      64              : void
      65         5416 : Parameterised::mergeParameters(const Parameterised::Map& mapArg, const std::string separator, bool uniqueValues) {
      66         7107 :     for (const auto& keyValue : mapArg) {
      67         1691 :         if (hasParameter(keyValue.first)) {
      68              :             bool append = true;
      69          877 :             if (uniqueValues) {
      70         1754 :                 if (getParameter(keyValue.first) == keyValue.second) {
      71              :                     append = false;
      72              :                 }
      73              :             }
      74              :             if (append) {
      75           36 :                 setParameter(keyValue.first, getParameter(keyValue.first) + separator + keyValue.second);
      76              :             }
      77              :         } else {
      78          814 :             setParameter(keyValue.first, keyValue.second);
      79              :         }
      80              :     }
      81         5416 : }
      82              : 
      83              : bool
      84    448472137 : Parameterised::hasParameter(const std::string& key) const {
      85    448472137 :     return myMap.find(key) != myMap.end();
      86              : }
      87              : 
      88              : 
      89              : const std::string
      90      9841933 : Parameterised::getParameter(const std::string& key, const std::string defaultValue) const {
      91              :     const auto i = myMap.find(key);
      92      9841933 :     if (i != myMap.end()) {
      93              :         return i->second;
      94              :     }
      95              :     return defaultValue;
      96              : }
      97              : 
      98              : 
      99              : double
     100      9650541 : Parameterised::getDouble(const std::string& key, const double defaultValue) const {
     101              :     const auto i = myMap.find(key);
     102      9650541 :     if (i != myMap.end()) {
     103              :         try {
     104         3416 :             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      1737900 : Parameterised::clearParameter() {
     140              :     myMap.clear();
     141      1737900 : }
     142              : 
     143              : 
     144              : const Parameterised::Map&
     145      8195375 : Parameterised::getParametersMap() const {
     146      8195375 :     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      1150553 : Parameterised::setParameters(const Parameterised& params) {
     168      1150553 :     myMap = params.getParametersMap();
     169      1150553 : }
     170              : 
     171              : 
     172              : void
     173          632 : 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         1264 :     std::vector<std::string> parameters = StringTokenizer(paramsString, sep).getVector();
     178              :     // iterate over all values
     179          638 :     for (const auto& keyValue : parameters) {
     180              :         // obtain key and value and save it in myParameters
     181           12 :         std::vector<std::string> keyValueStr = StringTokenizer(keyValue, kvsep).getVector();
     182            6 :         setParameter(keyValueStr.front(), keyValueStr.back());
     183            6 :     }
     184          632 : }
     185              : 
     186              : 
     187              : void
     188       975621 : Parameterised::writeParams(OutputDevice& device) const {
     189              :     // iterate over all parameters and write it
     190      1031073 :     for (const auto& keyValue : myMap) {
     191        55452 :         device.openTag(SUMO_TAG_PARAM);
     192        55452 :         device.writeAttr(SUMO_ATTR_KEY, StringUtils::escapeXML(keyValue.first));
     193        55452 :         device.writeAttr(SUMO_ATTR_VALUE, StringUtils::escapeXML(keyValue.second));
     194       110904 :         device.closeTag();
     195              :     }
     196       975621 : }
     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              :             return true;
     268              :         }
     269              :     } else {
     270              :         // invalid format
     271              :         return false;
     272              :     }
     273            0 : }
     274              : 
     275              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1