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 #ifdef MIRA_LINUX
297  return this->This()->template hasCodec<T>();
298 #else
299  return this->This()->hasCodec<T>();
300 #endif
301  }
302 
310  template <typename T>
311  bool codec(const T& obj)
312  {
313 #ifdef MIRA_LINUX
314  return this->This()->template codec(obj);
315 #else
316  return this->This()->codec(obj);
317 #endif
318  }
319 };
320 
322 
323 template <typename BinaryStream, uint8 BinaryFormatVersion, bool Buffered>
325 
338 template <typename BinaryStream, uint8 BinaryFormatVersion, bool Buffered, typename StreamType>
340 {
341 };
342 
343 template <typename Serializer, typename StreamType>
345 {
346 public:
348  static size_t formatVersionOverhead() { return 0; }
349 
350 protected:
351  typedef boost::mpl::bool_<false> requireReflectBarriers;
352  typedef void* ReflectState;
353 
354  typedef int VersionType; // format version 0 had int32 serialization versions
355 
358  Serializer& serializer,
359  StreamType& stream) { return NULL; }
360 
362  template <typename T>
363  void writeVersion(VersionType version, Serializer& serializer, StreamType& stream) {
364  serializer.atomic(version);
365  }
366 
368  void restoreVersionPtr(const ReflectState& prev) {}
369 };
370 
371 template <typename BinaryStream, bool Buffered, typename StreamType>
372 class SerializerFormatMixin<BinaryStream, 0, Buffered, StreamType> :
373  public SerializerFormatMixin01Base<ConcreteBinarySerializer<BinaryStream, 0, Buffered>, StreamType>
374 {
375 public:
376  static uint8 getSerializerFormatVersion() { return 0; }
377 
378 protected:
380  template <typename T>
381  bool writeFormatVersion(T& value, bool enableTypeCheck, StreamType& stream) { return true; }
382 };
383 
384 // This is just for sake of completeness, actually. There is no use case for serializing to v1.
385 // Where needed, v1 data should be created from v0 serialized data by just prepending the version
386 // marker bytes.
387 template <typename BinaryStream, bool Buffered, typename StreamType>
388 class SerializerFormatMixin<BinaryStream, 1, Buffered, StreamType> :
389  public SerializerFormatMixin01Base<ConcreteBinarySerializer<BinaryStream, 1, Buffered>, StreamType>
390 {
391 public:
392  static uint8 getSerializerFormatVersion() { return 1; }
393 
394 protected:
396  template <typename T>
397  bool writeFormatVersion(T& value, bool enableTypeCheck, StreamType& stream)
398  {
399  stream << (uint16)BINARY_VERSION_MARKER;
400  stream << getSerializerFormatVersion();
401  return true;
402  }
403 };
404 
405 template <typename BinaryStream, bool Buffered, typename StreamType>
406 class SerializerFormatMixin<BinaryStream, 2, Buffered, StreamType>
407 {
408 public:
409  static uint8 getSerializerFormatVersion() { return 2; }
410 
412  static size_t formatVersionOverhead() { return sizeof(uint16) + sizeof(uint8); }
413 protected:
415 
416  // Needs to know about independent reflection blocks to reserve space
417  // for a version number in the output for each of them.
418  typedef boost::mpl::bool_<true> requireReflectBarriers;
419 
420  // State consists of position for a version (placeholder) in the buffer
421  // and a flag to know if it was set by the reflected object.
422  // The third element is a context string, which should indicate the reflect() method
423  // we are in (typically the typename of the reflected class).
424  typedef std::tuple<typename StreamType::pos_type, bool, const char*> ReflectState;
425 
427 
428  SerializerFormatMixin() : mVersionPos(0), mContext(NULL) {}
429 
431  template <typename T>
432  bool writeFormatVersion(T& value, bool enableTypeCheck, StreamType& stream)
433  {
434 #ifdef CHECK_FORCE_SERIALIZE_BINARY_VERSION
436  if (v >= 0) {
437  MIRA_LOG(NOTICE) << "BinarySerializer: Forced serializing as binary "
438  << "format version " << v << ".";
439 
440  if (v == 0) {
441  // have to make this artificially depend on the template parameter,
442  // otherwise compiler complains about 'incomplete type'
443  typename Serializer::SimpleStreamType::buffer_type buffer;
445  v0.serialize(value, enableTypeCheck);
446  stream.write(buffer.data(), buffer.size());
447  return false;
448  }
449 
450  if (v == 1) {
451  typename Serializer::SimpleStreamType::buffer_type buffer;
453  v1.serialize(value, enableTypeCheck);
454  stream.write(buffer.data(), buffer.size());
455  return false;
456  }
457 
458  if (v != getSerializerFormatVersion()) {
459  MIRA_THROW(XIO, "BinarySerializer: Unhandled binary format, expected version "
460  << (int)this->getSerializerFormatVersion() << ", requested " << (int)v << ".");
461  }
462  }
463 #endif
464 
465  // TODO: omit this when serializing an AtomicSerializable type? (optimization)
466  // again, the tricky part is how to deal with it in the BinaryJSONConverter stuff??
467  stream << (uint16)BINARY_VERSION_MARKER;
468  stream << getSerializerFormatVersion();
469  return true;
470  }
471 
479  ReflectState insertVersionPlaceholder(const char* context, Serializer& serializer, StreamType& stream) {
480  ReflectState prevState = std::make_tuple(mVersionPos, mVersionSet, mContext);
481 
482  mVersionPos = stream.tellp();
483  if (mVersionPos == typename StreamType::pos_type(-1))
484  MIRA_THROW(XIO, "Failed querying stream position. The stream type does not seem to support repositioning. "
485  "Please use a buffered serializer (BufferedBinaryStreamSerializer).");
486 
487  mVersionSet = false;
488  mContext = context;
489  VersionType tmp = 0;
490  serializer.atomic(tmp);
491 
492  return prevState;
493  }
494 
498  template <typename T>
499  void writeVersion(VersionType version, Serializer& serializer, StreamType& stream) {
500 
501  if (mVersionSet) {
502  MIRA_THROW(XIO, "BinarySerializer: version() called repeatedly by serialization of type '"
503  << typeName<T>() << "'. Context = '" << (mContext ? mContext : "") << "'.");
504  }
505  std::size_t pos = stream.tellp();
506  stream.seekp(mVersionPos);
507  serializer.atomic(version);
508  stream.seekp(pos);
509  mVersionSet = true;
510  }
511 
516  void restoreVersionPtr(const ReflectState& prev) {
517  mVersionPos = std::get<0>(prev);
518  mVersionSet = std::get<1>(prev);
519  mContext = std::get<2>(prev);
520  }
521 
522 private:
523  typename StreamType::pos_type mVersionPos;
524  bool mVersionSet;
525  const char* mContext;
526 };
527 
529 
530 template <typename BinaryStream, uint8 BinaryFormatVersion, bool Buffered = false>
531 class ConcreteBinarySerializer : public BinarySerializer<ConcreteBinarySerializer<BinaryStream,
532  BinaryFormatVersion,
533  Buffered> >,
534  public BinarySerializerMixin,
535  public StreamAccessMixin<BinaryStream, Buffered>,
536  public SerializerFormatMixin<BinaryStream, BinaryFormatVersion, Buffered,
537  typename StreamAccessMixin<BinaryStream, Buffered>::StreamType>
538 {
539  typedef BinarySerializer<ConcreteBinarySerializer<BinaryStream, BinaryFormatVersion, Buffered> > Base;
540  typedef StreamAccessMixin<BinaryStream, Buffered> StreamAccess;
541  typedef SerializerFormatMixin<BinaryStream, BinaryFormatVersion, Buffered,
543 
544 public:
545 
547 
548 public:
549 
550  // We are not using human readable ids here. This will turn off the
551  // whole id-handling system of the serialization/reflection framework
552  // and dramatically improve the performance
553  typedef boost::mpl::bool_<false> useHumanReadableIDs;
554 
555  typedef typename Format::requireReflectBarriers requireReflectBarriers;
556  typedef typename Format::ReflectState ReflectState;
557 
558 public:
571  ConcreteBinarySerializer(typename BinaryStream::streambuffer_pointer buffer)
572  : StreamAccess(buffer), mLevel(0) {}
573 
581  ConcreteBinarySerializer(BinaryStream& stream) : StreamAccess(stream), mLevel(0) {}
582 
583 public:
584 
597  template <typename T>
598  void serialize(const T& value, bool enableTypeCheck = true)
599  {
600 #ifdef CHECK_FORCE_SERIALIZE_BINARY_VERSION
601  if (!Format::writeFormatVersion(value, enableTypeCheck, this->stream()))
602  return;
603 #else
604  Format::writeFormatVersion(value, enableTypeCheck, this->stream());
605 #endif
606 
607  if(enableTypeCheck) {
608  std::string fulltypename = typeName<T>();
609  Base::serialize("", fulltypename);
610  }
611  Base::serialize("", value);
612  }
613 
615 
616  template <typename T>
617  VersionType version(VersionType version, const T* caller = NULL) {
618  version = this->template queryDesiredClassVersion<T>(version, false);
619  this->template writeVersion<T>(version, *this, this->stream());
620  return version;
621  }
622 
623  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
624  VersionType version(VersionType version)) {
625  return this->template version<void>(version);
626  }
627 
629 
630  template <typename T>
632  version = this->template queryDesiredClassVersion<T>(version, true);
633  this->template writeVersion<T>(version, *this, this->stream());
634  return version;
635  }
636 
639 
640  template<typename T>
641  void atomic(T& member)
642  {
644  // write out the value in binary format
645  this->stream() << member;
646  }
647 
648  typename Format::ReflectState preReflect(const char* context = "")
649  {
650  ++mLevel;
651  return Format::insertVersionPlaceholder(context, *this, this->stream());
652  }
653 
654  void postReflect(const typename Format::ReflectState& prev)
655  {
656  Format::restoreVersionPtr(prev);
657  if (--mLevel == 0)
658  this->flushBuffer();
659  }
660 
662 
663  /*
664  * Pointers are stored with a prepended 1-byte marker that
665  * indicates the type of the pointer:
666  * 1 = PointerReference
667  * It is followed immediately by the object id (int) to the
668  * referenced object.
669  */
670  void pointerReference(int referencedObjectID) {
671  this->stream() << (uint8)POINTER_REFERENCE;
672  this->stream() << referencedObjectID;
673  }
674 
675  /*
676  * Pointers are stored with a prepended 1-byte marker that
677  * indicates the type of the pointer:
678  * 2 = NormalPointer
679  * It is followed by the serialized object.
680  */
682  this->stream() << (uint8)NORMAL_POINTER;
683  }
684 
685  /*
686  * Pointers are stored with a prepended 1-byte marker that
687  * indicates the type of the pointer:
688  * 3 = PolymorphicPointer
689  * It is followed immediately by the string of the class
690  * type of the object and afterwards the serialized object
691  * follows.
692  */
693  void pointerWithClassType(const std::string& type) {
694  this->stream() << (uint8)POLYMORPHIC_POINTER;
695  this->stream() << type;
696  }
697 
698  /*
699  * Pointers are stored with a prepended 1-byte marker that
700  * indicates the type of the pointer:
701  * 0 = NullPointer
702  */
703  void pointerNull() {
704  this->stream() << (uint8)NULL_POINTER;
705  }
706 
707  template<typename T>
708  void invokeOverwrite(T& object)
709  {
710  static const std::string context = "invokeOverwrite " + typeName<T>();
711  typename Format::ReflectState prevState = preReflect(context.c_str());
712 
713  Base::invokeOverwrite(object);
714 
715  postReflect(prevState);
716  }
717 
723  template<typename T>
724  void invokeOverwrite(serialization::PlainArray<T>& array)
725  {
726  static const std::string context = "invokeOverwrite PlainArray<" + typeName<T>() + ">";
727  typename Format::ReflectState prevState = preReflect(context.c_str());
728 
729  if(this->template isTrackingEnabled<T>() || !IsBitwiseSerializable<T>::value) {
730  // if tracking is enabled or the array's elements cannot be
731  // serialized bitwise we cannot even think about using optimized
732  // array serialization
733  Base::invokeOverwrite(array);
734  } else {
735  // otherwise, USE the optimized variant and dump the whole array
736  // into the stream as one block.
737  const char* buffer = reinterpret_cast<const char*>(array.data);
738  this->stream().write(buffer, array.getSizeInBytes());
739  }
740 
741  postReflect(prevState);
742  }
743 
744 public:
745 
746  template <typename T>
747  void write(const T* data, std::size_t count) {
748  this->stream().write(reinterpret_cast<const char*>(data),count*sizeof(T));
749  if (mLevel == 0)
750  this->flushBuffer();
751  }
752 
753 public:
754  // Codec support
755 
756 
765  if(!codec)
766  return;
767 
768  TypeId type = codec->getSupportedTypeId();
769  auto p = mCodecs.insert(std::make_pair(type, codec));
770  if(!p.second)
771  MIRA_THROW(XLogical, "A codec for the same type exists already");
772  }
773 
776  if(!codec)
777  return;
778 
779  TypeId type = codec->getSupportedTypeId();
780  auto it = mCodecs.find(type);
781  if(it==mCodecs.end())
782  return; // not registered
783 
784  if(it->second!=codec)
785  return; // not the same codec
786 
787  mCodecs.erase(it);
788  }
789 
795  template <typename T>
796  bool hasCodec() const {
797  return mCodecs.count(typeId<T>())!=0;
798  }
799 
807  template <typename T>
808  bool codec(const T& obj)
809  {
812 
813  auto it = mCodecs.find(typeId<T>());
814  if(it!=mCodecs.end()) {
815  // found codec
816  codec = it->second;
817  s = codec->getFourcc();
818  }
819 
820  if(!codec) {
821  write(s.fourcc, sizeof(s.fourcc));
822  return false;
823  }
824 
825  try {
826  // encode the data using the codec
827  const Buffer<uint8>& encodedData = codec->encode(obj);
828 
829  // write the signature of the codec not before successful encoding
830  write(s.fourcc, sizeof(s.fourcc));
831 
832  // write the encoded data immediately
833  this->stream() << encodedData;
834 
835  } catch(...) {
836 
837  // was not able to encode data, so serialize it normally
839  write(s.fourcc, sizeof(s.fourcc));
840  return false;
841  }
842 
843  // done
844  return true;
845  }
846 
847 private:
848  std::map<TypeId, BinarySerializerCodecPtr> mCodecs;
849 
850  uint32 mLevel;
851 };
852 
860 
869 
871 
927 template <typename Derived>
929 {
930 public:
933 
934  template <typename T>
935  VersionType version(VersionType version, const T* caller = NULL) {
936  return this->This()->template version<T>(version);
937  }
938 
939  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
940  VersionType version(VersionType version)) {
941  return this->template version<void>(version);
942  }
943 
944  template <typename T>
945  VersionType version(VersionType version, AcceptDesiredVersion, const T* caller = NULL)
946  {
947  return this->This()->template version<T>(version, AcceptDesiredVersion());
948  }
949 
950 public:
951  template <typename T>
952  void read(T* data, std::size_t count) {
953  this->This()->read(data,count);
954  }
955 
956 public:
962  template <typename T>
963  bool hasCodec() const {
964 #ifdef MIRA_LINUX
965  return this->This()->template hasCodec<T>();
966 #else
967  return this->This()->hasCodec<T>();
968 #endif
969  }
970 
977  template <typename T>
978  bool codec(T& obj)
979  {
980 #ifdef MIRA_LINUX
981  return this->This()->template codec(obj);
982 #else
983  return this->This()->codec(obj);
984 #endif
985  }
986 };
987 
989 
990 template <typename BinaryStream, uint8 BinaryFormatVersion>
992 
996 template <typename BinaryStream, uint8 BinaryVersionFormat>
998 {
999 };
1000 
1001 template <typename Deserializer, typename BinaryStream>
1003 {
1004 protected:
1005  typedef boost::mpl::bool_<false> requireReflectBarriers;
1006  typedef void* ReflectState;
1007 
1008  typedef int VersionType; // format version 0 had int32 serialization versions
1009 
1011  ReflectState readVersion(const char* context, Deserializer& deserializer) {
1012  return NULL;
1013  }
1014 
1016  template <typename T>
1018  VersionType v;
1019  deserializer.atomic(v);
1020  return v;
1021  }
1022 
1024  void restoreVersion(const ReflectState& prev) {}
1025 
1027  void reportVersionChecked(std::ostream& os) {}
1028 };
1029 
1030 template <typename BinaryStream>
1031 class DeserializerFormatMixin<BinaryStream, 0> :
1032  public DeserializerFormatMixin01Base<ConcreteBinaryDeserializer<BinaryStream, 0>, BinaryStream>
1033 {
1034 public:
1035  static uint8 getSerializerFormatVersion() { return 0; }
1036 
1037 protected:
1039  template <typename T>
1040  bool checkFormatVersion(T& value, bool enableTypeCheck, BinaryStream& stream) { return true; }
1041 };
1042 
1043 template <typename BinaryStream>
1044 class DeserializerFormatMixin<BinaryStream, 1> :
1045  public DeserializerFormatMixin01Base<ConcreteBinaryDeserializer<BinaryStream, 1>, BinaryStream>
1046 {
1047 public:
1048  static uint8 getSerializerFormatVersion() { return 1; }
1049 
1050 protected:
1052  template <typename T>
1053  bool checkFormatVersion(T& value, bool enableTypeCheck, BinaryStream& stream)
1054  {
1055  uint16 m;
1056  stream >> m;
1057 
1058  if (stream.fail())
1059  MIRA_THROW(XIO, "Failed to read binary format version number from binary stream: "
1060  "Reading from stream failed, e.g. empty or non-existent file.");
1061 
1062  if (m != BINARY_VERSION_MARKER)
1063  MIRA_THROW(XIO, "Failed to read binary format version number from binary stream: "
1064  "Expected marker not found, data invalid for binary format version 1.");
1065 
1066  uint8 v;
1067  stream >> v;
1068 
1069  if (v != getSerializerFormatVersion())
1070  MIRA_THROW(XIO, "BinaryDeserializer: Unhandled binary format, expected version "
1071  << (int)getSerializerFormatVersion() << ", found " << (int)v << ".");
1072 
1073  return true;
1074  }
1075 };
1076 
1077 template <typename BinaryStream>
1078 class DeserializerFormatMixin<BinaryStream, 2>
1079 {
1080 public:
1081  static uint8 getSerializerFormatVersion() { return 2; }
1082 
1084  static uint8 getDataFormatVersion(BinaryStream& stream)
1085  {
1086  uint16 m;
1087 
1088  typename BinaryStream::pos_type pos = stream.tellg();
1089 
1090  stream >> m;
1091 
1092  if (m == BINARY_VERSION_MARKER) {
1093  uint8 v;
1094  stream >> v;
1095  return v;
1096  } else {
1097  if (stream.fail())
1098  MIRA_THROW(XIO, "Failed to read binary format version number from binary stream: "
1099  "Reading from stream failed, e.g. empty or non-existent file.");
1100  // v0 did not store a version in binary data, so if we don't find it, it is v0
1101  if (pos == typename BinaryStream::pos_type(-1))
1102  MIRA_THROW(XIO, "Requiring fallback to legacy deserializer, but failing to query (and set) stream position. "
1103  "The stream type does not seem to support repositioning. "
1104  "You may try using a legacy deserializer directly, avoiding the need for setting the stream read position.");
1105  stream.seekg(pos);
1106  return 0;
1107  }
1108  }
1109 
1110 protected:
1112 
1113  // Needs to know about independent reflection blocks to read
1114  // a version number from the input for each of them.
1115  typedef boost::mpl::bool_<true> requireReflectBarriers;
1116 
1117  // State consists of a version number and a flag to know if it
1118  // was queried by the reflected object, plus context
1119  // provided to preReflect() (indicating the reflect() method
1120  // we are in, typically the typename of the reflected class).
1121  typedef std::tuple<serialization::VersionType, bool, const char*, bool> ReflectState;
1122 
1124 
1125  DeserializerFormatMixin() : mVersion(0), mContext(NULL),
1126  mUncheckedVersion(0), mUncheckedContext(NULL) {}
1127 
1132  template <typename T>
1133  bool checkFormatVersion(T& value, bool enableTypeCheck, BinaryStream& stream)
1134  {
1135  uint8 v;
1136 #ifdef CHECK_FORCE_SERIALIZE_BINARY_VERSION
1138  if (vf >= 0) {
1139  MIRA_LOG(NOTICE) << "BinaryDeserializer: Forced deserializing as binary "
1140  << "format version " << vf << ".";
1141  v = vf;
1142  if (v >= 1) // consume version data bytes from the stream
1143  getDataFormatVersion(stream); // (and ignore them)
1144  }
1145  else
1146 #endif
1147  v = getDataFormatVersion(stream);
1148 
1149 #ifndef NDEBUG
1150  if (v < getSerializerFormatVersion()) {
1151  // give a NOTICE in debug builds, else nothing (as it quickly turns into major spam,
1152  // and there is no efficient way to make sure it is displayed only once)
1153  MIRA_LOG(NOTICE) << "BinaryDeserializer: Found outdated binary format, version "
1154  << (int)v << ". Using legacy deserializer.";
1155  }
1156 #endif
1157 
1158  if (v == 0) {
1159  ConcreteBinaryDeserializer<BinaryStream, 0> v0(stream, stream.tellg());
1160  v0.deserialize(value, enableTypeCheck, true);
1161  stream.seekg(v0.streamPosition());
1162  return false;
1163  }
1164 
1165  if (v == 1) {
1166  ConcreteBinaryDeserializer<BinaryStream, 1> v1(stream, stream.tellg());
1167  v1.deserialize(value, enableTypeCheck, true);
1168  stream.seekg(v1.streamPosition());
1169  return false;
1170  }
1171 
1172  if (v != getSerializerFormatVersion()) {
1173  MIRA_THROW(XIO, "BinaryDeserializer: Unhandled binary format, expected version "
1174  << (int)getSerializerFormatVersion() << ", found " << (int)v << ".");
1175  }
1176 
1177  return true;
1178  }
1179 
1187  ReflectState readVersion(const char* context, Deserializer& deserializer) {
1188  ReflectState prevState;
1189  if ((mVersion > 0) && !mVersionChecked && (mUncheckedVersion == 0)) {
1190  mUncheckedVersion = mVersion;
1191  mUncheckedContext = mContext;
1192  prevState = std::make_tuple(mVersion, mVersionChecked, mContext, true);
1193  } else
1194  prevState = std::make_tuple(mVersion, mVersionChecked, mContext, false);
1195  deserializer.atomic(mVersion);
1196  mVersionChecked = false;
1197  mContext = context;
1198  return prevState;
1199  }
1200 
1204  template <typename T>
1206  // we could check for double query here, but rather not worth the extra work
1207  // if (mVersionChecked) {
1208  // MIRA_LOG(WARNING) << "BinaryDeserializer: version() called twice for type '"
1209  // << typeName<T>() << "'. Context = '" << (mContext ? mContext : "") << "'.";
1210  // }
1211  mVersionChecked = true;
1212  return mVersion;
1213  }
1214 
1219  void restoreVersion(const ReflectState& prev) {
1220  if ((mVersion > 0) && !mVersionChecked)
1221  MIRA_THROW(XIO, "Tried to deserialize versioned binary data (version " << (int)mVersion <<
1222  ") into unversioned type. Context = '" << (mContext ? mContext : "") << "'.");
1223  mVersion = std::get<0>(prev);
1224  mVersionChecked = std::get<1>(prev);
1225  mContext = std::get<2>(prev);
1226  if (std::get<3>(prev)) {
1227  mUncheckedVersion = 0;
1228  }
1229  }
1230 
1231  void reportVersionChecked(std::ostream& os) {
1232  if (mUncheckedVersion > 0) {
1233  os << " While trying to deserialize versioned binary data (version " << (int)mUncheckedVersion <<
1234  ") into type that is unversioned or not checking version before critical read. " <<
1235  "Context = '" << (mUncheckedContext ? mUncheckedContext : "") << "'.";
1236  } else if ((mVersion > 0) && !mVersionChecked) {
1237  os << " While trying to deserialize versioned binary data (version " << (int)mVersion <<
1238  ") into type that is unversioned or not checking version before critical read. " <<
1239  "Context = '" << (mContext ? mContext : "") << "'.";
1240  }
1241  }
1242 
1243 private:
1244  VersionType mVersion;
1245  bool mVersionChecked; // make sure the receiver of versioned data actually checks the version
1246  const char* mContext;
1247 
1248  VersionType mUncheckedVersion; // if there is some unchecked version, keep it in mind
1249  const char* mUncheckedContext; // to report when an error occurs (possibly somewhere "further down")
1250 };
1251 
1253 
1254 template <typename BinaryStream, uint8 BinaryFormatVersion>
1255 class ConcreteBinaryDeserializer : public BinaryDeserializer<ConcreteBinaryDeserializer<BinaryStream,
1256  BinaryFormatVersion> >,
1257  public BinarySerializerMixin,
1258  public DeserializerFormatMixin<BinaryStream, BinaryFormatVersion>
1259 {
1260  typedef BinaryDeserializer<ConcreteBinaryDeserializer<BinaryStream, BinaryFormatVersion> > Base;
1261  typedef DeserializerFormatMixin<BinaryStream, BinaryFormatVersion> Format;
1262 public:
1263 
1264  // We are not using human readable ids here. This will turn off the
1265  // whole id-handling system of the serialization/reflection framework
1266  // and dramatically improve the performance
1267  typedef boost::mpl::bool_<false> useHumanReadableIDs;
1268 
1270  typedef std::map<TypeId, BinarySerializerCodecPtr> CodecsMap;
1271 
1272  typedef typename Format::requireReflectBarriers requireReflectBarriers;
1273  typedef typename Format::ReflectState ReflectState;
1274 
1275 public:
1276 
1289  ConcreteBinaryDeserializer(typename BinaryStream::streambuffer_pointer buffer)
1290  : mStream(buffer) {}
1291 
1298  ConcreteBinaryDeserializer(BinaryStream& stream) : mStream(stream.rdbuf()) {}
1299 
1307  ConcreteBinaryDeserializer(BinaryStream& stream, typename BinaryStream::pos_type pos) :
1308  mStream(stream, pos) {}
1309 
1310 public:
1311 
1317  void reassign(typename BinaryStream::streambuffer_pointer buffer) {
1318  mStream = buffer;
1319  }
1320 
1321  typename BinaryStream::pos_type streamPosition() { return mStream.tellg(); }
1322 
1323 public:
1324 
1339  template <typename T>
1340  void deserialize(T& value, bool enableTypeCheck = true, bool recursive = false)
1341  {
1342  if (!recursive && !Format::checkFormatVersion(value, enableTypeCheck, mStream))
1343  return;
1344 
1345  if(enableTypeCheck) {
1346  std::string fulltypename;
1347  try {
1348  Base::deserialize("", fulltypename);
1349  }
1350  catch (...) {
1351  MIRA_THROW(XBadCast, "Failed reading type from binary data while " <<
1352  "deserializing into a variable of type '" << typeName<T>() << "'");
1353  }
1354 
1355  if(fulltypename != typeName<T>())
1356  MIRA_THROW(XBadCast, "Cannot deserialize the type '" << fulltypename <<
1357  "' into a variable of type '" << typeName<T>() << "'");
1358  }
1359  Base::deserialize("", value);
1360  }
1361 
1362 public:
1364 
1365  template <typename T>
1366  VersionType version(VersionType expectedVersion, const T* object = NULL) {
1367  VersionType version = this->template getVersion<T>(*this);
1368  if (version > expectedVersion)
1369  MIRA_THROW(XIO, "Trying to deserialize binary data of a newer version (" << (int)version <<
1370  ") of type " << typeName<T>() << " into an older version (" << (int)expectedVersion << ").");
1371  return version;
1372  }
1373 
1374  MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)",
1375  VersionType version(VersionType expectedVersion)) {
1376  return version<void>(expectedVersion);
1377  }
1378 
1380 
1381  template <typename T>
1382  VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T* object = NULL) {
1383  return this->template getVersion<T>(*this);
1384  }
1385 
1386  template<typename T>
1387  void atomic(T& member)
1388  {
1390  // read in the value from binary stream
1391  mStream >> member;
1392  if(mStream.fail()) {
1393  std::stringstream ss;
1394  ss << "Failed to read member of type '" << typeName<T>()
1395  << "' from binary stream at stream position " << streamPosition() << ".";
1396 
1397  Format::reportVersionChecked(ss);
1398 
1399  MIRA_THROW(XIO, ss.str());
1400  }
1401  }
1402 
1403  typename Format::ReflectState preReflect(const char* context = "")
1404  {
1405  return Format::readVersion(context, *this);
1406  }
1407 
1408  void postReflect(const typename Format::ReflectState& prev)
1409  {
1410  Format::restoreVersion(prev);
1411  }
1412 
1431  template<typename T>
1432  void pointer(T* &pointer)
1433  {
1434  // we always store a marker before each pointer
1435  // in Serializer::pointerReference / pointerNoReference
1436  uint8 pointerType8U;
1437  mStream >> pointerType8U;
1438 
1439  PointerType pointerType = (PointerType) pointerType8U;
1440 
1441  switch(pointerType)
1442  {
1443  case NULL_POINTER:
1444  pointer=NULL;
1445  break;
1446 
1447  case POINTER_REFERENCE:
1448  {
1449  int ref;
1450  mStream >> ref; // read the ref id
1451  // ... and resolve it
1452  pointer = this->template resolveReference<T>(ref);
1453  break;
1454  }
1455 
1456  case NORMAL_POINTER:
1457  // we have a "normal" pointer, so deserialize it
1458  mClassType.clear(); // we have no class type information here
1460  break;
1461 
1462  case POLYMORPHIC_POINTER:
1463  // we have a "polymorphic" pointer, so get class type
1464  mStream >> mClassType;
1465  // and deserialize it
1467  break;
1468  }
1469  }
1470 
1471  std::string pointerClassType() {
1472  return mClassType;
1473  }
1474 
1475 
1476  template<typename T>
1477  void invokeOverwrite(T& object)
1478  {
1479  // an object starts here - we are about to call a reflect() method
1480  static const std::string context = "invokeOverwrite " + typeName<T>();
1481  typename Format::ReflectState prevState = preReflect(context.c_str());
1482 
1483  Base::invokeOverwrite(object);
1484 
1485  // we are done with this object
1486  postReflect(prevState);
1487  }
1488 
1494  template<typename T>
1495  void invokeOverwrite(serialization::PlainArray<T>& array)
1496  {
1497  // an object starts here - we are about to call a reflect() method
1498  static const std::string context = "invokeOverwrite PlainArray<" + typeName<T>() +">";
1499  typename Format::ReflectState prevState = preReflect(context.c_str());
1500 
1501  if(this->template isTrackingEnabled<T>() || !IsBitwiseSerializable<T>::value) {
1502  // if tracking is enabled or the array's elements cannot be
1503  // serialized bitwise we cannot even think about using optimized
1504  // array deserialization
1505  Base::invokeOverwrite(array);
1506  } else {
1507 
1508  // otherwise, USE the optimized variant and read the whole array
1509  // from the stream as one block.
1510  char* buffer = reinterpret_cast<char*>(array.data);
1511  mStream.read(buffer, array.getSizeInBytes());
1512  }
1513 
1514  // we are done with this object
1515  postReflect(prevState);
1516  }
1517 
1518 public:
1519 
1520  template <typename T>
1521  void read(T* data, std::size_t count) {
1522  mStream.read(reinterpret_cast<char*>(data),count*sizeof(T));
1523  }
1524 
1525 public:
1526  // codec support
1527 
1532  template <typename T>
1533  bool hasCodec() const {
1534  //return mCodecs.count(typeId<T>())!=0;
1535  return false;
1536  }
1537 
1544  template <typename T>
1545  bool codec(T& obj)
1546  {
1549 
1550  // read the codec fourcc
1551  read(s.fourcc, sizeof(s.fourcc));
1552 
1554  return false; // no codec was used by serializer
1555 
1556  // try to find appropriate codec within our created codecs
1557  auto it = mCodecs.find(typeId<T>());
1558  if(it==mCodecs.end() || it->second->getFourcc()!=s) {
1559  // codec not found, so we must create one
1560  codec = BinarySerializerCodec::createCodec<T>(s);
1561  assert(codec);
1562  mCodecs[typeId<T>()] = codec;
1563  } else
1564  codec = it->second; // use existing codec
1565 
1566  assert(codec->getFourcc()==s);
1567  assert(codec->getSupportedTypeId()==typeId<T>());
1568 
1569  // read the encoded data
1570  Buffer<uint8> encodedData;
1571  mStream >> encodedData;
1572 
1573  // and decode
1574  codec->decode(encodedData, obj);
1575 
1576  // done
1577  return true;
1578  }
1579 
1581  const CodecsMap& getCodecs() const {
1582  return mCodecs;
1583  }
1584 
1586  void setCodecs(const CodecsMap& codecs) {
1587  mCodecs = codecs;
1588  }
1589 
1590 private:
1591 
1592  BinaryStream mStream;
1593  std::string mClassType;
1594 
1595  CodecsMap mCodecs;
1596 };
1597 
1606 
1615 
1617 
1618 } // namespace
1619 
1620 #endif
ConcreteBinarySerializer< BinaryBufferOstream, 2 > BinaryBufferSerializer
Typedef for BinarySerializer based on a Buffer.
Definition: BinarySerializer.h:858
boost::mpl::bool_< false > useHumanReadableIDs
Definition: BinarySerializer.h:553
ConcreteBinaryDeserializer< BinaryBufferIstream, 2 > BinaryBufferDeserializer
Typedef for BinaryDeserializer based on a Buffer.
Definition: BinarySerializer.h:1603
bool checkFormatVersion(T &value, bool enableTypeCheck, BinaryStream &stream)
Verify expected version data.
Definition: BinarySerializer.h:1053
ConcreteBinaryDeserializer< BinaryStlIstream, 2 > BinaryStreamDeserializer
Typedef for BinaryDeserializer based on a stl stream.
Definition: BinarySerializer.h:1612
Format::ReflectState ReflectState
Definition: BinarySerializer.h:556
Base::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:628
void restoreVersionPtr(const ReflectState &prev)
Do nothing.
Definition: BinarySerializer.h:368
Definition: BinarySerializer.h:324
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:1123
bool checkFormatVersion(T &value, bool enableTypeCheck, BinaryStream &stream)
Always accepts the input itself.
Definition: BinarySerializer.h:1040
Base::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:1379
Typedefs for OS independent basic data types.
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType expectedVersion))
Definition: BinarySerializer.h:1374
ConcreteBinarySerializer(BinaryStream &stream)
Create a new binary serializer and assign it to the specified binary output stream.
Definition: BinarySerializer.h:581
bool codec(T &obj)
Decodes the specified object from the serialized data.
Definition: BinarySerializer.h:1545
void pointer(T *&pointer)
Overwrites Deserializer::pointer.
Definition: BinarySerializer.h:1432
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:1495
ReflectorInterface< ConcreteBinarySerializer< mira::BinaryOstream, BinaryFormatVersion, false > >::VersionType VersionType
Definition: AbstractReflector.h:170
Format::ReflectState ReflectState
Definition: BinarySerializer.h:1273
void invokeOverwrite(T &object)
The actual invoke implementation, that may also be overwritten in derived classes to add additional f...
Definition: AbstractReflector.h:276
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:1006
ConcreteBinaryDeserializer(typename BinaryStream::streambuffer_pointer buffer)
Create a new binary deserializer based on the specified stream buffer object.
Definition: BinarySerializer.h:1289
VersionType version(VersionType version, const T *caller=NULL)
Definition: BinarySerializer.h:267
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:871
static size_t formatVersionOverhead()
Overhead 3 bytes with each serialize().
Definition: BinarySerializer.h:412
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:1133
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:528
bool hasCodec() const
Returns true, of there is a codec for the specified type T.
Definition: BinarySerializer.h:796
Definition: BinarySerializer.h:90
Used by BinaryDeserializer, see SerializerFormatMixin above.
Definition: BinarySerializer.h:997
#define BINARY_VERSION_MARKER
Definition: BinarySerializer.h:70
void pointerWithoutClassType()
Definition: BinarySerializer.h:681
void write(const T *data, std::size_t count)
Definition: BinarySerializer.h:747
void invokeOverwrite(serialization::PlainArray< T > &array)
Specialized for PlainArray to implement an optimized variant for serializing array, if possible (i.e.
Definition: BinarySerializer.h:724
VersionType getVersion(Deserializer &deserializer)
Get version value read at start of object.
Definition: BinarySerializer.h:1205
Definition: BinarySerializer.h:991
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:1048
Direct stream access.
Definition: BinarySerializer.h:128
Definition: BinarySerializer.h:344
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:1084
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:1035
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:1187
Definition: BinarySerializer.h:89
Used by BinarySerializer and BinaryDeserializer.
Definition: BinarySerializer.h:79
boost::mpl::bool_< false > useHumanReadableIDs
Definition: BinarySerializer.h:1267
Get compiler and platform independent typenames.
ConcreteBinarySerializer< BinaryStlOstream, 0 > BinaryStreamSerializerLegacy
Definition: BinarySerializer.h:868
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:1024
StreamAccessMixinBase(typename BinaryStream::streambuffer_pointer buffer)
Definition: BinarySerializer.h:105
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:1081
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:81
void reassign(typename BinaryStream::streambuffer_pointer buffer)
Reassigns the specified stream buffer to this deserializer.
Definition: BinarySerializer.h:1317
void serialize(const T &value, bool enableTypeCheck=true)
Provides a special serialize interface for the BinarySerializer.
Definition: BinarySerializer.h:598
bool codec(const T &obj)
Encodes the specified object containing the data using a matching codec.
Definition: BinarySerializer.h:311
BinaryBufferOstream SimpleStreamType
Definition: BinarySerializer.h:546
ConcreteBinaryDeserializer< BinaryBufferIstream, 0 > BinaryBufferDeserializerLegacy
Definition: BinarySerializer.h:1605
ConcreteBinaryDeserializer< BinaryStlIstream, 1 > BinaryStreamDeserializerLegacyMarked
Definition: BinarySerializer.h:1613
void pointerReference(int referencedObjectID)
Definition: BinarySerializer.h:670
Derived * This()
"Curiously recurring template pattern" (CRTP).
Definition: AbstractReflector.h:251
Format::requireReflectBarriers requireReflectBarriers
Definition: BinarySerializer.h:1272
bool writeFormatVersion(T &value, bool enableTypeCheck, StreamType &stream)
Write the format version number into the binary output.
Definition: BinarySerializer.h:397
boost::mpl::bool_< false > requireReflectBarriers
Definition: BinarySerializer.h:351
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:376
Used by BinarySerializer, defines the binary format in particular for class versioning information: 0...
Definition: BinarySerializer.h:339
bool hasCodec() const
Supported for compatibility with BinarySerializer in a common reflect method.
Definition: BinarySerializer.h:1533
DeserializerFormatMixin()
Definition: BinarySerializer.h:1125
ReflectState insertVersionPlaceholder(const char *context, Serializer &serializer, StreamType &stream)
Do nothing.
Definition: BinarySerializer.h:357
boost::mpl::bool_< true > requireReflectBarriers
Definition: BinarySerializer.h:1115
Definition: BinarySerializer.h:1002
Format::VersionType VersionType
Definition: BinarySerializer.h:1363
void registerCodec(BinarySerializerCodecPtr codec)
Registers the specified codec instance in this binary serializer.
Definition: BinarySerializer.h:764
ConcreteBinaryDeserializer< BinaryStlIstream, 0 > BinaryStreamDeserializerLegacy
Definition: BinarySerializer.h:1614
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:499
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:928
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:381
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:392
Format::ReflectState preReflect(const char *context="")
Definition: BinarySerializer.h:648
Contains base class for all deserializers.
const CodecsMap & getCodecs() const
Return the map of currently known codecs.
Definition: BinarySerializer.h:1581
void invokeOverwrite(T &object)
Definition: BinarySerializer.h:708
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:1366
Tag class used as parameter to ReflectorInterface::version() etc.
Definition: ReflectorInterface.h:80
ReflectorInterface< ConcreteBinarySerializer< mira::BinaryOstream, BinaryFormatVersion, false > >::AcceptDesiredVersion AcceptDesiredVersion
Definition: AbstractReflector.h:200
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:479
void restoreVersion(const ReflectState &prev)
Restore a previous version value.
Definition: BinarySerializer.h:1219
boost::mpl::bool_< false > requireReflectBarriers
Definition: BinarySerializer.h:1005
Base class for codecs for BinarySerializer and BinaryDeserializer.
void write(const T *data, std::size_t count)
Definition: BinarySerializer.h:284
ConcreteBinaryDeserializer< BinaryBufferIstream, 1 > BinaryBufferDeserializerLegacyMarked
Definition: BinarySerializer.h:1604
std::tuple< typename StreamType::pos_type, bool, const char * > ReflectState
Definition: BinarySerializer.h:424
void read(T *data, std::size_t count)
Definition: BinarySerializer.h:1521
ConcreteBinarySerializer(typename BinaryStream::streambuffer_pointer buffer)
Create a new binary serializer based on the specified stream buffer object.
Definition: BinarySerializer.h:571
serialization::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:264
void pointerNull()
Definition: BinarySerializer.h:703
VersionType version(VersionType version, AcceptDesiredVersion, const T *caller=NULL)
Definition: BinarySerializer.h:945
int TypeId
The type of the integral TypeId, that can be retrieved by typeId<T>()
Definition: TypeId.h:64
ConcreteBinarySerializer< BinaryStlOstream, 2, true > BufferedBinaryStreamSerializer
Definition: BinarySerializer.h:867
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:1307
void setCodecs(const CodecsMap &codecs)
Set the map of known codecs.
Definition: BinarySerializer.h:1586
VersionType version(VersionType version, const T *caller=NULL)
Definition: BinarySerializer.h:617
ReflectState readVersion(const char *context, Deserializer &deserializer)
Do nothing.
Definition: BinarySerializer.h:1011
ConcreteBinarySerializer< BinaryBufferOstream, 0 > BinaryBufferSerializerLegacy
Definition: BinarySerializer.h:859
VersionType version(VersionType version, const T *caller=NULL)
Definition: BinarySerializer.h:935
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:1017
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:963
Contains the BinaryIStream and BinaryOStream classes for fast and efficient streaming of binary data...
static size_t formatVersionOverhead()
Zero overhead here.
Definition: BinarySerializer.h:348
Format::ReflectState preReflect(const char *context="")
Definition: BinarySerializer.h:1403
int VersionType
Definition: BinarySerializer.h:1008
void restoreVersionPtr(const ReflectState &prev)
Restore a previous version placeholder position.
Definition: BinarySerializer.h:516
BinaryStream::pos_type streamPosition()
Definition: BinarySerializer.h:1321
void atomic(T &member)
Definition: BinarySerializer.h:1387
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:654
void deserialize(T &value, bool enableTypeCheck=true, bool recursive=false)
Provides a special deserialize interface for the BinaryDeserializer.
Definition: BinarySerializer.h:1340
void pointerWithClassType(const std::string &type)
Definition: BinarySerializer.h:693
ConcreteBinarySerializer< BinaryStream, 2, Buffered > Serializer
Definition: BinarySerializer.h:414
bool codec(T &obj)
Decodes the specified object from the serialized data.
Definition: BinarySerializer.h:978
VersionType version(VersionType expectedVersion, AcceptDesiredVersion, const T *object=NULL)
Definition: BinarySerializer.h:1382
Definition: BinarySerializer.h:257
Format::VersionType VersionType
Definition: BinarySerializer.h:614
ConcreteBinaryDeserializer(BinaryStream &stream)
Create a new binary deserializer and read the data from the specified binary stream.
Definition: BinarySerializer.h:1298
BinarySerializerTag Tag
Definition: BinarySerializer.h:260
std::tuple< serialization::VersionType, bool, const char *, bool > ReflectState
Definition: BinarySerializer.h:1121
ConcreteBinarySerializer< BinaryStlOstream, 2 > BinaryStreamSerializer
Typedef for BinarySerializer based on STL streams.
Definition: BinarySerializer.h:866
Format::requireReflectBarriers requireReflectBarriers
Definition: BinarySerializer.h:555
serialization::VersionType VersionType
Definition: BinarySerializer.h:931
void read(T *data, std::size_t count)
Definition: BinarySerializer.h:952
ConcreteBinaryDeserializer< BinaryStream, 2 > Deserializer
Definition: BinarySerializer.h:1111
void * ReflectState
Definition: BinarySerializer.h:352
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:418
BinaryBufferOstream StreamType
The type of stream the serializer writes to (the buffer stream here).
Definition: BinarySerializer.h:160
std::string pointerClassType()
Definition: BinarySerializer.h:1471
bool writeFormatVersion(T &value, bool enableTypeCheck, StreamType &stream)
Write the format version number into the binary output.
Definition: BinarySerializer.h:432
static Fourcc null()
Returns the &#39;NULL&#39; fourcc.
Definition: BinarySerializerCodec.h:142
void reportVersionChecked(std::ostream &os)
Definition: BinarySerializer.h:1231
void postReflect(const typename Format::ReflectState &prev)
Definition: BinarySerializer.h:1408
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType version))
Definition: BinarySerializer.h:623
serialization::AcceptDesiredVersion AcceptDesiredVersion
Definition: BinarySerializer.h:932
PointerType
Pointer type that is stored as 1-byte marker before storing the pointer.
Definition: BinarySerializer.h:86
serialization::VersionType VersionType
Definition: BinarySerializer.h:426
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:269
MIRA_DEPRECATED("Please call as version<MyType>(v) or version(v, this)", VersionType version(VersionType version))
Definition: BinarySerializer.h:939
void atomic(T &member)
Definition: BinarySerializer.h:641
void unregisterCodec(BinarySerializerCodecPtr codec)
Removes a previously registered codec.
Definition: BinarySerializer.h:775
static uint8 getSerializerFormatVersion()
Definition: BinarySerializer.h:409
void invokeOverwrite(T &object)
Definition: BinarySerializer.h:1477
Definition: LoggingCore.h:76
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:808
void writeVersion(VersionType version, Serializer &serializer, StreamType &stream)
Write version directly to stream.
Definition: BinarySerializer.h:363
std::map< TypeId, BinarySerializerCodecPtr > CodecsMap
A map of binary serialization codecs.
Definition: BinarySerializer.h:1270
void reportVersionChecked(std::ostream &os)
Do nothing.
Definition: BinarySerializer.h:1027
int VersionType
Definition: BinarySerializer.h:354
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:631
StreamAccessMixinBase(BinaryStream &stream)
Definition: BinarySerializer.h:108