LCOV - code coverage report
Current view: top level - src/utils/xml - GenericSAXHandler.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 107 116 92.2 %
Date: 2024-05-06 15:32:35 Functions: 15 19 78.9 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2002-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    GenericSAXHandler.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @author  Laura Bieker
      19             : /// @date    Sept 2002
      20             : ///
      21             : // A handler which converts occurring elements and attributes into enums
      22             : /****************************************************************************/
      23             : #include <config.h>
      24             : 
      25             : #include <cassert>
      26             : #include "GenericSAXHandler.h"
      27             : #include <utils/common/StringUtils.h>
      28             : #include <utils/common/StringUtils.h>
      29             : #include <utils/common/FileHelpers.h>
      30             : #include <utils/common/MsgHandler.h>
      31             : #include <utils/common/ToString.h>
      32             : #include "SUMOSAXAttributesImpl_Xerces.h"
      33             : #include "XMLSubSys.h"
      34             : 
      35             : 
      36             : // ===========================================================================
      37             : // class definitions
      38             : // ===========================================================================
      39      157919 : GenericSAXHandler::GenericSAXHandler(
      40             :     StringBijection<int>::Entry* tags, int terminatorTag,
      41             :     StringBijection<int>::Entry* attrs, int terminatorAttr,
      42      157919 :     const std::string& file, const std::string& expectedRoot)
      43      157919 :     : myParentHandler(nullptr), myParentIndicator(SUMO_TAG_NOTHING), myFileName(file),
      44      473757 :       myExpectedRoot(expectedRoot), myNextSectionStart(-1, nullptr) {
      45             :     int i = 0;
      46    47834231 :     while (tags[i].key != terminatorTag) {
      47    47676312 :         myTagMap.insert(TagMap::value_type(tags[i].str, tags[i].key));
      48    47676312 :         i++;
      49             :     }
      50             :     i = 0;
      51   104982085 :     while (attrs[i].key != terminatorAttr) {
      52             :         int key = attrs[i].key;
      53             :         assert(key >= 0);
      54   211069171 :         while (key >= (int)myPredefinedTags.size()) {
      55   106245005 :             myPredefinedTags.push_back(nullptr);
      56   212490010 :             myPredefinedTagsMML.push_back("");
      57             :         }
      58   104824166 :         myPredefinedTags[key] = convert(attrs[i].str);
      59   104824166 :         myPredefinedTagsMML[key] = attrs[i].str;
      60   104824166 :         i++;
      61             :     }
      62      157919 : }
      63             : 
      64             : 
      65      157466 : GenericSAXHandler::~GenericSAXHandler() {
      66   106097602 :     for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
      67   105940136 :         delete[](*i1);
      68             :     }
      69      157466 :     delete myNextSectionStart.second;
      70      314932 : }
      71             : 
      72             : 
      73             : void
      74      216687 : GenericSAXHandler::setFileName(const std::string& name) {
      75      216687 :     myFileName = name;
      76      216687 : }
      77             : 
      78             : 
      79             : const std::string&
      80      807057 : GenericSAXHandler::getFileName() const {
      81      807057 :     return myFileName;
      82             : }
      83             : 
      84             : 
      85             : XMLCh*
      86   104824166 : GenericSAXHandler::convert(const std::string& name) const {
      87   104824166 :     int len = (int)name.length();
      88   104824166 :     XMLCh* ret = new XMLCh[len + 1];
      89             :     int i = 0;
      90  1235147164 :     for (; i < len; i++) {
      91  1130322998 :         ret[i] = (XMLCh) name[i];
      92             :     }
      93   104824166 :     ret[i] = 0;
      94   104824166 :     return ret;
      95             : }
      96             : 
      97             : 
      98             : void
      99    16577464 : GenericSAXHandler::startElement(const XMLCh* const /*uri*/,
     100             :                                 const XMLCh* const /*localname*/,
     101             :                                 const XMLCh* const qname,
     102             :                                 const XERCES_CPP_NAMESPACE::Attributes& attrs) {
     103    16577464 :     std::string name = StringUtils::transcode(qname);
     104    16577464 :     if (!myRootSeen && myExpectedRoot != "" && name != myExpectedRoot) {
     105        1470 :         WRITE_WARNINGF(TL("Found root element '%' in file '%' (expected '%')."), name, getFileName(), myExpectedRoot);
     106             :     }
     107    16577464 :     myRootSeen = true;
     108             :     myCharactersVector.clear();
     109    16577464 :     const int element = convertTag(name);
     110    16577464 :     if (mySectionSeen && !mySectionOpen && element != mySection) {
     111         297 :         mySectionEnded = true;
     112         297 :         myNextSectionStart.first = element;
     113         297 :         myNextSectionStart.second = new SUMOSAXAttributesImpl_Xerces(attrs, myPredefinedTags, myPredefinedTagsMML, name);
     114             :         return;
     115             :     }
     116    16577167 :     if (element == mySection) {
     117      543563 :         mySectionSeen = true;
     118      543563 :         mySectionOpen = true;
     119             :     }
     120    16577167 :     SUMOSAXAttributesImpl_Xerces na(attrs, myPredefinedTags, myPredefinedTagsMML, name);
     121    16577167 :     if (element == SUMO_TAG_INCLUDE) {
     122         296 :         std::string file = na.getString(SUMO_ATTR_HREF);
     123         296 :         if (!FileHelpers::isAbsolute(file)) {
     124         592 :             file = FileHelpers::getConfigurationRelative(getFileName(), file);
     125             :         }
     126         296 :         XMLSubSys::runParser(*this, file);
     127             :     } else {
     128    16576871 :         myStartElement(element, na);
     129             :     }
     130    16577167 : }
     131             : 
     132             : 
     133             : void
     134    16571935 : GenericSAXHandler::endElement(const XMLCh* const /*uri*/,
     135             :                               const XMLCh* const /*localname*/,
     136             :                               const XMLCh* const qname) {
     137    16571935 :     std::string name = StringUtils::transcode(qname);
     138    16571935 :     int element = convertTag(name);
     139             :     // collect characters
     140    16571935 :     if (myCharactersVector.size() != 0) {
     141             :         int len = 0;
     142        5335 :         for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
     143        3146 :             len += (int)myCharactersVector[i].length();
     144             :         }
     145        2189 :         char* buf = new char[len + 1];
     146             :         int pos = 0;
     147        5335 :         for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
     148        3146 :             memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
     149        3146 :                    sizeof(char)*myCharactersVector[i].length());
     150        3146 :             pos += (int)myCharactersVector[i].length();
     151             :         }
     152        2189 :         buf[pos] = 0;
     153             : 
     154             :         // call user handler
     155             :         try {
     156        2189 :             myCharacters(element, buf);
     157           0 :         } catch (std::runtime_error&) {
     158           0 :             delete[] buf;
     159           0 :             throw;
     160           0 :         }
     161        2189 :         delete[] buf;
     162             :     }
     163    16571935 :     if (element == mySection) {
     164      543859 :         mySectionOpen = false;
     165             :     }
     166    16571935 :     if (element != SUMO_TAG_INCLUDE) {
     167    16571639 :         myEndElement(element);
     168    16571384 :         if (myParentHandler && myParentIndicator == element) {
     169        4002 :             XMLSubSys::setHandler(*myParentHandler);
     170        4002 :             myParentIndicator = SUMO_TAG_NOTHING;
     171        4002 :             myParentHandler = nullptr;
     172             :         }
     173             :     }
     174    16571680 : }
     175             : 
     176             : 
     177             : void
     178        4002 : GenericSAXHandler::registerParent(const int tag, GenericSAXHandler* handler) {
     179        4002 :     myParentHandler = handler;
     180        4002 :     myParentIndicator = tag;
     181        4002 :     XMLSubSys::setHandler(*this);
     182        4002 : }
     183             : 
     184             : 
     185             : void
     186    18006119 : GenericSAXHandler::characters(const XMLCh* const chars,
     187             :                               const XERCES3_SIZE_t length) {
     188    18006119 :     if (myCollectCharacterData) {
     189       12442 :         myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
     190             :     }
     191    18006119 : }
     192             : 
     193             : 
     194             : int
     195    33149399 : GenericSAXHandler::convertTag(const std::string& tag) const {
     196             :     TagMap::const_iterator i = myTagMap.find(tag);
     197    33149399 :     if (i == myTagMap.end()) {
     198             :         return SUMO_TAG_NOTHING;
     199             :     }
     200    32993384 :     return (*i).second;
     201             : }
     202             : 
     203             : 
     204             : std::string
     205         968 : GenericSAXHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
     206         968 :     std::ostringstream buf;
     207         968 :     char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
     208         968 :     buf << pMsg << std::endl;
     209         968 :     buf << TL(" In file '") << getFileName() << "'" << std::endl;
     210         968 :     buf << TL(" At line/column ") << exception.getLineNumber() + 1
     211         968 :         << '/' << exception.getColumnNumber() << "." << std::endl;
     212         968 :     XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
     213         968 :     return buf.str();
     214         968 : }
     215             : 
     216             : 
     217             : void
     218           0 : GenericSAXHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
     219           0 :     WRITE_WARNING(buildErrorMessage(exception));
     220           0 : }
     221             : 
     222             : 
     223             : void
     224         878 : GenericSAXHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
     225        1756 :     throw ProcessError(buildErrorMessage(exception));
     226             : }
     227             : 
     228             : 
     229             : void
     230          90 : GenericSAXHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
     231         180 :     throw ProcessError(buildErrorMessage(exception));
     232             : }
     233             : 
     234             : 
     235             : void
     236           0 : GenericSAXHandler::myStartElement(int, const SUMOSAXAttributes&) {}
     237             : 
     238             : 
     239             : void
     240           0 : GenericSAXHandler::myCharacters(int, const std::string&) {}
     241             : 
     242             : 
     243             : void
     244       67681 : GenericSAXHandler::myEndElement(int) {}
     245             : 
     246             : void
     247         477 : GenericSAXHandler::callParentEnd(int element) {
     248         477 :     if (myParentHandler) {
     249         435 :         myParentHandler->myEndElement(element);
     250             :     }
     251         477 : }
     252             : 
     253             : /****************************************************************************/

Generated by: LCOV version 1.14