MIRA
JSONSerializer.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_JSONSERIALIZER_H_
48 #define _MIRA_JSONSERIALIZER_H_
49 
50 #include <iostream>
51 #include <list>
52 #include <algorithm>
53 #include <stack>
54 
57 
58 #include <json/JSON.h>
59 
61 
62 namespace mira {
63 
65 
93 class JSONSerializer : public Serializer<JSONSerializer>
94 {
96 
97 public:
100  {
102  STANDARD = 0x00,
103 
106  };
107 
108  MIRA_ENUM_TO_FLAGS_INCLASS(OutputFormat) // generate logical operators for enum values
109 
110 
115  JSONSerializer(bool readOnly = false, OutputFormat format = STANDARD)
116  : mReadOnly(readOnly), mOutputFormat(format)
117  {}
118 
120  template<typename T>
121  json::Value serialize(const T& value)
122  {
123  mFirstComplex = true;
124  auto jvalue = json::Value();
125  mValuePtr = &jvalue;
127  return jvalue;
128  }
129 
130  json::Value serialize(const json::Value& value)
131  {
132  return value;
133  }
134 
136 
137  template<typename T>
138  VersionType version(VersionType version, const T* caller = NULL)
139  {
140  return this->version<T>(version, false);
141  }
142 
143  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
145  {
146  return versionLegacy(version);
147  }
148 
149  template<typename T>
151  {
152  return this->version<T>(version, true);
153  }
154 
155 private:
156  template<typename T>
157  VersionType version(VersionType version, bool acceptDesiredVersion)
158  {
159  version = this->template queryDesiredClassVersion<T>(version, acceptDesiredVersion);
160 
161  int vf = this->forcedSerializeVersion();
162  if ((vf == 0) || (vf == 1))
163  return versionLegacy(version);
164 
165  static const std::string v = std::string("@version[") + typeName<T>() + "]";
166  mValuePtr->get_obj()[v] = json::Value(json::cast(version));
167  return version;
168  }
169 
170  VersionType versionLegacy(VersionType version)
171  {
172  mValuePtr->get_obj()["@version"] = json::Value(json::cast((int)version));
173  return version;
174  }
175 
176 public:
177  template<typename T>
178  void atomic(T& member)
179  {
180  // member of a currently serialized object -> add member
181  if (mValuePtr->type() == json_spirit::obj_type) {
182  mValuePtr->get_obj()[getCurrentMemberMeta().id] = json::Value(json::cast(member));
183  }
184  // item of a currently serialized array -> add item
185  else if (mValuePtr->type() == json_spirit::array_type) {
186  mValuePtr->get_array().push_back(json::Value(json::cast(member)));
187  }
188  // no currently serialized value -> set member as new value
189  else {
190  *mValuePtr = json::Value(json::cast(member));
191  }
192  }
193 
195  {
196  // member of a currently serialized object -> add member
197  if (mValuePtr->type() == json_spirit::obj_type) {
198  mValuePtr->get_obj()[getCurrentMemberMeta().id] = member;
199  }
200  // item of a currently serialized array -> add item
201  else if (mValuePtr->type() == json_spirit::array_type) {
202  mValuePtr->get_array().push_back(member);
203  }
204  // no currently serialized value -> set member as new value
205  else {
206  *mValuePtr = member;
207  }
208  }
209 
210  template<typename T>
211  void object(T& member)
212  {
213  // in json the outer most object (the root object) has no name
214  if (mFirstComplex) {
215  *mValuePtr = json::Object();
216  mFirstComplex = false;
217  if (!mPointerClass.empty()) {
218  mValuePtr->get_obj()["@class"] = json::Value(mPointerClass);
219  mPointerClass.clear();
220  }
222  }
223  else {
224  json::Value* oldValue = mValuePtr;
225 
226  if (oldValue->type() == json_spirit::obj_type) {
227  json::Value& entry = oldValue->get_obj()[getCurrentMemberMeta().id];
228  entry = json::Object();
229  mValuePtr = &entry;
230  }
231  else if (oldValue->type() == json_spirit::array_type) {
232  oldValue->get_array().push_back(json::Object());
233  json::Value& entry = oldValue->get_array().back();
234  mValuePtr = &entry;
235  }
236 
237  if (!mPointerClass.empty()) {
238  mValuePtr->get_obj()["@class"] = json::Value(mPointerClass);
239  mPointerClass.clear();
240  }
242  mValuePtr = oldValue;
243  }
244  }
245 
246  template<typename T>
248  {
249  collectionInternal(member);
250  }
251 
252  template<typename mapped_type>
253  void collection(std::map<std::string, mapped_type>& member)
254  {
255  if (mOutputFormat & STRING_MAP_AS_OBJECT)
256  object(member);
257  else
258  collectionInternal(member);
259  }
260 
261  void pointerReference(int referencedObjectID)
262  {
263  json::Value val = json::Object();
264  val.get_obj()["@ref"] = json::Value(this->getHumanReadableFullID(referencedObjectID));
265  if (mValuePtr->type() == json_spirit::obj_type)
266  mValuePtr->get_obj()[getCurrentMemberMeta().id] = val;
267  else if (mValuePtr->type() == json_spirit::array_type)
268  mValuePtr->get_array().push_back(val);
269  }
270 
271  void pointerWithClassType(const std::string& type)
272  {
273  mPointerClass = type;
274  }
275 
276  void pointerNull()
277  {
278  if (mValuePtr->type() == json_spirit::obj_type)
279  mValuePtr->get_obj()[getCurrentMemberMeta().id] = json::Value();
280  else if (mValuePtr->type() == json_spirit::array_type)
281  mValuePtr->get_array().push_back(json::Value());
282  else
283  *mValuePtr = json::Value();
284  }
285 
286  template<typename T>
287  void roproperty(const char* name, const T& member, const char* comment,
289  {
290  if (!mReadOnly)
291  return;
292  // cast away constness, this is okay, since read only properties we
293  // will never write to the data
294  property(name, const_cast<T&>(member), comment, std::move(hint), flags);
295  }
296 
297  template<typename T>
298  void roproperty(const char* name, const std::string& id, const T& member, const char* comment,
300  {
301  if (!mReadOnly)
302  return;
303  // cast away constness, this is okay, since read only properties we
304  // will never write to the data
305  property(name, id, const_cast<T&>(member), comment, std::move(hint), flags);
306  }
307 
308  template<typename T>
309  void roproperty(const char* name, Getter<T> getter, const char* comment,
311  {
312  if (!mReadOnly)
313  return;
314  auto a = makeAccessor(getter, NullSetter<T>());
315  property(name, a, comment, std::move(hint), flags);
316  }
317 
318 public:
319  template<typename Container>
320  void mapEntry(int id, const typename Container::value_type& p)
321  {
322  using type = typename Container::mapped_type;
323 
324  if (mOutputFormat & STRING_MAP_AS_OBJECT) {
325  type& nonconstv = const_cast<type&>(p.second);
326  member(p.first.c_str(), nonconstv, "");
327  }
328  else {
329  serialization::reflectReadMapPair<JSONSerializer, Container>(*this, "item", id, p);
330  }
331  }
332 
333 private:
334  template<typename T>
335  void collectionInternal(T& member)
336  {
337  if (mFirstComplex) {
338  *mValuePtr = json::Array{};
339  mFirstComplex = false;
341  }
342  else {
343  json::Value* oldValue = mValuePtr;
344 
345  if (oldValue->type() == json_spirit::obj_type) {
346  json::Value& entry = oldValue->get_obj()[getCurrentMemberMeta().id];
347  entry = json::Array{};
348  mValuePtr = &entry;
349  }
350  else if (oldValue->type() == json_spirit::array_type) {
351  oldValue->get_array().push_back(json::Array{});
352  json::Value& entry = oldValue->get_array().back();
353  mValuePtr = &entry;
354  }
355  // serialize to adress of mValuePtr
357  mValuePtr = oldValue;
358  }
359  }
360 
361 private:
362  bool mFirstComplex;
363  bool mReadOnly;
364  json::Value* mValuePtr;
365  std::string mPointerClass;
366 
367  OutputFormat mOutputFormat;
368 };
369 
371 
401 {
403 
404 public:
405 
408  {
410  STANDARD = 0x00,
411 
416  ACCEPT_STRING_MAP_AS_OBJECT = 0x01
417  };
418 
419  MIRA_ENUM_TO_FLAGS_INCLASS(InputFormat) // generate logical operators for enum values
420 
421  JSONDeserializer(const json::Value& value, InputFormat format = STANDARD) :
422  mValue(&value), mStringMapAsObject(false), mInputFormat(format)
423  {
424  }
425 
426  template <typename T>
427  void deserialize(T& value)
428  {
429  mIndex = 0;
430  mFirstComplex = true;
431  Base::deserialize(MIRA_REFLECTOR_TOPLEVEL_NAME, value);
432  }
433 
435  {
436  value = *mValue;
437  }
438 
439  const json::Value* getMember(const json::Value* value, const std::string& name)
440  {
441  if (value->get_obj().count(name) == 0)
442  MIRA_THROW(XMemberNotFound, "Member '" << name << "' is missing"); // hence we have to abort with an exception
443  return &value->get_obj().at(name);
444  }
445 
446  const json::Value* getItem(const json::Value* value, std::size_t index)
447  {
448  if (value->get_array().size() <= index)
449  MIRA_THROW(XMemberNotFound, "Item[" << index << "] is missing"); // hence we have to abort with an exception
450  return &value->get_array()[index];
451  }
452 
454 
455  template <typename T>
456  VersionType version(VersionType expectedVersion, const T* object = NULL)
457  {
458  int vf = this->forcedDeserializeVersion();
459  if ((vf == 0) || (vf == 1))
460  return versionLegacy(expectedVersion);
461 
462  static const std::string v = std::string("@version[") + typeName<T>() + "]";
463  return getVersion<T>(expectedVersion, v);
464  }
465 
466  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
467  VersionType version(VersionType expectedVersion))
468  {
469  return versionLegacy(expectedVersion);
470  }
471 
472  template <typename T>
473  VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T* caller = NULL)
474  {
475  return this->version<T>(expectedVersion);
476  }
477 
478 private:
479 
480  VersionType versionLegacy(VersionType expectedVersion)
481  {
482  return getVersion<void>(expectedVersion, "@version");
483  }
484 
485  template <typename T>
486  VersionType getVersion(VersionType expectedVersion, const std::string& versionElement)
487  {
488  if (mValue->get_obj().count(versionElement) == 0)
489  return 0;
490  VersionType version = mValue->get_obj().at(versionElement).get_value<json::TypeTrait<int>::type >();
491  if (version > expectedVersion) {
492  MIRA_LOG(WARNING) << "Trying to deserialize JSON data of a newer version (" << (int)version <<
493  ") of type " << typeName<T>() << " into an older version (" << (int)expectedVersion << ").";
494  }
495  return version;
496  }
497 
498 public:
499 
500  template<typename T>
501  void atomic(T& member)
502  {
503  if ( mValue->type() == json_spirit::obj_type )
504  {
505  try
506  {
507  member = json::reverse_cast<T>(getMember(mValue, mCurrentMemberID)->get_value<typename json::TypeTrait<T>::type >());
508  }
509  catch(std::exception& ex)
510  {
511  MIRA_THROW(XMemberNotFound, "Error deserializing member '" << mCurrentMemberID
512  << "' (" << getCurrentMemberFullID()
513  << ") from object='" << json::write(*mValue)
514  << "' as " << typeName<T>() << ": " << ex.what());
515  }
516  }
517  else if ( mValue->type() == json_spirit::array_type )
518  {
519  try
520  {
521  member = json::reverse_cast<T>(getItem(mValue, mIndex++)->get_value<typename json::TypeTrait<T>::type >());
522  }
523  catch(std::exception& ex)
524  {
525  MIRA_THROW(XMemberNotFound, "Error deserializing item[" << mIndex-1
526  << "] (" << getCurrentMemberFullID()
527  << ") from collection='" << json::write(*mValue)
528  << "' as " << typeName<T>() << ": " << ex.what());
529  }
530  }
531  else
532  {
533  try
534  {
535  member = json::reverse_cast<T>(mValue->get_value<typename json::TypeTrait<T>::type>());
536  }
537  catch(std::exception& ex)
538  {
539  MIRA_THROW(XMemberNotFound, "Error deserializing atomic (" << getCurrentMemberFullID()
540  << ") with content='" << json::write(*mValue) << "' as " << typeName<T>() << ": " << ex.what());
541  }
542  }
543  }
544 
545  void atomic(json::Value& member)
546  {
547  if ( mValue->type() == json_spirit::obj_type )
548  member = *getMember(mValue, mCurrentMemberID);
549  else if ( mValue->type() == json_spirit::array_type )
550  member = *getItem(mValue, mIndex++);
551  else
552  member = *mValue;
553  }
554 
555  template<typename T>
556  void object(T& member)
557  {
558  if ( mFirstComplex )
559  {
560  mFirstComplex = false;
561  Base::object(member);
562  return;
563  }
564  const json::Value* oldValue = mValue;
565  std::size_t oldIndex = mIndex;
566  if ( mValue->type() == json_spirit::obj_type )
567  {
568  mValue = getMember(mValue, mCurrentMemberID);
569  }
570  else if ( mValue->type() == json_spirit::array_type )
571  {
572  mValue = getItem(mValue, oldIndex);
573  mIndex = 0;
574  }
575 
576  Base::object(member);
577 
578  mValue = oldValue;
579  mIndex = oldIndex+1;
580  }
581 
582  template<typename T>
583  void collection(T& member)
584  {
585  collectionInternal(member);
586  }
587 
588  template<typename mapped_type>
589  void collection(std::map<std::string, mapped_type>& member)
590  {
591  if (!(mInputFormat & ACCEPT_STRING_MAP_AS_OBJECT)) {
592  collectionInternal(member);
593  return;
594  }
595 
596  if (mStringMapAsObject) {
597  json::Object::const_iterator oldCurrentStringMapMember = mCurrentStringMapMember;
598  object(member);
599  mCurrentStringMapMember = oldCurrentStringMapMember;
600  return;
601  }
602 
603  assert(mStringMapAsObject == false);
604 
605  // backup deserializer state
606  const json::Value* oldValue = mValue;
607  std::size_t oldIndex = mIndex;
608  std::string memberID = mCurrentMemberID;
609  bool firstComplex = mFirstComplex;
610 
611  ObjectNameToInstanceMap trackingNames = mObjectNameToInstance;
612  ObjectsVector trackingInstances = mObjects;
613 
614  try {
615  try {
616  collectionInternal(member);
617  }
618  catch (XInvalidConfig& ex) {
619  MIRA_LOG(DEBUG) << "Deserialize map<string, T> as array failed, try as object:" << std::endl;
620 
621  // reset deserializer state to state before calling collection(), and try again, calling object()
622  mObjectNameToInstance = trackingNames;
623  mObjects = trackingInstances;
624 
625  mValue = oldValue;
626  mIndex = oldIndex;
627  mCurrentMemberID = memberID;
628  mFirstComplex = firstComplex;
629 
630  MIRA_LOG(DEBUG) << json::write(*mValue) << std::endl;
631 
632  mStringMapAsObject = true;
633  object(member);
634  }
635  }
636  // make sure we get to reset mStringMapAsObject as final statement on our way "up"
637  catch(Exception& ex) {
638  mStringMapAsObject = false;
639  MIRA_RETHROW(ex, "While trying to deserialize map<string, T> as object.");
640  }
641  catch(...) {
642  mStringMapAsObject = false;
643  throw;
644  }
645 
646  mStringMapAsObject = false;
647  }
648 
650  {
651  const json::Array* array;
652  try
653  {
654  array = &mValue->get_array();
655  }
656  catch(std::exception& ex)
657  {
658  MIRA_THROW(XInvalidConfig, "Error deserializing collection (" << getCurrentMemberFullID()
659  << ") from json::Value='" << json::write(*mValue) << "': " << ex.what());
660  }
661  return array;
662  }
663 
664  template<typename T>
665  void pointer(T* &pointer)
666  {
667  const json::Value* value;
668  if ( mFirstComplex )
669  value = mValue;
670  else
671  {
672  if ( mValue->type() == json_spirit::obj_type )
673  value = getMember(mValue, mCurrentMemberID);
674  else if ( mValue->type() == json_spirit::array_type )
675  value = getItem(mValue, mIndex);
676  }
677 
678  std::size_t oldIndex = mIndex;
679 
680  // do we have a null pointer?
681  if(value->is_null()) {
682  pointer = NULL;
683  }
684  // do we have a reference?
685  else {
686  assert(value->type() == json_spirit::obj_type);
687  auto it = value->get_obj().find("@ref");
688  if(it!=value->get_obj().end()) {
689  // we have a reference, so resolve it
690  pointer = resolveReference<T>(it->second.get_value<std::string>());
691  } else {
692  // we have a "normal" pointer, so deserialize it
693  Base::pointer(pointer);
694  }
695  }
696 
697  if (mValue->type() == json_spirit::array_type)
698  mIndex = oldIndex+1;
699  }
700 
701  std::string pointerClassType()
702  {
703  const json::Value* value;
704  if ( mFirstComplex )
705  value = mValue;
706  else
707  {
708  if ( mValue->type() == json_spirit::obj_type )
709  {
710  try
711  {
712  value = getMember(mValue, mCurrentMemberID);
713  }
714  catch(XMemberNotFound& ex)
715  {
716  MIRA_RETHROW(ex, "Error getting pointer class type of member '"
717  << mCurrentMemberID << "' (" << getCurrentMemberFullID()
718  << ") from object='" << json::write(*mValue)<< "'");
719  }
720  }
721  else if ( mValue->type() == json_spirit::array_type )
722  {
723  try
724  {
725  value = getItem(mValue, mIndex);
726  }
727  catch(XMemberNotFound& ex)
728  {
729  MIRA_RETHROW(ex, "Error getting pointer class type of item[" << mIndex
730  << "] (" << getCurrentMemberFullID()
731  << ") from collection='" << json::write(*mValue) << "'");
732  }
733  }
734  }
735  if(value->type() == json_spirit::obj_type)
736  {
737  auto it = value->get_obj().find("@class");
738  if(it!=value->get_obj().end())
739  return it->second.get_value<std::string>();
740  }
741  return "Unknown Class";
742  }
743 
744  // hijack the invokeOverwrite method for adding a starting and closing tag
745  // around the serialized data
746  template<typename T>
747  void invokeMemberOverwrite(T& member, const ReflectMemberMeta& meta)
748  {
749  std::string oldID = mCurrentMemberID;
750  if(meta.id!=NULL)
751  mCurrentMemberID = meta.id;
752  try
753  {
754  Base::invokeMemberOverwrite(member, meta);
755  }
756  catch(...)
757  {
758  if(meta.id!=NULL)
759  mCurrentMemberID = oldID;
760  throw;
761  }
762  if(meta.id!=NULL)
763  mCurrentMemberID = oldID;
764  }
765 
766 public:
767 
769  {
770  if (mStringMapAsObject) {
771  try {
772  const json::Object* o = &mValue->get_obj();
773  mCurrentStringMapMember = mValue->get_obj().begin();
774  return (uint32)o->size();
775  }
776  catch(std::exception& ex)
777  {
778  MIRA_THROW(XInvalidConfig, "Error counting object elements from json::Value='"
779  << json::write(*mValue) << "': " << ex.what());
780  }
781  } else {
782  const json::Array* a = getCollection();
783  return (uint32)a->size();
784  }
785  }
786 
787  template<typename Container>
788  void mapEntry(int id, Container& c, typename Container::iterator& hint)
789  {
790  typedef typename Container::value_type value_type;
791  typedef typename Container::mapped_type mapped_type;
792 
793  if (mStringMapAsObject) {
794  std::string key = mCurrentStringMapMember->first;
795  hint = c.insert(hint, value_type(key, mapped_type()));
796  property(key.c_str(), hint->second, "");
797  ++mCurrentStringMapMember;
798  } else {
799  serialization::reflectWriteMapPair(*this, "item", "key", id, c, hint);
800  }
801  }
802 
803 private:
804  template<typename T>
805  void collectionInternal(T& member)
806  {
807  if ( mFirstComplex )
808  {
809  mFirstComplex = false;
810  Base::object(member);
811  return;
812  }
813  const json::Value* oldValue = mValue;
814  std::size_t oldIndex = mIndex;
815  if ( mValue->type() == json_spirit::obj_type )
816  {
817  mValue = getMember(mValue, mCurrentMemberID);
818  mIndex = 0;
819  }
820  else if ( mValue->type() == json_spirit::array_type )
821  {
822  mValue = getItem(mValue, oldIndex);
823  mIndex = 0;
824  }
825 
826  Base::object(member);
827 
828  mValue = oldValue;
829  mIndex = oldIndex+1;
830  }
831 
832 private:
833  bool mFirstComplex;
834  std::size_t mIndex;
835  const json::Value* mValue;
836  std::string mCurrentMemberID;
837 
838  bool mStringMapAsObject;
839  json::Object::const_iterator mCurrentStringMapMember;
840 
841  InputFormat mInputFormat;
842 };
843 
844 namespace serialization { // our private namespace
845 
847 
855 template<typename Collection>
857 {
858  static void reflect(JSONSerializer& r, uint32& ioCount)
859  {
860  // do nothing
861  }
862 };
869 template<typename Collection>
871 {
872  static void reflect(JSONDeserializer& r, uint32& ioCount)
873  {
874  const json::Array* a = r.getCollection();
875  ioCount = (uint32)a->size();
876  }
877 };
878 
879 template<typename mapped_type>
880 struct ReflectCollectionCount<JSONDeserializer, std::map<std::string, mapped_type>>
881 {
882  static void reflect(JSONDeserializer& r, uint32& ioCount)
883  {
884  ioCount = r.getStringMapElementCount();
885  }
886 };
887 
888 template<typename mapped_type>
889 struct ReflectReadMapItems<JSONSerializer, std::map<std::string, mapped_type>>
890 {
891  typedef std::map<std::string, mapped_type> Container;
892  typedef typename Container::value_type value_type;
893 
894  static void reflect(JSONSerializer& r, Container& c)
895  {
896  // store each item
897  int id=0;
898  foreach(value_type& p, c)
899  {
900  r.mapEntry<Container>(id, p);
901  ++id;
902  }
903  }
904 };
905 
906 template<typename mapped_type>
907 struct ReflectWriteMapItems<JSONDeserializer, std::map<std::string, mapped_type>>
908 {
909  typedef std::map<std::string, mapped_type> Container;
910  typedef typename Container::iterator iterator;
911 
912  static void reflect(JSONDeserializer& r, Container& c, uint32 count)
913  {
914  iterator hint = c.begin();
915 
916  // restore each item and insert into the map
917  for(uint32 id=0; id<count; ++id)
918  r.mapEntry<Container>(id, c, hint);
919  }
920 };
921 
923 
924 }
925 
927 
928 } // namespace
929 
930 #endif
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:93
void deserialize(T &value)
Definition: JSONSerializer.h:427
Base::VersionType VersionType
Definition: JSONSerializer.h:453
void object(T &member)
Is called for each complex object.
Definition: RecursiveMemberReflector.h:302
void pointer(T *&pointer)
Definition: JSONSerializer.h:665
InputFormat
Flags for JSON input format.
Definition: JSONSerializer.h:407
void pointerNull()
Definition: JSONSerializer.h:276
TEigenFormat< Derived > format(Eigen::MatrixBase< Derived > &matrix, Eigen::IOFormat format=EigenFormat::matlab())
Function for formatting an Eigen matrix using a special format.
Definition: EigenFormat.h:522
void roproperty(const char *name, const T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: JSONSerializer.h:287
void mapEntry(int id, Container &c, typename Container::iterator &hint)
Definition: JSONSerializer.h:788
ReflectorInterface< JSONSerializer >::VersionType VersionType
Definition: AbstractReflector.h:170
Contains the Serializer template, a base class for all serializers.
static void reflect(JSONDeserializer &r, Container &c, uint32 count)
Definition: JSONSerializer.h:912
void roproperty(const char *name, Getter< T > getter, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: JSONSerializer.h:309
void reflectWriteMapPair(Derived &r, const char *itemName, const char *keyName, uint32 id, Container &c, typename Container::iterator &ioHint)
Definition: StlCollections.h:324
json_spirit::mArray Array
A representation of an array (vector) in JSON.
Definition: JSON.h:190
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
void member(const char *name, T &member, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:871
const std::string & getHumanReadableFullID(int objectID) const
Returns the full human readable object id / name for the given internal objectID. ...
Definition: Serializer.h:456
void atomic(json::Value &member)
Definition: JSONSerializer.h:545
std::map< std::string, mapped_type > Container
Definition: JSONSerializer.h:891
Is a special reflector that is used for serialization.
Definition: Serializer.h:126
std::map< std::string, mapped_type > Container
Definition: JSONSerializer.h:909
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:528
STL namespace.
#define MIRA_RETHROW(ex, msg)
Macro for rethrowing an exception with file and line information and for adding additional informatio...
Definition: Exception.h:144
void collection(T &member)
Definition: JSONSerializer.h:583
VersionType version(VersionType version, const T *caller=NULL)
Definition: JSONSerializer.h:138
Stores meta information for each member.
Definition: ReflectMemberMeta.h:64
std::vector< void *> ObjectsVector
Definition: Deserializer.h:302
void pointerWithClassType(const std::string &type)
Definition: JSONSerializer.h:271
Definition: StlCollections.h:339
void property(const char *name, T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:973
static void reflect(JSONSerializer &r, Container &c)
Definition: JSONSerializer.h:894
std::map< std::string, void *> ObjectNameToInstanceMap
Definition: Deserializer.h:298
void collection(T &member)
Definition: JSONSerializer.h:247
void serialize(const std::string &name, const T &value, const std::string &comment="")
Serializes the specified object value under the given name.
Definition: Serializer.h:204
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType expectedVersion))
Definition: JSONSerializer.h:466
void invokeMemberOverwrite(T &member, const ReflectMemberMeta &meta)
Definition: JSONSerializer.h:747
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
A property hint gives optional instructions to the property editor, i.e.
Definition: PropertyHint.h:82
const json::Value * getMember(const json::Value *value, const std::string &name)
Definition: JSONSerializer.h:439
VersionType version(VersionType expectedVersion, const T *object=NULL)
Definition: JSONSerializer.h:456
const ReflectMemberMeta & getCurrentMemberMeta() const
Returns the meta-information of the current member that is reflected.
Definition: RecursiveMemberReflector.h:451
uint32 getStringMapElementCount()
Definition: JSONSerializer.h:768
MIRA_ENUM_TO_FLAGS_INCLASS(OutputFormat) JSONSerializer(bool readOnly
Construct a serializer.
MIRA_BASE_EXPORT void write(const Value &value, std::ostream &ioStream, bool formatted=false, int precision=-1)
Writes a json::Value into a given stream using the JSON format.
void object(T &member)
Definition: JSONSerializer.h:211
Deserializer for serializing objects from JSON format.
Definition: JSONSerializer.h:400
void roproperty(const char *name, const std::string &id, const T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: JSONSerializer.h:298
VersionType version(VersionType version, AcceptDesiredVersion, const T *caller=NULL)
Definition: JSONSerializer.h:150
No flags.
Definition: ReflectControlFlags.h:65
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
Contains base class for all deserializers.
void atomic(T &member)
Definition: JSONSerializer.h:501
ReflectorInterface< JSONSerializer >::AcceptDesiredVersion AcceptDesiredVersion
Definition: AbstractReflector.h:200
static void reflect(JSONDeserializer &r, uint32 &ioCount)
Definition: JSONSerializer.h:872
Getter< T > getter(T(*f)())
Creates a Getter for global or static class methods returning the result by value.
Definition: GetterSetter.h:136
void atomic(json::Value &member)
Definition: JSONSerializer.h:194
json_spirit::mObject Object
A representation of an object (class, struct) in JSON.
Definition: JSON.h:183
void collection(std::map< std::string, mapped_type > &member)
Definition: JSONSerializer.h:253
void collection(std::map< std::string, mapped_type > &member)
Definition: JSONSerializer.h:589
void mapEntry(int id, const typename Container::value_type &p)
Definition: JSONSerializer.h:320
Base class for exceptions.
Definition: Exception.h:194
Base::VersionType VersionType
Definition: Serializer.h:154
MIRA_ENUM_TO_FLAGS_INCLASS(InputFormat) JSONDeserializer(const json
Definition: JSONSerializer.h:419
json_spirit::mValue Value
A value is an abstract description of data in JSON (underlying data can either be one of the JSON bas...
Definition: JSON.h:176
void deserialize(json::Value &value)
Definition: JSONSerializer.h:434
VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T *caller=NULL)
Definition: JSONSerializer.h:473
static int forcedSerializeVersion()
Returns either the version number from value of environment variable &#39;MIRA_FORCE_SERIALIZE_VERSION&#39;, or -1 (= do not force a version).
Definition: Serializer.h:145
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType version))
Definition: JSONSerializer.h:143
Can be specialized for a concrete derived RecursiveMemberReflector to reflect the size of collections...
Definition: ReflectCollection.h:69
Holds a boost::function object to a special getter function that must meet the signature "T method()"...
Definition: GetterSetter.h:87
Definition: LoggingCore.h:75
void object(T &member)
Definition: JSONSerializer.h:556
const json::Value * getItem(const json::Value *value, std::size_t index)
Definition: JSONSerializer.h:446
static void reflect(JSONDeserializer &r, uint32 &ioCount)
Definition: JSONSerializer.h:882
static constexpr auto MIRA_REFLECTOR_TOPLEVEL_NAME
Use this when a reflector needs to choose a name for serializing an object.
Definition: RecursiveMemberReflector.h:250
Default format.
Definition: JSONSerializer.h:102
ReflectCtrlFlags
Control Flags that can modify the behavior of certain reflectors.
Definition: ReflectControlFlags.h:63
"Null-Setter" tag-class where the AccessorSetterPart does nothing.
Definition: Accessor.h:198
OutputFormat
Flags for JSON output format.
Definition: JSONSerializer.h:99
Definition: LoggingCore.h:77
const json::Array * getCollection()
Definition: JSONSerializer.h:649
Wrappers for JSON.
Accessor< Getter, Setter > makeAccessor(const Getter &getter, const Setter &setter)
Helper method that creates an accessor from a different combination of either direct access to a vari...
Definition: Accessor.h:300
Serialize associative containers with string keys as JSON object (keys = member names) ...
Definition: JSONSerializer.h:105
const char * id
The id (used for containers where the name is identical, in all other cases the id usually is equal t...
Definition: ReflectMemberMeta.h:73
void atomic(T &member)
Definition: JSONSerializer.h:178
Helpers for serialization and deserialization of STL containers.
Definition: StlCollections.h:391
std::string pointerClassType()
Definition: JSONSerializer.h:701
static void reflect(JSONSerializer &r, uint32 &ioCount)
Definition: JSONSerializer.h:858
void pointerReference(int referencedObjectID)
Definition: JSONSerializer.h:261
OutputFormat format
Definition: JSONSerializer.h:115