JsonWriter.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @author Simon Ottenhaus (simon dot ottenhaus at kit dot edu)
17 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
18 * GNU General Public License
19 */
20 
21 #include "JsonWriter.h"
22 
23 #include <iomanip>
24 
25 #include <boost/regex.hpp>
26 
28 
29 namespace armarx
30 {
31  JsonWriter::JsonWriter(int indenting, const std::string& indentChars, bool jsStyleKeys) :
32  indenting(indenting), nesting(0), indentChars(indentChars), jsStyleKeys(jsStyleKeys)
33  {
34  }
35 
36  void
38  {
39  beginValue();
40 
41  stack.push(eEmptyObject);
42  ss << "{";
43  nesting++;
44  }
45 
46  void
48  {
49  if (stack.size() == 0)
50  {
51  throw LocalException("Stack is empty");
52  }
53 
54  if (stack.top() != eEmptyObject && stack.top() != eObject)
55  {
56  throw LocalException("Wrong type");
57  }
58 
59  nesting--;
60  endArrayOrObject();
61  stack.pop();
62  ss << "}";
63  endValue();
64  }
65 
66  void
67  JsonWriter::writeKey(const std::string& key)
68  {
69  beginKey();
70  if (jsStyleKeys && isId(key))
71  {
72  ss << key << (indenting == 2 ? ": " : ":");
73  }
74  else
75  {
76  ss << EscapeQuote(key) << (indenting == 2 ? ": " : ":");
77  }
78  endKey();
79  }
80 
81  void
83  {
84  beginValue();
85  stack.push(eEmptyArray);
86  ss << "[";
87  nesting++;
88  }
89 
90  void
92  {
93  if (stack.size() == 0)
94  {
95  throw LocalException("Stack is empty");
96  }
97 
98  if (stack.top() != eEmptyArray && stack.top() != eArray)
99  {
100  throw LocalException("Wrong type");
101  }
102 
103  nesting--;
104  endArrayOrObject();
105  stack.pop();
106  ss << "]";
107  endValue();
108  }
109 
110  void
111  JsonWriter::writeRawValue(const std::string& value)
112  {
113  beginValue();
114  ss << value;
115  endValue();
116  }
117 
118  std::string
120  {
121  return ss.str();
122  }
123 
124  bool
125  JsonWriter::isId(const std::string& str)
126  {
127  boost::cmatch result;
128  return boost::regex_search(str.c_str(),
129  result,
130  boost::regex("^[_A-Za-z]\\w*$"),
131  boost::regex_constants::match_default);
132  }
133 
134  std::string
135  JsonWriter::EscapeQuote(const std::string& str)
136  {
137  return "\"" + Escape(str) + "\"";
138  }
139 
140  std::string
141  JsonWriter::Escape(const std::string& str)
142  {
143  std::ostringstream ss;
144 
145  for (auto iter = str.cbegin(); iter != str.cend(); iter++)
146  {
147  switch (*iter)
148  {
149  case '\\':
150  ss << "\\\\";
151  break;
152 
153  case '"':
154  ss << "\\\"";
155  break;
156 
157  case '\b':
158  ss << "\\b";
159  break;
160 
161  case '\f':
162  ss << "\\f";
163  break;
164 
165  case '\n':
166  ss << "\\n";
167  break;
168 
169  case '\r':
170  ss << "\\r";
171  break;
172 
173  case '\t':
174  ss << "\\t";
175  break;
176 
177  default:
178  if (IsControlChar(*iter))
179  {
180  ss << "\\u" << std::hex << std::uppercase << std::setfill('0')
181  << std::setw(4) << static_cast<int>(*iter);
182  }
183  else
184  {
185  ss << *iter;
186  }
187 
188  break;
189  }
190  }
191 
192  return ss.str();
193  }
194 
195  void
196  JsonWriter::writeNewLine()
197  {
198  if (indenting == 2)
199  {
200  ss << "\n";
201 
202  for (int i = 0; i < nesting; i++)
203  {
204  ss << indentChars;
205  }
206  }
207  }
208 
209  void
210  JsonWriter::beginValue()
211  {
212  if (stack.size() == 0)
213  {
214  return;
215  }
216 
217  if (stack.top() == eArray)
218  {
219  ss << (indenting == 1 ? ", " : ",");
220  }
221 
222  if (stack.top() != eObjectKey)
223  {
224  writeNewLine();
225  }
226 
227  if (stack.top() != eEmptyArray && stack.top() != eArray && stack.top() != eObjectKey)
228  {
229  throw LocalException("Wrong type");
230  }
231  }
232 
233  void
234  JsonWriter::beginKey()
235  {
236  if (stack.size() == 0)
237  {
238  throw LocalException("Stack is empty");
239  }
240 
241  if (stack.top() != eEmptyObject && stack.top() != eObject)
242  {
243  throw LocalException("Wrong type");
244  }
245 
246  if (stack.top() == eObject)
247  {
248  ss << (indenting == 1 ? ", " : ",");
249  }
250 
251  writeNewLine();
252  }
253 
254  void
255  JsonWriter::endKey()
256  {
257  stack.pop();
258  stack.push(eObjectKey);
259  }
260 
261  void
262  JsonWriter::endValue()
263  {
264  if (stack.size() == 0)
265  {
266  stack.push(eFinal);
267  }
268  else if (stack.top() == eEmptyArray)
269  {
270  stack.top() = eArray;
271  }
272  else if (stack.top() == eObjectKey)
273  {
274  stack.top() = eObject;
275  }
276  }
277 
278  void
279  JsonWriter::endArrayOrObject()
280  {
281  if (stack.top() == eArray || stack.top() == eObject)
282  {
283  writeNewLine();
284  }
285  }
286 } // namespace armarx
armarx::JsonWriter::writeRawValue
void writeRawValue(const std::string &value)
Definition: JsonWriter.cpp:111
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:43
armarx::JsonWriter::writeKey
void writeKey(const std::string &key)
Definition: JsonWriter.cpp:67
armarx::JsonWriter::startArray
void startArray()
Definition: JsonWriter.cpp:82
armarx::JsonWriter::endObject
void endObject()
Definition: JsonWriter.cpp:47
armarx::JsonWriter::toString
std::string toString()
Definition: JsonWriter.cpp:119
armarx::JsonWriter::IsControlChar
static bool IsControlChar(char c)
Definition: JsonWriter.h:99
armarx::JsonWriter::isId
bool isId(const std::string &str)
Definition: JsonWriter.cpp:125
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::JsonWriter::Escape
static std::string Escape(const std::string &str)
Definition: JsonWriter.cpp:141
armarx::JsonWriter::EscapeQuote
static std::string EscapeQuote(const std::string &str)
Definition: JsonWriter.cpp:135
armarx::JsonWriter::startObject
void startObject()
Definition: JsonWriter.cpp:37
armarx::JsonWriter::JsonWriter
JsonWriter(int indenting=0, const std::string &indentChars=" ", bool jsStyleKeys=false)
Definition: JsonWriter.cpp:31
armarx::JsonWriter::endArray
void endArray()
Definition: JsonWriter.cpp:91
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
Exception.h
JsonWriter.h