LCOV - code coverage report
Current view: top level - src/utils/xml - SUMOSAXAttributes.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 81.8 % 203 166
Test Date: 2024-12-21 15:45:41 Functions: 96.2 % 26 25

            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     16875621 : SUMOSAXAttributes::SUMOSAXAttributes(const std::string& objectType):
      46     16875621 :     myObjectType(objectType) {}
      47              : 
      48              : 
      49              : const std::string invalid_return<std::string>::value = "";
      50              : template<>
      51     34693808 : std::string SUMOSAXAttributes::fromString(const std::string& value) const {
      52     34693808 :     if (value == "") {
      53          683 :         throw EmptyData();
      54              :     }
      55     34693125 :     return value;
      56              : }
      57              : 
      58              : 
      59              : SUMOTime
      60       553723 : SUMOSAXAttributes::getSUMOTimeReporting(int attr, const char* objectid,
      61              :                                         bool& ok, bool report) const {
      62              :     try {
      63       553723 :         bool isPresent = true;
      64       553723 :         const std::string& val = getString(attr, &isPresent);
      65       553723 :         if (!isPresent) {
      66           13 :             if (report) {
      67           50 :                 emitUngivenError(getName(attr), objectid);
      68              :             }
      69           13 :             ok = false;
      70           13 :             return -1;
      71              :         }
      72       553710 :         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      4771503 : SUMOSAXAttributes::getOptSUMOTimeReporting(int attr, const char* objectid,
     124              :         bool& ok, SUMOTime defaultValue, bool report) const {
     125              :     try {
     126      4771503 :         bool isPresent = true;
     127      4771503 :         const std::string& val = getString(attr, &isPresent);
     128      4771503 :         if (!isPresent) {
     129              :             return defaultValue;
     130              :         }
     131        72488 :         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       110960 : SUMOSAXAttributes::getOptOffsetReporting(int attr, const char* objectid,
     148              :         bool& ok, SUMOTime defaultValue, bool report) const {
     149              :     try {
     150       110960 :         bool isPresent = true;
     151       110960 :         const std::string& val = getString(attr, &isPresent);
     152       110960 :         if (!isPresent) {
     153              :             return defaultValue;
     154              :         }
     155       110854 :         if (val == "begin") {
     156              :             return SUMOTime_MAX;
     157              :         } else {
     158       110851 :             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        46418 : SUMOSAXAttributes::getOptPeriod(const char* objectid, bool& ok, SUMOTime defaultValue, bool report) const {
     176              :     int attr = SUMO_ATTR_PERIOD;
     177              :     try {
     178        46418 :         bool isPresent = true;
     179        46418 :         const std::string& val = getString(attr, &isPresent);
     180        46418 :         if (!isPresent) {
     181              :             // try 'freq' as alias for 'period'
     182              :             attr = SUMO_ATTR_FREQUENCY;
     183        24997 :             isPresent = true;
     184        24997 :             const std::string& valFreq = getString(attr, &isPresent);
     185        24997 :             if (!isPresent) {
     186              :                 return defaultValue;
     187              :             }
     188         7725 :             return string2time(valFreq);
     189              :         }
     190        21421 :         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     12683697 : int SUMOSAXAttributes::fromString(const std::string& value) const {
     250     12683697 :     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      9162742 : double SUMOSAXAttributes::fromString(const std::string& value) const {
     264      9162742 :     return StringUtils::toDouble(value);
     265              : }
     266              : 
     267              : 
     268              : const bool invalid_return<bool>::value = false;
     269              : template<>
     270       972246 : bool SUMOSAXAttributes::fromString(const std::string& value) const {
     271       972246 :     return StringUtils::toBool(value);
     272              : }
     273              : 
     274              : 
     275              : const RGBColor invalid_return<RGBColor>::value = RGBColor();
     276              : template<>
     277        65730 : RGBColor SUMOSAXAttributes::fromString(const std::string& value) const {
     278       131452 :     return RGBColor::parseColor(value);
     279              : }
     280              : 
     281              : 
     282              : const Position invalid_return<Position>::value = Position();
     283              : template<>
     284         1188 : Position SUMOSAXAttributes::fromString(const std::string& value) const {
     285         1188 :     StringTokenizer st(value);
     286              :     // check StringTokenizer
     287         1188 :     while (st.hasNext()) {
     288              :         // obtain position
     289         2376 :         StringTokenizer pos(st.next(), ",");
     290              :         // check that position has X-Y or X-Y-Z
     291         1188 :         if ((pos.size() != 2) && (pos.size() != 3)) {
     292            0 :             throw FormatException("is not a valid position");
     293              :         }
     294              :         // obtain x and y
     295         1188 :         double x = StringUtils::toDouble(pos.next());
     296         1188 :         double y = StringUtils::toDouble(pos.next());
     297              :         // check if return a X-Y or a X-Y-Z Position
     298         1188 :         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         1188 :     }
     306              :     // empty positions aren't allowed
     307            0 :     throw FormatException("is not a valid position");
     308         1188 : }
     309              : 
     310              : 
     311              : const PositionVector invalid_return<PositionVector>::value = PositionVector();
     312              : template<>
     313      3303863 : PositionVector SUMOSAXAttributes::fromString(const std::string& value) const {
     314      3303863 :     StringTokenizer st(value);
     315      3303863 :     PositionVector shape;
     316     15068001 :     while (st.hasNext()) {
     317     23528492 :         StringTokenizer pos(st.next(), ",");
     318     11764246 :         if (pos.size() != 2 && pos.size() != 3) {
     319           84 :             throw FormatException("is not a valid list of positions");
     320              :         }
     321     11764204 :         double x = StringUtils::toDouble(pos.next());
     322     11764268 :         double y = StringUtils::toDouble(pos.next());
     323     11764138 :         if (pos.size() == 2) {
     324     11736483 :             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     11764246 :     }
     330      3303755 :     return shape;
     331      3303971 : }
     332              : 
     333              : 
     334              : const Boundary invalid_return<Boundary>::value = Boundary();
     335              : template<>
     336       108702 : Boundary SUMOSAXAttributes::fromString(const std::string& value) const {
     337       326106 :     StringTokenizer st(value, ",");
     338       108702 :     if (st.size() != 4) {
     339            0 :         throw FormatException("is not a valid boundary");
     340              :     }
     341       108702 :     const double xmin = StringUtils::toDouble(st.next());
     342       108702 :     const double ymin = StringUtils::toDouble(st.next());
     343       108702 :     const double xmax = StringUtils::toDouble(st.next());
     344       108702 :     const double ymax = StringUtils::toDouble(st.next());
     345       217404 :     return Boundary(xmin, ymin, xmax, ymax);
     346       108702 : }
     347              : 
     348              : 
     349              : const SumoXMLEdgeFunc invalid_return<SumoXMLEdgeFunc>::value = SumoXMLEdgeFunc::NORMAL;
     350              : template<>
     351      1412398 : SumoXMLEdgeFunc SUMOSAXAttributes::fromString(const std::string& value) const {
     352              :     if (SUMOXMLDefinitions::EdgeFunctions.hasString(value)) {
     353      1412388 :         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       728326 : SumoXMLNodeType SUMOSAXAttributes::fromString(const std::string& value) const {
     362              :     if (SUMOXMLDefinitions::NodeTypes.hasString(value)) {
     363       728296 :         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          983 : ParkingType SUMOSAXAttributes::fromString(const std::string& value) const {
     392          983 :     if (value == toString(ParkingType::OPPORTUNISTIC)) {
     393              :         return ParkingType::OPPORTUNISTIC;
     394              :     } else {
     395          983 :         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        48541 : std::vector<std::string> SUMOSAXAttributes::fromString(const std::string& value) const {
     403        97082 :     const std::vector<std::string>& ret = StringTokenizer(value).getVector();
     404        48541 :     if (ret.empty()) {
     405         8643 :         throw EmptyData();
     406              :     }
     407        79796 :     return ret;
     408        48541 : }
     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