Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
ParBuffer.h
Go to the documentation of this file.
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/****************************************************************************/
18// Class for the string serialization and deserialization of parameters
19/****************************************************************************/
20
21#pragma once
22#include <config.h>
23
24#include <cstddef>
25#include <string>
26#include <sstream>
27#include <algorithm>
28
29class ParBuffer {
30public:
31 ParBuffer() : SEP(':'), ESC('\\'), QUO('"'), was_empty(false) {}
32 ParBuffer(std::string buf) : SEP(':'), ESC('\\'), QUO('"'),
33 was_empty(false) {
34 inBuffer = buf;
35 }
36
37 template<typename T> ParBuffer& operator <<(const T& v) {
38 std::stringstream ss;
39 std::string str_value;
40 ss << v;
41 str_value = escape(ss.str());
42 if (outBuffer.str().length() == 0) {
43 outBuffer << str_value;
44 } else {
45 outBuffer << SEP << str_value;
46 }
47 return *this;
48 }
49
50 size_t next_escape(std::string str, size_t pos) {
51 size_t c_pos = str.find(SEP, pos);
52 size_t e_pos = str.find(ESC, pos);
53 if (c_pos == std::string::npos) {
54 return e_pos;
55 }
56 if (e_pos == std::string::npos) {
57 return c_pos;
58 }
59 return std::min(c_pos, e_pos);
60 }
61
62 std::string escape(std::string str) {
63 size_t pos, last_pos = 0;
64 std::stringstream escaping;
65 std::string escaped;
66 while ((pos = next_escape(str, last_pos)) != std::string::npos) {
67 escaping << str.substr(last_pos, pos - last_pos);
68 escaping << ESC << str.substr(pos, 1);
69 last_pos = pos + 1;
70 }
71 if (last_pos != str.size()) {
72 escaping << str.substr(last_pos);
73 }
74 escaped = escaping.str();
75 if (escaped.empty() || (escaped.c_str()[0] == QUO && escaped.c_str()[escaped.length() - 1] == QUO)) {
76 escaping.str("");
77 escaping.clear();
78 escaping << QUO << escaped << QUO;
79 escaped = escaping.str();
80 }
81 return escaped;
82 }
83
84 std::string unescape(std::string str) {
85 size_t pos, last_pos = 0;
86 std::stringstream unescaped;
87 std::string escaped;
88 if (str.c_str()[0] == QUO && str.c_str()[str.length() - 1] == QUO) {
89 str = str.substr(1, str.length() - 2);
90 }
91 while ((pos = str.find(ESC, last_pos)) != std::string::npos) {
92 unescaped << str.substr(last_pos, pos - last_pos);
93 unescaped << str.substr(pos + 1, 1);
94 last_pos = pos + 2;
95 }
96 if (last_pos != str.size()) {
97 unescaped << str.substr(last_pos);
98 }
99 return unescaped.str();
100 }
101
102 std::string next() {
103 if (inBuffer.size() == 0) {
104 return "";
105 }
106
107 size_t sep = std::string::npos;
108 do {
109 sep = inBuffer.find(SEP, sep + 1);
110 } while (!(sep == std::string::npos || sep == 0 || inBuffer.c_str()[sep - 1] != ESC));
111
112 std::string value;
113 if (sep == std::string::npos) {
114 value = unescape(inBuffer);
115 inBuffer = "";
116 } else {
117 value = unescape(inBuffer.substr(0, sep));
118 inBuffer = inBuffer.substr(sep + 1);
119 }
120 return value;
121 }
122
123 template <typename T> ParBuffer& operator>>(T& v) {
124 std::string value = next();
125 std::stringstream ss(value);
126 ss >> v;
127 // stringstream doesn't write to v if value is an empty string. the
128 // only solution is letting the user know that the last parsed
129 // portion was empty
130 if (value == "") {
131 was_empty = true;
132 } else {
133 was_empty = false;
134 }
135 return *this;
136 }
137
138 bool last_empty() {
139 return was_empty;
140 }
141
142 void set(std::string buf) {
143 inBuffer = buf;
144 }
145 void clear() {
146 outBuffer.clear();
147 }
148 std::string str() const {
149 return outBuffer.str();
150 }
151
152private:
153 const char SEP;
154 const char ESC;
155 const char QUO;
156 std::stringstream outBuffer;
157 std::string inBuffer;
159
160};
size_t next_escape(std::string str, size_t pos)
Definition ParBuffer.h:50
bool was_empty
Definition ParBuffer.h:158
std::string inBuffer
Definition ParBuffer.h:157
std::stringstream outBuffer
Definition ParBuffer.h:156
ParBuffer & operator>>(T &v)
Definition ParBuffer.h:123
std::string str() const
Definition ParBuffer.h:148
std::string next()
Definition ParBuffer.h:102
std::string unescape(std::string str)
Definition ParBuffer.h:84
const char QUO
Definition ParBuffer.h:155
const char ESC
Definition ParBuffer.h:154
std::string escape(std::string str)
Definition ParBuffer.h:62
const char SEP
Definition ParBuffer.h:153
void set(std::string buf)
Definition ParBuffer.h:142
void clear()
Definition ParBuffer.h:145
ParBuffer & operator<<(const T &v)
Definition ParBuffer.h:37
bool last_empty()
Definition ParBuffer.h:138