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 
24 
25 #include <iomanip>
26 #include <boost/regex.hpp>
27 
28 namespace armarx
29 {
30  JsonWriter::JsonWriter(int indenting, const std::string& indentChars, bool jsStyleKeys)
31  : indenting(indenting), nesting(0), indentChars(indentChars), jsStyleKeys(jsStyleKeys)
32  {
33  }
34 
36  {
37  beginValue();
38 
39  stack.push(eEmptyObject);
40  ss << "{";
41  nesting++;
42  }
43 
45  {
46  if (stack.size() == 0)
47  {
48  throw LocalException("Stack is empty");
49  }
50 
51  if (stack.top() != eEmptyObject && stack.top() != eObject)
52  {
53  throw LocalException("Wrong type");
54  }
55 
56  nesting--;
57  endArrayOrObject();
58  stack.pop();
59  ss << "}";
60  endValue();
61  }
62 
63  void JsonWriter::writeKey(const std::string& key)
64  {
65  beginKey();
66  if (jsStyleKeys && isId(key))
67  {
68  ss << key << (indenting == 2 ? ": " : ":");
69  }
70  else
71  {
72  ss << EscapeQuote(key) << (indenting == 2 ? ": " : ":");
73  }
74  endKey();
75  }
76 
78  {
79  beginValue();
80  stack.push(eEmptyArray);
81  ss << "[";
82  nesting++;
83  }
84 
86  {
87  if (stack.size() == 0)
88  {
89  throw LocalException("Stack is empty");
90  }
91 
92  if (stack.top() != eEmptyArray && stack.top() != eArray)
93  {
94  throw LocalException("Wrong type");
95  }
96 
97  nesting--;
98  endArrayOrObject();
99  stack.pop();
100  ss << "]";
101  endValue();
102  }
103 
104  void JsonWriter::writeRawValue(const std::string& value)
105  {
106  beginValue();
107  ss << value;
108  endValue();
109  }
110 
111  std::string JsonWriter::toString()
112  {
113  return ss.str();
114  }
115 
116  bool JsonWriter::isId(const std::string& str)
117  {
118  boost::cmatch result;
119  return boost::regex_search(str.c_str(), result, boost::regex("^[_A-Za-z]\\w*$"), boost::regex_constants::match_default);
120  }
121 
122  std::string JsonWriter::EscapeQuote(const std::string& str)
123  {
124  return "\"" + Escape(str) + "\"";
125  }
126 
127  std::string JsonWriter::Escape(const std::string& str)
128  {
129  std::ostringstream ss;
130 
131  for (auto iter = str.cbegin(); iter != str.cend(); iter++)
132  {
133  switch (*iter)
134  {
135  case '\\':
136  ss << "\\\\";
137  break;
138 
139  case '"':
140  ss << "\\\"";
141  break;
142 
143  case '\b':
144  ss << "\\b";
145  break;
146 
147  case '\f':
148  ss << "\\f";
149  break;
150 
151  case '\n':
152  ss << "\\n";
153  break;
154 
155  case '\r':
156  ss << "\\r";
157  break;
158 
159  case '\t':
160  ss << "\\t";
161  break;
162 
163  default:
164  if (IsControlChar(*iter))
165  {
166  ss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*iter);
167  }
168  else
169  {
170  ss << *iter;
171  }
172 
173  break;
174  }
175  }
176 
177  return ss.str();
178  }
179 
180  void JsonWriter::writeNewLine()
181  {
182  if (indenting == 2)
183  {
184  ss << "\n";
185 
186  for (int i = 0; i < nesting; i++)
187  {
188  ss << indentChars;
189  }
190  }
191  }
192 
193  void JsonWriter::beginValue()
194  {
195  if (stack.size() == 0)
196  {
197  return;
198  }
199 
200  if (stack.top() == eArray)
201  {
202  ss << (indenting == 1 ? ", " : ",");
203  }
204 
205  if (stack.top() != eObjectKey)
206  {
207  writeNewLine();
208  }
209 
210  if (stack.top() != eEmptyArray && stack.top() != eArray && stack.top() != eObjectKey)
211  {
212  throw LocalException("Wrong type");
213  }
214  }
215 
216  void JsonWriter::beginKey()
217  {
218  if (stack.size() == 0)
219  {
220  throw LocalException("Stack is empty");
221  }
222 
223  if (stack.top() != eEmptyObject && stack.top() != eObject)
224  {
225  throw LocalException("Wrong type");
226  }
227 
228  if (stack.top() == eObject)
229  {
230  ss << (indenting == 1 ? ", " : ",");
231  }
232 
233  writeNewLine();
234  }
235 
236  void JsonWriter::endKey()
237  {
238  stack.pop();
239  stack.push(eObjectKey);
240  }
241 
242  void JsonWriter::endValue()
243  {
244  if (stack.size() == 0)
245  {
246  stack.push(eFinal);
247  }
248  else if (stack.top() == eEmptyArray)
249  {
250  stack.top() = eArray;
251  }
252  else if (stack.top() == eObjectKey)
253  {
254  stack.top() = eObject;
255  }
256  }
257 
258  void JsonWriter::endArrayOrObject()
259  {
260  if (stack.top() == eArray || stack.top() == eObject)
261  {
262  writeNewLine();
263  }
264  }
265 }
armarx::JsonWriter::writeRawValue
void writeRawValue(const std::string &value)
Definition: JsonWriter.cpp:104
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:42
armarx::JsonWriter::writeKey
void writeKey(const std::string &key)
Definition: JsonWriter.cpp:63
armarx::JsonWriter::startArray
void startArray()
Definition: JsonWriter.cpp:77
armarx::JsonWriter::endObject
void endObject()
Definition: JsonWriter.cpp:44
armarx::JsonWriter::toString
std::string toString()
Definition: JsonWriter.cpp:111
armarx::JsonWriter::IsControlChar
static bool IsControlChar(char c)
Definition: JsonWriter.h:86
armarx::JsonWriter::isId
bool isId(const std::string &str)
Definition: JsonWriter.cpp:116
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::JsonWriter::Escape
static std::string Escape(const std::string &str)
Definition: JsonWriter.cpp:127
armarx::JsonWriter::EscapeQuote
static std::string EscapeQuote(const std::string &str)
Definition: JsonWriter.cpp:122
armarx::JsonWriter::startObject
void startObject()
Definition: JsonWriter.cpp:35
armarx::JsonWriter::JsonWriter
JsonWriter(int indenting=0, const std::string &indentChars=" ", bool jsStyleKeys=false)
Definition: JsonWriter.cpp:30
armarx::JsonWriter::endArray
void endArray()
Definition: JsonWriter.cpp:85
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
Exception.h
JsonWriter.h