Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
6.usage_total.h
[詳解]
1 //############################################################################
2 /*!
3  @brief ドキュメント・ファイル-使用方法(全体)
4  @ingroup Documents
5  @file 6.usage_total.h
6  @author Yoshinori Tahara
7  @date 2016/11/01 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 /*!
38  @page UsageTotal 使用方法(全体)
39 
40 ここでは、Theolizerの使い方を説明します。
41 
42 TheolizerはAPIの機能テストをできるだけ自動化してます。<br>
43 そして、APIの機能テストは詳細仕様を規定することでもあります。複雑なプログラムでは文書として読み取ることは困難ですが、単純なプログラムであれば、文書としての機能を果たせるのではないかと考えています。
44 
45 そこで、各機能についてそれをテストするための多数のテスト群の内、代表的なものを使って説明し、詳細テストの関連部分のソースも提示します。できるだけ読み取るのに苦労しない形式でプログラムを記述し、詳細仕様書として有用であることを目指します。
46 
47 まず、1~3節で全体的な説明を行い、4節以降で各機能について説明します。
48 
49 <br>
50 //############################################################################
51 @section Naming 1.名前の付け方
52 //############################################################################
53 
54 TheolizerのAPIは名前空間に入れています。また、マクロは決まったプリフィクスを付けています。
55 少し意味を持たせていますので説明します。
56 
57 // ***************************************************************************
58 @subsection Namespace 1-1.名前空間
59 // ***************************************************************************
60 
61 ほぼ全てのシンボルを <b>theolizer</b> 名前空間へ入れています。<br>
62 一部、入れると実装が難しいものについては、シンボルに <b>Theolizer</b> を含みます。<br>
63 これにより既存のコードと被ることはまずない筈です。
64 
65 次に、内部的に使用するシンボルは <b>internal</b> 名前空間へ入れています。<br>
66 これらのシンボルが付けられたクラスや関数等は、Theolizerのアップデート時、上位互換性を考慮しませんので使用しないようお願いします。
67 
68 // ***************************************************************************
69 @subsection MacroName 1-2.マクロ名
70 // ***************************************************************************
71 
72 全てのマクロは <b>THEOLIZER_</b> で始めています。<br>
73 これにより既存のコードと被ることはまずない筈です。
74 
75 次に、内部的に使用するマクロは、 <b>THEOLIZER_INTERNAL_</b> で始めています。<br>
76 また、Theolizerが自動生成するマクロを、 <b>THEOLIZER_GENERATED_</b> で始めています。<br>
77 これらのマクロは、Theolizerのアップデート時、上位互換性を考慮しませんので使用しないようお願いします。
78 <br>
79 //############################################################################
80 @section BasicUsage 2.基本的な使い方
81 //############################################################################
82 
83 Theolizerをインストールした後、あなたのデータをTheolizerでシリアライズするために、あなたのプログラムを下記の順序を守るようにして下さい。
84 
85 1. Theolizerヘッダをインクルード
86 2. シリアライズするクラスとenum型の定義
87 3. Theolizerの自動生成ファイルをインクルード
88 4. シリアライズ処理
89 
90 // ***************************************************************************
91 @subsection TheolizerHeader 2-1.Theolizerヘッダをインクルード
92 // ***************************************************************************
93 
94 一部例外(*1)はありますが原則として、<b>シリアライズするクラスとenum型の定義</b> 前にシリアライザのヘッダをインクルードして下さい。<br>
95 
96 <b>Json形式シリアライザ・ヘッダのインクルードと型定義の例:(source/samples/example/example.cpp)</b>
97 @code
98 #include <theolizer/serializer_json.h>
99 #include "ユーザ定義.h"
100 @endcode
101 <div style="margin-top: 20px;"></div>
102 <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px; background-color: #d0d0d0;">
103 (*1) 例外:<b>非侵入型</b>(@ref Basic12)のクラスやenum型の<b>非侵入型完全自動</b>については、<b>シリアライザのヘッダをインクルード</b>する前でも定義できます。<br>
104 </div>
105 
106 現在、サポートしているシリアライザはJson形式、独自Binary形式、Xml形式、メモリ内専用のFast形式の4種類です。
107 それぞれ、下記ヘッダをインクールドして下さい。
108 
109 
110 |形式|インクルードするヘッダ|注意事項|
111 |----|----------------------|--------|
112 |Json形式|<theolizer/serializer_json.h>|fstreamはテキスト・モードでオープンする|
113 |独自Binary形式|<theolizer/serializer_binary.h>|fstreamは<b>バイナリ・モード(std::ios_base::binary)</b>でオープンする|
114 |Xml形式|<theolizer/serializer_xml.h>|fstreamはテキスト・モードでオープンする|
115 |メモリ内専用Fast形式|上記のどちから、もしくは、<theolizer/serializer.h>|fstreamは<b>バイナリ・モード(std::ios_base::binary)</b>でオープンする|
116 
117 <br>
118 // ***************************************************************************
119 @subsection DefineClassEnum 2-2.シリアライズするクラスとenum型の定義
120 // ***************************************************************************
121 
122 <b>シリアライズするクラスとenum型の定義</b>後に、<b>Theolizerの自動生成ファイルをインスクルード</b> します。この順序に例外はありません。<br>
123 
124 なお、シリアライズ対象の型を含まないヘッダ・ファイルは、Theolizerに関する順序制限はありません。
125 
126 // ***************************************************************************
127 @subsection IncludeAutoGeneratedFile 2-3.Theolizerの自動生成ファイルをインクルード
128 // ***************************************************************************
129 
130 @ref Mechanism で説明したようにTheolizerはシリアライズに必要なソース・コードを自動生成します。<br>
131 このファイルはコンパイル単位(通常は.cppファイル)毎に生成され、当該.cppファイルと同じフォルダへ自動的に生成されます。<br>
132 Theolizerは、バージョンを上げた時に古いクラス定義やenum型定義をここに残します。これにより古いシリアライズ・データを回復できます。<br>
133 そこで、このファイルをお使いのバージョン管理システム(gitやsvn等)へ登録することをお勧めします。
134 
135 自動生成するファイルのファイル名は、そのコンパイル単位のファイル名に".theolzier.hpp"を繋げたものです。<br>
136 例えば、<b>example.cpp</b> の場合は、<b>example.cpp.theolizer.hpp</b> となります。
137 
138 <b>クラス定義と*.theolizer.hppインクルード指定例:(source/samples/example/example.cpp)</b>
139 
140 @dontinclude example.cpp
141 @skip include
142 @until example.cpp.theolizer.hpp
143 
144 この例では、example.cppの頭でクラスを定義していますが、example.hで定義し、\#include "example.h" にてインクルードするのが一般的です。
145 
146 // ***************************************************************************
147 @subsection SerializingProcess 2-4.シリアライズ処理
148 // ***************************************************************************
149 
150 シリアライズは下記の3つで行います。
151  - シリアライザ・インスタンスの生成
152  - シリアライズ処理要求(シリアライズするインスタンスを指定する)
153  - シリアライザ・インスタンスの破棄
154 
155 @subsubsection ConstructSerializer 2-4-1.シリアライザ・インスタンスの生成
156 その際、シリアライズ先のデータ・ストリームを指定します。ファイル・ストリームや[TCP/IPストリーム](http://localhost/theolizer/tcp_ip_sample/)を指定して下さい。<br>
157 保存や送信時はstd::ostreamを、回復や受信時はstd::istreamを与えて下さい。
158 
159  - <b>保存(送信用)シリアライザ</b> <br>
160  theolizer::JsonOSerializer<br>
161  theolizer::BinaryOSerializer<br>
162  theolizer::XmlOSerializer<br>
163  theolizer::FastOSerializer<br>
164 
165  - <b>回復(受信用)シリアライザ(デシリアライザ)</b> <br>
166  theolizer::JsonISerializer<br>
167  theolizer::BinaryISerializer<br>
168  theolizer::XmlISerializer<br>
169  theolizer::FastISerializer<br>
170 
171 @subsubsection Request 2-4-2.シリアライズ処理要求
172 下記マクロでシリアライズします。保存用シリアライザを指定すると保存、回復用シリアライザを指定すると回復動作となります。<br>
173 これはいつくでも記述して良いです。
174 
175 <b>THEOLIZER_PROCESS(dSerializer, dInstance)</b>
176  - dSerializer : シリアライザのインスタンスを指定します。<br>
177  - dInstance : 保存/回復するインスタンスを指定します。<br>
178 
179 dInstanceを保存/回復します。<br>
180 ポインタ型を指定した場合は、アドレス回復のためにポイント先のオブジェクト追跡を行います。<br>
181 
182 <b>THEOLIZER_PROCESS_POINTEE(dSerializer, dInstance)</b>
183  - dSerializer : シリアライザのインスタンスを指定します。<br>
184  - dInstance : 保存/回復する被ポインタでもあるインスタンスを指定します。<br>
185 
186 <b>THEOLIZER_PROCESS_OWNER(dSerializer, dInstance)</b>
187  - dSerializer : シリアライザのインスタンスを指定します。<br>
188  - dInstance : 保存/回復する所有権を持つインスタンスへのポインタを指定します。<br>
189 
190 @see @ref ObjectTracking
191 
192 <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px; background-color: #d0d0d0;">
193 このようにシリアライザを問わず、全て同じマクロでシリアライズ処理できます。
194 </div>
195 
196 @subsubsection DestructSerializer 2-4-3.シリアライザ・インスタンスの破棄
197 最後にシリアライザ・インスタンスを破棄することでシリアライズ処理を完了します。<br>
198 生成時に例外発生を禁止していた場合に、エラー状態をリセットしないまま破棄すると、プロセスをアボートします。これはエラー状態の見逃しを回避するための仕様です。<br>
199 例外発生を禁止している場合は、破棄する前には必ずエラー情報をチェクした上で、エラー状態をリセットして下さい。<br>
200 具体的手順は@ref ErrorReport にて説明します。
201 
202 <b>ファイルへの保存例:(source/samples/example/example.cpp)</b>
203 
204 @dontinclude example.cpp
205 @skip 保存
206 @until }
207 
208 <b>ファイルからの回復例:(source/samples/example/example.cpp)</b>
209 
210 @skip 回復
211 @until }
212 
213 <br>
214 //############################################################################
215 @section Serializers 3.各シリアライザの説明
216 //############################################################################
217 現在、サポートしているシリアライザはJson形式、独自Binary形式、メモリ内専用のFast形式の3種類です。<br>
218 ここではそれぞれの使い方を説明します。
219 
220 // ***************************************************************************
221 @subsection Serializer 3-1.共通事項
222 // ***************************************************************************
223 
224 全てのシリアライザについて共通な事項について説明します。
225 
226 @subsubsection CheckMode 3-1-1.型チェック・モード
227 Theolizerのシリアライザは回復時に型が一致していることをチェックできます。<br>
228 その方法としてシリライズ・データ内に「型名を保存する方法」と「型に割り当てたインデックス番号(TypeIndex)を保存する方法」の2種類を用意しています。
229 
230 theolizer::CheckMode
231 |列挙値|意味|
232 |------|----|
233 |NoTypeCheck|型チェック無し|
234 |TypeCheck|型名による型チェック|
235 |TypeCheckByIndex|TypeIndexによる型チェック|
236 
237 NoTypeCheckは型情報をシリライズ・データに含みませんのでデータ量が少ない場合の効率は良いです。しかし、メンバ名をヘッダではなくデータ側に含むためデータ量が多くなると効率は悪化します。<br>
238 TypeCheckはテキスト型の場合、データを目視確認し易いです。データ量が少ない時の効率はNoTypeCheckの次に良いです。<br>
239 TypeCheckByIndexはデータ量が多い時は3種のCheckModeの中で最大の効率を発揮します。
240 
241 型情報等の管理データを下記のように記録します。
242  - <b>シリアライズ・データのヘッダ部</b><br>
243  <b>NoTypeCheck:</b>型情報を記録しません。<br>
244  <b>TypeCheck:</b>クラスについて、各メンバのメンバ名(@link Basic121 名前対応@endlink時)と型名を記録します。<br>
245  <b>TypeCheckByIndex:</b>全ての型について、TypeIndexに対応する型名を記録します。
246  更にクラスについては、各メンバのメンバ名(@link Basic121 名前対応@endlink時)とTypeIndexを記録します。<br>
247 <br>
248 
249  - <b>シリアライズ・データの各データ部</b><br>
250  <b>NoTypeCheck:</b>クラスについて、各メンバのデータとメンバ名(@link Basic121 名前対応@endlink時)をセットで記録します。<br>
251  <b>TypeCheck:</b>THEOLIZER_PROCESS()マクロで指定したデータと共にその型名を記録します。<br>
252  <b>TypeCheckByIndex:</b>THEOLIZER_PROCESS()マクロで指定したデータと共にそのTypeIndexを記録します。<br>
253 
254 回復時に回復先の変数の型と上記の情報と照らし合わせることで型チェックを行います。<br>
255 
256 @subsubsection MemberFunctions 3-1-2.メンバ関数
257 幾つかの制御のため、各シリアライザは下記のメンバ関数を公開しています。
258 
259 |メンバ名|意味|
260 |--------|----|
261 |unsigned getGlobalVersionNo() const;|処理中のグローバル・バージョン番号を返却します。|
262 |void clearTracking() ;|オブジェクト追跡の区切り(@ref ObjectTracking 参照)|
263 |bool getRequireClearTracking() const;|clearTracking()が必要な時trueを返却します。|
264 |theolizer::CheckMode getCheckMode() const;|現在のCheckModeを返却します。|
265 |void setCharIsMultiByte();|Windowsにおいて、EncodedStringがtrueのシリアライザにおいて<br>std::string変数の文字エンコードをMultiByte文字列として処理するかどうかを指定します。|
266 |theolizer::ErrorInfo const& getErrorInfo() const;|エラー情報を返却します。|
267 |bool isError() const;|エラーが発生している時trueを返却します。|
268 |void resetError();|エラー状態を解除します。(@ref ErrorReport3 参照)|
269 
270 @subsubsection Property 3-1-3.プロパティ
271 各シリアライザは、その属性をプロバティとして提供しています。
272 
273 |プロバティ名|意味|Json|Binary|Fast|
274 |------------|----|----|------|----|
275 |IsSaver|保存処理用ならtrue、回復処理用ならfalse|--|--|--|
276 |EncodedString|文字列のエンコードを処理する|true|false|false|
277 |SupportModifying|クラスやenum型の定義変更に対応する|true|true|false|
278 |BinaryOpen|fstreamをstd::ios_base::binaryモードでオープンする必要がある|false|true|true|
279 
280 プロパテイは以下の構文で受け取ります。
281 
282 @code
283 bool property = <シリアライザ・クラス>::hasProperty(theolizer::Property::<プロパティ名>);
284 @endcode
285 <br>
286 
287 @subsubsection EncodedString 3-1-4.EncodedStringについて補足
288 テキスト型のシリアライザは、文字列を読める形式で記録されます。<br>
289 そのため、例えばJsonフォーマットはデフォルトではUTF-8でエンコードすると規定されています。<br>
290 そして、C++の各`std::string`シリーズもUnicodeでエンコードされることが期待されます。(そうしないことも可能です。)
291 
292 そこで、TheolizerのEncodedStringプロパティをサポートしたシリアライザ(現在はJsonのみ)は、下記のように`std::string`シリーズを処理します。
293 
294 - <b>setCharIsMultiByte(false)</b>(デフォルト)<br>
295 全ての文字列を特定のUnicodeエンコードで記録する。(JsonシリアライザはUTF-8)<br>
296 `std::string`はUnicodeでエンコードされているものとして処理する。(そのまま保存/回復する。)<br>
297 以下は全てUnicodeへ変換して保存し、読み出し後当該エンコードへ変換する。<br>
298 `std::wstring`はUTF-16かUTF-32(wchar_tのサイズによる)でエンコードされているものとして処理する。<br>
299 `std::u16string`はUTF-16でエンコードされているものとして処理する。<br>
300 `std::u32string`はUTF-32でエンコードされているものとして処理する。<br>
301 <br>
302 
303 - <b>setCharIsMultiByte(true)</b><br>
304 std::stringはMultiByte文字列としてエンコードされているものとして処理する。(Unicodeへ変換して保存/回復する。)<br>
305 その他は、デフォルトと同じ。<br>
306 
307 つまり、例えば、UTF-8でエンコードされた`std::string`型の変数を保存し、それをUTF-16でエンコードされた`std::u16string`型の変数へ回復できます。
308 
309 <b>サンプル・ソース(source/reference_and_test/basic/test_basic_process.cpp)</b><br>
310 
311 @dontinclude test_basic_process.cpp
312 @skip #if defined(_WIN32)
313 @until #endif
314 @skip void tutoriseBasic()
315 @until {
316 @skip //-
317 @until // char
318 @until THEOLIZER_PROCESS(aSerializer, aString);
319 @until THEOLIZER_PROCESS(aSerializer, aString);
320 @until THEOLIZER_PROCESS(aSerializer, aString);
321 @skip }
322 @until }
323 @until THEOLIZER_EQUAL(aU32String
324 @skip }
325 @until }
326 @skip "tutoriseBasic() end"
327 @skip }
328 @until }
329 
330 @subsubsection BinaryOpen 3-1-5.BinaryOpenについて補足
331 
332 バイナリ形式のシリアライザをfstreamで用いる時は、必ずバイナリ・モード(std::ios_base::binary)でfstreamをオープンする必要があります。<br>
333 Windowsの場合、fstreamがテキスト・モードでオープンされ、ストリームへ数値26(0x1A)が出力されると、0x1AはWindowsではEOFコードなので回復時にEOFエラーになります。また、Windowsで数値10(0x0A)が出力されるとCR LFへ展開されてしまい、適切に回復できません。<br>
334 このような事態をさけるため、Theolizer側でエラーにしたいのですが、iostreamではそのオープン・モードを確認できないためチェックが困難なのです。<br>
335 
336 バイナリ形式のシリアライザは、hasProperty(theolzier::Property::BinaryOpen)がtrueになります。
337 また、各シリアライザはstd::ios_base::openmode型の静的定数kOpenModeを定義しています。
338 バイナリ形式のシリアライザではstd::ios_base::binary、それ以外のシリアライザで 0 となっています。
339 
340 <b>サンプル・ソース(source/reference_and_test/basic/test_basic_process.cpp)</b><br>
341 
342 @snippet basic/test_basic_process.cpp BinaryOpen
343 
344 <br>
345 // ***************************************************************************
346 @subsection JsonSerializer 3-2.Json形式(JsonSerializer)
347 // ***************************************************************************
348 Json形式でシリアライズする場合は、<b>theolizer/serializer_json.h</b>をインクルードして下さい。
349 
350 @subsubsection JsonOSerialzier 3-2-1.保存用JsonSerialzier
351 @link theolizer::JsonOSerializer::JsonOSerializer(std::ostream&,unsigned,CheckMode,bool,bool)
352 @copybrief theolizer::JsonOSerializer::JsonOSerializer(std::ostream&,unsigned,CheckMode,bool,bool)
353 @endlink
354 
355 @code
356 JsonOSerializer
357 (
358  std::ostream& iOStream,
359  unsigned iGlobalVersionNo=kLastGlobalVersionNo,
360  CheckMode iCheckMode=CheckMode::NoTypeCheck,
361  bool iNoPrettyPrint=false,
362  bool iNoThrowException=false
363 );
364 @endcode
365 
366 @link theolizer::JsonOSerializer::JsonOSerializer(std::ostream&,CheckMode,bool,bool)
367 @copybrief theolizer::JsonOSerializer::JsonOSerializer(std::ostream&,CheckMode,bool,bool)
368 @endlink
369 
370 @code
371 JsonOSerializer
372 (
373  std::ostream& iOStream,
374  CheckMode iCheckMode,
375  bool iNoPrettyPrint=false,
376  bool iNoThrowException=false
377 );
378 @endcode
379 
380 |パラメータ名|意味|
381 |------------|----|
382 |iOStream|出力先のストリーム(ofstreamはテキスト・モードでオープンして下さい)|
383 |iGlobalVersionNo|保存するグローバル・バージョン番号(省略時は最新版)|
384 |iCheckMode|型チェック・モード(省略時はNoTypeCheck)|
385 |iNoPrettyPrint|整形出力しない時true(省略時はfalse)|
386 |iNoThrowException|例外禁止時true(省略時はfalse)|
387 
388 #### 専用継承関数
389 
390 <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px; background-color: #d0d0d0;">
391 <b>void setCharIsMultiByte(bool iCharIsMultiByte);</b><br>
392 iCharIsMultiByte=trueの時、std::stringをWindowsマルチ・バイト文字コードとして取り扱います。<br>
393 コンストラクト直後はiCharIsMultiByte=falseです。<br>
394 Windowsのみ機能します。それ以外のOSではUTF-8のままです。
395 </div>
396 
397 @subsubsection JsonISerialzier 3-2-2.回復用JsonSerialzier
398 @link theolizer::JsonISerializer::JsonISerializer(std::istream&,bool)
399 @copybrief theolizer::JsonISerializer::JsonISerializer(std::istream&,bool)
400 @endlink
401 
402 @code
403 JsonISerializer
404 (
405  std::istream& iIStream,
406  bool iNoThrowException=false
407 );
408 @endcode
409 
410 |パラメータ名|意味|
411 |------------|----|
412 |iIStream|入力元のストリーム(ofstreamならテキスト・モードでオープンして下さい)|
413 |iNoThrowException|例外禁止時true(省略時はfalse)|
414 
415 #### 専用継承関数
416 
417 <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px; background-color: #d0d0d0;">
418 <b>void setCharIsMultiByte(bool iCharIsMultiByte);</b><br>
419 iCharIsMultiByte=trueの時、std::stringをWindowsマルチ・バイト文字コードとして取り扱います。<br>
420 コンストラクト直後はiCharIsMultiByte=falseです。<br>
421 Windowsのみ機能します。それ以外のOSではUTF-8のままです。
422 </div>
423 
424 <br>
425 // ***************************************************************************
426 @subsection BinarySerializer 3-3.独自Binary形式(BinarySerializer)
427 // ***************************************************************************
428 独自Binary形式でシリアライズする場合は、<b>theolizer/serializer_binary.h</b>をインクルードして下さい。<br>
429 
430 Big Endianでエンコードします。Little Endianの処理系の場合Big Endianとの間で自動変換します。<br>
431 整数型は値を表現するために十分なバイト数で保存します。例えば、long long型でも値が10ならタグと値で合わせて2バイトで保存します。<br>
432 浮動小数点型はIEEE754フォーマットのみサポートします。バイト単位でEndian変換します。<br>
433 long doubleは「radix==2、digits==64、max_exponent==16384」の80ビット拡張精度形式である処理系(gcc)とbinary64である処理系(msvc)に対応しています。<br>
434 文字コードの変換は行いません。Endianのみ変換してシリアライズします。<br>
435 
436 @subsubsection BinaryOSerialzier 3-3-1.保存用BinarySerialzier
437 @link theolizer::BinaryOSerializer::BinaryOSerializer(std::ostream&,unsigned,CheckMode,bool)
438 @copybrief theolizer::BinaryOSerializer::BinaryOSerializer(std::ostream&,unsigned,CheckMode,bool)
439 @endlink
440 
441 @code
442 BinaryOSerializer
443 (
444  std::ostream& iOStream,
445  unsigned iGlobalVersionNo=kLastGlobalVersionNo,
446  CheckMode iCheckMode=CheckMode::NoTypeCheck,
447  bool iNoThrowException=false
448 );
449 @endcode
450 
451 @link theolizer::BinaryOSerializer::BinaryOSerializer(std::ostream&,CheckMode,bool)
452 @copybrief theolizer::BinaryOSerializer::BinaryOSerializer(std::ostream&,CheckMode,bool)
453 @endlink
454 
455 @code
456 BinaryOSerializer
457 (
458  std::ostream& iOStream,
459  CheckMode iCheckMode,
460  bool iNoThrowException=false
461 );
462 @endcode
463 
464 |パラメータ名|意味|
465 |------------|----|
466 |iOStream|出力先のストリーム(ofstreamはstd::ios_base::binaryでオープンして下さい)|
467 |iGlobalVersionNo|保存するグローバル・バージョン番号(省略時は最新版)|
468 |iCheckMode|型チェック・モード(省略時はNoTypeCheck)|
469 |iNoThrowException|例外禁止時true(省略時はfalse)|
470 
471 @subsubsection BinaryISerializer 3-3-2.回復用BinarySerialzier
472 @link theolizer::BinaryISerializer::BinaryISerializer(std::istream&,bool)
473 @copybrief theolizer::BinaryISerializer::BinaryISerializer(std::istream&,bool)
474 @endlink
475 
476 @code
477 BinaryISerializer
478 (
479  std::istream& iIStream,
480  bool iNoThrowException=false
481 );
482 @endcode
483 
484 |パラメータ名|意味|
485 |------------|----|
486 |iIStream|入力元のストリーム(ofstreamはstd::ios_base::binaryでオープンして下さい)|
487 |iNoThrowException|例外禁止時true(省略時はfalse)|
488 
489 <br>
490 // ***************************************************************************
491 @subsection XmlSerializer 3-4.Xml形式(XmlSerializer)
492 // ***************************************************************************
493 
494 @subsubsection SpecXml 3-4-1.仕様
495 Xml形式でシリアライズする場合は、<b>theolizer/serializer_xml.h</b>をインクルードして下さい。<br>
496 
497 __名前空間__<br>
498 名前空間として`https://theolizer.com/theoride/xml-1`を使います。(特に何も置いていません。識別用だけです。)
499 現時点では下記要素名と属性名を定義しています。(接頭辞はthを用いていますので接頭辞付きで表記します。)
500 
501 |識別子|要素名/<br>属性名|c++の型 or 意味|
502 |------|----|----|
503 |th:bool|要素名|bool 型|
504 |th:int8|要素名|int8_t 型|
505 |th:int16|要素名|int16_t 型|
506 |th:int32|要素名|int32_t 型|
507 |th:int64|要素名|int64_t 型|
508 |th:unit8|要素名|unit8_t 型|
509 |th:uint16|要素名|uint16_t 型|
510 |th:uint32|要素名|uint32_t 型|
511 |th:uint64|要素名|uint64_t 型|
512 |th:float32|要素名|IEEE754のbinary32型|
513 |th:float64|要素名|IEEE754のbinary64型|
514 |th:float80|要素名|IEEE754の拡張型(仮数部64bit、指数部15bit)|
515 |th:string|要素名|UTF-8文字列|
516 |th:Array|要素名|配列(ネストすることで多次元配列を表現する)|
517 |th:Pointer|要素名|ポインタ型(@ref HowToObjectTracking 参照)|
518 |th:Pointee|要素名|被ポインタ(@ref HowToObjectTracking 参照)|
519 |th:OwnerPointer|要素名|オーナ-・ポインタ(@ref HowToObjectTracking 参照)|
520 |th:Reference|要素名|動的ポリモーフィズムされた参照(@ref Basic123 参照)|
521 |th:Type|属性名|ポインタの指す先の型|
522 |th:ObjectId|属性名|ポインタ or 被ポインタのオブジェクトID<br>(@ref Basic24 参照)|
523 |th:MemberName|属性名|メンバ変数名|
524 |th:GlobalVersionNo|属性名|グローバル・バージョン番号(ヘッダにのみ出現する)|
525 |ユーザ・クラス名|要素名|ユーザ定義のクラス名|
526 |ユーザenum型名|要素名|ユーザ定義のenum型名|
527 
528 各数値型(intやdouble等)は処理系に毎に異なりますが、適切なth:int??, th:float??名が割り当てられます。<br>
529 std::numelic_limitsのis_signed, digits, max_exponentを用いて振り分けています。
530 
531 __型チェックと要素名の使い方について__<br>
532 Xmlフォーマットを用いるシリアライザは、要素名としてメンバ変数名を用いるものが多いですが、当Xmlシリアライザは要素名として型名を用いることにしました。
533 
534 1. __Theolizerとしての要件__<br>
535 Theolizerは、クラスのメンバ変数を回復する際、名前対応と順序対応の2つを用意しています。「新しい」クラスは変更が予想されるため名前で対応することで変更を容易にしています。「枯れた」クラスは名前を保存する記憶スペースを省略し効率を上げます。Xmlの場合、重複する文字列の保存が多いため後者のメリットはあまり効果的ではありませんが、他のシリアライザと同等の扱いとしています。<br>
536 従って、クラスのメンバ変数の名前をシリアライズしないケースがあります。
537 
538 2. __トップ・レベルの変数名や配列の各要素、ヒープ上のオブジェクト__<br>
539 トップ・レベルの(プログラマが直接保存/回復を指示する)変数は、保存時と回復時の変数名が一致しない場合も少なくないと思います。また、C++の場合、配列全体に名前は付いている場合が多いですが、配列の各要素には名前がありません。更に、ヒープ上のオブジェクトにはそもそも名前がありません。ポインタには名前がありますが、オブジェクト自身には名前がありません。<br>
540 これらの名前を付けたくないものや名前の無いものは、変数名をシリアライズしない方が自然です。
541 
542 3. __C++は静的型付け言語__<br>
543 ですので、変数には必ず型が存在し、型の異なる変数への回復をエラーチェックすると好ましいです。<br>
544 
545 以上に理由により、要素名(Xml要素が必ず必要とする名前)を「型名」とし、回復時に必ず型チェックするようにしました。
546 
547 従って、CheckModeパラメータは指定しません。
548 
549 @subsubsection XmlOSerialzier 3-4-2.保存用XmlSerialzier
550 @link theolizer::XmlOSerializer::XmlOSerializer(std::ostream&,unsigned,bool,bool)
551 @copybrief theolizer::XmlOSerializer::XmlOSerializer(std::ostream&,unsigned,bool,bool)
552 @endlink
553 
554 @code
555 XmlOSerializer
556 (
557  std::ostream& iOStream,
558  unsigned iGlobalVersionNo=kLastGlobalVersionNo,
559  bool iNoPrettyPrint=false,
560  bool iNoThrowException=false
561 );
562 @endcode
563 
564 @link theolizer::XmlOSerializer::XmlOSerializer(std::ostream&,bool,bool)
565 @copybrief theolizer::XmlOSerializer::XmlOSerializer(std::ostream&,bool,bool)
566 @endlink
567 
568 @code
569 XmlOSerializer
570 (
571  std::ostream& iOStream,
572  bool iNoPrettyPrint=false,
573  bool iNoThrowException=false
574 );
575 @endcode
576 
577 |パラメータ名|意味|
578 |------------|----|
579 |iOStream|出力先のストリーム(ofstreamはstd::ios_base::binaryでオープンして下さい)|
580 |iGlobalVersionNo|保存するグローバル・バージョン番号(省略時は最新版)|
581 |iNoPrettyPrint|整形出力しない時true(省略時はfalse)|
582 |iNoThrowException|例外禁止時true(省略時はfalse)|
583 
584 @subsubsection XmlISerializer 3-4-3.回復用XmlSerialzier
585 @link theolizer::XmlISerializer::XmlISerializer(std::istream&,bool)
586 @copybrief theolizer::XmlISerializer::XmlISerializer(std::istream&,bool)
587 @endlink
588 
589 @code
590 XmlISerializer
591 (
592  std::istream& iIStream,
593  bool iNoThrowException=false
594 );
595 @endcode
596 
597 |パラメータ名|意味|
598 |------------|----|
599 |iIStream|入力元のストリーム(ofstreamはstd::ios_base::binaryでオープンして下さい)|
600 |iNoThrowException|例外禁止時true(省略時はfalse)|
601 
602 @subsubsection ExampleXml 3-4-4.使い方
603 
604 サンプルのsource/samples/example/example.cppをxml用に修正した場合の出力例です。
605 
606 @code
607 #include <iostream>
608 #include <fstream>
609 #include <string>
610 #include <theolizer/serializer_xml.h>
611 
612 struct Foo
613 {
614  std::string name;
615  int age;
616 };
617 
618 #include "example.cpp.theolizer.hpp" // Theolizer自動生成先
619 
620 int main()
621 {
622  // 保存
623  {
624  Foo foo;
625  foo.name="Taro Yamada";
626  foo.age=22;
627 
628  std::ofstream ofs("sample.txt");
629  theolizer::XmlOSerializer<> xos(ofs); // シリアライザを生成
630  THEOLIZER_PROCESS(xos, foo); // ファイルへfooを保存
631  }
632 
633  // 回復
634  {
635  Foo foo;
636  std::ifstream ifs("sample.txt");
637  theolizer::XmlISerializer<> xis(ifs); // デシリアライザを生成
638  THEOLIZER_PROCESS(xis, foo); // ファイルからfooを回復
639 
640  theolizer::XmlOSerializer<> xos(std::cout);
641  THEOLIZER_PROCESS(xos, foo); // 回復結果の簡易表示
642  }
643 }
644 @endcode
645 
646 __出力__
647 @code
648 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
649 <th:XmlTheolizer xmlns:th="https://theolizer.com/theoride/xml-1" th:GlobalVersionNo="1">
650 <Foo>
651  <th:string th:MemberName="name">Taro Yamada</th:string>
652  <th:int32 th:MemberName="age">22</th:int32>
653 </Foo>
654 </th:XmlTheolizer>
655 @endcode
656 
657 <br>
658 // ***************************************************************************
659 @subsection FastSerializer 3-5.メモリ内専用のFast形式(FastSerializer)
660 // ***************************************************************************
661 FastSerializerの使用目的はデータ構造のプログラム内コピーです。外部プログラムとのデータ交換は想定していません<br>
662 
663 Theolizerが内部的に使用していますので、他のシリアライザのヘッダをインクルードすれば改めてヘッダをインクルードする必要はありません。<br>
664 もし、他のシリアライザを使用しない時は、theolizer/serializer.hをインクルードして下さい。<br>
665 また、ストリームはstd::stringstreamを用いることを想定していますが、もしも、ファイル・ストリームを与える場合は必ず std::ios_base::binaryモード でオープンして下さい。<br>
666 FastSerializerはデータ変換しません。バージョンの相違にも対応していません。<br>
667 オーナー指定ポインタでない通常のポインタは、ポイント先をシリアライズしていない場合はシャロー・コピーになります。(ポインタ値を単純にコピーする。)<br>
668 
669 @subsubsection FastOSerializer 3-5-1.保存用FastSerializer
670 @link theolizer::FastOSerializer::FastOSerializer(std::ostream&,bool)
671 @copybrief theolizer::FastOSerializer::FastOSerializer(std::ostream&,bool)
672 @endlink
673 
674 @code
675 FastOSerializer
676 (
677  std::ostream& iOStream,
678  bool iNoThrowException=false
679 );
680 @endcode
681 
682 |パラメータ名|意味|
683 |------------|----|
684 |iOStream|出力先のストリーム(ofstreamはstd::ios_base::binaryでオープンして下さい)|
685 |iNoThrowException|例外禁止時true(省略時はfalse)|
686 
687 @subsubsection FastISerializer 3-5-2.回復用FastSerializer
688 @link theolizer::FastISerializer::FastISerializer(std::istream&,bool)
689 @copybrief theolizer::FastISerializer::FastISerializer(std::istream&,bool)
690 @endlink
691 
692 @code
693 FastISerializer
694 (
695  std::istream& iIStream,
696  bool iNoThrowException=false
697 );
698 @endcode
699 
700 |パラメータ名|意味|
701 |------------|----|
702 |iIStream|入力元のストリーム(ofstreamはstd::ios_base::binaryでオープンして下さい)|
703 |iNoThrowException|例外禁止時true(省略時はfalse)|
704 
705 #### FastSerializerを用いたグローバル関数
706 
707 <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px; background-color: #d0d0d0;">
708 <b>template<typename tType><br>
709 void copySerializable(tType const& iSource, tType& oDestination);</b><br>
710 tType型の変数iSourceをoDestinationへコピーします。<br>
711 iSourceをFastSerializerでメモリ・ストリームへシリアライズし、続けてoDestinationへ回復することでコピーします。<br>
712 保存先指定も有効ですので、柔軟なデータ構造のコピーを容易に実装できます。
713 </div>
714 
715 <br>
716 //############################################################################
717 @section TestProgram 4.テスト・プログラムの構造
718 //############################################################################
719 
720 <br>
721 // ***************************************************************************
722 @subsection TestProgram41 4-1.テスト・プログラムの全体構造
723 // ***************************************************************************
724 
725 @subsubsection TestProgram411 4-1-1.アップデートとバージョンのバリエーション
726 
727 主な機能テスト・プログラムは、 <b>source/reference_and_test</b> 以下にアップデート/バージョン・アップによる変更(修正版)毎にフォルダを分けて保存しています。
728 
729 Theolizerはenum型とclass/struct型について定義変更に対応しています。そのテストも行うため、以下のように分類してテストを行います。
730 
731 1. 基本的なシリアライズ機能の定義変更を除く様々なバリエーションのテスト
732 
733 2. バージョン番号を更新しない定義変更のテスト
734 
735 3. バージョン番号を更新する定義変更のテスト
736 
737 現時点では下記修正版を用意しています。
738 
739 |フォルダ名|バージョン番号|説明|
740 |----------|--------------|----|
741 |basic|無し|基本的なシリアライズ機能の定義変更を除く様々なバリエーションのテスト|
742 |basic2|無し|同上|
743 |ver1a|1|最初のバージョン|
744 |ver1b|1|バージョン番号を変えずに可能な定義変更のテスト|
745 |ver1c|1|バージョン番号を変えるための準備のテスト|
746 |ver2a|2|バージョン番号を変更した時の定義変更のテスト|
747 |ver3a|3|更にバージョン番号を変更のテスト|
748 |ver3b|3|そしてバージョン番号を変えずに定義変更のテスト|
749 
750 class/structでメンバ変数を削除した場合、1つ前のバージョンの自動生成ソースに削除されたことを反映します。なので、最新版と1つ前のバージョンと、更にもう1つ前に問題が出ないかテストするため、3つのバージョンでテストします。
751 
752 各変更テスト・プログラムは他の変更テスト・プログラムが出力したデータを読み込んで回復できることやエラーを検出できることをテストします。
753 
754 @subsubsection TestProgram412 4-1-2.テストの組み合わせ
755 
756 下記組み合わせとなります。1行毎に各修正版プログラムが出力するデータ概要を記述しています。<br>
757 列に記載した各バージョンのプログラムが当該データの回復テストをする時◯印を付けています。
758 
759 |プロ<br>グラ<br>ム|バー<br>ジョン<br>指定|ファイル名|basic|basic2|ver1a|ver1b|ver1c|ver2a|ver3a|ver3b|
760 |----------|--------------|----------|-----|-----|-----|-----|-----|-----|-----|-----|
761 |basic |指定無し |①-basic-② |◯ | | | | | | | |
762 |basic |1 |①-basic-basic-② |◯ | | | | | | | |
763 |basic2|指定無し |①-basic2-②| |◯ | | | | | | |
764 |basic2|1 |①-basic-basic2-② | |◯ | | | | | | |
765 |ver1a |指定無し |①-ver1a-② | | |◯ |◯ |◯ |◯ |◯ |◯ |
766 |ver1a |1 |①-ver1a-ver1a-② | | |◯ |◯ |◯ |◯ |◯ |◯ |
767 |ver1b |指定無し |①-ver1b-② | | | |◯ |◯ |◯ |◯ |◯ |
768 |ver1b |1 |①-ver1b-ver1b-② | | | |◯ |◯ |◯ |◯ |◯ |
769 |ver1c |指定無し |①-ver1c-② | | | | |◯ |◯ |◯ |◯ |
770 |ver1c |1 |①-ver1c-ver1c-② | | | | |◯ |◯ |◯ |◯ |
771 |ver2a |指定無し |①-ver2a-② | | | | | |◯ |◯ |◯ |
772 |ver2a |1 |①-ver1c-ver2a-② | | | | |◯ |◯ |◯ |◯ |
773 |ver2a |2 |①-ver2a-ver2a-② | | | | | |◯ |◯ |◯ |
774 |ver3a |指定無し |①-ver3a-② | | | | | | |◯ |◯ |
775 |ver3a |1 |①-ver1c-ver3a-② | | | | |◯ |◯ |◯ |◯ |
776 |ver3a |2 |①-ver2a-ver3a-② | | | | | |◯ |◯ |◯ |
777 |ver3a |3 |①-ver3a-ver3a-② | | | | | | |◯ |◯ |
778 |ver3b |指定無し |①-ver3b-② | | | | | | | |◯ |
779 |ver3b |1 |①-ver1c-ver3b-② | | | | |◯ |◯ |◯ |◯ |
780 |ver3b |2 |①-ver2a-ver3b-② | | | | | |◯ |◯ |◯ |
781 |ver3b |3 |①-ver3b-ver3b-② | | | | | | | |◯ |
782 
783 ①にはシリアライザ名と一部のオプションが入ります。
784 
785 - json-np (非整形出力)
786 - json-pp (整形出力)
787 - binary
788 - xml-np (非整形出力)
789 - xml-pp (整形出力)
790 - fast
791 
792 ②は以下の通りです。
793 
794 - 残りのオプション指定
795  - jsonとbinaryの場合
796  - NoTypeCheck
797  - TypeCheck
798  - TypeCheckByIndex
799  - xmlの場合
800  - NoTypeCheck(実際には型チェックします)
801  - fastの場合は、最新版のみ対応でオプションもないため、上記表の「指定無し」のみです。
802 <br><br>
803 
804 - 保存先指定用のサフィックス
805  - 無印
806  - A(保存先DestA)
807  - B(保存先DestB)
808  - AB(保存先DestA | DestB)
809 <br><br>
810 
811 - 拡張子
812  - jsonの拡張子はjson
813  - binaryとfastの拡張子はbin
814 
815 例えば、json整形出力で、ver3aのプログラムがver1cデータを型チェック無し、保存先指定無しで出力したファイル名は、"json-pp-ver1c-ver3a-NoTypeCheck.json"となります。
816 
817 <br>
818 // ***************************************************************************
819 @subsection TestProgram42 4-2.テスト・プログラムの構造
820 // ***************************************************************************
821 
822 basic、および、各変更テスト用プログラムは共通部分があります。それらはreference_and_testフォルダ直下に配置し、ビルドする時に各サブ・フォルダへコピーしています。
823 
824 ### 共通部
825 
826 |ファイル|関数|概要|
827 |--------|----|----|
828 |disable_test.h ||各個別テストをディセーブルするシンボル定義。<br>デバッグ時の便利のために用意。|
829 |all_common.h ||テスト用の全バージョン共通定義。<br>アップデートとバージョン名とバージョン番号対応表のgVersionListを定義。|
830 |main.inc |main() |各サブ・フォルダ内のmain.cppから#includeされる。<br>コマンドライン解析を行い、パラメータが無い時は保存処理、ある時は回復処理を実行する。<br>4-1節 表の全組み合わせを生成し、callTests()を呼び出す。|
831 |↑|callTests()|各シリアライザのパラメータを振ってインスタンスを生成し、<br>saveBasic(), loadBasic(),callSaveDestinations(),callLoadDestinations()を呼び出す。|
832 
833 ### 各サブフォルダ部
834 
835 |ファイル|関数|概要|
836 |--------|----|----|
837 |main.cpp ||各個別フォルダ内テスト関数を呼び出す。|
838 |↑|saveBasic()|自動テスト基本部の保存処理。個別テストを呼び出す。|
839 |↑|loadBasic()|自動テスト基本部の回復処理。個別テストを呼び出す。|
840 |↑|callSaveDestinations()|自動テスト保存先指定部の保存処理。個別テストを呼び出す。|
841 |↑|callLoadDestinations()|自動テスト保存先指定部の回復処理。個別テストを呼び出す。|
842 
843 各個別テストは別途*.cppファイルを用意し、その中で定義しています。<br>
844 それぞれについては @ref UsageIndividual にて解説します。
845 
846 <br>
847 // ***************************************************************************
848 @subsection TestProgram43 4-3.説明で用いるマクロについて
849 // ***************************************************************************
850 テスト用のマクロはtest_tool.hで定義しています。<br>
851 その内、使い方の説明(兼 自動テスト)で用いるマクロについてここで簡単に説明します。
852 
853 1.@ref THEOLIZER_EQUAL(dLhs, dRhs, ...)
854 
855 (dLhs == dRhs) ならばPASS、そうでないならFAILと判定します。<br>
856 PASSならば、テストの数とPASS数をインクリメントします。<br>
857 FAILならば、テストの数とFAIL数をインクリメントし、テストを失敗させます。<br>
858 また、dRhsとそれ以降のアイテム(1個以上7個まで)を標準出力へ出力します。
859 
860 下記はシリアライザを使って回復したint型のaIntの値が-3000であることをチェックしています。
861 
862 @dontinclude basic/test_basic_process.cpp
863 @skip aInt=0;
864 @until THEOLIZER_EQUAL
865 
866 */