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