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 11211 : OptionsLoader::OptionsLoader(OptionsCont& customOptions, const bool rootOnly) :
47 11211 : myRootOnly(rootOnly),
48 11211 : myOptions(customOptions),
49 11211 : myItem() {
50 11211 : }
51 :
52 :
53 11211 : OptionsLoader::~OptionsLoader() {}
54 :
55 :
56 130019 : void OptionsLoader::startElement(const XMLCh* const name, XERCES_CPP_NAMESPACE::AttributeList& attributes) {
57 130019 : myItem = StringUtils::transcode(name);
58 130019 : if (!myRootOnly) {
59 233731 : for (int i = 0; i < (int)attributes.getLength(); i++) {
60 103712 : const std::string& key = StringUtils::transcode(attributes.getName(i));
61 103712 : const std::string& value = StringUtils::transcode(attributes.getValue(i));
62 103712 : if (key == "value" || key == "v") {
63 82441 : setValue(myItem, value);
64 : }
65 : // could give a hint here about unsupported attributes in configuration files
66 : }
67 130019 : myValue = "";
68 : }
69 130019 : }
70 :
71 :
72 82441 : void OptionsLoader::setValue(const std::string& key, const std::string& value) {
73 82441 : if (value.length() > 0) {
74 : // try to add value in option container
75 : try {
76 82437 : 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 82441 : }
86 :
87 :
88 165763 : void OptionsLoader::characters(const XMLCh* const chars, const XERCES3_SIZE_t length) {
89 165763 : myValue = myValue + StringUtils::transcode(chars, (int) length);
90 165763 : }
91 :
92 :
93 : bool
94 82437 : OptionsLoader::setSecure(OptionsCont& options, const std::string& name, const std::string& value) const {
95 82437 : if (options.isWriteable(name)) {
96 82431 : options.set(name, value);
97 82431 : return true;
98 : }
99 : return false;
100 : }
101 :
102 :
103 : void
104 129995 : OptionsLoader::endElement(const XMLCh* const /*name*/) {
105 129995 : if (myItem.length() == 0 || myValue.length() == 0) {
106 : return;
107 : }
108 47354 : 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 4 : 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 11211 : OptionsLoader::errorOccurred() const {
149 11211 : return myError;
150 : }
151 :
152 : /****************************************************************************/
|