LCOV - code coverage report
Current view: top level - src/utils/xml - SUMOSAXAttributes.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 76.8 % 203 156
Test Date: 2024-11-20 15:55:46 Functions: 92.3 % 26 24

            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     16705363 : SUMOSAXAttributes::SUMOSAXAttributes(const std::string& objectType):
      46     16705363 :     myObjectType(objectType) {}
      47              : 
      48              : 
      49              : const std::string invalid_return<std::string>::value = "";
      50              : template<>
      51     34383631 : std::string SUMOSAXAttributes::fromString(const std::string& value) const {
      52     34383631 :     if (value == "") {
      53          683 :         throw EmptyData();
      54              :     }
      55     34382948 :     return value;
      56              : }
      57              : 
      58              : 
      59              : SUMOTime
      60       551120 : SUMOSAXAttributes::getSUMOTimeReporting(int attr, const char* objectid,
      61              :                                         bool& ok, bool report) const {
      62              :     try {
      63       551120 :         bool isPresent = true;
      64       551120 :         const std::string& val = getString(attr, &isPresent);
      65       551120 :         if (!isPresent) {
      66           13 :             if (report) {
      67           50 :                 emitUngivenError(getName(attr), objectid);
      68              :             }
      69           13 :             ok = false;
      70           13 :             return -1;
      71              :         }
      72       551107 :         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           24 :             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          559 : SUMOSAXAttributes::getPeriod(const char* objectid, bool& ok, bool report) const {
      89              :     int attr = SUMO_ATTR_PERIOD;
      90              :     try {
      91          559 :         bool isPresent = true;
      92          559 :         const std::string& val = getString(attr, &isPresent);
      93          559 :         if (!isPresent) {
      94              :             // try 'freq' as alias for 'period'
      95              :             attr = SUMO_ATTR_FREQUENCY;
      96          528 :             isPresent = true;
      97          528 :             const std::string& valFreq = getString(attr, &isPresent);
      98          528 :             if (!isPresent) {
      99          528 :                 if (report) {
     100            0 :                     emitUngivenError(getName(SUMO_ATTR_PERIOD), objectid);
     101              :                 }
     102          528 :                 ok = false;
     103          528 :                 return -1;
     104              :             }
     105            0 :             return string2time(valFreq);
     106              :         }
     107           31 :         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      4728267 : SUMOSAXAttributes::getOptSUMOTimeReporting(int attr, const char* objectid,
     124              :         bool& ok, SUMOTime defaultValue, bool report) const {
     125              :     try {
     126      4728267 :         bool isPresent = true;
     127      4728267 :         const std::string& val = getString(attr, &isPresent);
     128      4728267 :         if (!isPresent) {
     129              :             return defaultValue;
     130              :         }
     131        72340 :         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           72 :             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       110601 : SUMOSAXAttributes::getOptOffsetReporting(int attr, const char* objectid,
     148              :         bool& ok, SUMOTime defaultValue, bool report) const {
     149              :     try {
     150       110601 :         bool isPresent = true;
     151       110601 :         const std::string& val = getString(attr, &isPresent);
     152       110601 :         if (!isPresent) {
     153              :             return defaultValue;
     154              :         }
     155       110495 :         if (val == "begin") {
     156              :             return SUMOTime_MAX;
     157              :         } else {
     158       110492 :             return string2time(val);
     159              :         }
     160            0 :     } catch (EmptyData&) {
     161            0 :         if (report) {
     162            0 :             emitEmptyError(getName(attr), objectid);
     163              :         }
     164            0 :     } catch (ProcessError&) {
     165            0 :         if (report) {
     166            0 :             emitFormatError(getName(attr), "is not a valid time value", objectid);
     167              :         }
     168            0 :     }
     169            0 :     ok = false;
     170            0 :     return -1;
     171              : }
     172              : 
     173              : 
     174              : SUMOTime
     175        30434 : SUMOSAXAttributes::getOptPeriod(const char* objectid, bool& ok, SUMOTime defaultValue, bool report) const {
     176              :     int attr = SUMO_ATTR_PERIOD;
     177              :     try {
     178        30434 :         bool isPresent = true;
     179        30434 :         const std::string& val = getString(attr, &isPresent);
     180        30434 :         if (!isPresent) {
     181              :             // try 'freq' as alias for 'period'
     182              :             attr = SUMO_ATTR_FREQUENCY;
     183         9424 :             isPresent = true;
     184         9424 :             const std::string& valFreq = getString(attr, &isPresent);
     185         9424 :             if (!isPresent) {
     186              :                 return defaultValue;
     187              :             }
     188         7718 :             return string2time(valFreq);
     189              :         }
     190        21010 :         return string2time(val);
     191           40 :     } catch (EmptyData&) {
     192           20 :         if (report) {
     193           40 :             emitEmptyError(getName(attr), objectid);
     194              :         }
     195           40 :     } catch (ProcessError&) {
     196           20 :         if (report) {
     197           40 :             emitFormatError(getName(attr), "is not a valid time value", objectid);
     198              :         }
     199           20 :     }
     200           40 :     ok = false;
     201           40 :     return -1;
     202              : }
     203              : 
     204              : 
     205              : void
     206          292 : SUMOSAXAttributes::emitUngivenError(const std::string& attrname, const char* objectid) const {
     207          292 :     std::ostringstream oss;
     208          292 :     oss << "Attribute '" << attrname << "' is missing in definition of ";
     209          292 :     if (objectid == nullptr || objectid[0] == 0) {
     210              :         oss << "a " << myObjectType;
     211              :     } else {
     212          160 :         oss << myObjectType << " '" << objectid << "'";
     213              :     }
     214          292 :     oss << ".";
     215          292 :     WRITE_ERROR(oss.str());
     216          292 : }
     217              : 
     218              : 
     219              : void
     220          550 : SUMOSAXAttributes::emitEmptyError(const std::string& attrname, const char* objectid) const {
     221          550 :     std::ostringstream oss;
     222          550 :     oss << "Attribute '" << attrname << "' in definition of ";
     223          550 :     if (objectid == nullptr || objectid[0] == 0) {
     224              :         oss << "a " << myObjectType;
     225              :     } else {
     226          392 :         oss << myObjectType << " '" << objectid << "'";
     227              :     }
     228          550 :     oss << " is empty.";
     229          550 :     WRITE_ERROR(oss.str());
     230          550 : }
     231              : 
     232              : 
     233              : void
     234          302 : SUMOSAXAttributes::emitFormatError(const std::string& attrname, const std::string& type, const char* objectid) const {
     235          302 :     std::ostringstream oss;
     236          302 :     oss << "Attribute '" << attrname << "' in definition of ";
     237          302 :     if (objectid == nullptr || objectid[0] == 0) {
     238              :         oss << "a " << myObjectType;
     239              :     } else {
     240          282 :         oss << myObjectType << " '" << objectid << "'";
     241              :     }
     242          302 :     oss << " " << type << ".";
     243          302 :     WRITE_ERROR(oss.str());
     244          302 : }
     245              : 
     246              : 
     247              : const int invalid_return<int>::value = -1;
     248              : template<>
     249     12573098 : int SUMOSAXAttributes::fromString(const std::string& value) const {
     250     12573098 :     return StringUtils::toInt(value);
     251              : }
     252              : 
     253              : 
     254              : const long long int invalid_return<long long int>::value = -1;
     255              : template<>
     256       993121 : long long int SUMOSAXAttributes::fromString(const std::string& value) const {
     257       993121 :     return StringUtils::toLong(value);
     258              : }
     259              : 
     260              : 
     261              : const double invalid_return<double>::value = -1;
     262              : template<>
     263      9082975 : double SUMOSAXAttributes::fromString(const std::string& value) const {
     264      9082975 :     return StringUtils::toDouble(value);
     265              : }
     266              : 
     267              : 
     268              : const bool invalid_return<bool>::value = false;
     269              : template<>
     270       960118 : bool SUMOSAXAttributes::fromString(const std::string& value) const {
     271       960118 :     return StringUtils::toBool(value);
     272              : }
     273              : 
     274              : 
     275              : const RGBColor invalid_return<RGBColor>::value = RGBColor();
     276              : template<>
     277        65210 : RGBColor SUMOSAXAttributes::fromString(const std::string& value) const {
     278       130412 :     return RGBColor::parseColor(value);
     279              : }
     280              : 
     281              : 
     282              : const Position invalid_return<Position>::value = Position();
     283              : template<>
     284            0 : Position SUMOSAXAttributes::fromString(const std::string& value) const {
     285            0 :     StringTokenizer st(value);
     286              :     // check StringTokenizer
     287            0 :     while (st.hasNext()) {
     288              :         // obtain position
     289            0 :         StringTokenizer pos(st.next(), ",");
     290              :         // check that position has X-Y or X-Y-Z
     291            0 :         if ((pos.size() != 2) && (pos.size() != 3)) {
     292            0 :             throw FormatException("is not a valid position");
     293              :         }
     294              :         // obtain x and y
     295            0 :         double x = StringUtils::toDouble(pos.next());
     296            0 :         double y = StringUtils::toDouble(pos.next());
     297              :         // check if return a X-Y or a X-Y-Z Position
     298            0 :         if (pos.size() == 2) {
     299              :             return Position(x, y);
     300              :         } else {
     301              :             // obtain z
     302            0 :             double z = StringUtils::toDouble(pos.next());
     303              :             return Position(x, y, z);
     304              :         }
     305            0 :     }
     306              :     // empty positions aren't allowed
     307            0 :     throw FormatException("is not a valid position");
     308            0 : }
     309              : 
     310              : 
     311              : const PositionVector invalid_return<PositionVector>::value = PositionVector();
     312              : template<>
     313      3270968 : PositionVector SUMOSAXAttributes::fromString(const std::string& value) const {
     314      3270968 :     StringTokenizer st(value);
     315      3270968 :     PositionVector shape;
     316     14915304 :     while (st.hasNext()) {
     317     23288888 :         StringTokenizer pos(st.next(), ",");
     318     11644444 :         if (pos.size() != 2 && pos.size() != 3) {
     319           84 :             throw FormatException("is not a valid list of positions");
     320              :         }
     321     11644402 :         double x = StringUtils::toDouble(pos.next());
     322     11644466 :         double y = StringUtils::toDouble(pos.next());
     323     11644336 :         if (pos.size() == 2) {
     324     11616681 :             shape.push_back(Position(x, y));
     325              :         } else {
     326        27655 :             double z = StringUtils::toDouble(pos.next());
     327        27655 :             shape.push_back(Position(x, y, z));
     328              :         }
     329     11644444 :     }
     330      3270860 :     return shape;
     331      3271076 : }
     332              : 
     333              : 
     334              : const Boundary invalid_return<Boundary>::value = Boundary();
     335              : template<>
     336       107624 : Boundary SUMOSAXAttributes::fromString(const std::string& value) const {
     337       322872 :     StringTokenizer st(value, ",");
     338       107624 :     if (st.size() != 4) {
     339            0 :         throw FormatException("is not a valid boundary");
     340              :     }
     341       107624 :     const double xmin = StringUtils::toDouble(st.next());
     342       107624 :     const double ymin = StringUtils::toDouble(st.next());
     343       107624 :     const double xmax = StringUtils::toDouble(st.next());
     344       107624 :     const double ymax = StringUtils::toDouble(st.next());
     345       215248 :     return Boundary(xmin, ymin, xmax, ymax);
     346       107624 : }
     347              : 
     348              : 
     349              : const SumoXMLEdgeFunc invalid_return<SumoXMLEdgeFunc>::value = SumoXMLEdgeFunc::NORMAL;
     350              : template<>
     351      1398596 : SumoXMLEdgeFunc SUMOSAXAttributes::fromString(const std::string& value) const {
     352              :     if (SUMOXMLDefinitions::EdgeFunctions.hasString(value)) {
     353      1398586 :         return SUMOXMLDefinitions::EdgeFunctions.get(value);
     354              :     }
     355           20 :     throw FormatException("is not a valid edge function");
     356              : }
     357              : 
     358              : 
     359              : const SumoXMLNodeType invalid_return<SumoXMLNodeType>::value = SumoXMLNodeType::UNKNOWN;
     360              : template<>
     361       721388 : SumoXMLNodeType SUMOSAXAttributes::fromString(const std::string& value) const {
     362              :     if (SUMOXMLDefinitions::NodeTypes.hasString(value)) {
     363       721358 :         return SUMOXMLDefinitions::NodeTypes.get(value);
     364              :     }
     365           60 :     throw FormatException("is not a valid node type");
     366              : }
     367              : 
     368              : 
     369              : const RightOfWay invalid_return<RightOfWay>::value = RightOfWay::DEFAULT;
     370              : template<>
     371            4 : RightOfWay SUMOSAXAttributes::fromString(const std::string& value) const {
     372              :     if (SUMOXMLDefinitions::RightOfWayValues.hasString(value)) {
     373            4 :         return SUMOXMLDefinitions::RightOfWayValues.get(value);
     374              :     }
     375            0 :     throw FormatException("is not a valid right of way value");
     376              : }
     377              : 
     378              : 
     379              : const FringeType invalid_return<FringeType>::value = FringeType::DEFAULT;
     380              : template<>
     381          232 : FringeType SUMOSAXAttributes::fromString(const std::string& value) const {
     382              :     if (SUMOXMLDefinitions::FringeTypeValues.hasString(value)) {
     383          232 :         return SUMOXMLDefinitions::FringeTypeValues.get(value);
     384              :     }
     385            0 :     throw FormatException("is not a valid fringe type");
     386              : }
     387              : 
     388              : 
     389              : const ParkingType invalid_return<ParkingType>::value = ParkingType::ONROAD;
     390              : template<>
     391          959 : ParkingType SUMOSAXAttributes::fromString(const std::string& value) const {
     392          959 :     if (value == toString(ParkingType::OPPORTUNISTIC)) {
     393              :         return ParkingType::OPPORTUNISTIC;
     394              :     } else {
     395          959 :         return StringUtils::toBool(value) ? ParkingType::OFFROAD : ParkingType::ONROAD;
     396              :     }
     397              : }
     398              : 
     399              : 
     400              : const std::vector<std::string> invalid_return<std::vector<std::string> >::value = std::vector<std::string>();
     401              : template<>
     402        47952 : std::vector<std::string> SUMOSAXAttributes::fromString(const std::string& value) const {
     403        95904 :     const std::vector<std::string>& ret = StringTokenizer(value).getVector();
     404        47952 :     if (ret.empty()) {
     405         8634 :         throw EmptyData();
     406              :     }
     407        78636 :     return ret;
     408        47952 : }
     409              : 
     410              : 
     411              : const std::vector<int> invalid_return<std::vector<int> >::value = std::vector<int>();
     412              : template<>
     413          299 : std::vector<int> SUMOSAXAttributes::fromString(const std::string& value) const {
     414          598 :     const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
     415          299 :     if (tmp.empty()) {
     416            0 :         throw EmptyData();
     417              :     }
     418              :     std::vector<int> ret;
     419          721 :     for (const std::string& s : tmp) {
     420          422 :         ret.push_back(StringUtils::toInt(s));
     421              :     }
     422          299 :     return ret;
     423          299 : }
     424              : 
     425              : 
     426              : const std::vector<double> invalid_return<std::vector<double> >::value = std::vector<double>();
     427              : template<>
     428            0 : std::vector<double> SUMOSAXAttributes::fromString(const std::string& value) const {
     429            0 :     const std::vector<std::string>& tmp = StringTokenizer(value).getVector();
     430            0 :     if (tmp.empty()) {
     431            0 :         throw EmptyData();
     432              :     }
     433              :     std::vector<double> ret;
     434            0 :     for (const std::string& s : tmp) {
     435            0 :         ret.push_back(StringUtils::toDouble(s));
     436              :     }
     437            0 :     return ret;
     438            0 : }
     439              : 
     440              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1