Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
serializer_binary.h
1 //############################################################################
2 // Binaryシリアライザ
3 /*
4  © 2016 Theoride Technology (http://theolizer.com/) All Rights Reserved.
5  "Theolizer" is a registered trademark of Theoride Technology.
6 
7  "Theolizer" License
8  In the case where you are in possession of a valid “Theolizer” License,
9  you may use this file in accordance with the terms and conditions of
10  the use license determined by Theoride Technology.
11 
12  General Public License Version 3 ("GPLv3")
13  You may use this file in accordance with the terms and conditions of
14  GPLv3 published by Free Software Foundation.
15  Please confirm the contents of GPLv3 at https://www.gnu.org/licenses/gpl.txt .
16  A copy of GPLv3 is also saved in a LICENSE.TXT file.
17 
18  商用ライセンス
19  あなたが有効なTheolizer商用ライセンスを保持している場合、
20  セオライド テクノロジーの定める使用許諾書の条件に従って、
21  このファイルを取り扱うことができます。
22 
23  General Public License Version 3(以下GPLv3)
24  Free Software Foundationが公表するGPLv3の使用条件に従って、
25  あなたはこのファイルを取り扱うことができます。
26  GPLv3の内容を https://www.gnu.org/licenses/gpl.txt にて確認して下さい。
27  またGPLv3のコピーをLICENSE.TXTファイルにおいてます。
28 */
29 //############################################################################
30 
31 #if !defined(THEOLIZER_INTERNAL_SERIALIZER_BINARY_H)
32 #define THEOLIZER_INTERNAL_SERIALIZER_BINARY_H
33 
34 #include "serializer.h"
35 
36 //############################################################################
37 // Begin
38 //############################################################################
39 
40 // ***************************************************************************
41 // 警告抑止
42 // ***************************************************************************
43 
44 #ifdef _MSC_VER
45  #pragma warning(push)
46  #pragma warning(disable:4100 4251 4702)
47 #endif
48 
49 namespace theolizer
50 {
51 
52 //############################################################################
53 // 共通定義
54 //############################################################################
55 
56 namespace internal
57 {
58 #ifndef THEOLIZER_INTERNAL_DOXYGEN
59 
60 // ***************************************************************************
61 // タグ・コード定義
62 // ***************************************************************************
63 
64 class BinaryTag
65 {
66 public:
67  enum TagCode : uint8_t
68  {
69  KindMask = 0xf0, // 種別マスク
70  SizeMask = 0x0f, // サイズマスク
71 
72  None = 0x00, // 未設定
73  Primitive = 0x10, // プリミティブ
74  Primitive1 = 0x11, // 1バイトのプリミティブ
75  Primitive2 = 0x12, // 2バイトのプリミティブ
76  Primitive4 = 0x13, // 4バイトのプリミティブ
77  Primitive8 = 0x14, // 8バイトのプリミティブ
78  Primitive10 = 0x15, // 10バイトのプリミティブ
79 
80  MinusValue = 0x20, // 負の整数の絶対値
81  MinusValue1 = 0x21, // 1バイトの負の整数の絶対値
82  MinusValue2 = 0x22, // 2バイトの負の整数の絶対値
83  MinusValue4 = 0x23, // 4バイトの負の整数の絶対値
84  MinusValue8 = 0x24, // 8バイトの負の整数の絶対値
85  MinusValue10 = 0x25, // 10バイトの負の整数の絶対値
86 
87  ByteString = 0x30, // バイト列
88  ByteString1 = 0x31, // バイト列(長さフィールド= 1バイト)
89  ByteString2 = 0x32, // バイト列(長さフィールド= 2バイト)
90  ByteString4 = 0x33, // バイト列(長さフィールド= 4バイト)
91  ByteString8 = 0x34, // バイト列(長さフィールド= 8バイト)
92  ByteString10 = 0x35, // バイト列(長さフィールド=10バイト)
93 
94  ClassEnd = 0x40, // クラス終了マーク
95  ClassStartName = 0x50, // クラス開始マーク(名前対応)
96  ClassStartOrder = 0x60 // クラス開始マーク(順序対応)
97  };
98 
99 private:
100  TagCode mTagCode; // タグ・コード
101 
102  TagCode getByteSize(TagCode iTagKind, unsigned iSize)
103  {
104  switch(iSize)
105  {
106  case 0: return static_cast<TagCode>(iTagKind | 0);
107  case 1: return static_cast<TagCode>(iTagKind | 1);
108  case 2: return static_cast<TagCode>(iTagKind | 2);
109  case 4: return static_cast<TagCode>(iTagKind | 3);
110  case 8: return static_cast<TagCode>(iTagKind | 4);
111  case 10: return static_cast<TagCode>(iTagKind | 5);
112  }
113  THEOLIZER_INTERNAL_ABORT(u8"Illegal size in BinaryTag::getByteSize().");
114  }
115 
116 public:
117  BinaryTag() : mTagCode(None) { }
118  BinaryTag(TagCode iTagCode) : mTagCode(iTagCode) { }
119  BinaryTag(TagCode iTagKind, unsigned iSize) :
120  mTagCode(getByteSize(iTagKind, iSize))
121  { }
122 
123  BinaryTag(uint8_t iByte) : mTagCode(static_cast<TagCode>(iByte)) { }
124  operator TagCode() const {return mTagCode;}
125  operator uint8_t() const {return mTagCode;}
126  unsigned get() const {return mTagCode;}
127  BinaryTag& operator=(uint8_t iByte)
128  {
129  mTagCode=static_cast<TagCode>(iByte);
130  return *this;
131  }
132 
133  bool isPrimitive() const
134  {
135  return ((mTagCode&KindMask)==Primitive)||(mTagCode&KindMask)==MinusValue;
136  }
137  bool isMinusValue() const {return (mTagCode&KindMask) == MinusValue;}
138  bool isByteString() const {return (mTagCode&KindMask) == ByteString;}
139  bool isClassEnd() const {return (mTagCode == ClassEnd);}
140  bool isClassStart() const {return (mTagCode==ClassStartName)||(mTagCode==ClassStartOrder);}
141  bool isClassStartName() const {return (mTagCode==ClassStartName);}
142  bool isClassStartOrder() const {return (mTagCode==ClassStartOrder);}
143  bool isTagCode(TagCode iTagCode) const {return (mTagCode == iTagCode);}
144 
145  TagCode getKind() const
146  {
147  return static_cast<TagCode>(mTagCode & KindMask);
148  }
149 
150  unsigned getSize() const
151  {
152  switch(mTagCode & SizeMask)
153  {
154  case 0: return 0;
155  case 1: return 1;
156  case 2: return 2;
157  case 3: return 4;
158  case 4: return 8;
159  case 5: return 10;
160  }
161  THEOLIZER_INTERNAL_DATA_ERROR(u8"Illegal BinaryTag size(TagCode=0x%02x).", get());
162 
163  return 0;
164  }
165 };
166 
167 // ***************************************************************************
168 // Binaryシリアライザのバージョン番号とシリアライザ名
169 // 注意事項:
170 // このバージョンはサイズに「幅」がない。(厳密に一致することが必要)
171 // 余裕を持たせる場合、下記工夫が必要
172 // シリアライズ時は実型を表現できるシリアライズ型へ
173 // デシリアライズ時はシリアライズ型を表現できる実型へ
174 // そこそこ手間が掛かりそうななので、必要が生じたら対応を検討する
175 // long doubleはdouble形式で保存する
176 // ***************************************************************************
177 
178 const static char kBinarySerializerName[]="BinaryTheolizer";
179 const static unsigned kBinarySerializerVersionNo=1;
180 
181 // ***************************************************************************
182 // プロバティ返却
183 // 必要な場合直接見えた方が良いのでここで定義
184 // ***************************************************************************
185 
186 inline bool hasPropertyBinary(Property iProperty, bool iIsSaver)
187 {
188  bool ret=false;
189  switch(iProperty)
190  {
191  case Property::IsSaver:
192  ret=iIsSaver;
193  break;
194 
195  case Property::EncodedString:
196  ret=false;
197  break;
198 
199  case Property::SupportModifying:
200  ret=true;
201  break;
202 
203  case Property::BinaryOpen:
204  ret=true;
205  break;
206  }
207 
208  return ret;
209 }
210 
211 // ***************************************************************************
212 // プリミティブ(組み込み型)名生成
213 // ***************************************************************************
214 
215 class BinaryMidOSerializer;
216 class BinaryMidISerializer;
217 
218 #define THEOLIZER_INTERNAL_INTEGRAL(dSigned, dDigits, dName1) \
219  template<class tMidSerializer, typename tPrimitive> \
220  struct PrimitiveName \
221  < \
222  tMidSerializer, \
223  tPrimitive, \
224  EnableIf \
225  < \
226  (std::is_same<tMidSerializer, BinaryMidOSerializer>::value \
227  || std::is_same<tMidSerializer, BinaryMidISerializer>::value) \
228  && (std::numeric_limits<tPrimitive>::is_signed == dSigned) \
229  && (std::numeric_limits<tPrimitive>::radix == 2) \
230  && (std::numeric_limits<tPrimitive>::digits == dDigits) \
231  && (std::numeric_limits<tPrimitive>::max_exponent == 0) \
232  > \
233  > \
234  { \
235  static char const* getPrimitiveName(unsigned iSerializerVersionNo) \
236  { \
237  switch(iSerializerVersionNo) \
238  { \
239  case 1: return dName1; \
240  } \
241  THEOLIZER_INTERNAL_ABORT("getPrimitiveName() : iVersionNo is illegal.");\
242  return ""; \
243  } \
244  }
245 
246 #define THEOLIZER_INTERNAL_FLOAT(dDigits, dMaxExponent, dName1) \
247  template<class tMidSerializer, typename tPrimitive> \
248  struct PrimitiveName \
249  < \
250  tMidSerializer, \
251  tPrimitive, \
252  EnableIf \
253  < \
254  (std::is_same<tMidSerializer, BinaryMidOSerializer>::value \
255  || std::is_same<tMidSerializer, BinaryMidISerializer>::value) \
256  && (std::numeric_limits<tPrimitive>::is_signed == 1) \
257  && (std::numeric_limits<tPrimitive>::radix == 2) \
258  && (std::numeric_limits<tPrimitive>::digits == dDigits) \
259  && (std::numeric_limits<tPrimitive>::max_exponent == dMaxExponent)\
260  > \
261  > \
262  { \
263  static char const* getPrimitiveName(unsigned iSerializerVersionNo) \
264  { \
265  switch(iSerializerVersionNo) \
266  { \
267  case 1: return dName1; \
268  } \
269  THEOLIZER_INTERNAL_ABORT("getPrimitiveName() : iVersionNo is illegal.");\
270  return ""; \
271  } \
272  }
273 
274 #define THEOLIZER_INTERNAL_STRING(dBytes, dName1) \
275  template<class tMidSerializer, typename tPrimitive> \
276  struct PrimitiveName \
277  < \
278  tMidSerializer, \
279  tPrimitive, \
280  EnableIf \
281  < \
282  (std::is_same<tMidSerializer, BinaryMidOSerializer>::value \
283  || std::is_same<tMidSerializer, BinaryMidISerializer>::value) \
284  && (IsString<tPrimitive>::value) \
285  && (sizeof(typename tPrimitive::value_type) == dBytes) \
286  > \
287  > \
288  { \
289  static char const* getPrimitiveName(unsigned iSerializerVersionNo) \
290  { \
291  switch(iSerializerVersionNo) \
292  { \
293  case 1: return dName1; \
294  } \
295  THEOLIZER_INTERNAL_ABORT("getPrimitiveName() : iVersionNo is illegal.");\
296  return ""; \
297  } \
298  }
299 
300 THEOLIZER_INTERNAL_INTEGRAL(0, 1, "bool");
301 
302 THEOLIZER_INTERNAL_INTEGRAL(1, 7, "int8");
303 THEOLIZER_INTERNAL_INTEGRAL(1, 15, "int16");
304 THEOLIZER_INTERNAL_INTEGRAL(1, 31, "int32");
305 THEOLIZER_INTERNAL_INTEGRAL(1, 63, "int64");
306 
307 THEOLIZER_INTERNAL_INTEGRAL(0, 8, "unit8");
308 THEOLIZER_INTERNAL_INTEGRAL(0, 16, "uint16");
309 THEOLIZER_INTERNAL_INTEGRAL(0, 32, "uint32");
310 THEOLIZER_INTERNAL_INTEGRAL(0, 64, "uint64");
311 
312 THEOLIZER_INTERNAL_FLOAT(24, 128, "float32");
313 THEOLIZER_INTERNAL_FLOAT(53, 1024, "float64");
314 THEOLIZER_INTERNAL_FLOAT(64, 16384, "float80");
315 
316 THEOLIZER_INTERNAL_STRING(1, "String");
317 THEOLIZER_INTERNAL_STRING(2, "U16string");
318 THEOLIZER_INTERNAL_STRING(4, "U32string");
319 
320 #undef THEOLIZER_INTERNAL_INTEGRAL
321 #undef THEOLIZER_INTERNAL_FLOAT
322 #undef THEOLIZER_INTERNAL_STRING
323 
324 //----------------------------------------------------------------------------
325 // プリミティブ名からC++名へ変換
326 //----------------------------------------------------------------------------
327 
328 #ifdef THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
329 THEOLIZER_INTERNAL_DLL
330 char const* getCppNameBinary(std::string const& iPrimitiveName, unsigned iSerializerVersionNo);
331 #endif // THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
332 
333 #endif // THEOLIZER_INTERNAL_DOXYGEN
334 //############################################################################
335 // Binary Serializer実装部
336 // プリミティブの注意事項
337 // エンディアンの相違は吸収する(並び順は整数型で決まるものとする)
338 // 符号付き整数型の負数はタグで負数を示し、絶対値表現
339 // 浮動小数点型はIEEE754形式
340 // 整数型のサイズは1, 2, 4, 8Bytes
341 // 浮動小数点型のサイズは4, 8Bytes
342 //
343 // 内部表現も上記の通りと仮定する
344 //############################################################################
345 
346 // ***************************************************************************
347 /*!
348 @brief 保存用中間BinarySerializer
349 @details 主な処理はここで行うが、インスタンスを作れないよう抽象クラスとする。
350 */
351 // ***************************************************************************
352 
353 class THEOLIZER_INTERNAL_DLL BinaryMidOSerializer : public BaseSerializer
354 {
355 private:
356  friend class BaseSerializer;
357  THEOLIZER_INTERNAL_FRIENDS_FOR_INTERNAL;
358 
359 //----------------------------------------------------------------------------
360 // 基本
361 //----------------------------------------------------------------------------
362 
363  std::ostream& mOStream;
364 
365  static const unsigned kLastVersionNo=kBinarySerializerVersionNo;
366 
368  typedef BinaryMidOSerializer MetaOSerializer; // メタ・シリアライザ
369  typedef BinaryMidISerializer MetaISerializer; // メタ・デシリアライザ
370 
371 protected:
372  static char const* const kSerializerName;
373  static std::ios_base::openmode kOpenMode;
374 
376  (
377  std::ostream& iOStream,
378  Destinations const& iDestinations,
379  GlobalVersionNoTableBase const*const iGlobalVersionNoTable,
380  unsigned iGlobalVersionNo,
381  unsigned iLastGlobalVersionNo,
382  CheckMode iCheckMode,
383  bool iNoThrowException
384  );
385 
386 //----------------------------------------------------------------------------
387 // 型情報保存
388 //----------------------------------------------------------------------------
389 
390 private:
391 
392 // ---<<< ヘッダ保存 >>>---
393 
394  void writeHeader();
395 
396 //----------------------------------------------------------------------------
397 // データ保存
398 //----------------------------------------------------------------------------
399 
400 // ---<<< 制御情報保存 >>>---
401 
402  void saveSigned(long long iControl);
403  void saveUnsigned
404  (
405  unsigned long long iControl,
406  BinaryTag::TagCode iTagCode=BinaryTag::TagCode::Primitive
407  );
408 
409  void saveControl(int iControl) {saveSigned(iControl);}
410  void saveControl(long iControl) {saveSigned(iControl);}
411  void saveControl(long long iControl) {saveSigned(iControl);}
412  void saveControl(unsigned iControl) {saveUnsigned(iControl);}
413  void saveControl(unsigned long iControl) {saveUnsigned(iControl);}
414  void saveControl(unsigned long long iControl) {saveUnsigned(iControl);}
415  void saveControl(std::string const& iControl) {saveByteString(iControl);}
416 
417 // ---<<< プリミティブ保存 >>>---
418 
419  template<typename tType>
420  void saveFloat(tType iFloat);
421 
422  #define THEOLIZER_INTERNAL_DEF_SAVE
423  #include "internal/primitive.inc"
424 
425 // ---<<< バイト列保存 >>>---
426 
427  void saveByteString(std::string const& iString);
428 
429 // ---<<< Element前処理 >>>---
430 
431  void writePreElement(bool iDoProcess=false) { }
432 
433 //----------------------------------------------------------------------------
434 // 内部処理
435 //----------------------------------------------------------------------------
436 
437 private:
438 
439 // ---<<< グループ処理 >>>---
440 
441  void saveGroupStart(bool iIsTop=false);
442  void saveGroupEnd(bool iIsTop=false);
443 
444 // ---<<< 各種構造処理 >>>---
445 
446  void saveStructureStart(Structure iStructure, std::string& ioTypeName, std::size_t iOjbectId);
447  void saveStructureEnd(Structure iStructure, std::string const& iTypeName);
448 
449 // ---<<< プリミティブ名返却 >>>---
450 
451  template<typename tType>
452  static char const* getPrimitiveName(unsigned iSerializerVersionNo)
453  {
454  static_assert(Ignore<tType>::kFalse, "Unknown primitive name.");
455  return "";
456  }
457 
458 // ---<<< Element名保存 >>>---
459 // 名前対応時のみ保存する
460 
461  void saveElementName(ElementsMapping iElementsMapping, char const* iElementName)
462  {
463  if (iElementsMapping == emName)
464  {
465  saveByteString(iElementName);
466  }
467  }
468 
469 // ---<<< 1バイト書き込み >>>---
470 
471  void writeByte(uint8_t iByte);
472 
473 // ---<<< プリミティブ名からC++型名返却 >>>---
474 
475 #ifdef THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
476  static char const* getCppName(std::string const& iPrimitiveName, unsigned iSerializerVersionNo)
477  {
478  return getCppNameBinary(iPrimitiveName, iSerializerVersionNo);
479  }
480 #endif // THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
481 };
482 #ifndef THEOLIZER_INTERNAL_DOXYGEN
483 
484 //----------------------------------------------------------------------------
485 // プリミティブ名返却
486 //----------------------------------------------------------------------------
487 
488 #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSymbol) \
489  template<> \
490  inline char const* BinaryMidOSerializer:: \
491  getPrimitiveName<dType>(unsigned iSerializerVersionNo) \
492  { \
493  return PrimitiveName<BinaryMidOSerializer, dType>::getPrimitiveName(iSerializerVersionNo);\
494  }
495 #include "internal/primitive.inc"
496 
497 #endif // THEOLIZER_INTERNAL_DOXYGEN
498 // ***************************************************************************
499 /*!
500 @brief 回復用中間BinarySerializer
501 @details 主な処理はここで行うが、インスタンスを作れないよう抽象クラスとする。
502 */
503 // ***************************************************************************
504 
505 class THEOLIZER_INTERNAL_DLL BinaryMidISerializer : public BaseSerializer
506 {
507 private:
508  friend class BaseSerializer;
509  THEOLIZER_INTERNAL_FRIENDS_FOR_INTERNAL;
510 
511 //----------------------------------------------------------------------------
512 // 基本
513 //----------------------------------------------------------------------------
514 
515  std::istream& mIStream;
516  bool mTerminated;
517  BinaryTag mBinaryTag;
518 
519  static const unsigned kLastVersionNo=kBinarySerializerVersionNo;
520 
522  typedef BinaryMidOSerializer MetaOSerializer; // メタ・シリアライザ
523  typedef BinaryMidISerializer MetaISerializer; // メタ・デシリアライザ
524 
525 protected:
526  static char const* const kSerializerName;
527  static std::ios_base::openmode kOpenMode;
528 
530  (
531  std::istream& iIStream,
532  Destinations const& iDestinations,
533  GlobalVersionNoTableBase const*const iGlobalVersionNoTable,
534  unsigned iLastGlobalVersionNo,
535  std::ostream* iOStream,
536  bool iNoThrowException
537  );
538 
539 //----------------------------------------------------------------------------
540 // ヘッダ回復と型チェック
541 //----------------------------------------------------------------------------
542 
543 private:
544 
545 // ---<<< ヘッダ情報回復 >>>---
546 
547  void readHeader();
548 
549 // ---<<< TypeIndex一致判定 >>>---
550 
551  bool isMatchTypeIndex(size_t iSerializedTypeIndex,
552  size_t iProgramTypeIndex);
553 
554 //----------------------------------------------------------------------------
555 // データ回復
556 //----------------------------------------------------------------------------
557 
558 // ---<<< 制御情報回復 >>>---
559 
560  long long loadSigned();
561  unsigned long long loadUnsigned(BinaryTag::TagCode iTagCode=BinaryTag::TagCode::Primitive);
562 
563  void loadControl(int& oControl) {oControl=static_cast<int>(loadSigned());}
564  void loadControl(long& oControl) {oControl=static_cast<long>(loadSigned());}
565  void loadControl(long long& oControl) {oControl=loadSigned();}
566  void loadControl(unsigned& oControl) {oControl=static_cast<unsigned>(loadSigned());}
567  void loadControl(unsigned long& oControl) {oControl=static_cast<unsigned long>(loadSigned());}
568  void loadControl(unsigned long long& oControl) {oControl=loadSigned();}
569  void loadControl(std::string& oControl) {loadByteString(oControl);}
570 
571 // ---<<< プリミティブ回復 >>>---
572 
573  template<typename tType>
574  void loadFloat(tType& oFloat);
575 
576  #define THEOLIZER_INTERNAL_DEF_LOAD
577  #include "internal/primitive.inc"
578 
579 // ---<<< バイト列回復 >>>---
580 
581  void loadByteString(std::string& iString);
582 
583 // ---<<< Element前処理 >>>---
584 // 戻り値:
585 // 次がないなら、Terminated(mTerminated=true)
586 // 次があるなら、Continue (mTerminated=false)
587 // それ以外なら、例外
588 
589  ReadStat readPreElement(bool iDoProcess=false);
590 
591 // ---<<< 要素破棄処理 >>>---
592 
593  void disposeElement();
594 
595 //----------------------------------------------------------------------------
596 // 内部処理
597 //----------------------------------------------------------------------------
598 
599 private:
600 
601 // ---<<< グループ処理 >>>---
602 // loadGroupEnd()呼び出し以前に、readPreElement()呼び出しにより、
603 // mTerminatedをtrueにしておくこと。
604 
605  void loadGroupStart(bool iIsTop=false);
606  void loadGroupEnd(bool iIsTop=false);
607 
608 // ---<<< 各種構造処理 >>>---
609 
610  void loadStructureStart(Structure iStructure, std::string& ioTypeName, std::size_t* oObjectId);
611  void loadStructureEnd(Structure iStructure, std::string const& iTypeName);
612 
613 // ---<<< プリミティブ名返却 >>>---
614 
615  template<typename tType>
616  static char const* getPrimitiveName(unsigned iSerializerVersionNo)
617  {
618  static_assert(Ignore<tType>::kFalse, "Unknown primitive name.");
619  return "";
620  }
621 
622 // ---<<< Element名回復 >>>---
623 // ヘッダが有る時はElementsMappingの値に関係なく名前対応可能である。
624 // そのような派生Serializerに対応するためのI/Fである。
625 // なお、BinaryMid?Serializerはこの機能に対応していない。
626 // ヘッダはデバッグ用オプションなので、ヘッダの有無で動作を変えないため。
627 // 戻り値:
628 // 名前対応するなら、名前返却
629 // 順序対応するなら、empty返却
630 // 注意事項:
631 // 同じTheolizerVersion<>に対しては名前対応と順序対応を変えてはいけない
632 
633  std::string loadElementName(ElementsMapping iElementsMapping);
634 
635 // ---<<< 次のバイト獲得 >>>---
636 // クラス終了ならfalse
637 
638  bool readNext();
639 
640 // ---<<< 1バイト読み出し >>>---
641 
642  uint8_t readByte();
643 
644 // ---<<< プリミティブ名からC++型名返却 >>>---
645 
646 #ifdef THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
647  static char const* getCppName(std::string const& iPrimitiveName, unsigned iSerializerVersionNo)
648  {
649  return getCppNameBinary(iPrimitiveName, iSerializerVersionNo);
650  }
651 #endif // THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
652 };
653 #ifndef THEOLIZER_INTERNAL_DOXYGEN
654 
655 //----------------------------------------------------------------------------
656 // プリミティブ名返却
657 //----------------------------------------------------------------------------
658 
659 #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSymbol) \
660  template<> \
661  inline char const* BinaryMidISerializer:: \
662  getPrimitiveName<dType>(unsigned iSerializerVersionNo) \
663  { \
664  return PrimitiveName<BinaryMidISerializer, dType>::getPrimitiveName(iSerializerVersionNo);\
665  }
666 #include "internal/primitive.inc"
667 
668 #endif // THEOLIZER_INTERNAL_DOXYGEN
669 } // namespace internal
670 
671 //############################################################################
672 // Binary Serializer I/Fクラス
673 // 保存先をテンプレートで指定する。
674 //
675 // 注意事項:
676 // BinaryBaseI/OSerializerから派生してテンプレート化している。
677 // BinaryBaseI/OSerializerを直接保存先のテンプレートとした場合、
678 // 使用した保存先全てに対して、コードが複製される。
679 // それを防ぐことが目的である。
680 //############################################################################
681 
682 // ***************************************************************************
683 //! 保存用BinarySerializer
684 // ***************************************************************************
685 
686 template<Destination uDefault=theolizerD::All, Destination... uDestinations>
688 {
689  THEOLIZER_INTERNAL_FRIENDS;
690 
691  void AbstructSerializer() { } // インスタンス生成許可
692 
693  static internal::Destinations const& getDestinations()
694  {
695  static const internal::Destinations destinations{uDefault, uDestinations...};
696  return destinations;
697  }
698 
699  // グローバル・バージョン番号テーブルへのポインタへのポインタ
700  // グローバル・バージョン番号テーブルへのポインタの値は初期化時、
701  // 確定していない可能性があるが、ポインタ自身のアドレスは確定している。
702  // なお、sGlobalVersionNoTableは外部リンケージを持たないものであり、
703  // Theolizerのクライアントをコンパイルする時に使われるsGlobalVersionNoTableを
704  // 取込む必要があるため、テンプレートであるトップ・シリアライザで処理する。
705  constexpr static internal::GlobalVersionNoTableBase const*const*const
706  kPtrGlobalVersionNoTable=&internal::sGlobalVersionNoTable;
707 
710 
711  // Switcherアクセス用
712  using MidSerializer::kSerializerName;
713  using BaseSerializer::mIsSaver;
714 
715 public:
716  //! ofstream用std::ios_base::openmode
717  using MidSerializer::kOpenMode;
718 
719 #ifndef THEOLIZER_INTERNAL_DOXYGEN
720  static const bool kHasDestination=true;
721 #endif // THEOLIZER_INTERNAL_DOXYGEN
722 
723  //! 通常のコンストラクタ
725  (
726  std::ostream& iOStream,
727  unsigned iGlobalVersionNo=kLastGlobalVersionNo,
729  bool iNoThrowException=false
730  ) : BinaryMidOSerializer
731  (
732  iOStream,
733  getDestinations(),
734  internal::sGlobalVersionNoTable,
735  iGlobalVersionNo,
736  kLastGlobalVersionNo,
737  iCheckMode,
738  iNoThrowException
739  )
740  { }
741 
742  //! GlobalVersionNo以外のオプションを指定するコンストラクタ
744  (
745  std::ostream& iOStream,
746  CheckMode iCheckMode,
747  bool iNoThrowException=false
748  ) : BinaryMidOSerializer
749  (
750  iOStream,
751  getDestinations(),
752  internal::sGlobalVersionNoTable,
753  kLastGlobalVersionNo,
754  kLastGlobalVersionNo,
755  iCheckMode,
756  iNoThrowException
757  )
758  { }
759 
760  //! BinaryOSerializerのプロパティ返却(@ref Property 参照)
761  static bool hasProperty(Property iProperty)
762  {
763  return internal::hasPropertyBinary(iProperty, true);
764  }
765 
768  using BaseSerializer::getRequireClearTracking;
770  using ErrorBase::isError;
771  using ErrorBase::resetError;
772 };
773 
774 #ifndef THEOLIZER_INTERNAL_DOXYGEN
775 // MidSerializer登録(トライバ処理用)
776 THEOLIZER_INTERNAL_REGISTER_MID_SERIALIZER(BinaryOSerializer);
777 #endif // THEOLIZER_INTERNAL_DOXYGEN
778 
779 // ***************************************************************************
780 //! 回復用BinarySerializer
781 // ***************************************************************************
782 
783 template<Destination uDefault=theolizerD::All, Destination... uDestinations>
785 {
786  THEOLIZER_INTERNAL_FRIENDS;
787 
788  void AbstructSerializer() { } // インスタンス生成許可
789 
790  static internal::Destinations const& getDestinations()
791  {
792  static const internal::Destinations destinations{uDefault, uDestinations...};
793  return destinations;
794  }
795 
796  // グローバル・バージョン番号テーブルへのポインタへのポインタ
797  constexpr static internal::GlobalVersionNoTableBase const*const*const
798  kPtrGlobalVersionNoTable=&internal::sGlobalVersionNoTable;
799 
801  typedef internal::BinaryMidISerializer MidSerializer;
802 
803  // Switcherアクセス用
804  using MidSerializer::kSerializerName;
805  using BaseSerializer::mIsSaver;
806 
807 public:
808  //! ifstream用std::ios_base::openmode
809  using MidSerializer::kOpenMode;
810 
811 #ifndef THEOLIZER_INTERNAL_DOXYGEN
812  static const bool kHasDestination=true;
813 #endif // THEOLIZER_INTERNAL_DOXYGEN
814 
815  //! 通常のコンストラクタ
817  (
818  std::istream& iIStream,
819  bool iNoThrowException=false
820  ) : BinaryMidISerializer
821  (
822  iIStream,
823  getDestinations(),
824  internal::sGlobalVersionNoTable,
825  kLastGlobalVersionNo,
826  nullptr,
827  iNoThrowException
828  )
829  { }
830 
831  //! BinaryISerializerのプロパティ返却(@ref Property 参照)
832  static bool hasProperty(Property iProperty)
833  {
834  return internal::hasPropertyBinary(iProperty, false);
835  }
836 
837  // 継承メンバー関数群
840  using BaseSerializer::getRequireClearTracking;
843  using ErrorBase::isError;
844  using ErrorBase::resetError;
845 
846 #ifndef THEOLIZER_INTERNAL_DOXYGEN
847  // メタ・デシリアライズ用
848  /*
849  メタ・シリアライズ処理検討後決定
850  現時点でメタ・シリアライズは実験的な実装なので、実用性がない。
851  それを製品版に含めるのはどうかと思う。
852  できるだけ、別ファイルへ分離することを検討する。
853  */
855  (
856  std::istream& iIStream,
857  std::ostream& iOStream,
858  bool iNoThrowException=false
859  ) : BinaryMidISerializer
860  (
861  iIStream,
862  getDestinations(),
863  internal::sGlobalVersionNoTable,
864  kLastGlobalVersionNo,
865  &iOStream,
866  iNoThrowException
867  )
868  { }
869 #endif // THEOLIZER_INTERNAL_DOXYGEN
870 };
871 
872 #ifndef THEOLIZER_INTERNAL_DOXYGEN
873 // MidSerializer登録(トライバ処理用)
874 THEOLIZER_INTERNAL_REGISTER_MID_SERIALIZER(BinaryISerializer);
875 #endif // THEOLIZER_INTERNAL_DOXYGEN
876 
877 //############################################################################
878 // End
879 //############################################################################
880 
881 } // namespace theolizer
882 
883 // ***************************************************************************
884 // 警告抑止解除
885 // ***************************************************************************
886 
887 #ifdef _MSC_VER
888  #pragma warning(pop)
889 #endif
890 
891 #endif // THEOLIZER_INTERNAL_SERIALIZER_BINARY_H
保存用BinarySerializer
CheckMode
型チェック・モード
ErrorInfo const & getErrorInfo() const
エラー情報返却(3-1-2.メンバ関数 参照)
Definition: report.h:861
theolizer名前空間
Definition: base.h:53
unsigned getGlobalVersionNo() const
処理中のグローバル・バージョン番号返却(3-1-2.メンバ関数 参照)
void clearTracking()
オブジェクト追跡の区切り(3-1-2.メンバ関数 参照)
TheolizerライブラリのAPI部
static bool hasProperty(Property iProperty)
BinaryISerializerのプロパティ返却(3-1-3.プロパティ 参照)
static bool hasProperty(Property iProperty)
BinaryOSerializerのプロパティ返却(3-1-3.プロパティ 参照)
回復用BinarySerializer
bool isError()
エラー発生ならtrue(3-1-2.メンバ関数 参照)
Definition: report.h:864
型チェック無し
Destination
保存先シンボルを定義するscoped enum型
回復用中間BinarySerializer
Property
シリアライザが提供する機能(プロパティ)のリスト
保存用中間BinarySerializer
CheckMode getCheckMode()
現在のCheckMode返却(3-1-2.メンバ関数 参照)