MIRA
BinarySerializer.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_BINARYSERIALIZER_H_
48 #define _MIRA_BINARYSERIALIZER_H_
49 
50 #include <tuple>
51 
52 #include <stream/BinaryStream.h>
53 
56 
58 
60 #include <platform/Types.h>
61 #include <platform/Typename.h>
62 
63 namespace mira {
64 
66 
67 // a marker to mark occurrence of format version number in serialized data.
68 // not 100% unique when looking at serialized data created before binary format
69 // version was included, but it will have to do
70 #define BINARY_VERSION_MARKER 65432u
71 
72 #ifndef NDEBUG
73 #define CHECK_FORCE_SERIALIZE_BINARY_VERSION
74 #endif
75 
77 
80 {
81 public:
87  {
92  };
93 };
94 
96 
101 template <typename BinaryStream>
103 {
104 protected:
105  StreamAccessMixinBase(typename BinaryStream::streambuffer_pointer buffer)
106  : mStream(buffer) {}
107 
108  StreamAccessMixinBase(BinaryStream& stream) : mStream(stream.rdbuf()) {}
109 
110 public:
116  void reassign(typename BinaryStream::streambuffer_pointer buffer) { mStream = buffer; }
117 
118 protected:
120  BinaryStream& stream() { return mStream; }
121 
122 private:
123  BinaryStream mStream;
124 };
125 
127 template <typename BinaryStream, bool Buffered>
128 class StreamAccessMixin : public StreamAccessMixinBase<BinaryStream>
129 {
131 
132 public:
134  typedef BinaryStream StreamType;
135 
136 protected:
137  StreamAccessMixin(typename BinaryStream::streambuffer_pointer buffer)
138  : Base(buffer) {}
139 
140  StreamAccessMixin(BinaryStream& stream) : Base(stream) {}
141 
146  void flushBuffer() {}
147 };
148 
153 template <typename BinaryStream>
154 class StreamAccessMixin<BinaryStream, true> : public StreamAccessMixinBase<BinaryStream>
155 {
157 
158 public:
161 
162 protected:
163  StreamAccessMixin(typename BinaryStream::streambuffer_pointer buffer)
164  : Base(buffer), mBufferStream(&mBuffer) {}
165 
166  StreamAccessMixin(BinaryStream& stream) : Base(stream), mBufferStream(&mBuffer) {}
167 
169  {
170  flushBuffer(); // just to make sure everything is written out
171  }
172 
177  BinaryBufferOstream& stream() { return mBufferStream; }
178 
180  void flushBuffer()
181  {
182  Base::stream().write(mBuffer.data(), mBuffer.size());
183  mBuffer.clear();
184  mBufferStream.seekp(0);
185  }
186 
187 private:
189  BinaryBufferOstream mBufferStream;
190 };
191 
193 
255 
256 template <typename Derived>
257 class BinarySerializer : public Serializer<Derived>
258 {
259 public:
261 
262 public:
265 
266  template <typename T>
267  VersionType version(VersionType version, const T* caller = NULL) {
268  return this->This()->template version<T>(version);
269  }
270 
271  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
273  return this->template version<void>(version);
274  }
275 
276  template <typename T>
278  {
279  return this->This()->template version<T>(version, AcceptDesiredVersion());
280  }
281 
282 public:
283  template <typename T>
284  void write(const T* data, std::size_t count) {
285  this->This()->write(data,count);
286  }
287 
288 public:
294  template <typename T>
295  bool hasCodec() const {
296  return this->This()->template hasCodec<T>();
297  }
298 
306  template <typename T>
307  bool codec(const T& obj)
308  {
309  return this->This()->template codec(obj);
310  }
311 };
312 
314 
315 template <typename BinaryStream, uint8 BinaryFormatVersion, bool Buffered>
317 
330 template <typename BinaryStream, uint8 BinaryFormatVersion, bool Buffered, typename StreamType>
332 {
333 };
334 
335 template <typename Serializer, typename StreamType>
337 {
338 public:
340  static size_t formatVersionOverhead() { return 0; }
341 
342 protected:
343  typedef boost::mpl::bool_<false> requireReflectBarriers;
344  typedef void* ReflectState;
345 
346  typedef int VersionType; // format version 0 had int32 serialization versions
347 
350  Serializer& serializer,
351  StreamType& stream) { return NULL; }
352 
354  template <typename T>
355  void writeVersion(VersionType version, Serializer& serializer, StreamType& stream) {
356  serializer.atomic(version);
357  }
358 
360  void restoreVersionPtr(const ReflectState& prev) {}
361 };
362 
363 template <typename BinaryStream, bool Buffered, typename StreamType>
366 {
367 public:
368  static uint8 getSerializerFormatVersion() { return 0; }
369 
370 protected:
372  template <typename T>
373  bool writeFormatVersion(T& value, bool enableTypeCheck, StreamType& stream) { return true; }
374 };
375 
376 // This is just for sake of completeness, actually. There is no use case for serializing to v1.
377 // Where needed, v1 data should be created from v0 serialized data by just prepending the version
378 // marker bytes.
379 template <typename BinaryStream, bool Buffered, typename StreamType>
380 class SerializerFormatMixin<BinaryStream, 1, Buffered, StreamType> :
381  public SerializerFormatMixin01Base<ConcreteBinarySerializer<BinaryStream, 1, Buffered>, StreamType>
382 {
383 public:
384  static uint8 getSerializerFormatVersion() { return 1; }
385 
386 protected:
388  template <typename T>
389  bool writeFormatVersion(T& value, bool enableTypeCheck, StreamType& stream)
390  {
391  stream << (uint16)BINARY_VERSION_MARKER;
392  stream << getSerializerFormatVersion();
393  return true;
394  }
395 };
396 
397 template <typename BinaryStream, bool Buffered, typename StreamType>
398 class SerializerFormatMixin<BinaryStream, 2, Buffered, StreamType>
399 {
400 public:
401  static uint8 getSerializerFormatVersion() { return 2; }
402 
404  static size_t formatVersionOverhead() { return sizeof(uint16) + sizeof(uint8); }
405 protected:
407 
408  // Needs to know about independent reflection blocks to reserve space
409  // for a version number in the output for each of them.
410  typedef boost::mpl::bool_<true> requireReflectBarriers;
411 
412  // State consists of position for a version (placeholder) in the buffer
413  // and a flag to know if it was set by the reflected object.
414  // The third element is a context string, which should indicate the reflect() method
415  // we are in (typically the typename of the reflected class).
416  typedef std::tuple<typename StreamType::pos_type, bool, const char*> ReflectState;
417 
419 
420  SerializerFormatMixin() : mVersionPos(0), mContext(NULL) {}
421 
423  template <typename T>
424  bool writeFormatVersion(T& value, bool enableTypeCheck, StreamType& stream)
425  {
426 #ifdef CHECK_FORCE_SERIALIZE_BINARY_VERSION
428  if (v >= 0) {
429  MIRA_LOG(NOTICE) << "BinarySerializer: Forced serializing as binary "
430  << "format version " << v << ".";
431 
432  if (v == 0) {
433  // have to make this artificially depend on the template parameter,
434  // otherwise compiler complains about 'incomplete type'
435  typename Serializer::SimpleStreamType::buffer_type buffer;
437  v0.serialize(value, enableTypeCheck);
438  stream.write(buffer.data(), buffer.size());
439  return false;
440  }
441 
442  if (v == 1) {
443  typename Serializer::SimpleStreamType::buffer_type buffer;
445  v1.serialize(value, enableTypeCheck);
446  stream.write(buffer.data(), buffer.size());
447  return false;
448  }
449 
450  if (v != getSerializerFormatVersion()) {
451  MIRA_THROW(XIO, "BinarySerializer: Unhandled binary format, expected version "
452  << (int)this->getSerializerFormatVersion() << ", requested " << (int)v << ".");
453  }
454  }
455 #endif
456 
457  // TODO: omit this when serializing an AtomicSerializable type? (optimization)
458  // again, the tricky part is how to deal with it in the BinaryJSONConverter stuff??
459  stream << (uint16)BINARY_VERSION_MARKER;
460  stream << getSerializerFormatVersion();
461  return true;
462  }
463 
471  ReflectState insertVersionPlaceholder(const char* context, Serializer& serializer, StreamType& stream) {
472  ReflectState prevState = std::make_tuple(mVersionPos, mVersionSet, mContext);
473 
474  mVersionPos = stream.tellp();
475  if (mVersionPos == typename StreamType::pos_type(-1))
476  MIRA_THROW(XIO, "Failed querying stream position. The stream type does not seem to support repositioning. "
477  "Please use a buffered serializer (BufferedBinaryStreamSerializer).");
478 
479  mVersionSet = false;
480  mContext = context;
481  VersionType tmp = 0;
482  serializer.atomic(tmp);
483 
484  return prevState;
485  }
486 
490  template <typename T>
491  void writeVersion(VersionType version, Serializer& serializer, StreamType& stream) {
492 
493  if (mVersionSet) {
494  MIRA_THROW(XIO, "BinarySerializer: version() called repeatedly by serialization of type '"
495  << typeName<T>() << "'. Context = '" << (mContext ? mContext : "") << "'.");
496  }
497  std::size_t pos = stream.tellp();
498  stream.seekp(mVersionPos);
499  serializer.atomic(version);
500  stream.seekp(pos);
501  mVersionSet = true;
502  }
503 
508  void restoreVersionPtr(const ReflectState& prev) {
509  mVersionPos = std::get<0>(prev);
510  mVersionSet = std::get<1>(prev);
511  mContext = std::get<2>(prev);
512  }
513 
514 private:
515  typename StreamType::pos_type mVersionPos;
516  bool mVersionSet;
517  const char* mContext;
518 };
519 
521 
522 template <typename BinaryStream, uint8 BinaryFormatVersion, bool Buffered = false>
523 class ConcreteBinarySerializer : public BinarySerializer<ConcreteBinarySerializer<BinaryStream,
524  BinaryFormatVersion,
525  Buffered> >,
526  public BinarySerializerMixin,
527  public StreamAccessMixin<BinaryStream, Buffered>,
528  public SerializerFormatMixin<BinaryStream, BinaryFormatVersion, Buffered,
529  typename StreamAccessMixin<BinaryStream, Buffered>::StreamType>
530 {
531  typedef BinarySerializer<ConcreteBinarySerializer<BinaryStream, BinaryFormatVersion, Buffered> > Base;
532  typedef StreamAccessMixin<BinaryStream, Buffered> StreamAccess;
533  typedef SerializerFormatMixin<BinaryStream, BinaryFormatVersion, Buffered,
535 
536 public:
537 
539 
540 public:
541 
542  // We are not using human readable ids here. This will turn off the
543  // whole id-handling system of the serialization/reflection framework
544  // and dramatically improve the performance
545  typedef boost::mpl::bool_<false> useHumanReadableIDs;
546 
547  typedef typename Format::requireReflectBarriers requireReflectBarriers;
548  typedef typename Format::ReflectState ReflectState;
549 
550 public:
563  ConcreteBinarySerializer(typename BinaryStream::streambuffer_pointer buffer)
564  : StreamAccess(buffer), mLevel(0) {}
565 
573  ConcreteBinarySerializer(BinaryStream& stream) : StreamAccess(stream), mLevel(0) {}
574 
575 public:
576 
589  template <typename T>
590  void serialize(const T& value, bool enableTypeCheck = true)
591  {
592 #ifdef CHECK_FORCE_SERIALIZE_BINARY_VERSION
593  if (!Format::writeFormatVersion(value, enableTypeCheck, this->stream()))
594  return;
595 #else
596  Format::writeFormatVersion(value, enableTypeCheck, this->stream());
597 #endif
598 
599  if(enableTypeCheck) {
600  std::string fulltypename = typeName<T>();
601  Base::serialize("", fulltypename);
602  }
603  Base::serialize("", value);
604  }
605 
607 
608  template <typename T>
609  VersionType version(VersionType version, const T* caller = NULL) {
610  version = this->template queryDesiredClassVersion<T>(version, false);
611  this->template writeVersion<T>(version, *this, this->stream());
612  return version;
613  }
614 
615  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
616  VersionType version(VersionType version)) {
617  return this->template version<void>(version);
618  }
619 
621 
622  template <typename T>
624  version = this->template queryDesiredClassVersion<T>(version, true);
625  this->template writeVersion<T>(version, *this, this->stream());
626  return version;
627  }
628 
631 
632  template<typename T>
633  void atomic(T& member)
634  {
636  // write out the value in binary format
637  this->stream() << member;
638  }
639 
640  typename Format::ReflectState preReflect(const char* context = "")
641  {
642  ++mLevel;
643  return Format::insertVersionPlaceholder(context, *this, this->stream());
644  }
645 
646  void postReflect(const typename Format::ReflectState& prev)
647  {
648  Format::restoreVersionPtr(prev);
649  if (--mLevel == 0)
650  this->flushBuffer();
651  }
652 
654 
655  /*
656  * Pointers are stored with a prepended 1-byte marker that
657  * indicates the type of the pointer:
658  * 1 = PointerReference
659  * It is followed immediately by the object id (int) to the
660  * referenced object.
661  */
662  void pointerReference(int referencedObjectID) {
663  this->stream() << (uint8)POINTER_REFERENCE;
664  this->stream() << referencedObjectID;
665  }
666 
667  /*
668  * Pointers are stored with a prepended 1-byte marker that
669  * indicates the type of the pointer:
670  * 2 = NormalPointer
671  * It is followed by the serialized object.
672  */
674  this->stream() << (uint8)NORMAL_POINTER;
675  }
676 
677  /*
678  * Pointers are stored with a prepended 1-byte marker that
679  * indicates the type of the pointer:
680  * 3 = PolymorphicPointer
681  * It is followed immediately by the string of the class
682  * type of the object and afterwards the serialized object
683  * follows.
684  */
685  void pointerWithClassType(const std::string& type) {
686  this->stream() << (uint8)POLYMORPHIC_POINTER;
687  this->stream() << type;
688  }
689 
690  /*
691  * Pointers are stored with a prepended 1-byte marker that
692  * indicates the type of the pointer:
693  * 0 = NullPointer
694  */
695  void pointerNull() {
696  this->stream() << (uint8)NULL_POINTER;
697  }
698 
699  template<typename T>
700  void invokeOverwrite(T& object)
701  {
702  static const std::string context = "invokeOverwrite " + typeName<T>();
703  typename Format::ReflectState prevState = preReflect(context.c_str());
704 
705  Base::invokeOverwrite(object);
706 
707  postReflect(prevState);
708  }
709 
715  template<typename T>
716  void invokeOverwrite(serialization::PlainArray<T>& array)
717  {
718  static const std::string context = "invokeOverwrite PlainArray<" + typeName<T>() + ">";
719  typename Format::ReflectState prevState = preReflect(context.c_str());
720 
721  if(this->template isTrackingEnabled<T>() || !IsBitwiseSerializable<T>::value) {
722  // if tracking is enabled or the array's elements cannot be
723  // serialized bitwise we cannot even think about using optimized
724  // array serialization
725  Base::invokeOverwrite(array);
726  } else {
727  // otherwise, USE the optimized variant and dump the whole array
728  // into the stream as one block.
729  const char* buffer = reinterpret_cast<const char*>(array.data);
730  this->stream().write(buffer, array.getSizeInBytes());
731  }
732 
733  postReflect(prevState);
734  }
735 
736 public:
737 
738  template <typename T>
739  void write(const T* data, std::size_t count) {
740  this->stream().write(reinterpret_cast<const char*>(data),count*sizeof(T));
741  if (mLevel == 0)
742  this->flushBuffer();
743  }
744 
745 public:
746  // Codec support
747 
748 
757  if(!codec)
758  return;
759 
760  TypeId type = codec->getSupportedTypeId();
761  auto p = mCodecs.insert(std::make_pair(type, codec));
762  if(!p.second)
763  MIRA_THROW(XLogical, "A codec for the same type exists already");
764  }
765 
768  if(!codec)
769  return;
770 
771  TypeId type = codec->getSupportedTypeId();
772  auto it = mCodecs.find(type);
773  if(it==mCodecs.end())
774  return; // not registered
775 
776  if(it->second!=codec)
777  return; // not the same codec
778 
779  mCodecs.erase(it);
780  }
781 
787  template <typename T>
788  bool hasCodec() const {
789  return mCodecs.count(typeId<T>())!=0;
790  }
791 
799  template <typename T>
800  bool codec(const T& obj)
801  {
804 
805  auto it = mCodecs.find(typeId<T>());
806  if(it!=mCodecs.end()) {
807  // found codec
808  codec = it->second;
809  s = codec->getFourcc();
810  }
811 
812  if(!codec) {
813  write(s.fourcc, sizeof(s.fourcc));
814  return false;
815  }
816 
817  try {
818  // encode the data using the codec
819  const Buffer<uint8>& encodedData = codec->encode(obj);
820 
821  // write the signature of the codec not before successful encoding
822  write(s.fourcc, sizeof(s.fourcc));
823 
824  // write the encoded data immediately
825  this->stream() << encodedData;
826 
827  } catch(...) {
828 
829  // was not able to encode data, so serialize it normally
831  write(s.fourcc, sizeof(s.fourcc));
832  return false;
833  }
834 
835  // done
836  return true;
837  }
838 
839 private:
840  std::map<TypeId, BinarySerializerCodecPtr> mCodecs;
841 
842  uint32 mLevel;
843 };
844 
850 extern template class ConcreteBinarySerializer<BinaryBufferOstream, 2>;
854 
866 
868 
924 template <typename Derived>
926 {
927 public:
930 
931  template <typename T>
932  VersionType version(VersionType version, const T* caller = NULL) {
933  return this->This()->template version<T>(version);
934  }
935 
936  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
937  VersionType version(VersionType version)) {
938  return this->template version<void>(version);
939  }
940 
941  template <typename T>
942  VersionType version(VersionType version, AcceptDesiredVersion, const T* caller = NULL)
943  {
944  return this->This()->template version<T>(version, AcceptDesiredVersion());
945  }
946 
947 public:
948  template <typename T>
949  void read(T* data, std::size_t count) {
950  this->This()->read(data,count);
951  }
952 
953 public:
959  template <typename T>
960  bool hasCodec() const {
961  return this->This()->template hasCodec<T>();
962  }
963 
970  template <typename T>
971  bool codec(T& obj)
972  {
973  return this->This()->template codec(obj);
974  }
975 };
976 
978 
979 template <typename BinaryStream, uint8 BinaryFormatVersion>
981 
985 template <typename BinaryStream, uint8 BinaryVersionFormat>
987 {
988 };
989 
990 template <typename Deserializer, typename BinaryStream>
992 {
993 protected:
994  typedef boost::mpl::bool_<false> requireReflectBarriers;
995  typedef void* ReflectState;
996 
997  typedef int VersionType; // format version 0 had int32 serialization versions
998 
1000  ReflectState readVersion(const char* context, Deserializer& deserializer) {
1001  return NULL;
1002  }
1003 
1005  template <typename T>
1007  VersionType v;
1008  deserializer.atomic(v);
1009  return v;
1010  }
1011 
1013  void restoreVersion(const ReflectState& prev) {}
1014 
1016  void reportVersionChecked(std::ostream& os) {}
1017 };
1018 
1019 template <typename BinaryStream>
1022 {
1023 public:
1024  static uint8 getSerializerFormatVersion() { return 0; }
1025 
1026 protected:
1028  template <typename T>
1029  bool checkFormatVersion(T& value, bool enableTypeCheck, BinaryStream& stream) { return true; }
1030 };
1031 
1032 template <typename BinaryStream>
1033 class DeserializerFormatMixin<BinaryStream, 1> :
1034  public DeserializerFormatMixin01Base<ConcreteBinaryDeserializer<BinaryStream, 1>, BinaryStream>
1035 {
1036 public:
1037  static uint8 getSerializerFormatVersion() { return 1; }
1038 
1039 protected:
1041  template <typename T>
1042  bool checkFormatVersion(T& value, bool enableTypeCheck, BinaryStream& stream)
1043  {
1044  uint16 m;
1045  stream >> m;
1046 
1047  if (stream.fail())
1048  MIRA_THROW(XIO, "Failed to read binary format version number from binary stream: "
1049  "Reading from stream failed, e.g. empty or non-existent file.");
1050 
1051  if (m != BINARY_VERSION_MARKER)
1052  MIRA_THROW(XIO, "Failed to read binary format version number from binary stream: "
1053  "Expected marker not found, data invalid for binary format version 1.");
1054 
1055  uint8 v;
1056  stream >> v;
1057 
1058  if (v != getSerializerFormatVersion())
1059  MIRA_THROW(XIO, "BinaryDeserializer: Unhandled binary format, expected version "
1060  << (int)getSerializerFormatVersion() << ", found " << (int)v << ".");
1061 
1062  return true;
1063  }
1064 };
1065 
1066 template <typename BinaryStream>
1067 class DeserializerFormatMixin<BinaryStream, 2>
1068 {
1069 public:
1070  static uint8 getSerializerFormatVersion() { return 2; }
1071 
1073  static uint8 getDataFormatVersion(BinaryStream& stream)
1074  {
1075  uint16 m;
1076 
1077  typename BinaryStream::pos_type pos = stream.tellg();
1078 
1079  stream >> m;
1080 
1081  if (m == BINARY_VERSION_MARKER) {
1082  uint8 v;
1083  stream >> v;
1084  return v;
1085  } else {
1086  if (stream.fail())
1087  MIRA_THROW(XIO, "Failed to read binary format version number from binary stream: "
1088  "Reading from stream failed, e.g. empty or non-existent file.");
1089  // v0 did not store a version in binary data, so if we don't find it, it is v0
1090  if (pos == typename BinaryStream::pos_type(-1))
1091  MIRA_THROW(XIO, "Requiring fallback to legacy deserializer, but failing to query (and set) stream position. "
1092  "The stream type does not seem to support repositioning. "
1093  "You may try using a legacy deserializer directly, avoiding the need for setting the stream read position.");
1094  stream.seekg(pos);
1095  return 0;
1096  }
1097  }
1098 
1099 protected:
1101 
1102  // Needs to know about independent reflection blocks to read
1103  // a version number from the input for each of them.
1104  typedef boost::mpl::bool_<true> requireReflectBarriers;
1105 
1106  // State consists of a version number and a flag to know if it
1107  // was queried by the reflected object, plus context
1108  // provided to preReflect() (indicating the reflect() method
1109  // we are in, typically the typename of the reflected class).
1110  typedef std::tuple<serialization::VersionType, bool, const char*, bool> ReflectState;
1111 
1113 
1114  DeserializerFormatMixin() : mVersion(0), mContext(NULL),
1115  mUncheckedVersion(0), mUncheckedContext(NULL) {}
1116 
1121  template <typename T>
1122  bool checkFormatVersion(T& value, bool enableTypeCheck, BinaryStream& stream)
1123  {
1124  uint8 v;
1125 #ifdef CHECK_FORCE_SERIALIZE_BINARY_VERSION
1127  if (vf >= 0) {
1128  MIRA_LOG(NOTICE) << "BinaryDeserializer: Forced deserializing as binary "
1129  << "format version " << vf << ".";
1130  v = vf;
1131  if (v >= 1) // consume version data bytes from the stream
1132  getDataFormatVersion(stream); // (and ignore them)
1133  }
1134  else
1135 #endif
1136  v = getDataFormatVersion(stream);
1137 
1138 #ifndef NDEBUG
1139  if (v < getSerializerFormatVersion()) {
1140  // give a NOTICE in debug builds, else nothing (as it quickly turns into major spam,
1141  // and there is no efficient way to make sure it is displayed only once)
1142  MIRA_LOG(NOTICE) << "BinaryDeserializer: Found outdated binary format, version "
1143  << (int)v << ". Using legacy deserializer.";
1144  }
1145 #endif
1146 
1147  if (v == 0) {
1148  ConcreteBinaryDeserializer<BinaryStream, 0> v0(stream, stream.tellg());
1149  v0.deserialize(value, enableTypeCheck, true);
1150  stream.seekg(v0.streamPosition());
1151  return false;
1152  }
1153 
1154  if (v == 1) {
1155  ConcreteBinaryDeserializer<BinaryStream, 1> v1(stream, stream.tellg());
1156  v1.deserialize(value, enableTypeCheck, true);
1157  stream.seekg(v1.streamPosition());
1158  return false;
1159  }
1160 
1161  if (v != getSerializerFormatVersion()) {
1162  MIRA_THROW(XIO, "BinaryDeserializer: Unhandled binary format, expected version "
1163  << (int)getSerializerFormatVersion() << ", found " << (int)v << ".");
1164  }
1165 
1166  return true;
1167  }
1168 
1176  ReflectState readVersion(const char* context, Deserializer& deserializer) {
1177  ReflectState prevState;
1178  if ((mVersion > 0) && !mVersionChecked && (mUncheckedVersion == 0)) {
1179  mUncheckedVersion = mVersion;
1180  mUncheckedContext = mContext;
1181  prevState = std::make_tuple(mVersion, mVersionChecked, mContext, true);
1182  } else
1183  prevState = std::make_tuple(mVersion, mVersionChecked, mContext, false);
1184  deserializer.atomic(mVersion);
1185  mVersionChecked = false;
1186  mContext = context;
1187  return prevState;
1188  }
1189 
1193  template <typename T>
1195  // we could check for double query here, but rather not worth the extra work
1196  // if (mVersionChecked) {
1197  // MIRA_LOG(WARNING) << "BinaryDeserializer: version() called twice for type '"
1198  // << typeName<T>() << "'. Context = '" << (mContext ? mContext : "") << "'.";
1199  // }
1200  mVersionChecked = true;
1201  return mVersion;
1202  }
1203 
1208  void restoreVersion(const ReflectState& prev) {
1209  if ((mVersion > 0) && !mVersionChecked)
1210  MIRA_THROW(XIO, "Tried to deserialize versioned binary data (version " << (int)mVersion <<
1211  ") into unversioned type. Context = '" << (mContext ? mContext : "") << "'.");
1212  mVersion = std::get<0>(prev);
1213  mVersionChecked = std::get<1>(prev);
1214  mContext = std::get<2>(prev);
1215  if (std::get<3>(prev)) {
1216  mUncheckedVersion = 0;
1217  }
1218  }
1219 
1220  void reportVersionChecked(std::ostream& os) {
1221  if (mUncheckedVersion > 0) {
1222  os << " While trying to deserialize versioned binary data (version " << (int)mUncheckedVersion <<
1223  ") into type that is unversioned or not checking version before critical read. " <<
1224  "Context = '" << (mUncheckedContext ? mUncheckedContext : "") << "'.";
1225  } else if ((mVersion > 0) && !mVersionChecked) {
1226  os << " While trying to deserialize versioned binary data (version " << (int)mVersion <<
1227  ") into type that is unversioned or not checking version before critical read. " <<
1228  "Context = '" << (mContext ? mContext : "") << "'.";
1229  }
1230  }
1231 
1232 private:
1233  VersionType mVersion;
1234  bool mVersionChecked; // make sure the receiver of versioned data actually checks the version
1235  const char* mContext;
1236 
1237  VersionType mUncheckedVersion; // if there is some unchecked version, keep it in mind
1238  const char* mUncheckedContext; // to report when an error occurs (possibly somewhere "further down")
1239 };
1240 
1242 
1243 template <typename BinaryStream, uint8 BinaryFormatVersion>
1244 class ConcreteBinaryDeserializer : public BinaryDeserializer<ConcreteBinaryDeserializer<BinaryStream,
1245  BinaryFormatVersion> >,
1246  public BinarySerializerMixin,
1247  public DeserializerFormatMixin<BinaryStream, BinaryFormatVersion>
1248 {
1249  typedef BinaryDeserializer<ConcreteBinaryDeserializer<BinaryStream, BinaryFormatVersion> > Base;
1250  typedef DeserializerFormatMixin<BinaryStream, BinaryFormatVersion> Format;
1251 public:
1252 
1253  // We are not using human readable ids here. This will turn off the
1254  // whole id-handling system of the serialization/reflection framework
1255  // and dramatically improve the performance
1256  typedef boost::mpl::bool_<false> useHumanReadableIDs;
1257 
1259  typedef std::map<TypeId, BinarySerializerCodecPtr> CodecsMap;
1260 
1261  typedef typename Format::requireReflectBarriers requireReflectBarriers;
1262  typedef typename Format::ReflectState ReflectState;
1263 
1264 public:
1265 
1278  ConcreteBinaryDeserializer(typename BinaryStream::streambuffer_pointer buffer)
1279  : mStream(buffer) {}
1280 
1287  ConcreteBinaryDeserializer(BinaryStream& stream) : mStream(stream.rdbuf()) {}
1288 
1296  ConcreteBinaryDeserializer(BinaryStream& stream, typename BinaryStream::pos_type pos) :
1297  mStream(stream, pos) {}
1298 
1299 public:
1300 
1306  void reassign(typename BinaryStream::streambuffer_pointer buffer) {
1307  mStream = buffer;
1308  }
1309 
1310  typename BinaryStream::pos_type streamPosition() { return mStream.tellg(); }
1311 
1312 public:
1313 
1328  template <typename T>
1329  void deserialize(T& value, bool enableTypeCheck = true, bool recursive = false)
1330  {
1331  if (!recursive && !Format::checkFormatVersion(value, enableTypeCheck, mStream))
1332  return;
1333 
1334  if(enableTypeCheck) {
1335  std::string fulltypename;
1336  try {
1337  Base::deserialize("", fulltypename);
1338  }
1339  catch (...) {
1340  MIRA_THROW(XBadCast, "Failed reading type from binary data while " <<
1341  "deserializing into a variable of type '" << typeName<T>() << "'");
1342  }
1343 
1344  if(fulltypename != typeName<T>())
1345  MIRA_THROW(XBadCast, "Cannot deserialize the type '" << fulltypename <<
1346  "' into a variable of type '" << typeName<T>() << "'");
1347  }
1348  Base::deserialize("", value);
1349  }
1350 
1351 public:
1353 
1354  template <typename T>
1355  VersionType version(VersionType expectedVersion, const T* object = NULL) {
1356  VersionType version = this->template getVersion<T>(*this);
1357  if (version > expectedVersion)
1358  MIRA_THROW(XIO, "Trying to deserialize binary data of a newer version (" << (int)version <<
1359  ") of type " << typeName<T>() << " into an older version (" << (int)expectedVersion << ").");
1360  return version;
1361  }
1362 
1363  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
1364  VersionType version(VersionType expectedVersion)) {
1365  return version<void>(expectedVersion);
1366  }
1367 
1369 
1370  template <typename T>
1371  VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T* object = NULL) {
1372  return this->template getVersion<T>(*this);
1373  }
1374 
1375  template<typename T>
1376  void atomic(T& member)
1377  {
1379  // read in the value from binary stream
1380  mStream >> member;
1381  if(mStream.fail()) {
1382  std::stringstream ss;
1383  ss << "Failed to read member of type '" << typeName<T>()
1384  << "' from binary stream at stream position " << streamPosition() << ".";
1385 
1386  Format::reportVersionChecked(ss);
1387 
1388  MIRA_THROW(XIO, ss.str());
1389  }
1390  }
1391 
1392  typename Format::ReflectState preReflect(const char* context = "")
1393  {
1394  return Format::readVersion(context, *this);
1395  }
1396 
1397  void postReflect(const typename Format::ReflectState& prev)
1398  {
1399  Format::restoreVersion(prev);
1400  }
1401 
1420  template<typename T>
1421  void pointer(T* &pointer)
1422  {
1423  // we always store a marker before each pointer
1424  // in Serializer::pointerReference / pointerNoReference
1425  uint8 pointerType8U;
1426  mStream >> pointerType8U;
1427 
1428  PointerType pointerType = (PointerType) pointerType8U;
1429 
1430  switch(pointerType)
1431  {
1432  case NULL_POINTER:
1433  pointer=NULL;
1434  break;
1435 
1436  case POINTER_REFERENCE:
1437  {
1438  int ref;
1439  mStream >> ref; // read the ref id
1440  // ... and resolve it
1441  pointer = this->template resolveReference<T>(ref);
1442  break;
1443  }
1444 
1445  case NORMAL_POINTER:
1446  // we have a "normal" pointer, so deserialize it
1447  mClassType.clear(); // we have no class type information here
1449  break;
1450 
1451  case POLYMORPHIC_POINTER:
1452  // we have a "polymorphic" pointer, so get class type
1453  mStream >> mClassType;
1454  // and deserialize it
1456  break;
1457  }
1458  }
1459 
1460  std::string pointerClassType() {
1461  return mClassType;
1462  }
1463 
1464 
1465  template<typename T>
1466  void invokeOverwrite(T& object)
1467  {
1468  // an object starts here - we are about to call a reflect() method
1469  static const std::string context = "invokeOverwrite " + typeName<T>();
1470  typename Format::ReflectState prevState = preReflect(context.c_str());
1471 
1472  Base::invokeOverwrite(object);
1473 
1474  // we are done with this object
1475  postReflect(prevState);
1476  }
1477 
1483  template<typename T>
1484  void invokeOverwrite(serialization::PlainArray<T>& array)
1485  {
1486  // an object starts here - we are about to call a reflect() method
1487  static const std::string context = "invokeOverwrite PlainArray<" + typeName<T>() +">";
1488  typename Format::ReflectState prevState = preReflect(context.c_str());
1489 
1490  if(this->template isTrackingEnabled<T>() || !IsBitwiseSerializable<T>::value) {
1491  // if tracking is enabled or the array's elements cannot be
1492  // serialized bitwise we cannot even think about using optimized
1493  // array deserialization
1494  Base::invokeOverwrite(array);
1495  } else {
1496 
1497  // otherwise, USE the optimized variant and read the whole array
1498  // from the stream as one block.
1499  char* buffer = reinterpret_cast<char*>(array.data);
1500  mStream.read(buffer, array.getSizeInBytes());
1501  }
1502 
1503  // we are done with this object
1504  postReflect(prevState);
1505  }
1506 
1507 public:
1508 
1509  template <typename T>
1510  void read(T* data, std::size_t count) {
1511  mStream.read(reinterpret_cast<char*>(data),count*sizeof(T));
1512  }
1513 
1514 public:
1515  // codec support
1516 
1521  template <typename T>
1522  bool hasCodec() const {
1523  //return mCodecs.count(typeId<T>())!=0;
1524  return false;
1525  }
1526 
1533  template <typename T>
1534  bool codec(T& obj)
1535  {
1538 
1539  // read the codec fourcc
1540  read(s.fourcc, sizeof(s.fourcc));
1541 
1543  return false; // no codec was used by serializer
1544 
1545  // try to find appropriate codec within our created codecs
1546  auto it = mCodecs.find(typeId<T>());
1547  if(it==mCodecs.end() || it->second->getFourcc()!=s) {
1548  // codec not found, so we must create one
1549  codec = BinarySerializerCodec::createCodec<T>(s);
1550  assert(codec);
1551  mCodecs[typeId<T>()] = codec;
1552  } else
1553  codec = it->second; // use existing codec
1554 
1555  assert(codec->getFourcc()==s);
1556  assert(codec->getSupportedTypeId()==typeId<T>());
1557 
1558  // read the encoded data
1559  Buffer<uint8> encodedData;
1560  mStream >> encodedData;
1561 
1562  // and decode
1563  codec->decode(encodedData, obj);
1564 
1565  // done
1566  return true;
1567  }
1568 
1570  const CodecsMap& getCodecs() const {
1571  return mCodecs;
1572  }
1573 
1575  void setCodecs(const CodecsMap& codecs) {
1576  mCodecs = codecs;
1577  }
1578 
1579 private:
1580 
1581  BinaryStream mStream;
1582  std::string mClassType;
1583 
1584  CodecsMap mCodecs;
1585 };
1586 
1592 extern template class ConcreteBinaryDeserializer<BinaryBufferIstream, 2>;
1598 
1610 
1612 
1613 } // namespace
1614 
1615 #endif
boost::mpl::bool_< false > useHumanReadableIDs
Definition: BinarySerializer.h:545
bool checkFormatVersion(T &value, bool enableTypeCheck, BinaryStream &stream)
Verify expected version data.
Definition: BinarySerializer.h:1042
Format::ReflectState ReflectState
Definition: BinarySerializer.h:548
Base::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:620
void restoreVersionPtr(const ReflectState &prev)
Do nothing.
Definition: BinarySerializer.h:360
Definition: BinarySerializer.h:316
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType version))
Definition: BinarySerializer.h:271
serialization::VersionType VersionType
Definition: BinarySerializer.h:1112
bool checkFormatVersion(T &value, bool enableTypeCheck, BinaryStream &stream)
Always accepts the input itself.
Definition: BinarySerializer.h:1029
Base::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:1368
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType expectedVersion))
Definition: BinarySerializer.h:1363
ConcreteBinarySerializer(BinaryStream &stream)
Create a new binary serializer and assign it to the specified binary output stream.
Definition: BinarySerializer.h:573
bool codec(T &obj)
Decodes the specified object from the serialized data.
Definition: BinarySerializer.h:1534
void pointer(T *&pointer)
Overwrites Deserializer::pointer.
Definition: BinarySerializer.h:1421
void invokeOverwrite(serialization::PlainArray< T > &array)
Specialized for Array to implement an optimized variant for deserializing an array, if possible (i.e.
Definition: BinarySerializer.h:1484
Format::ReflectState ReflectState
Definition: BinarySerializer.h:1262
void invokeOverwrite(T &object)
The actual invoke implementation, that may also be overwritten in derived classes to add additional f...
Definition: AbstractReflector.h:271
Contains the Serializer template, a base class for all serializers.
void deserialize(const std::string &name, T &value)
Deserializes the specified object value with the given name.
Definition: Deserializer.h:133
StreamAccessMixin(typename BinaryStream::streambuffer_pointer buffer)
Definition: BinarySerializer.h:137
VersionType version(VersionType version, AcceptDesiredVersion, const T *caller=NULL)
Definition: BinarySerializer.h:277
Definition: BinarySerializer.h:88
void * ReflectState
Definition: BinarySerializer.h:995
ConcreteBinaryDeserializer(typename BinaryStream::streambuffer_pointer buffer)
Create a new binary deserializer based on the specified stream buffer object.
Definition: BinarySerializer.h:1278
VersionType version(VersionType version, const T *caller=NULL)
Definition: BinarySerializer.h:267
typename ReflectorInterface< ConcreteBinarySerializer< mira::BinaryOstream, BinaryFormatVersion, false > >::AcceptDesiredVersion AcceptDesiredVersion
Definition: AbstractReflector.h:195
Type trait that indicates whether a type can be serialized bitwise by just copying the data buffer...
Definition: IsBitwiseSerializable.h:70
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
Definition: BinarySerializer.h:91
void member(const char *name, T &member, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:883
static size_t formatVersionOverhead()
Overhead 3 bytes with each serialize().
Definition: BinarySerializer.h:404
Serializer that uses BinaryOstream to serialize the objects in binary format.
Definition: BinarySerializer.h:254
bool checkFormatVersion(T &value, bool enableTypeCheck, BinaryStream &stream)
Checks for format version info in the stream.
Definition: BinarySerializer.h:1122
static int forcedDeserializeVersion()
Returns either the version number from value of environment variable &#39;MIRA_FORCE_DESERIALIZE_VERSION&#39;...
Definition: Deserializer.h:118
Is a special reflector that is used for serialization.
Definition: Serializer.h:126
void flushBuffer()
Flush stream buffer (write to underlying stream), nothing to do for unbuffered access.
Definition: BinarySerializer.h:146
~StreamAccessMixin()
Definition: BinarySerializer.h:168
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:529
bool hasCodec() const
Returns true, of there is a codec for the specified type T.
Definition: BinarySerializer.h:788
Definition: BinarySerializer.h:90
Used by BinaryDeserializer, see SerializerFormatMixin above.
Definition: BinarySerializer.h:986
#define BINARY_VERSION_MARKER
Definition: BinarySerializer.h:70
uint32_t uint32
Definition: Types.h:64
void pointerWithoutClassType()
Definition: BinarySerializer.h:673
void write(const T *data, std::size_t count)
Definition: BinarySerializer.h:739
void invokeOverwrite(serialization::PlainArray< T > &array)
Specialized for PlainArray to implement an optimized variant for serializing array, if possible (i.e.
Definition: BinarySerializer.h:716
VersionType getVersion(Deserializer &deserializer)
Get version value read at start of object.
Definition: BinarySerializer.h:1194
Definition: BinarySerializer.h:980
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:1037
Direct stream access.
Definition: BinarySerializer.h:128
Definition: BinarySerializer.h:336
StreamAccessMixin(BinaryStream &stream)
Definition: BinarySerializer.h:140
static uint8 getDataFormatVersion(BinaryStream &stream)
advances the stream to after the format information (if present)!
Definition: BinarySerializer.h:1073
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:1024
ReflectState readVersion(const char *context, Deserializer &deserializer)
Read version from binary input, memorize it for later when (if) the reflected object will ask us for ...
Definition: BinarySerializer.h:1176
Definition: BinarySerializer.h:89
Used by BinarySerializer and BinaryDeserializer.
Definition: BinarySerializer.h:79
boost::mpl::bool_< false > useHumanReadableIDs
Definition: BinarySerializer.h:1256
Definition: BinarySerializer.h:1020
Get compiler and platform independent typenames.
Base for buffered/unbuffered stream access.
Definition: BinarySerializer.h:102
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
void restoreVersion(const ReflectState &prev)
Do nothing.
Definition: BinarySerializer.h:1013
StreamAccessMixinBase(typename BinaryStream::streambuffer_pointer buffer)
Definition: BinarySerializer.h:105
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:1070
serialization::VersionType VersionType
Definition: BinarySerializer.h:263
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:78
void reassign(typename BinaryStream::streambuffer_pointer buffer)
Reassigns the specified stream buffer to this deserializer.
Definition: BinarySerializer.h:1306
void serialize(const T &value, bool enableTypeCheck=true)
Provides a special serialize interface for the BinarySerializer.
Definition: BinarySerializer.h:590
bool codec(const T &obj)
Encodes the specified object containing the data using a matching codec.
Definition: BinarySerializer.h:307
BinaryBufferOstream SimpleStreamType
Definition: BinarySerializer.h:538
void pointerReference(int referencedObjectID)
Definition: BinarySerializer.h:662
Derived * This()
"Curiously recurring template pattern" (CRTP).
Definition: AbstractReflector.h:246
Format::requireReflectBarriers requireReflectBarriers
Definition: BinarySerializer.h:1261
bool writeFormatVersion(T &value, bool enableTypeCheck, StreamType &stream)
Write the format version number into the binary output.
Definition: BinarySerializer.h:389
boost::mpl::bool_< false > requireReflectBarriers
Definition: BinarySerializer.h:343
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:368
Used by BinarySerializer, defines the binary format in particular for class versioning information: 0...
Definition: BinarySerializer.h:331
bool hasCodec() const
Supported for compatibility with BinarySerializer in a common reflect method.
Definition: BinarySerializer.h:1522
DeserializerFormatMixin()
Definition: BinarySerializer.h:1114
ReflectState insertVersionPlaceholder(const char *context, Serializer &serializer, StreamType &stream)
Do nothing.
Definition: BinarySerializer.h:349
boost::mpl::bool_< true > requireReflectBarriers
Definition: BinarySerializer.h:1104
Definition: BinarySerializer.h:991
Format::VersionType VersionType
Definition: BinarySerializer.h:1352
void registerCodec(BinarySerializerCodecPtr codec)
Registers the specified codec instance in this binary serializer.
Definition: BinarySerializer.h:756
bool hasCodec() const
Returns true, of there is a codec for the specified type T.
Definition: BinarySerializer.h:295
void writeVersion(VersionType version, Serializer &serializer, StreamType &stream)
Write version value to version placeholder position.
Definition: BinarySerializer.h:491
A four-character code that is used to identify data formats and codecs.
Definition: BinarySerializerCodec.h:121
Deserializer that uses BinaryIstream to deserialize the objects from binary format.
Definition: BinarySerializer.h:925
bool writeFormatVersion(T &value, bool enableTypeCheck, StreamType &stream)
Do nothing (format version 0 does not contain format version info) and return true.
Definition: BinarySerializer.h:373
Provides type trait that indicates whether a type can be serialized bitwise.
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:384
Format::ReflectState preReflect(const char *context="")
Definition: BinarySerializer.h:640
Contains base class for all deserializers.
const CodecsMap & getCodecs() const
Return the map of currently known codecs.
Definition: BinarySerializer.h:1570
void invokeOverwrite(T &object)
Definition: BinarySerializer.h:700
uint8_t uint8
Definition: Types.h:62
BinaryBufferOstream & stream()
Get access to the read/write stream, returns reference to buffer stream (overriding the base class&#39; s...
Definition: BinarySerializer.h:177
VersionType version(VersionType expectedVersion, const T *object=NULL)
Definition: BinarySerializer.h:1355
Tag class used as parameter to ReflectorInterface::version() etc.
Definition: ReflectorInterface.h:80
ReflectState insertVersionPlaceholder(const char *context, Serializer &serializer, StreamType &stream)
Put a dummy version in the binary output as placeholder, memorize the position for later when (if) th...
Definition: BinarySerializer.h:471
void restoreVersion(const ReflectState &prev)
Restore a previous version value.
Definition: BinarySerializer.h:1208
boost::mpl::bool_< false > requireReflectBarriers
Definition: BinarySerializer.h:994
Base class for codecs for BinarySerializer and BinaryDeserializer.
void write(const T *data, std::size_t count)
Definition: BinarySerializer.h:284
std::tuple< typename StreamType::pos_type, bool, const char * > ReflectState
Definition: BinarySerializer.h:416
void read(T *data, std::size_t count)
Definition: BinarySerializer.h:1510
ConcreteBinarySerializer(typename BinaryStream::streambuffer_pointer buffer)
Create a new binary serializer based on the specified stream buffer object.
Definition: BinarySerializer.h:563
uint16_t uint16
Definition: Types.h:63
serialization::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:264
void pointerNull()
Definition: BinarySerializer.h:695
VersionType version(VersionType version, AcceptDesiredVersion, const T *caller=NULL)
Definition: BinarySerializer.h:942
typename ReflectorInterface< ConcreteBinarySerializer< mira::BinaryOstream, BinaryFormatVersion, false > >::VersionType VersionType
Definition: AbstractReflector.h:165
int TypeId
The type of the integral TypeId, that can be retrieved by typeId<T>()
Definition: TypeId.h:64
StreamAccessMixin(BinaryStream &stream)
Definition: BinarySerializer.h:166
ConcreteBinaryDeserializer(BinaryStream &stream, typename BinaryStream::pos_type pos)
Create a new binary deserializer and read the data from the specified binary stream, starting at the specified position.
Definition: BinarySerializer.h:1296
void setCodecs(const CodecsMap &codecs)
Set the map of known codecs.
Definition: BinarySerializer.h:1575
VersionType version(VersionType version, const T *caller=NULL)
Definition: BinarySerializer.h:609
ReflectState readVersion(const char *context, Deserializer &deserializer)
Do nothing.
Definition: BinarySerializer.h:1000
VersionType version(VersionType version, const T *caller=NULL)
Definition: BinarySerializer.h:932
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
StreamAccessMixin(typename BinaryStream::streambuffer_pointer buffer)
Definition: BinarySerializer.h:163
VersionType getVersion(Deserializer &deserializer)
Read version directly from stream.
Definition: BinarySerializer.h:1006
void flushBuffer()
Flush buffer stream to underlying stream.
Definition: BinarySerializer.h:180
bool hasCodec() const
Returns true, of there is a codec for the specified type T.
Definition: BinarySerializer.h:960
Contains the BinaryIStream and BinaryOStream classes for fast and efficient streaming of binary data...
static size_t formatVersionOverhead()
Zero overhead here.
Definition: BinarySerializer.h:340
Format::ReflectState preReflect(const char *context="")
Definition: BinarySerializer.h:1392
int VersionType
Definition: BinarySerializer.h:997
void restoreVersionPtr(const ReflectState &prev)
Restore a previous version placeholder position.
Definition: BinarySerializer.h:508
BinaryStream::pos_type streamPosition()
Definition: BinarySerializer.h:1310
void atomic(T &member)
Definition: BinarySerializer.h:1376
BinaryStream StreamType
The type of stream the serializer writes to (the actual output stream here)
Definition: BinarySerializer.h:134
void postReflect(const typename Format::ReflectState &prev)
Definition: BinarySerializer.h:646
void deserialize(T &value, bool enableTypeCheck=true, bool recursive=false)
Provides a special deserialize interface for the BinaryDeserializer.
Definition: BinarySerializer.h:1329
void pointerWithClassType(const std::string &type)
Definition: BinarySerializer.h:685
ConcreteBinarySerializer< BinaryStream, 2, Buffered > Serializer
Definition: BinarySerializer.h:406
bool codec(T &obj)
Decodes the specified object from the serialized data.
Definition: BinarySerializer.h:971
VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T *object=NULL)
Definition: BinarySerializer.h:1371
Definition: BinarySerializer.h:257
Format::VersionType VersionType
Definition: BinarySerializer.h:606
ConcreteBinaryDeserializer(BinaryStream &stream)
Create a new binary deserializer and read the data from the specified binary stream.
Definition: BinarySerializer.h:1287
BinarySerializerTag Tag
Definition: BinarySerializer.h:260
std::tuple< serialization::VersionType, bool, const char *, bool > ReflectState
Definition: BinarySerializer.h:1110
Format::requireReflectBarriers requireReflectBarriers
Definition: BinarySerializer.h:547
serialization::VersionType VersionType
Definition: BinarySerializer.h:928
void read(T *data, std::size_t count)
Definition: BinarySerializer.h:949
ConcreteBinaryDeserializer< BinaryStream, 2 > Deserializer
Definition: BinarySerializer.h:1100
void * ReflectState
Definition: BinarySerializer.h:344
BinaryStream & stream()
Get access to the read/write stream (direct reference to underlying stream).
Definition: BinarySerializer.h:120
boost::mpl::bool_< true > requireReflectBarriers
Definition: BinarySerializer.h:410
BinaryBufferOstream StreamType
The type of stream the serializer writes to (the buffer stream here).
Definition: BinarySerializer.h:160
std::string pointerClassType()
Definition: BinarySerializer.h:1460
bool writeFormatVersion(T &value, bool enableTypeCheck, StreamType &stream)
Write the format version number into the binary output.
Definition: BinarySerializer.h:424
static Fourcc null()
Returns the &#39;NULL&#39; fourcc.
Definition: BinarySerializerCodec.h:142
void reportVersionChecked(std::ostream &os)
Definition: BinarySerializer.h:1220
void postReflect(const typename Format::ReflectState &prev)
Definition: BinarySerializer.h:1397
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType version))
Definition: BinarySerializer.h:615
serialization::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:929
PointerType
Pointer type that is stored as 1-byte marker before storing the pointer.
Definition: BinarySerializer.h:86
serialization::VersionType VersionType
Definition: BinarySerializer.h:418
char fourcc[4]
Definition: BinarySerializerCodec.h:165
void reassign(typename BinaryStream::streambuffer_pointer buffer)
Reassigns the specified stream buffer to this (serializer).
Definition: BinarySerializer.h:116
void atomic(T &member)
Is called if the member is an atomic type (int, float, etc).
Definition: RecursiveMemberReflector.h:288
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType version))
Definition: BinarySerializer.h:936
void atomic(T &member)
Definition: BinarySerializer.h:633
void unregisterCodec(BinarySerializerCodecPtr codec)
Removes a previously registered codec.
Definition: BinarySerializer.h:767
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:401
void invokeOverwrite(T &object)
Definition: BinarySerializer.h:1466
Definition: LoggingCore.h:77
Is a special reflector that is used for deserialization.
Definition: Deserializer.h:99
bool codec(const T &obj)
Encodes the specified object containing the data using a matching codec.
Definition: BinarySerializer.h:800
void writeVersion(VersionType version, Serializer &serializer, StreamType &stream)
Write version directly to stream.
Definition: BinarySerializer.h:355
std::map< TypeId, BinarySerializerCodecPtr > CodecsMap
A map of binary serialization codecs.
Definition: BinarySerializer.h:1259
void reportVersionChecked(std::ostream &os)
Do nothing.
Definition: BinarySerializer.h:1016
int VersionType
Definition: BinarySerializer.h:346
boost::shared_ptr< BinarySerializerCodec > BinarySerializerCodecPtr
Shared pointer of BinarySerializerCodec.
Definition: BinarySerializerCodec.h:64
VersionType version(VersionType version, AcceptDesiredVersion, const T *caller=NULL)
Definition: BinarySerializer.h:623
StreamAccessMixinBase(BinaryStream &stream)
Definition: BinarySerializer.h:108