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