Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
CSVFormatter.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2012-2026 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/****************************************************************************/
18// Output formatter for CSV output
19/****************************************************************************/
20#pragma once
21#include <config.h>
22
23#include <memory>
24#include <algorithm>
25#include "OutputFormatter.h"
28
29
30// ===========================================================================
31// class definitions
32// ===========================================================================
38public:
40 CSVFormatter(const std::string& columnNames, const char separator = ';');
41
43 virtual ~CSVFormatter() { }
44
51 void openTag(std::ostream& into, const std::string& xmlElement);
52
58 void openTag(std::ostream& into, const SumoXMLTag& xmlElement);
59
66 bool closeTag(std::ostream& into, const std::string& comment = "");
67
74 template <class T>
75 void writeAttr(std::ostream& into, const SumoXMLAttr attr, const T& val, const bool isNull) {
76 checkAttr(attr);
77 myValues.emplace_back(isNull ? "" : toString(val, into.precision()));
78 }
79
80 template <class T>
81 void writeAttr(std::ostream& into, const std::string& attr, const T& val, const bool isNull) {
82 assert(!myCheckColumns);
83 checkHeader(attr);
84 myValues.emplace_back(isNull ? "" : toString(val, into.precision()));
85 }
86
87 void writeTime(std::ostream& /* into */, const SumoXMLAttr attr, const SUMOTime val) {
88 checkAttr(attr);
89 myValues.emplace_back(time2string(val));
90 }
91
92 bool wroteHeader() const {
93 return myWroteHeader;
94 }
95
96 void setExpectedAttributes(const SumoXMLAttrMask& expected, const int depth = 2) {
97 myExpectedAttrs = expected;
98 myMaxDepth = depth;
99 myCheckColumns = expected.any();
100 }
101
102private:
109 inline void checkAttr(const SumoXMLAttr attr) {
110 if (myCheckColumns && myMaxDepth == (int)myXMLStack.size()) {
111 mySeenAttrs.set(attr);
112 if (!myExpectedAttrs.test(attr)) {
113 throw ProcessError(TLF("Unexpected attribute '%', this file format does not support CSV output yet.", toString(attr)));
114 }
115 }
116 checkHeader(attr);
117 }
118
119 template <class ATTR_TYPE>
120 inline void checkHeader(const ATTR_TYPE& attr) {
121 myNeedsWrite = true;
122 if (!myWroteHeader) {
123 std::string headerName = toString(attr);
124 if (myHeaderFormat != "plain" && !(myHeaderFormat == "auto" && std::find(myHeader.begin(), myHeader.end(), headerName) == myHeader.end())) {
125 headerName = myCurrentTag + "_" + headerName;
126 }
127 if (std::find(myHeader.begin(), myHeader.end(), headerName) == myHeader.end()) {
128 for (std::string& row : myBufferedRows) {
129 row += mySeparator;
130 }
131 while (myValues.size() < myHeader.size()) {
132 myValues.emplace_back("");
133 }
134 myHeader.emplace_back(headerName);
135 }
136 }
137 }
138
140 const std::string myHeaderFormat;
141
143 const char mySeparator;
144
146 std::vector<std::string> myHeader;
147
149 std::string myCurrentTag;
150
152 std::vector<int> myXMLStack;
153
155 std::vector<std::string> myValues;
156
158 int myMaxDepth = 2;
159
161 bool myWroteHeader = false;
162
164 bool myNeedsWrite = false;
165
167 std::vector<std::string> myBufferedRows;
168
170 bool myCheckColumns = false;
171
174
177};
long long int SUMOTime
Definition GUI.h:36
#define TLF(string,...)
Definition MsgHandler.h:306
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
SumoXMLTag
Numbers representing SUMO-XML - element names.
std::bitset< 96 > SumoXMLAttrMask
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
Output formatter for CSV output.
const std::string myHeaderFormat
the format to use for the column names
void writeAttr(std::ostream &into, const std::string &attr, const T &val, const bool isNull)
bool myNeedsWrite
whether any attribute has been written since the last row was emitted
std::string myCurrentTag
the currently read tag (only valid when generating the header)
bool wroteHeader() const
Returns whether a header has been written. Useful to detect whether a file is being used by multiple ...
void writeAttr(std::ostream &into, const SumoXMLAttr attr, const T &val, const bool isNull)
writes a named attribute
SumoXMLAttrMask myExpectedAttrs
which CSV columns are expected (just for checking completeness)
void setExpectedAttributes(const SumoXMLAttrMask &expected, const int depth=2)
Set the expected attributes to write. This is used for tracking which attributes are expected in tabl...
SumoXMLAttrMask mySeenAttrs
which CSV columns have been set (just for checking completeness)
std::vector< int > myXMLStack
The number of attributes in the currently open XML elements.
std::vector< std::string > myHeader
the CSV header
virtual ~CSVFormatter()
Destructor.
int myMaxDepth
the maximum depth of the XML hierarchy (excluding the root element)
bool myCheckColumns
whether the columns should be checked for completeness
const char mySeparator
The value separator.
bool closeTag(std::ostream &into, const std::string &comment="")
Closes the most recently opened tag.
void openTag(std::ostream &into, const std::string &xmlElement)
Keeps track of an open XML tag by adding a new element to the stack.
void checkHeader(const ATTR_TYPE &attr)
void writeTime(std::ostream &, const SumoXMLAttr attr, const SUMOTime val)
void checkAttr(const SumoXMLAttr attr)
Helper function to keep track of the written attributes and accumulate the header....
bool myWroteHeader
whether the CSV header line has been written
std::vector< std::string > myValues
the current attribute / column values
std::vector< std::string > myBufferedRows
partial rows buffered before the schema is known (depth < myMaxDepth)
Abstract base class for output formatters.