LCOV - code coverage report
Current view: top level - src/utils/xml - SUMOSAXAttributes.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 154 192 80.2 %
Date: 2024-05-06 15:32:35 Functions: 23 25 92.0 %

          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.cpp
      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             : #include <config.h>
      23             : 
      24             : #include <string>
      25             : #include <iostream>
      26             : #include <sstream>
      27             : #include <utils/common/MsgHandler.h>
      28             : #include <utils/common/RGBColor.h>
      29             : #include <utils/common/StringTokenizer.h>
      30             : #include <utils/common/StringUtils.h>
      31             : #include <utils/geom/Boundary.h>
      32             : #include <utils/geom/PositionVector.h>
      33             : #include "SUMOSAXAttributes.h"
      34             : 
      35             : 
      36             : // ===========================================================================
      37             : // static members
      38             : // ===========================================================================
      39             : const std::string SUMOSAXAttributes::ENCODING = " encoding=\"UTF-8\"";
      40             : 
      41             : 
      42             : // ===========================================================================
      43             : // method definitions
      44             : // ===========================================================================
      45    16588388 : SUMOSAXAttributes::SUMOSAXAttributes(const std::string& objectType):
      46    16588388 :     myObjectType(objectType) {}
      47             : 
      48             : 
      49             : const std::string invalid_return<std::string>::value = "";
      50             : template<>
      51    31683916 : std::string SUMOSAXAttributes::fromString(const std::string& value) const {
      52    31683916 :     if (value == "") {
      53         998 :         throw EmptyData();
      54             :     }
      55    31682918 :     return value;
      56             : }
      57             : 
      58             : 
      59             : SUMOTime
      60      587791 : SUMOSAXAttributes::getSUMOTimeReporting(int attr, const char* objectid,
      61             :                                         bool& ok, bool report) const {
      62             :     try {
      63      587791 :         bool isPresent = true;
      64      587791 :         const std::string& val = getString(attr, &isPresent);
      65      587791 :         if (!isPresent) {
      66          13 :             if (report) {
      67          50 :                 emitUngivenError(getName(attr), objectid);
      68             :             }
      69          13 :             ok = false;
      70          13 :             return -1;
      71             :         }
      72      587778 :         return string2time(val);
      73          24 :     } catch (EmptyData&) {
      74          12 :         if (report) {
      75          24 :             emitEmptyError(getName(attr), objectid);
      76             :         }
      77          24 :     } catch (ProcessError&) {
      78          12 :         if (report) {
      79          36 :             emitFormatError(getName(attr), "is not a valid time value", objectid);
      80             :         }
      81          12 :     }
      82          24 :     ok = false;
      83          24 :     return -1;
      84             : }
      85             : 
      86             : 
      87             : SUMOTime
      88        1071 : SUMOSAXAttributes::getPeriod(const char* objectid, bool& ok, bool report) const {
      89             :     int attr = SUMO_ATTR_PERIOD;
      90             :     try {
      91        1071 :         bool isPresent = true;
      92        1071 :         const std::string& val = getString(attr, &isPresent);
      93        1071 :         if (!isPresent) {
      94             :             // try 'freq' as alias for 'period'
      95             :             attr = SUMO_ATTR_FREQUENCY;
      96        1046 :             isPresent = true;
      97        1046 :             const std::string& valFreq = getString(attr, &isPresent);
      98        1046 :             if (!isPresent) {
      99        1046 :                 if (report) {
     100           0 :                     emitUngivenError(getName(SUMO_ATTR_PERIOD), objectid);
     101             :                 }
     102        1046 :                 ok = false;
     103        1046 :                 return -1;
     104             :             }
     105           0 :             return string2time(valFreq);
     106             :         }
     107          25 :         return string2time(val);
     108           0 :     } catch (EmptyData&) {
     109           0 :         if (report) {
     110           0 :             emitEmptyError(getName(attr), objectid);
     111             :         }
     112           0 :     } catch (ProcessError&) {
     113           0 :         if (report) {
     114           0 :             emitFormatError(getName(attr), "is not a valid time value", objectid);
     115             :         }
     116           0 :     }
     117           0 :     ok = false;
     118           0 :     return -1;
     119             : }
     120             : 
     121             : 
     122             : SUMOTime
     123     5261420 : SUMOSAXAttributes::getOptSUMOTimeReporting(int attr, const char* objectid,
     124             :         bool& ok, SUMOTime defaultValue, bool report) const {
     125             :     try {
     126     5261420 :         bool isPresent = true;
     127     5261420 :         const std::string& val = getString(attr, &isPresent);
     128     5261420 :         if (!isPresent) {
     129             :             return defaultValue;
     130             :         }
     131      157203 :         return string2time(val);
     132          36 :     } catch (EmptyData&) {
     133           0 :         if (report) {
     134           0 :             emitEmptyError(getName(attr), objectid);
     135             :         }
     136          36 :     } catch (ProcessError&) {
     137          36 :         if (report) {
     138         108 :             emitFormatError(getName(attr), "is not a valid time value", objectid);
     139             :         }
     140          36 :     }
     141          36 :     ok = false;
     142          36 :     return -1;
     143             : }
     144             : 
     145             : 
     146             : SUMOTime
     147       15187 : SUMOSAXAttributes::getOptPeriod(const char* objectid, bool& ok, SUMOTime defaultValue, bool report) const {
     148             :     int attr = SUMO_ATTR_PERIOD;
     149             :     try {
     150       15187 :         bool isPresent = true;
     151       15187 :         const std::string& val = getString(attr, &isPresent);
     152       15187 :         if (!isPresent) {
     153             :             // try 'freq' as alias for 'period'
     154             :             attr = SUMO_ATTR_FREQUENCY;
     155       11417 :             isPresent = true;
     156       11417 :             const std::string& valFreq = getString(attr, &isPresent);
     157       11417 :             if (!isPresent) {
     158             :                 return defaultValue;
     159             :             }
     160       10107 :             return string2time(valFreq);
     161             :         }
     162        3770 :         return string2time(val);
     163          40 :     } catch (EmptyData&) {
     164          20 :         if (report) {
     165          40 :             emitEmptyError(getName(attr), objectid);
     166             :         }
     167          40 :     } catch (ProcessError&) {
     168          20 :         if (report) {
     169          60 :             emitFormatError(getName(attr), "is not a valid time value", objectid);
     170             :         }
     171          20 :     }
     172          40 :     ok = false;
     173          40 :     return -1;
     174             : }
     175             : 
     176             : 
     177             : void
     178         437 : SUMOSAXAttributes::emitUngivenError(const std::string& attrname, const char* objectid) const {
     179         437 :     std::ostringstream oss;
     180         437 :     oss << "Attribute '" << attrname << "' is missing in definition of ";
     181         437 :     if (objectid == nullptr || objectid[0] == 0) {
     182             :         oss << "a " << myObjectType;
     183             :     } else {
     184         240 :         oss << myObjectType << " '" << objectid << "'";
     185             :     }
     186         437 :     oss << ".";
     187         437 :     WRITE_ERROR(oss.str());
     188         437 : }
     189             : 
     190             : 
     191             : void
     192         695 : SUMOSAXAttributes::emitEmptyError(const std::string& attrname, const char* objectid) const {
     193         695 :     std::ostringstream oss;
     194         695 :     oss << "Attribute '" << attrname << "' in definition of ";
     195         695 :     if (objectid == nullptr || objectid[0] == 0) {
     196             :         oss << "a " << myObjectType;
     197             :     } else {
     198         452 :         oss << myObjectType << " '" << objectid << "'";
     199             :     }
     200         695 :     oss << " is empty.";
     201         695 :     WRITE_ERROR(oss.str());
     202         695 : }
     203             : 
     204             : 
     205             : void
     206         462 : SUMOSAXAttributes::emitFormatError(const std::string& attrname, const std::string& type, const char* objectid) const {
     207         462 :     std::ostringstream oss;
     208         462 :     oss << "Attribute '" << attrname << "' in definition of ";
     209         462 :     if (objectid == nullptr || objectid[0] == 0) {
     210             :         oss << "a " << myObjectType;
     211             :     } else {
     212         442 :         oss << myObjectType << " '" << objectid << "'";
     213             :     }
     214         462 :     oss << " " << type << ".";
     215         462 :     WRITE_ERROR(oss.str());
     216         462 : }
     217             : 
     218             : 
     219             : const int invalid_return<int>::value = -1;
     220             : template<>
     221    10776349 : int SUMOSAXAttributes::fromString(const std::string& value) const {
     222    10776349 :     return StringUtils::toInt(value);
     223             : }
     224             : 
     225             : 
     226             : const long long int invalid_return<long long int>::value = -1;
     227             : template<>
     228     1556383 : long long int SUMOSAXAttributes::fromString(const std::string& value) const {
     229     1556383 :     return StringUtils::toLong(value);
     230             : }
     231             : 
     232             : 
     233             : const double invalid_return<double>::value = -1;
     234             : template<>
     235     8121206 : double SUMOSAXAttributes::fromString(const std::string& value) const {
     236     8121206 :     return StringUtils::toDouble(value);
     237             : }
     238             : 
     239             : 
     240             : const bool invalid_return<bool>::value = false;
     241             : template<>
     242      766598 : bool SUMOSAXAttributes::fromString(const std::string& value) const {
     243      766598 :     return StringUtils::toBool(value);
     244             : }
     245             : 
     246             : 
     247             : const RGBColor invalid_return<RGBColor>::value = RGBColor();
     248             : template<>
     249       66231 : RGBColor SUMOSAXAttributes::fromString(const std::string& value) const {
     250      132454 :     return RGBColor::parseColor(value);
     251             : }
     252             : 
     253             : 
     254             : const Position invalid_return<Position>::value = Position();
     255             : template<>
     256           0 : Position SUMOSAXAttributes::fromString(const std::string& value) const {
     257           0 :     StringTokenizer st(value);
     258             :     // check StringTokenizer
     259           0 :     while (st.hasNext()) {
     260             :         // obtain position
     261           0 :         StringTokenizer pos(st.next(), ",");
     262             :         // check that position has X-Y or X-Y-Z
     263           0 :         if ((pos.size() != 2) && (pos.size() != 3)) {
     264           0 :             throw FormatException("is not a valid position");
     265             :         }
     266             :         // obtain x and y
     267           0 :         double x = StringUtils::toDouble(pos.next());
     268           0 :         double y = StringUtils::toDouble(pos.next());
     269             :         // check if return a X-Y or a X-Y-Z Position
     270           0 :         if (pos.size() == 2) {
     271             :             return Position(x, y);
     272             :         } else {
     273             :             // obtain z
     274           0 :             double z = StringUtils::toDouble(pos.next());
     275             :             return Position(x, y, z);
     276             :         }
     277           0 :     }
     278             :     // empty positions aren't allowed
     279           0 :     throw FormatException("is not a valid position");
     280           0 : }
     281             : 
     282             : 
     283             : const PositionVector invalid_return<PositionVector>::value = PositionVector();
     284             : template<>
     285     2560212 : PositionVector SUMOSAXAttributes::fromString(const std::string& value) const {
     286     2560212 :     StringTokenizer st(value);
     287     2560212 :     PositionVector shape;
     288    11775990 :     while (st.hasNext()) {
     289    18431972 :         StringTokenizer pos(st.next(), ",");
     290     9215986 :         if (pos.size() != 2 && pos.size() != 3) {
     291         164 :             throw FormatException("is not a valid list of positions");
     292             :         }
     293     9215904 :         double x = StringUtils::toDouble(pos.next());
     294     9216028 :         double y = StringUtils::toDouble(pos.next());
     295     9215778 :         if (pos.size() == 2) {
     296     9187916 :             shape.push_back(Position(x, y));
     297             :         } else {
     298       27862 :             double z = StringUtils::toDouble(pos.next());
     299       27862 :             shape.push_back(Position(x, y, z));
     300             :         }
     301     9215986 :     }
     302     2560004 :     return shape;
     303     2560420 : }
     304             : 
     305             : 
     306             : const Boundary invalid_return<Boundary>::value = Boundary();
     307             : template<>
     308       83756 : Boundary SUMOSAXAttributes::fromString(const std::string& value) const {
     309      251268 :     StringTokenizer st(value, ",");
     310       83756 :     if (st.size() != 4) {
     311           0 :         throw FormatException("is not a valid boundary");
     312             :     }
     313       83756 :     const double xmin = StringUtils::toDouble(st.next());
     314       83756 :     const double ymin = StringUtils::toDouble(st.next());
     315       83756 :     const double xmax = StringUtils::toDouble(st.next());
     316       83756 :     const double ymax = StringUtils::toDouble(st.next());
     317      167512 :     return Boundary(xmin, ymin, xmax, ymax);
     318       83756 : }
     319             : 
     320             : 
     321             : const SumoXMLEdgeFunc invalid_return<SumoXMLEdgeFunc>::value = SumoXMLEdgeFunc::NORMAL;
     322             : template<>
     323     1093751 : SumoXMLEdgeFunc SUMOSAXAttributes::fromString(const std::string& value) const {
     324     1093751 :     if (SUMOXMLDefinitions::EdgeFunctions.hasString(value)) {
     325     1093731 :         return SUMOXMLDefinitions::EdgeFunctions.get(value);
     326             :     }
     327          40 :     throw FormatException("is not a valid edge function");
     328             : }
     329             : 
     330             : 
     331             : const SumoXMLNodeType invalid_return<SumoXMLNodeType>::value = SumoXMLNodeType::UNKNOWN;
     332             : template<>
     333      600675 : SumoXMLNodeType SUMOSAXAttributes::fromString(const std::string& value) const {
     334      600675 :     if (SUMOXMLDefinitions::NodeTypes.hasString(value)) {
     335      600615 :         return SUMOXMLDefinitions::NodeTypes.get(value);
     336             :     }
     337         120 :     throw FormatException("is not a valid node type");
     338             : }
     339             : 
     340             : 
     341             : const RightOfWay invalid_return<RightOfWay>::value = RightOfWay::DEFAULT;
     342             : template<>
     343           4 : RightOfWay SUMOSAXAttributes::fromString(const std::string& value) const {
     344           4 :     if (SUMOXMLDefinitions::RightOfWayValues.hasString(value)) {
     345           4 :         return SUMOXMLDefinitions::RightOfWayValues.get(value);
     346             :     }
     347           0 :     throw FormatException("is not a valid right of way value");
     348             : }
     349             : 
     350             : 
     351             : const FringeType invalid_return<FringeType>::value = FringeType::DEFAULT;
     352             : template<>
     353         190 : FringeType SUMOSAXAttributes::fromString(const std::string& value) const {
     354         190 :     if (SUMOXMLDefinitions::FringeTypeValues.hasString(value)) {
     355         190 :         return SUMOXMLDefinitions::FringeTypeValues.get(value);
     356             :     }
     357           0 :     throw FormatException("is not a valid fringe type");
     358             : }
     359             : 
     360             : 
     361             : const ParkingType invalid_return<ParkingType>::value = ParkingType::ONROAD;
     362             : template<>
     363         892 : ParkingType SUMOSAXAttributes::fromString(const std::string& value) const {
     364         892 :     if (value == toString(ParkingType::OPPORTUNISTIC)) {
     365             :         return ParkingType::OPPORTUNISTIC;
     366             :     } else {
     367         892 :         return StringUtils::toBool(value) ? ParkingType::OFFROAD : ParkingType::ONROAD;
     368             :     }
     369             : }
     370             : 
     371             : 
     372             : const std::vector<std::string> invalid_return<std::vector<std::string> >::value = std::vector<std::string>();
     373             : template<>
     374       33739 : std::vector<std::string> SUMOSAXAttributes::fromString(const std::string& value) const {
     375       42105 :     const std::vector<std::string>& ret = StringTokenizer(value).getVector();
     376       33739 :     if (ret.empty()) {
     377       13528 :         throw EmptyData();
     378             :     }
     379       40422 :     return ret;
     380       33739 : }
     381             : 
     382             : 
     383             : const std::vector<int> invalid_return<std::vector<int> >::value = std::vector<int>();
     384             : template<>
     385         215 : std::vector<int> SUMOSAXAttributes::fromString(const std::string& value) const {
     386         217 :     const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
     387         215 :     if (tmp.empty()) {
     388           0 :         throw EmptyData();
     389             :     }
     390             :     std::vector<int> ret;
     391         525 :     for (const std::string& s : tmp) {
     392         310 :         ret.push_back(StringUtils::toInt(s));
     393             :     }
     394         215 :     return ret;
     395         215 : }
     396             : 
     397             : 
     398             : const std::vector<double> invalid_return<std::vector<double> >::value = std::vector<double>();
     399             : template<>
     400           0 : std::vector<double> SUMOSAXAttributes::fromString(const std::string& value) const {
     401           0 :     const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
     402           0 :     if (tmp.empty()) {
     403           0 :         throw EmptyData();
     404             :     }
     405             :     std::vector<double> ret;
     406           0 :     for (const std::string& s : tmp) {
     407           0 :         ret.push_back(StringUtils::toDouble(s));
     408             :     }
     409           0 :     return ret;
     410           0 : }
     411             : 
     412             : /****************************************************************************/

Generated by: LCOV version 1.14