Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2012-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 PlainXMLFormatter.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @date 2012
18 : ///
19 : // Output formatter for plain XML output
20 : /****************************************************************************/
21 : #pragma once
22 : #include <config.h>
23 :
24 : #ifdef HAVE_FMT
25 : #include <fmt/ostream.h>
26 : #endif
27 :
28 : #include "OutputFormatter.h"
29 :
30 :
31 : // ===========================================================================
32 : // class definitions
33 : // ===========================================================================
34 : /**
35 : * @class PlainXMLFormatter
36 : * @brief Output formatter for plain XML output
37 : *
38 : * PlainXMLFormatter format XML like output into the output stream.
39 : */
40 : class PlainXMLFormatter : public OutputFormatter {
41 : public:
42 : /// @brief Constructor
43 : PlainXMLFormatter(const int defaultIndentation = 0);
44 :
45 :
46 : /// @brief Destructor
47 1488031 : virtual ~PlainXMLFormatter() { }
48 :
49 :
50 : /** @brief Writes an XML header with optional configuration
51 : *
52 : * If something has been written (myXMLStack is not empty), nothing
53 : * is written and false returned.
54 : *
55 : * @param[in] into The output stream to use
56 : * @param[in] rootElement The root element to use
57 : * @param[in] attrs Additional attributes to save within the rootElement
58 : * @todo Describe what is saved
59 : */
60 : bool writeXMLHeader(std::ostream& into, const std::string& rootElement,
61 : const std::map<SumoXMLAttr, std::string>& attrs,
62 : bool includeConfig = true);
63 :
64 :
65 : /** @brief Writes an XML header with optional configuration
66 : *
67 : * If something has been written (myXMLStack is not empty), nothing
68 : * is written and false returned.
69 : *
70 : * @param[in] into The output stream to use
71 : * @param[in] rootElement The root element to use
72 : */
73 : bool writeHeader(std::ostream& into, const SumoXMLTag& rootElement);
74 :
75 :
76 : /** @brief Opens an XML tag
77 : *
78 : * An indentation, depending on the current xml-element-stack size, is written followed
79 : * by the given xml element ("<" + xmlElement)
80 : * The xml element is added to the stack, then.
81 : *
82 : * @param[in] into The output stream to use
83 : * @param[in] xmlElement Name of element to open
84 : * @return The OutputDevice for further processing
85 : */
86 : void openTag(std::ostream& into, const std::string& xmlElement);
87 :
88 :
89 : /** @brief Opens an XML tag
90 : *
91 : * Helper method which finds the correct string before calling openTag.
92 : *
93 : * @param[in] into The output stream to use
94 : * @param[in] xmlElement Id of the element to open
95 : */
96 : void openTag(std::ostream& into, const SumoXMLTag& xmlElement);
97 :
98 :
99 : /** @brief Closes the most recently opened tag
100 : *
101 : * @param[in] into The output stream to use
102 : * @return Whether a further element existed in the stack and could be closed
103 : * @todo it is not verified that the topmost element was closed
104 : */
105 : bool closeTag(std::ostream& into, const std::string& comment = "");
106 :
107 :
108 : /** @brief writes a preformatted tag to the device but ensures that any
109 : * pending tags are closed
110 : * @param[in] into The output stream to use
111 : * @param[in] val The preformatted data
112 : */
113 : void writePreformattedTag(std::ostream& into, const std::string& val);
114 :
115 : /** @brief writes arbitrary padding
116 : */
117 : void writePadding(std::ostream& into, const std::string& val);
118 :
119 :
120 : /** @brief writes an arbitrary attribute
121 : *
122 : * @param[in] into The output stream to use
123 : * @param[in] attr The attribute (name)
124 : * @param[in] val The attribute value
125 : */
126 : template <class T>
127 19010631 : static void writeAttr(std::ostream& into, const std::string& attr, const T& val) {
128 38021052 : into << " " << attr << "=\"" << toString(val, into.precision()) << "\"";
129 19010631 : }
130 :
131 :
132 : /** @brief writes a named attribute
133 : *
134 : * @param[in] into The output stream to use
135 : * @param[in] attr The attribute (name)
136 : * @param[in] val The attribute value
137 : */
138 : template <class T>
139 7592856 : static void writeAttr(std::ostream& into, const SumoXMLAttr attr, const T& val) {
140 30254229 : into << " " << toString(attr) << "=\"" << toString(val, into.precision()) << "\"";
141 7592856 : }
142 :
143 240252 : bool wroteHeader() const {
144 240252 : return !myXMLStack.empty();
145 : }
146 :
147 : private:
148 : /// @brief The stack of begun xml elements
149 : std::vector<std::string> myXMLStack;
150 :
151 : /// @brief The initial indentation level
152 : int myDefaultIndentation;
153 :
154 : /// @brief whether a closing ">" might be missing
155 : bool myHavePendingOpener;
156 : };
157 :
158 :
159 : // ===========================================================================
160 : // specialized template implementations (for speedup)
161 : // ===========================================================================
162 : template <>
163 27372592 : inline void PlainXMLFormatter::writeAttr(std::ostream& into, const SumoXMLAttr attr, const double& val) {
164 : #ifdef HAVE_FMT
165 : fmt::print(into, " {}=\"{:.{}f}\"", toString(attr), val, into.precision());
166 : #else
167 54745184 : into << " " << toString(attr) << "=\"" << val << "\"";
168 : #endif
169 27372592 : }
170 :
171 :
172 : template <>
173 19841768 : inline void PlainXMLFormatter::writeAttr(std::ostream& into, const SumoXMLAttr attr, const std::string& val) {
174 39683536 : into << " " << toString(attr) << "=\"" << val << "\"";
175 19841768 : }
|