Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2001-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 OptionsLoader.cpp 15 : /// @author Daniel Krajzewicz 16 : /// @author Jakob Erdmann 17 : /// @author Michael Behrisch 18 : /// @date Mon, 17 Dec 2001 19 : /// 20 : // A SAX-Handler for loading options 21 : /****************************************************************************/ 22 : #include <config.h> 23 : 24 : #include <algorithm> 25 : #include <string> 26 : #include <vector> 27 : #include <xercesc/sax/HandlerBase.hpp> 28 : #include <xercesc/sax/AttributeList.hpp> 29 : #include <xercesc/sax/SAXParseException.hpp> 30 : #include <xercesc/sax/SAXException.hpp> 31 : #include <utils/common/StringUtils.h> 32 : #include <utils/common/StringTokenizer.h> 33 : #include <utils/common/UtilExceptions.h> 34 : #include <utils/common/FileHelpers.h> 35 : #include <utils/common/MsgHandler.h> 36 : #include <utils/common/ToString.h> 37 : #include "OptionsIO.h" 38 : #include "OptionsCont.h" 39 : #include "OptionsLoader.h" 40 : 41 : 42 : // =========================================================================== 43 : // method definitions 44 : // =========================================================================== 45 : 46 10405 : OptionsLoader::OptionsLoader(OptionsCont& customOptions, const bool rootOnly) : 47 10405 : myRootOnly(rootOnly), 48 10405 : myOptions(customOptions), 49 10405 : myItem() { 50 10405 : } 51 : 52 : 53 10405 : OptionsLoader::~OptionsLoader() {} 54 : 55 : 56 102534 : void OptionsLoader::startElement(const XMLCh* const name, XERCES_CPP_NAMESPACE::AttributeList& attributes) { 57 102534 : myItem = StringUtils::transcode(name); 58 102534 : if (!myRootOnly) { 59 176987 : for (int i = 0; i < (int)attributes.getLength(); i++) { 60 74453 : const std::string& key = StringUtils::transcode(attributes.getName(i)); 61 74453 : const std::string& value = StringUtils::transcode(attributes.getValue(i)); 62 83980 : if (key == "value" || key == "v") { 63 64926 : setValue(myItem, value); 64 : } 65 : // could give a hint here about unsupported attributes in configuration files 66 : } 67 102534 : myValue = ""; 68 : } 69 102534 : } 70 : 71 : 72 64926 : void OptionsLoader::setValue(const std::string& key, const std::string& value) { 73 64926 : if (value.length() > 0) { 74 : // try to add value in option container 75 : try { 76 64918 : if (!setSecure(myOptions, key, value)) { 77 0 : WRITE_ERRORF(TL("Could not set option '%' (probably defined twice)."), key); 78 0 : myError = true; 79 : } 80 6 : } catch (ProcessError& e) { 81 6 : WRITE_ERROR(e.what()); 82 6 : myError = true; 83 6 : } 84 : } 85 64926 : } 86 : 87 : 88 128491 : void OptionsLoader::characters(const XMLCh* const chars, const XERCES3_SIZE_t length) { 89 256982 : myValue = myValue + StringUtils::transcode(chars, (int) length); 90 128491 : } 91 : 92 : 93 : bool 94 64918 : OptionsLoader::setSecure(OptionsCont& options, const std::string& name, const std::string& value) const { 95 64918 : if (options.isWriteable(name)) { 96 64912 : options.set(name, value); 97 64912 : return true; 98 : } 99 : return false; 100 : } 101 : 102 : 103 : void 104 102482 : OptionsLoader::endElement(const XMLCh* const /*name*/) { 105 102482 : if (myItem.length() == 0 || myValue.length() == 0) { 106 : return; 107 : } 108 37156 : if (myValue.find_first_not_of("\n\t \a") == std::string::npos) { 109 : return; 110 : } 111 0 : setValue(myItem, myValue); 112 : myItem = ""; 113 : myValue = ""; 114 : } 115 : 116 : 117 : void 118 0 : OptionsLoader::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) { 119 0 : WRITE_WARNING(StringUtils::transcode(exception.getMessage())); 120 0 : WRITE_WARNING(" (At line/column " \ 121 : + toString(exception.getLineNumber() + 1) + '/' \ 122 : + toString(exception.getColumnNumber()) + ")."); 123 0 : myError = true; 124 0 : } 125 : 126 : 127 : void 128 0 : OptionsLoader::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) { 129 0 : WRITE_ERROR(StringUtils::transcode(exception.getMessage())); 130 0 : WRITE_ERROR(" (At line/column " 131 : + toString(exception.getLineNumber() + 1) + '/' 132 : + toString(exception.getColumnNumber()) + ")."); 133 0 : myError = true; 134 0 : } 135 : 136 : 137 : void 138 1 : OptionsLoader::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) { 139 1 : WRITE_ERROR(StringUtils::transcode(exception.getMessage())); 140 2 : WRITE_ERROR(" (At line/column " 141 : + toString(exception.getLineNumber() + 1) + '/' 142 : + toString(exception.getColumnNumber()) + ")."); 143 1 : myError = true; 144 1 : } 145 : 146 : 147 : bool 148 10405 : OptionsLoader::errorOccurred() const { 149 10405 : return myError; 150 : } 151 : 152 : /****************************************************************************/