LCOV - code coverage report
Current view: top level - src/utils/xml - GenericSAXHandler.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 11 11
Test Date: 2024-11-20 15:55:46 Functions: - 0 0

            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.h
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // A handler which converts occurring elements and attributes into enums
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <map>
      27              : #include <stack>
      28              : #include <sstream>
      29              : #include <vector>
      30              : #include <xercesc/sax2/Attributes.hpp>
      31              : #include <xercesc/sax2/DefaultHandler.hpp>
      32              : #include <utils/common/UtilExceptions.h>
      33              : #include <utils/common/StringBijection.h>
      34              : #include "SUMOSAXAttributes.h"
      35              : 
      36              : 
      37              : // ===========================================================================
      38              : // class definitions
      39              : // ===========================================================================
      40              : /**
      41              :  * @class GenericSAXHandler
      42              :  * @brief A handler which converts occurring elements and attributes into enums
      43              :  *
      44              :  * Normally, when using a standard SAX-handler, we would have to compare
      45              :  *  the incoming XMLCh*-element names with the ones we can parse. The same
      46              :  *  applies to parsing the attributes. This was assumed to be very time consuming,
      47              :  *  that's why we derive our handlers from this class.
      48              :  *
      49              :  * The idea behind this second handler layer was avoid repeated conversion
      50              :  *  from strings/whatever to XMLCh* and back again. The usage is quite straight
      51              :  *  forward, the only overhead is the need to define the enums - both elements
      52              :  *  and attributes within "SUMOXMLDefinitions". Still, it maybe helps to avoid typos.
      53              :  *
      54              :  * This class implements the SAX-callback and offers a new set of callbacks
      55              :  *  which must be implemented by derived classes. Instead of XMLCh*-values,
      56              :  *  element names are supplied to the derived classes as enums (int).
      57              :  *
      58              :  * Also, this class allows to retrieve attributes using enums (int) within
      59              :  *  the implemented "myStartElement" method.
      60              :  *
      61              :  * Basically, GenericSAXHandler is not derived within SUMO directly, but via SUMOSAXHandler
      62              :  *  which knows all tags/attributes used by SUMO. It is still kept separate for
      63              :  *  an easier maintainability and later extensions.
      64              :  */
      65              : class GenericSAXHandler : public XERCES_CPP_NAMESPACE::DefaultHandler {
      66              : 
      67              : public:
      68              :     /**
      69              :      * @brief Constructor
      70              :      *
      71              :      * This constructor gets the lists of known tag and attribute names with
      72              :      *  their enums (sumotags and sumoattrs in most cases). The end of the list
      73              :      *  is signaled by terminatorTag/terminatorAttr respectively.
      74              :      *
      75              :      * The attribute names are converted into XMLCh* and stored within an
      76              :      *  internal container. This container is cleared within the destructor.
      77              :      *
      78              :      * @param[in] tags The list of known tags
      79              :      * @param[in] terminatorTag The tag which indicates the end of tags (usually the last entry)
      80              :      * @param[in] attrs The list of known attributes
      81              :      * @param[in] terminatorAttr The attr which indicates the end of attrs (usually the last entry)
      82              :      * @param[in] file The name of the processed file
      83              :      * @param[in] expectedRoot The expected root element, empty string disables the check
      84              :      *
      85              :      * @todo Why are both lists non-const and given as pointers?
      86              :      */
      87              :     GenericSAXHandler(
      88              :         SequentialStringBijection::Entry* tags, int terminatorTag,
      89              :         SequentialStringBijection::Entry* attrs, int terminatorAttr,
      90              :         const std::string& file, const std::string& expectedRoot = "");
      91              : 
      92              : 
      93              :     /** @brief Destructor */
      94              :     virtual ~GenericSAXHandler();
      95              : 
      96              : 
      97              :     /**
      98              :      * @brief The inherited method called when a new tag opens
      99              :      *
     100              :      * The method parses the supplied XMLCh*-qname using the internal name/enum-map
     101              :      *  to obtain the enum representation of the attribute name.
     102              :      *
     103              :      * Then, "myStartElement" is called supplying the enumeration value, the
     104              :      *  string-representation of the name and the attributes.
     105              :      *
     106              :      * @todo recheck/describe encoding of the string-representation
     107              :      * @todo do not generate and report the string-representation
     108              :      */
     109              :     void startElement(const XMLCh* const uri, const XMLCh* const localname,
     110              :                       const XMLCh* const qname, const XERCES_CPP_NAMESPACE::Attributes& attrs);
     111              : 
     112              : 
     113              :     /**
     114              :      * @brief The inherited method called when characters occurred
     115              :      *
     116              :      * The retrieved characters are converted into a string and appended into a
     117              :      *  private buffer. They are reported as soon as the element ends.
     118              :      *
     119              :      * @todo recheck/describe what happens with characters when a new element is opened
     120              :      * @todo describe characters processing in the class' head
     121              :      */
     122              :     void characters(const XMLCh* const chars, const XERCES3_SIZE_t length);
     123              : 
     124              : 
     125              :     /**
     126              :      * @brief The inherited method called when a tag is being closed
     127              :      *
     128              :      * This method calls the user-implemented methods myCharacters with the previously
     129              :      *  collected and converted characters.
     130              :      *
     131              :      * Then, myEndElement is called, supplying it the qname converted to its enum-
     132              :      *  and string-representations.
     133              :      *
     134              :      * @todo recheck/describe encoding of the string-representation
     135              :      * @todo do not generate and report the string-representation
     136              :      */
     137              :     void endElement(const XMLCh* const uri, const XMLCh* const localname,
     138              :                     const XMLCh* const qname);
     139              : 
     140              : 
     141              :     /**
     142              :      * @brief Assigning a parent handler which is enabled when the specified tag is closed
     143              :      */
     144              :     void registerParent(const int tag, GenericSAXHandler* handler);
     145              : 
     146              : 
     147              :     /**
     148              :      * @brief Sets the current file name
     149              :      *
     150              :      * @param[in] name The name of the currently processed file
     151              :      *
     152              :      * @todo Hmmm - this is as unsafe as having a direct access to the variable; recheck
     153              :      */
     154              :     void setFileName(const std::string& name);
     155              : 
     156              : 
     157              :     /**
     158              :      * @brief returns the current file name
     159              :      *
     160              :      * @return The name of the currently processed file
     161              :      */
     162              :     const std::string& getFileName() const;
     163              : 
     164              : 
     165              :     /// @name SAX ErrorHandler callbacks
     166              :     //@{
     167              : 
     168              :     /**
     169              :      * @brief Handler for XML-warnings
     170              :      *
     171              :      * The message is built using buildErrorMessage and reported
     172              :      *  to the warning-instance of the MsgHandler.
     173              :      *
     174              :      * @param[in] exception The occurred exception to process
     175              :      */
     176              :     void warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception);
     177              : 
     178              : 
     179              :     /**
     180              :      * @brief Handler for XML-errors
     181              :      *
     182              :      * The message is built using buildErrorMessage and thrown within a ProcessError.
     183              :      *
     184              :      * @param[in] exception The occurred exception to process
     185              :      * @exception ProcessError On any call
     186              :      */
     187              :     void error(const XERCES_CPP_NAMESPACE::SAXParseException& exception);
     188              : 
     189              : 
     190              :     /**
     191              :      * @brief Handler for XML-errors
     192              :      *
     193              :      * The message is built using buildErrorMessage and thrown within a ProcessError.
     194              :      *
     195              :      * @exception ProcessError On any call
     196              :      * @param[in] exception The occurred exception to process
     197              :      */
     198              :     void fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception);
     199              :     //@}
     200              : 
     201              : 
     202              :     void setSection(const int element, const bool seen) {
     203          461 :         mySection = element;
     204          461 :         mySectionSeen = seen;
     205          461 :         mySectionOpen = seen;
     206          461 :         mySectionEnded = false;
     207          461 :     }
     208              : 
     209              :     bool sectionFinished() const {
     210      3494793 :         return mySectionEnded;
     211              :     }
     212              : 
     213              :     std::pair<int, SUMOSAXAttributes*> retrieveNextSectionStart() {
     214          288 :         std::pair<int, SUMOSAXAttributes*> ret = myNextSectionStart;
     215          288 :         myNextSectionStart.first = -1;
     216          288 :         myNextSectionStart.second = nullptr;
     217              :         return ret;
     218              :     }
     219              : 
     220              :     void needsCharacterData(const bool value = true) {
     221           25 :         myCollectCharacterData = value;
     222            3 :     }
     223              : 
     224              :     // Reader needs access to myStartElement, myEndElement
     225              :     friend class SUMOSAXReader;
     226              : 
     227              : 
     228              : protected:
     229              :     /**
     230              :      * @brief Builds an error message
     231              :      *
     232              :      * The error message includes the file name and the line/column information
     233              :      *  as supported by the given SAXParseException
     234              :      *
     235              :      * @param[in] exception The name of the currently processed file
     236              :      * @return A string describing the given exception
     237              :      */
     238              :     std::string buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception);
     239              : 
     240              : 
     241              :     /**
     242              :      * @brief Callback method for an opening tag to implement by derived classes
     243              :      *
     244              :      * Called by "startElement" (see there).
     245              :      * @param[in] element The element that contains the characters, given as a int
     246              :      * @param[in] attrs The SAX-attributes, wrapped as SUMOSAXAttributes
     247              :      * @exceptions ProcessError These method may throw a ProcessError if something fails
     248              :      */
     249              :     virtual void myStartElement(int element,
     250              :                                 const SUMOSAXAttributes& attrs);
     251              : 
     252              : 
     253              :     /**
     254              :      * @brief Callback method for characters to implement by derived classes
     255              :      *
     256              :      * Called by "endElement" (see there).
     257              :      * @param[in] element The opened element, given as a int
     258              :      * @param[in] chars The complete embedded character string
     259              :      * @exceptions ProcessError These method may throw a ProcessError if something fails
     260              :      */
     261              :     virtual void myCharacters(int element,
     262              :                               const std::string& chars);
     263              : 
     264              : 
     265              :     /** @brief Callback method for a closing tag to implement by derived classes
     266              :      *
     267              :      * Called by "endElement" (see there).
     268              :      * @param[in] element The closed element, given as a int
     269              :      * @exceptions ProcessError These method may throw a ProcessError if something fails
     270              :      */
     271              :     virtual void myEndElement(int element);
     272              : 
     273              :     /// @brief signal endElement to the parent handler (special case for MSCalibrator)
     274              :     void callParentEnd(int element);
     275              : 
     276              : private:
     277              :     /**
     278              :      * @brief converts from c++-string into unicode
     279              :      *
     280              :      * @todo recheck encoding
     281              :      * @param[in] name The string to convert
     282              :      * @return The string converted into a XMLCh-string
     283              :      */
     284              :     XMLCh* convert(const std::string& name) const;
     285              : 
     286              : 
     287              :     /**
     288              :      * @brief Converts a tag from its string into its numerical representation
     289              :      *
     290              :      * Returns the enum-representation stored for the given tag. If the tag is not
     291              :      *  known, SUMO_TAG_NOTHING is returned.
     292              :      * @param[in] tag The string to convert
     293              :      * @return The int-value that represents the string, SUMO_TAG_NOTHING if the named attribute is not known
     294              :      */
     295              :     int convertTag(const std::string& tag) const;
     296              : 
     297              : 
     298              : private:
     299              :     /// @name attributes parsing
     300              :     //@{
     301              : 
     302              :     // the type of the map from ids to their unicode-string representation
     303              :     typedef std::vector<XMLCh*> AttrMap;
     304              : 
     305              :     // the map from ids to their unicode-string representation
     306              :     AttrMap myPredefinedTags;
     307              : 
     308              :     /// the map from ids to their string representation
     309              :     std::vector<std::string> myPredefinedTagsMML;
     310              :     //@}
     311              : 
     312              : 
     313              :     /// @name elements parsing
     314              :     //@{
     315              : 
     316              :     // the type of the map that maps tag names to ints
     317              :     typedef std::map<std::string, int> TagMap;
     318              : 
     319              :     // the map of tag names to their internal numerical representation
     320              :     TagMap myTagMap;
     321              :     //@}
     322              : 
     323              :     /// A list of character strings obtained so far to build the complete characters string at the end
     324              :     std::vector<std::string> myCharactersVector;
     325              : 
     326              :     /// @brief The handler to give control back to
     327              :     GenericSAXHandler* myParentHandler;
     328              : 
     329              :     /// @brief The tag indicating that control should be given back
     330              :     int myParentIndicator;
     331              : 
     332              :     /// @brief The name of the currently parsed file
     333              :     std::string myFileName;
     334              : 
     335              :     /// @brief The root element to expect, empty string disables the check
     336              :     std::string myExpectedRoot;
     337              : 
     338              :     /// @brief whether the reader should collect character data
     339              :     bool myCollectCharacterData = false;
     340              : 
     341              :     /// @brief whether the reader has already seen the root element
     342              :     bool myRootSeen = false;
     343              : 
     344              :     /// @brief The tag indicating the current section to parse
     345              :     int mySection = -1;
     346              : 
     347              :     /// @brief whether the reader has already seen the begin of the section
     348              :     bool mySectionSeen = false;
     349              : 
     350              :     /// @brief whether the reader has already seen the end of the section
     351              :     bool mySectionEnded = false;
     352              : 
     353              :     /// @brief whether an element of the current section is open
     354              :     bool mySectionOpen = false;
     355              : 
     356              :     std::pair<int, SUMOSAXAttributes*> myNextSectionStart;
     357              : 
     358              : private:
     359              :     /// @brief invalidated copy constructor
     360              :     GenericSAXHandler(const GenericSAXHandler& s);
     361              : 
     362              :     /// @brief invalidated assignment operator
     363              :     const GenericSAXHandler& operator=(const GenericSAXHandler& s);
     364              : 
     365              : };
        

Generated by: LCOV version 2.0-1