TreeTypedJSONConverter.cpp
Go to the documentation of this file.
2 
3 #include <SimoxUtility/json/eigen_conversion.h>
4 
6 
11 
13 {
15  {
16  jsonStack.push({"", nlohmann::json()});
17  }
18 
19  const nlohmann::json&
21  {
22  nlohmann::json& obj = jsonStack.top().second;
23  if (obj.front().is_object())
24  {
25  return obj.front();
26  }
27  return obj;
28  }
29 
30  /* We override this method because we need to handle untyped members in the hierarchy.
31  * The other get*Elements() methods will either not be called with a null type or can handle it.
32  */
35  {
36  return GetObjectElementsWithNullType(elementData, elementType);
37  }
38 
39  void
41  {
42  std::string key = "";
43  aron::Path path;
44  if (elementData)
45  {
46  path = elementData->getPath();
47  }
48  else if (elementType)
49  {
50  path = elementType->getPath();
51  }
52  else
53  {
54  // should not happen
55  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
56  }
57 
58  try
59  {
60  key = path.getLastElement();
61  if (!elementData)
62  {
63  // push NULL
64  jsonStack.push({key, nullptr});
65  }
66  else
67  {
68  // push new object as there is data
69  jsonStack.push({key, nlohmann::json(nlohmann::json::value_t::object)});
70  }
71  }
72  catch (const aron::error::AronException& e)
73  {
74  // This happens when we start at the top-level object.
75  jsonStack.push({key, nlohmann::json(nlohmann::json::value_t::object)});
76  }
77  }
78 
79  void
81  TypeInput& /*elementType*/)
82  {
83  auto obj = jsonStack.top();
84  jsonStack.pop();
85  insertIntoJSON(obj.first, obj.second);
86  }
87 
88  void
90  {
91  this->visitObjectOnEnter(elementData, elementType);
92  }
93 
94  void
96  {
97  this->visitObjectOnExit(elementData, elementType);
98  }
99 
100  void
102  {
103  this->visitListOnEnter(elementData, elementType);
104  }
105 
106  void
108  {
109  this->visitListOnExit(elementData, elementType);
110  }
111 
112  void
114  {
115  this->visitListOnEnter(elementData, elementType);
116  }
117 
118  void
120  {
121  this->visitListOnExit(elementData, elementType);
122  }
123 
124  void
126  {
127  std::string key = "";
128  aron::Path path;
129  if (elementData)
130  {
131  path = elementData->getPath();
132  }
133  else if(elementType)
134  {
135  path = elementType->getPath();
136  }
137  else
138  {
139  // should not happen
140  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
141  }
142 
143  key = path.getLastElement();
144 
145  if (!elementData)
146  {
147  jsonStack.push({key, nlohmann::json(nlohmann::json::value_t::array)});
148  }
149  else
150  {
151  jsonStack.push({key, nullptr});
152  }
153  }
154 
155  void
156  TreeTypedJSONConverter::visitListOnExit(DataInput& /*elementData*/, TypeInput& /*elementType*/)
157  {
158  auto list = jsonStack.top();
159  jsonStack.pop();
160  insertIntoJSON(list.first, list.second);
161  }
162 
163  void
165  {
166  if (elementData)
167  {
168  auto e = aron::data::NDArray::DynamicCast(elementData);
169  auto t = *aron::type::Matrix::DynamicCastAndCheck(elementType);
170 
171  auto& nd = *e;
172  const std::string key = nd.getPath().getLastElement();
173 
174  nlohmann::json obj;
175  if (nd.getType() == "float") // TODO: are these types correct?
176  {
177  Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>> m(
178  reinterpret_cast<float*>(nd.getData()), t.getRows(), t.getCols());
179  Eigen::to_json(obj, m);
180  }
181  else if (nd.getType() == "double")
182  {
183  Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> m(
184  reinterpret_cast<double*>(nd.getData()), t.getRows(), t.getCols());
185  Eigen::to_json(obj, m);
186  }
187  else
188  {
189  obj = handleGenericNDArray(nd);
190  }
191 
192  insertIntoJSON(key, obj);
193  }
194  else if(elementType)
195  {
196  std::string key = elementType->getPath().getLastElement();
197  insertNULLIntoJSON(key);
198  }
199  else
200  {
201  // should not happen
202  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
203  }
204  }
205 
206  void
208  {
209  if (elementData)
210  {
211  const std::string key = elementData->getPath().getLastElement();
212  auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
213  insertIntoJSON(key, handleGenericNDArray(nd));
214  }
215  else if(elementType)
216  {
217  std::string key = elementType->getPath().getLastElement();
218  insertNULLIntoJSON(key);
219  }
220  else
221  {
222  // should not happen
223  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
224  }
225  }
226 
227  void
229  {
230  if (elementData)
231  {
232  const std::string key = elementData->getPath().getLastElement();
233  auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
234  nlohmann::json obj;
236  insertIntoJSON(key, obj);
237  }
238  else if (elementType)
239  {
240  std::string key = elementType->getPath().getLastElement();
241  insertNULLIntoJSON(key);
242  }
243  else
244  {
245  // should not happen
246  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
247  }
248 
249  }
250 
251  void
253  {
254  if (elementData)
255  {
256  const std::string key = elementData->getPath().getLastElement();
257  auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
258  insertIntoJSON(key, handleGenericNDArray(nd));
259  }
260  else if (elementType)
261  {
262  std::string key = elementType->getPath().getLastElement();
263  insertNULLIntoJSON(key);
264  }
265  else
266  {
267  // should not happen
268  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
269  }
270  }
271 
272  void
274  {
275  if (elementData)
276  {
277  const std::string key = elementData->getPath().getLastElement();
278  auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
279  insertIntoJSON(key, handleGenericNDArray(nd));
280  }
281  else if (elementType)
282  {
283  std::string key = elementType->getPath().getLastElement();
284  insertNULLIntoJSON(key);
285  }
286  else
287  {
288  // should not happen
289  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
290  }
291  }
292 
293  void
295  {
296  this->visitInt(elementData, elementType);
297  }
298 
299  void
301  {
302  if (elementData)
303  {
304  const std::string key = elementData->getPath().getLastElement();
305  int i = *aron::data::Int::DynamicCastAndCheck(elementData);
306  insertIntoJSON(key, i);
307  }
308  else if (elementType)
309  {
310  std::string key = elementType->getPath().getLastElement();
311  insertNULLIntoJSON(key);
312  }
313  else
314  {
315  // should not happen
316  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
317  }
318  }
319 
320  void
322  {
323  if (elementData)
324  {
325  const std::string key = elementData->getPath().getLastElement();
326  int64_t l = *aron::data::Long::DynamicCastAndCheck(elementData);
327  insertIntoJSON(key, l);
328  }
329  else if (elementType)
330  {
331  std::string key = elementType->getPath().getLastElement();
332  insertNULLIntoJSON(key);
333  }
334  else
335  {
336  // should not happen
337  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
338  }
339  }
340 
341  void
343  {
344  if (elementData)
345  {
346  const std::string key = elementData->getPath().getLastElement();
347  float f = *aron::data::Float::DynamicCastAndCheck(elementData);
348  insertIntoJSON(key, f);
349  }
350  else if (elementType)
351  {
352  std::string key = elementType->getPath().getLastElement();
353  insertNULLIntoJSON(key);
354  }
355  else
356  {
357  // should not happen
358  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
359  }
360  }
361 
362  void
364  {
365  if (elementData)
366  {
367  const std::string key = elementData->getPath().getLastElement();
368  double d = *aron::data::Double::DynamicCastAndCheck(elementData);
369  insertIntoJSON(key, d);
370  }
371  else if (elementType)
372  {
373  std::string key = elementType->getPath().getLastElement();
374  insertNULLIntoJSON(key);
375  }
376  else
377  {
378  // should not happen
379  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
380  }
381  }
382 
383  void
385  {
386  if (elementData)
387  {
388  const std::string key = elementData->getPath().getLastElement();
389  bool b = *aron::data::Bool::DynamicCastAndCheck(elementData);
390  insertIntoJSON(key, b);
391  }
392  else if (elementType)
393  {
394  std::string key = elementType->getPath().getLastElement();
395  insertNULLIntoJSON(key);
396  }
397  else
398  {
399  // should not happen
400  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
401  }
402  }
403 
404  void
406  {
407  if (elementData)
408  {
409  const std::string key = elementData->getPath().getLastElement();
410  std::string s = *aron::data::String::DynamicCastAndCheck(elementData);
411  insertIntoJSON(key, s);
412  }
413  else if (elementType)
414  {
415  std::string key = elementType->getPath().getLastElement();
416  insertNULLIntoJSON(key);
417  }
418  else
419  {
420  // should not happen
421  throw aron::error::AronException(__PRETTY_FUNCTION__, "Both, data and type are NULL.");
422  }
423  }
424 
425  //void
426  //TreeTypedJSONConverter::visitDateTime(DataInput& elementData, TypeInput& /*elementType*/)
427  /*{
428  const std::string key = elementData->getPath().getLastElement();
429  int64_t l = *aron::data::Long::DynamicCastAndCheck(elementData);
430  armem::Time time { armem::Duration::MicroSeconds(l) };
431  insertIntoJSON(key, l);
432  if (!jsonStack.top().second.is_array())
433  {
434  insertIntoJSON(key + "_hr", armem::toDateTimeMilliSeconds(time));
435  }
436  }*/
437 
438  template <typename ElementType>
439  void
440  TreeTypedJSONConverter::insertIntoJSON(const std::string& key, const ElementType& data)
441  {
442  if (jsonStack.top().second.is_object())
443  {
444  jsonStack.top().second[key] = nlohmann::json(data);
445  }
446  else
447  {
448  jsonStack.top().second.emplace_back(data);
449  }
450  }
451 
452  void
453  TreeTypedJSONConverter::insertNULLIntoJSON(const std::string& key)
454  {
455  if (jsonStack.top().second.is_object())
456  {
457  jsonStack.top().second[key] = nullptr;
458  }
459  else
460  {
461  jsonStack.top().second.emplace_back(nullptr);
462  }
463  }
464 
465  nlohmann::json
466  TreeTypedJSONConverter::handleGenericNDArray(const aron::data::NDArray& nd)
467  {
468  nlohmann::json ndobj;
469  std::vector<int> shape = nd.getShape();
470  ndobj["dimensions"] = shape;
471  ndobj["type"] = nd.getType();
472 
473  int elements =
474  shape.empty()
475  ? 0
476  : std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>());
477  std::vector<unsigned char> d = std::vector<unsigned char>(elements);
478  memcpy(d.data(), nd.getData(), elements);
479  ndobj["data"] = d;
480  return ndobj;
481  }
482 } // namespace armarx::armem::gui::instance
armarx::aron::error::AronException
A base class for aron exceptions.
Definition: Exception.h:42
armarx::armem::gui::instance::TreeTypedJSONConverter::visitLong
void visitLong(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:321
armarx::armem::gui::instance::TreeTypedJSONConverter::visitDictOnEnter
void visitDictOnEnter(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:89
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::armem::gui::instance::TreeTypedJSONConverter::visitTupleOnExit
void visitTupleOnExit(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:119
armarx::armem::gui::instance::TreeTypedJSONConverter::visitDictOnExit
void visitDictOnExit(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:95
armarx::aron::data::RecursiveTypedVisitor< const data::VariantPtr, const type::VariantPtr >::MapElements
std::map< std::string, std::pair< DataInputNonConst, TypeInputNonConst > > MapElements
Definition: RecursiveVisitor.h:86
armarx::aron::data::RecursiveConstTypedVariantVisitor::GetObjectElementsWithNullType
static MapElements GetObjectElementsWithNullType(DataInput &o, TypeInput &t)
Definition: VariantVisitor.cpp:508
armarx::armem::gui::instance::TreeTypedJSONConverter::TreeTypedJSONConverter
TreeTypedJSONConverter()
Definition: TreeTypedJSONConverter.cpp:14
armarx::armem::gui::instance::TreeTypedJSONConverter::visitObjectOnExit
void visitObjectOnExit(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:80
armarx::armem::gui::instance::TreeTypedJSONConverter::visitImage
void visitImage(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:252
armarx::armem::gui::instance::TreeTypedJSONConverter::getObjectElements
MapElements getObjectElements(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:34
armarx::aron::data::detail::SpecializedVariantBase< data::dto::NDArray, NDArray >::DynamicCastAndCheck
static PointerType DynamicCastAndCheck(const VariantPtr &n)
Definition: SpecializedVariant.h:135
armarx::armem::gui::instance::TreeTypedJSONConverter::visitPointCloud
void visitPointCloud(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:273
armarx::aron::data::detail::SpecializedVariantBase< data::dto::NDArray, NDArray >::DynamicCast
static PointerType DynamicCast(const VariantPtr &n)
Definition: SpecializedVariant.h:117
armarx::aron::Path
The Path class.
Definition: Path.h:36
armarx::armem::gui::instance::TreeTypedJSONConverter::visitIntEnum
void visitIntEnum(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:294
armarx::armem::gui::instance
Definition: AronDataView.cpp:2
armarx::aron::data::RecursiveTypedVisitor< const data::VariantPtr, const type::VariantPtr >::TypeInput
typename TypedVisitorBase< const data::VariantPtr, const type::VariantPtr >::TypeInput TypeInput
Definition: RecursiveVisitor.h:81
armarx::armem::gui::instance::TreeTypedJSONConverter::visitNDArray
void visitNDArray(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:207
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::armem::gui::instance::TreeTypedJSONConverter::visitPairOnExit
void visitPairOnExit(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:107
armarx::armem::gui::instance::TreeTypedJSONConverter::visitFloat
void visitFloat(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:342
TreeTypedJSONConverter.h
armarx::armem::gui::instance::TreeTypedJSONConverter::visitDouble
void visitDouble(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:363
All.h
EigenConverter.h
armarx::ElementTypes::ElementType
ElementType
Definition: AbstractObjectSerializer.h:32
armarx::aron::data::converter::AronEigenConverter::ConvertToQuaternionf
static Eigen::Quaternion< float > ConvertToQuaternionf(const data::NDArrayPtr &)
Definition: EigenConverter.cpp:33
armarx::armem::gui::instance::TreeTypedJSONConverter::visitListOnEnter
void visitListOnEnter(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:125
armarx::armem::gui::instance::TreeTypedJSONConverter::getJSON
const nlohmann::json & getJSON()
Definition: TreeTypedJSONConverter.cpp:20
armarx::armem::gui::instance::TreeTypedJSONConverter::visitBool
void visitBool(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:384
armarx::aron::data::RecursiveTypedVisitor< const data::VariantPtr, const type::VariantPtr >::DataInput
typename TypedVisitorBase< const data::VariantPtr, const type::VariantPtr >::DataInput DataInput
Definition: RecursiveVisitor.h:80
armarx::armem::gui::instance::TreeTypedJSONConverter::visitInt
void visitInt(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:300
armarx::aron::Path::getLastElement
std::string getLastElement() const
Definition: Path.cpp:91
armarx::data::to_json
void to_json(nlohmann::json &j, const PackagePath &pp)
Definition: json_conversions.h:36
Exception.h
armarx::armem::gui::instance::TreeTypedJSONConverter::visitPairOnEnter
void visitPairOnEnter(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:101
armarx::armem::gui::instance::TreeTypedJSONConverter::visitTupleOnEnter
void visitTupleOnEnter(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:113
Time.h
armarx::aron::type::detail::SpecializedVariantBase< type::dto::Matrix, Matrix >::DynamicCastAndCheck
static std::shared_ptr< Matrix > DynamicCastAndCheck(const VariantPtr &n)
Definition: SpecializedVariant.h:124
armarx::armem::gui::instance::TreeTypedJSONConverter::visitObjectOnEnter
void visitObjectOnEnter(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:40
Logging.h
armarx::armem::gui::instance::TreeTypedJSONConverter::visitMatrix
void visitMatrix(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:164
armarx::armem::gui::instance::TreeTypedJSONConverter::visitListOnExit
void visitListOnExit(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:156
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx::armem::gui::instance::TreeTypedJSONConverter::visitQuaternion
void visitQuaternion(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:228
armarx::aron::Path::getPath
std::vector< std::string > getPath() const
Definition: Path.cpp:85
armarx::armem::gui::instance::TreeTypedJSONConverter::visitString
void visitString(DataInput &elementData, TypeInput &elementType) override
Definition: TreeTypedJSONConverter.cpp:405