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, "Missing member '" << name
443  << "' (" << getCurrentMemberFullID()
444  << ") while deserializing object='" << json::write(*mValue));
445  return &value->get_obj().at(name);
446  }
447 
448  const json::Value* getItem(const json::Value* value, std::size_t index)
449  {
450  if (value->get_array().size() <= index)
451  MIRA_THROW(XMemberNotFound, "Missing item[" << index
452  << "] (" << getCurrentMemberFullID()
453  << ") while deserializing collection='" << json::write(*mValue));
454  return &value->get_array()[index];
455  }
456 
458 
459  template <typename T>
460  VersionType version(VersionType expectedVersion, const T* object = NULL)
461  {
462  int vf = this->forcedDeserializeVersion();
463  if ((vf == 0) || (vf == 1))
464  return versionLegacy(expectedVersion);
465 
466  static const std::string v = std::string("@version[") + typeName<T>() + "]";
467  return getVersion<T>(expectedVersion, v);
468  }
469 
470  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
471  VersionType version(VersionType expectedVersion))
472  {
473  return versionLegacy(expectedVersion);
474  }
475 
476  template <typename T>
477  VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T* caller = NULL)
478  {
479  return this->version<T>(expectedVersion);
480  }
481 
482 private:
483 
484  VersionType versionLegacy(VersionType expectedVersion)
485  {
486  return getVersion<void>(expectedVersion, "@version");
487  }
488 
489  template <typename T>
490  VersionType getVersion(VersionType expectedVersion, const std::string& versionElement)
491  {
492  if (mValue->get_obj().count(versionElement) == 0)
493  return 0;
494  VersionType version = mValue->get_obj().at(versionElement).get_value<json::TypeTrait<int>::type >();
495  if (version > expectedVersion) {
496  MIRA_LOG(WARNING) << "Trying to deserialize JSON data of a newer version (" << (int)version <<
497  ") of type " << typeName<T>() << " into an older version (" << (int)expectedVersion << ").";
498  }
499  return version;
500  }
501 
502 public:
503 
504  template<typename T>
505  void atomic(T& member)
506  {
507  if ( mValue->type() == json_spirit::obj_type )
508  {
509  const json::Value* item = getMember(mValue, mCurrentMemberID);
510  try {
511  member = json::reverse_cast<T>(item->get_value<typename json::TypeTrait<T>::type >());
512  }
513  catch(std::exception& ex)
514  {
515  MIRA_THROW(XInvalidConfig, "Error deserializing member '" << mCurrentMemberID
516  << "' (" << getCurrentMemberFullID()
517  << ") from object='" << json::write(*mValue)
518  << "' as " << typeName<T>() << ": " << ex.what());
519  }
520  }
521  else if ( mValue->type() == json_spirit::array_type )
522  {
523  const json::Value* item = getItem(mValue, mIndex++);
524  try {
525  member = json::reverse_cast<T>(item->get_value<typename json::TypeTrait<T>::type >());
526  }
527  catch(std::exception& ex)
528  {
529  MIRA_THROW(XInvalidConfig, "Error deserializing item[" << mIndex-1
530  << "] (" << getCurrentMemberFullID()
531  << ") from collection='" << json::write(*mValue)
532  << "' as " << typeName<T>() << ": " << ex.what());
533  }
534  }
535  else
536  {
537  try
538  {
539  member = json::reverse_cast<T>(mValue->get_value<typename json::TypeTrait<T>::type>());
540  }
541  catch(std::exception& ex)
542  {
543  MIRA_THROW(XMemberNotFound, "Error deserializing atomic (" << getCurrentMemberFullID()
544  << ") with content='" << json::write(*mValue) << "' as " << typeName<T>() << ": " << ex.what());
545  }
546  }
547  }
548 
549  void atomic(json::Value& member)
550  {
551  if ( mValue->type() == json_spirit::obj_type )
552  member = *getMember(mValue, mCurrentMemberID);
553  else if ( mValue->type() == json_spirit::array_type )
554  member = *getItem(mValue, mIndex++);
555  else
556  member = *mValue;
557  }
558 
559  template<typename T>
560  void object(T& member)
561  {
562  if ( mFirstComplex )
563  {
564  mFirstComplex = false;
565  Base::object(member);
566  return;
567  }
568  const json::Value* oldValue = mValue;
569  std::size_t oldIndex = mIndex;
570  if ( mValue->type() == json_spirit::obj_type )
571  {
572  mValue = getMember(mValue, mCurrentMemberID);
573  }
574  else if ( mValue->type() == json_spirit::array_type )
575  {
576  mValue = getItem(mValue, oldIndex);
577  mIndex = 0;
578  }
579 
580  Base::object(member);
581 
582  mValue = oldValue;
583  mIndex = oldIndex+1;
584  }
585 
586  template<typename T>
587  void collection(T& member)
588  {
589  collectionInternal(member);
590  }
591 
592  template<typename mapped_type>
593  void collection(std::map<std::string, mapped_type>& member)
594  {
595  if (!(mInputFormat & ACCEPT_STRING_MAP_AS_OBJECT)) {
596  collectionInternal(member);
597  return;
598  }
599 
600  if (mStringMapAsObject) {
601  json::Object::const_iterator oldCurrentStringMapMember = mCurrentStringMapMember;
602  object(member);
603  mCurrentStringMapMember = oldCurrentStringMapMember;
604  return;
605  }
606 
607  assert(mStringMapAsObject == false);
608 
609  // backup deserializer state
610  const json::Value* oldValue = mValue;
611  std::size_t oldIndex = mIndex;
612  std::string memberID = mCurrentMemberID;
613  bool firstComplex = mFirstComplex;
614 
615  ObjectNameToInstanceMap trackingNames = mObjectNameToInstance;
616  ObjectsVector trackingInstances = mObjects;
617 
618  try {
619  try {
620  collectionInternal(member);
621  }
622  catch (XInvalidConfig& ex) {
623  MIRA_LOG(DEBUG) << "Deserialize map<string, T> as array failed, try as object:" << std::endl;
624 
625  // reset deserializer state to state before calling collection(), and try again, calling object()
626  mObjectNameToInstance = trackingNames;
627  mObjects = trackingInstances;
628 
629  mValue = oldValue;
630  mIndex = oldIndex;
631  mCurrentMemberID = memberID;
632  mFirstComplex = firstComplex;
633 
634  MIRA_LOG(DEBUG) << json::write(*mValue) << std::endl;
635 
636  mStringMapAsObject = true;
637  object(member);
638  }
639  }
640  // make sure we get to reset mStringMapAsObject as final statement on our way "up"
641  catch(Exception& ex) {
642  mStringMapAsObject = false;
643  MIRA_RETHROW(ex, "While trying to deserialize map<string, T> as object.");
644  }
645  catch(...) {
646  mStringMapAsObject = false;
647  throw;
648  }
649 
650  mStringMapAsObject = false;
651  }
652 
654  {
655  const json::Array* array;
656  try
657  {
658  array = &mValue->get_array();
659  }
660  catch(std::exception& ex)
661  {
662  MIRA_THROW(XInvalidConfig, "Error deserializing collection (" << getCurrentMemberFullID()
663  << ") from json::Value='" << json::write(*mValue) << "': " << ex.what());
664  }
665  return array;
666  }
667 
668  template<typename T>
669  void pointer(T* &pointer)
670  {
671  const json::Value* value;
672  if ( mFirstComplex )
673  value = mValue;
674  else
675  {
676  if ( mValue->type() == json_spirit::obj_type )
677  value = getMember(mValue, mCurrentMemberID);
678  else if ( mValue->type() == json_spirit::array_type )
679  value = getItem(mValue, mIndex);
680  }
681 
682  std::size_t oldIndex = mIndex;
683 
684  // do we have a null pointer?
685  if(value->is_null()) {
686  pointer = NULL;
687  }
688  // do we have a reference?
689  else {
690  assert(value->type() == json_spirit::obj_type);
691  auto it = value->get_obj().find("@ref");
692  if(it!=value->get_obj().end()) {
693  // we have a reference, so resolve it
694  pointer = resolveReference<T>(it->second.get_value<std::string>());
695  } else {
696  // we have a "normal" pointer, so deserialize it
697  Base::pointer(pointer);
698  }
699  }
700 
701  if (mValue->type() == json_spirit::array_type)
702  mIndex = oldIndex+1;
703  }
704 
705  std::string pointerClassType()
706  {
707  const json::Value* value;
708  if ( mFirstComplex )
709  value = mValue;
710  else
711  {
712  if ( mValue->type() == json_spirit::obj_type )
713  {
714  try
715  {
716  value = getMember(mValue, mCurrentMemberID);
717  }
718  catch(XMemberNotFound& ex)
719  {
720  MIRA_RETHROW(ex, "Error getting pointer class type of member '"
721  << mCurrentMemberID << "' (" << getCurrentMemberFullID()
722  << ") from object='" << json::write(*mValue)<< "'");
723  }
724  }
725  else if ( mValue->type() == json_spirit::array_type )
726  {
727  try
728  {
729  value = getItem(mValue, mIndex);
730  }
731  catch(XMemberNotFound& ex)
732  {
733  MIRA_RETHROW(ex, "Error getting pointer class type of item[" << mIndex
734  << "] (" << getCurrentMemberFullID()
735  << ") from collection='" << json::write(*mValue) << "'");
736  }
737  }
738  }
739  if(value->type() == json_spirit::obj_type)
740  {
741  auto it = value->get_obj().find("@class");
742  if(it!=value->get_obj().end())
743  return it->second.get_value<std::string>();
744  }
745  return "Unknown Class";
746  }
747 
748  // hijack the invokeOverwrite method for adding a starting and closing tag
749  // around the serialized data
750  template<typename T>
751  void invokeMemberOverwrite(T& member, const ReflectMemberMeta& meta)
752  {
753  std::string oldID = mCurrentMemberID;
754  if(meta.id!=NULL)
755  mCurrentMemberID = meta.id;
756  try
757  {
758  Base::invokeMemberOverwrite(member, meta);
759  }
760  catch(...)
761  {
762  if(meta.id!=NULL)
763  mCurrentMemberID = oldID;
764  throw;
765  }
766  if(meta.id!=NULL)
767  mCurrentMemberID = oldID;
768  }
769 
770 public:
771 
773  {
774  if (mStringMapAsObject) {
775  try {
776  const json::Object* o = &mValue->get_obj();
777  mCurrentStringMapMember = mValue->get_obj().begin();
778  return (uint32)o->size();
779  }
780  catch(std::exception& ex)
781  {
782  MIRA_THROW(XInvalidConfig, "Error counting object elements from json::Value='"
783  << json::write(*mValue) << "': " << ex.what());
784  }
785  } else {
786  const json::Array* a = getCollection();
787  return (uint32)a->size();
788  }
789  }
790 
791  template<typename Container>
792  void mapEntry(int id, Container& c, typename Container::iterator& hint)
793  {
794  typedef typename Container::value_type value_type;
795  typedef typename Container::mapped_type mapped_type;
796 
797  if (mStringMapAsObject) {
798  std::string key = mCurrentStringMapMember->first;
799  hint = c.insert(hint, value_type(key, mapped_type()));
800  property(key.c_str(), hint->second, "");
801  ++mCurrentStringMapMember;
802  } else {
803  serialization::reflectWriteMapPair(*this, "item", "key", id, c, hint);
804  }
805  }
806 
807 private:
808  template<typename T>
809  void collectionInternal(T& member)
810  {
811  if ( mFirstComplex )
812  {
813  mFirstComplex = false;
814  Base::object(member);
815  return;
816  }
817  const json::Value* oldValue = mValue;
818  std::size_t oldIndex = mIndex;
819  if ( mValue->type() == json_spirit::obj_type )
820  {
821  mValue = getMember(mValue, mCurrentMemberID);
822  mIndex = 0;
823  }
824  else if ( mValue->type() == json_spirit::array_type )
825  {
826  mValue = getItem(mValue, oldIndex);
827  mIndex = 0;
828  }
829 
830  Base::object(member);
831 
832  mValue = oldValue;
833  mIndex = oldIndex+1;
834  }
835 
836 private:
837  bool mFirstComplex;
838  std::size_t mIndex;
839  const json::Value* mValue;
840  std::string mCurrentMemberID;
841 
842  bool mStringMapAsObject;
843  json::Object::const_iterator mCurrentStringMapMember;
844 
845  InputFormat mInputFormat;
846 };
847 
848 namespace serialization { // our private namespace
849 
851 
859 template<typename Collection>
861 {
862  static void reflect(JSONSerializer& r, uint32& ioCount)
863  {
864  // do nothing
865  }
866 };
873 template<typename Collection>
875 {
876  static void reflect(JSONDeserializer& r, uint32& ioCount)
877  {
878  const json::Array* a = r.getCollection();
879  ioCount = (uint32)a->size();
880  }
881 };
882 
883 template<typename mapped_type>
884 struct ReflectCollectionCount<JSONDeserializer, std::map<std::string, mapped_type>>
885 {
886  static void reflect(JSONDeserializer& r, uint32& ioCount)
887  {
888  ioCount = r.getStringMapElementCount();
889  }
890 };
891 
892 template<typename mapped_type>
893 struct ReflectReadMapItems<JSONSerializer, std::map<std::string, mapped_type>>
894 {
895  typedef std::map<std::string, mapped_type> Container;
896  typedef typename Container::value_type value_type;
897 
898  static void reflect(JSONSerializer& r, Container& c)
899  {
900  // store each item
901  int id=0;
902  foreach(value_type& p, c)
903  {
904  r.mapEntry<Container>(id, p);
905  ++id;
906  }
907  }
908 };
909 
910 template<typename mapped_type>
911 struct ReflectWriteMapItems<JSONDeserializer, std::map<std::string, mapped_type>>
912 {
913  typedef std::map<std::string, mapped_type> Container;
914  typedef typename Container::iterator iterator;
915 
916  static void reflect(JSONDeserializer& r, Container& c, uint32 count)
917  {
918  iterator hint = c.begin();
919 
920  // restore each item and insert into the map
921  for(uint32 id=0; id<count; ++id)
922  r.mapEntry<Container>(id, c, hint);
923  }
924 };
925 
927 
928 }
929 
931 
932 } // namespace
933 
934 #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:457
void object(T &member)
Is called for each complex object.
Definition: RecursiveMemberReflector.h:301
void pointer(T *&pointer)
Definition: JSONSerializer.h:669
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:792
Contains the Serializer template, a base class for all serializers.
static void reflect(JSONDeserializer &r, Container &c, uint32 count)
Definition: JSONSerializer.h:916
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
typename ReflectorInterface< JSONSerializer >::AcceptDesiredVersion AcceptDesiredVersion
Definition: AbstractReflector.h:195
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:862
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:549
std::map< std::string, mapped_type > Container
Definition: JSONSerializer.h:895
Is a special reflector that is used for serialization.
Definition: Serializer.h:126
std::map< std::string, mapped_type > Container
Definition: JSONSerializer.h:913
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:529
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:148
void collection(T &member)
Definition: JSONSerializer.h:587
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:964
static void reflect(JSONSerializer &r, Container &c)
Definition: JSONSerializer.h:898
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:470
void invokeMemberOverwrite(T &member, const ReflectMemberMeta &meta)
Definition: JSONSerializer.h:751
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:82
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:460
const ReflectMemberMeta & getCurrentMemberMeta() const
Returns the meta-information of the current member that is reflected.
Definition: RecursiveMemberReflector.h:459
uint32 getStringMapElementCount()
Definition: JSONSerializer.h:772
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:505
static void reflect(JSONDeserializer &r, uint32 &ioCount)
Definition: JSONSerializer.h:876
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:593
void mapEntry(int id, const typename Container::value_type &p)
Definition: JSONSerializer.h:320
Base class for exceptions.
Definition: Exception.h:199
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
typename ReflectorInterface< JSONSerializer >::VersionType VersionType
Definition: AbstractReflector.h:165
void deserialize(json::Value &value)
Definition: JSONSerializer.h:434
VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T *caller=NULL)
Definition: JSONSerializer.h:477
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:76
void object(T &member)
Definition: JSONSerializer.h:560
const json::Value * getItem(const json::Value *value, std::size_t index)
Definition: JSONSerializer.h:448
static void reflect(JSONDeserializer &r, uint32 &ioCount)
Definition: JSONSerializer.h:886
static constexpr auto MIRA_REFLECTOR_TOPLEVEL_NAME
Use this when a reflector needs to choose a name for serializing an object.
Definition: RecursiveMemberReflector.h:249
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:78
const json::Array * getCollection()
Definition: JSONSerializer.h:653
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:705
static void reflect(JSONSerializer &r, uint32 &ioCount)
Definition: JSONSerializer.h:862
void pointerReference(int referencedObjectID)
Definition: JSONSerializer.h:261
OutputFormat format
Definition: JSONSerializer.h:115