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