SUMO - Simulation of Urban MObility
GenericSAXHandler.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00010 // A handler which converts occuring elements and attributes into enums
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <cassert>
00035 #include "GenericSAXHandler.h"
00036 #include <utils/common/TplConvert.h>
00037 #include <utils/common/TplConvertSec.h>
00038 #include <utils/common/FileHelpers.h>
00039 #include <utils/common/MsgHandler.h>
00040 #include <utils/common/ToString.h>
00041 #include "SUMOSAXAttributesImpl_Xerces.h"
00042 #include "XMLSubSys.h"
00043 
00044 #ifdef CHECK_MEMORY_LEAKS
00045 #include <foreign/nvwa/debug_new.h>
00046 #endif // CHECK_MEMORY_LEAKS
00047 
00048 
00049 // ===========================================================================
00050 // class definitions
00051 // ===========================================================================
00052 GenericSAXHandler::GenericSAXHandler(
00053     StringBijection<int>::Entry* tags, int terminatorTag,
00054     StringBijection<int>::Entry* attrs, int terminatorAttr,
00055     const std::string& file)
00056     : myParentHandler(0), myParentIndicator(SUMO_TAG_NOTHING), myFileName(file) {
00057     int i = 0;
00058     while (tags[i].key != terminatorTag) {
00059         myTagMap.insert(TagMap::value_type(tags[i].str, tags[i].key));
00060         i++;
00061     }
00062     i = 0;
00063     while (attrs[i].key != terminatorAttr) {
00064         assert(myPredefinedTags.find(attrs[i].key) == myPredefinedTags.end());
00065         myPredefinedTags[attrs[i].key] = convert(attrs[i].str);
00066         myPredefinedTagsMML[attrs[i].key] = attrs[i].str;
00067         i++;
00068     }
00069 }
00070 
00071 
00072 GenericSAXHandler::~GenericSAXHandler() {
00073     for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
00074         delete[](*i1).second;
00075     }
00076 }
00077 
00078 
00079 void
00080 GenericSAXHandler::setFileName(const std::string& name) {
00081     myFileName = name;
00082 }
00083 
00084 
00085 const std::string&
00086 GenericSAXHandler::getFileName() const {
00087     return myFileName;
00088 }
00089 
00090 
00091 XMLCh*
00092 GenericSAXHandler::convert(const std::string& name) const {
00093     size_t len = name.length();
00094     XMLCh* ret = new XMLCh[len + 1];
00095     size_t i = 0;
00096     for (; i < len; i++) {
00097         ret[i] = (XMLCh) name[i];
00098     }
00099     ret[i] = 0;
00100     return ret;
00101 }
00102 
00103 
00104 void
00105 GenericSAXHandler::startElement(const XMLCh* const /*uri*/,
00106                                 const XMLCh* const /*localname*/,
00107                                 const XMLCh* const qname,
00108                                 const Attributes& attrs) {
00109     std::string name = TplConvert<XMLCh>::_2str(qname);
00110     int element = convertTag(name);
00111     myCharactersVector.clear();
00112     SUMOSAXAttributesImpl_Xerces na(attrs, myPredefinedTags, myPredefinedTagsMML, name);
00113     if (element == SUMO_TAG_INCLUDE) {
00114         std::string file = na.getString(SUMO_ATTR_HREF);
00115         if (!FileHelpers::isAbsolute(file)) {
00116             file = FileHelpers::getConfigurationRelative(getFileName(), file);
00117         }
00118         XMLSubSys::runParser(*this, file);
00119     } else {
00120         myStartElement(element, na);
00121     }
00122 }
00123 
00124 
00125 void
00126 GenericSAXHandler::endElement(const XMLCh* const /*uri*/,
00127                               const XMLCh* const /*localname*/,
00128                               const XMLCh* const qname) {
00129     std::string name = TplConvert<XMLCh>::_2str(qname);
00130     int element = convertTag(name);
00131     // collect characters
00132     if (myCharactersVector.size() != 0) {
00133         size_t len = 0;
00134         unsigned i;
00135         for (i = 0; i < myCharactersVector.size(); ++i) {
00136             len += myCharactersVector[i].length();
00137         }
00138         char* buf = new char[len + 1];
00139         size_t pos = 0;
00140         for (i = 0; i < myCharactersVector.size(); ++i) {
00141             memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
00142                    sizeof(char)*myCharactersVector[i].length());
00143             pos += myCharactersVector[i].length();
00144         }
00145         buf[pos] = 0;
00146 
00147         // call user handler
00148         try {
00149             myCharacters(element, buf);
00150         } catch (std::runtime_error&) {
00151             delete[] buf;
00152             throw;
00153         }
00154         delete[] buf;
00155     }
00156     if (element != SUMO_TAG_INCLUDE) {
00157         myEndElement(element);
00158         if (myParentHandler && myParentIndicator == element) {
00159             XMLSubSys::setHandler(*myParentHandler);
00160             myParentIndicator = SUMO_TAG_NOTHING;
00161             myParentHandler = 0;
00162         }
00163     }
00164 }
00165 
00166 
00167 void
00168 GenericSAXHandler::registerParent(const int tag, GenericSAXHandler* handler) {
00169     myParentHandler = handler;
00170     myParentIndicator = tag;
00171     XMLSubSys::setHandler(*this);
00172 }
00173 
00174 
00175 void
00176 GenericSAXHandler::characters(const XMLCh* const chars,
00177                               const XERCES3_SIZE_t length) {
00178     myCharactersVector.push_back(TplConvert<XMLCh>::_2str(chars, static_cast<unsigned int>(length)));
00179 }
00180 
00181 
00182 int
00183 GenericSAXHandler::convertTag(const std::string& tag) const {
00184     TagMap::const_iterator i = myTagMap.find(tag);
00185     if (i == myTagMap.end()) {
00186         return SUMO_TAG_NOTHING;
00187     }
00188     return (*i).second;
00189 }
00190 
00191 
00192 std::string
00193 GenericSAXHandler::buildErrorMessage(const SAXParseException& exception) {
00194     std::ostringstream buf;
00195     char* pMsg = XMLString::transcode(exception.getMessage());
00196     buf << pMsg << std::endl;
00197     buf << " In file '" << getFileName() << "'" << std::endl;
00198     buf << " At line/column " << exception.getLineNumber() + 1
00199         << '/' << exception.getColumnNumber() << "." << std::endl;
00200     XMLString::release(&pMsg);
00201     return buf.str();
00202 }
00203 
00204 
00205 void
00206 GenericSAXHandler::warning(const SAXParseException& exception) {
00207     WRITE_WARNING(buildErrorMessage(exception));
00208 }
00209 
00210 
00211 void
00212 GenericSAXHandler::error(const SAXParseException& exception) {
00213     throw ProcessError(buildErrorMessage(exception));
00214 }
00215 
00216 
00217 void
00218 GenericSAXHandler::fatalError(const SAXParseException& exception) {
00219     throw ProcessError(buildErrorMessage(exception));
00220 }
00221 
00222 
00223 void
00224 GenericSAXHandler::myStartElement(int, const SUMOSAXAttributes&) {}
00225 
00226 
00227 void
00228 GenericSAXHandler::myCharacters(int, const std::string&) {}
00229 
00230 
00231 void
00232 GenericSAXHandler::myEndElement(int) {}
00233 
00234 
00235 /****************************************************************************/
00236 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines