Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
report.h
[詳解]
1 //############################################################################
2 /*!
3  @brief Theolizerシステム部
4  @details ①Theolizerからのエラー返却<br>
5    エラー・コード<br>
6    エラー通知用構造体<br>
7    エラー・ログ<br>
8    エラー通知用例外(エラー・ログが無い時、例外で通知)<br>
9  ②Theolizerの稼働記録<br>
10    Theolizerログ<br>
11  ③デバッグ・ツール<br>
12    ASSERT/ABORTマクロ<br>
13  @ingroup TheolizerLib
14  @file report.h
15  @author Yoshinori Tahara
16  @date 2015/08/06 Created
17 */
18 /*
19  © 2016 Theoride Technology (http://theolizer.com/) All Rights Reserved.
20  "Theolizer" is a registered trademark of Theoride Technology.
21 
22  "Theolizer" License
23  In the case where you are in possession of a valid “Theolizer” License,
24  you may use this file in accordance with the terms and conditions of
25  the use license determined by Theoride Technology.
26 
27  General Public License Version 3 ("GPLv3")
28  You may use this file in accordance with the terms and conditions of
29  GPLv3 published by Free Software Foundation.
30  Please confirm the contents of GPLv3 at https://www.gnu.org/licenses/gpl.txt .
31  A copy of GPLv3 is also saved in a LICENSE.TXT file.
32 
33  商用ライセンス
34  あなたが有効なTheolizer商用ライセンスを保持している場合、
35  セオライド テクノロジーの定める使用許諾書の条件に従って、
36  このファイルを取り扱うことができます。
37 
38  General Public License Version 3(以下GPLv3)
39  Free Software Foundationが公表するGPLv3の使用条件に従って、
40  あなたはこのファイルを取り扱うことができます。
41  GPLv3の内容を https://www.gnu.org/licenses/gpl.txt にて確認して下さい。
42  またGPLv3のコピーをLICENSE.TXTファイルにおいてます。
43 */
44 //############################################################################
45 
46 #if !defined(THEOLIZER_INTERNAL_REPORT_H)
47 #define THEOLIZER_INTERNAL_REPORT_H
48 
49 #include "u8string.h" // インクルード漏れチェックのため最初にインクルード
50 #include "internal/base.h"
51 
52 //############################################################################
53 // Begin
54 //############################################################################
55 
56 // ***************************************************************************
57 // 警告抑止
58 // ***************************************************************************
59 
60 #ifdef _MSC_VER
61  #pragma warning(push)
62  #pragma warning(disable:4100 4251)
63 #endif
64 
65 namespace theolizer
66 {
67 
68 //############################################################################
69 // ASSERT/ABORTマクロ
70 //############################################################################
71 
72 namespace internal
73 {
74 #ifndef THEOLIZER_INTERNAL_DOXYGEN
75 
76 // ***************************************************************************
77 // std::coutへメッセージを出力後、プロセスを強制終了する
78 // ***************************************************************************
79 
80 THEOLIZER_INTERNAL_DLL
81 void abort[[ noreturn ]](char const* iFile, unsigned iLine, u8string const& iMessage);
82 
83 #define THEOLIZER_INTERNAL_ABORT(...) \
84  theolizer::internal::abort \
85  ( \
86  THEOLIZER_INTERNAL_FILE, \
87  __LINE__, \
88  theolizer::print(__VA_ARGS__) \
89  ) \
90 
91 // ***************************************************************************
92 // !dJudgeの時、std::coutへメッセージを出力後、プロセスを強制終了する
93 // ***************************************************************************
94 
95 void asserted(std::string const& iMessage, char const* iFile, unsigned iLine);
96 #define THEOLIZER_INTERNAL_ASSERT(dJudge, ...) \
97  do {if (!(dJudge)) THEOLIZER_INTERNAL_ABORT(__VA_ARGS__);}while(0) \
98 
99 //############################################################################
100 // theolizer::printf
101 // boost::formatの書式を用いるC++的なprintf
102 //############################################################################
103 
104 // ***************************************************************************
105 // boost::formatのラッパ
106 // ***************************************************************************
107 
108 class THEOLIZER_INTERNAL_DLL Format
109 {
110 private:
111  // ヘッダ依存回避用
112  struct Indep;
113  std::unique_ptr<Indep> mIndep;
114 
115  // コピー禁止
116  Format(Format const&) = delete;
117  Format& operator=(Format const&) = delete;
118 
119 public:
120  // コンストラクタ/デストラクタ
121  Format(u8string const& iFormat) noexcept;
122  ~Format() noexcept;
123 
124  // ムーブ許可
125  Format(Format&& iRhs);
126  Format& operator=(Format&& iRhs);
127 
128  // クリア
129  Format& clear();
130 
131  // 出力演算子
132  #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSymbol) \
133  Format& operator%(dType iValue);
134  #define THEOLIZER_INTERNAL_DEF_CHAR(dType, dSymbol) \
135  Format& operator%(dType const* iValue);
136  Format& operator%(const u8string& iValue);
137 
138  #define THEOLIZER_INTERNAL_DEF_BOOL(dType, dSymbol)
139  #define THEOLIZER_INTERNAL_DEF_STRING(dType, dSymbol)
140  #define THEOLIZER_INTERNAL_DEF_WCHAR(dType, dSymbol)
141  #define THEOLIZER_INTERNAL_DEF_CHAR16(dType, dSymbol)
142  #define THEOLIZER_INTERNAL_DEF_CHAR32(dType, dSymbol)
143  #include "internal/primitive.inc"
144 
145  Format& operator%(void* iValue);
146 
147  // theolizer::u8stringで取出す
148  u8string str();
149  operator u8string();
150 };
151 
152 // ***************************************************************************
153 // 可変長テンプレート実装部
154 // ***************************************************************************
155 
156 inline u8string printImpl(Format& iFormat)
157 {
158  return iFormat.str();
159 }
160 
161 template<typename tFirst, typename... tParams>
162 u8string printImpl(Format& iFormat, tFirst iFirst, tParams... iParams)
163 {
164  iFormat % iFirst;
165  return printImpl(iFormat, iParams...);
166 }
167 
168 #endif // THEOLIZER_INTERNAL_DOXYGEN
169 } // namespace internal
170 
171 // ***************************************************************************
172 // theolizer::print()
173 // ***************************************************************************
174 
175 /*!
176 @brief boost::formatのラッパ。
177 @details operator%ではなく、()内でカンマ区切りで表示したいアイテムを与える。<br>
178  書式指定(iFormat)は<a href=http://www.boost.org/doc/libs/release/libs/format/>boost::format</a>参照のこと。
179 */
180 template<typename... tParams>
181 u8string print(u8string const& iFormat, tParams... iParams)
182 {
183  internal::Format aFormat(iFormat);
184  return internal::printImpl(aFormat, iParams...);
185 }
186 
187 namespace internal
188 {
189 #ifndef THEOLIZER_INTERNAL_DOXYGEN
190 
191 //############################################################################
192 // Theolizerログ
193 //
194 // 考え方
195 // 1種類のログに対して、複数のログ・ファイルを生成する。
196 // iFileSizeを超えたら、次のファイルへ書き込む。
197 // ファイル番号は0からiFileCount-1まで変化する。
198 // 若い番号から使用され、iFileCountになったら、0へ戻る。
199 // 使い方
200 // ログ出力は、getLogStream()にてLogStreamクラスのインタンスを得て
201 // それに出力を行う。(原則、1行出力したら開放する。)
202 // LogStreamのコンストラクタで行ヘッダ(時刻やスレッドID等)
203 // が出力される。
204 //
205 // 行ヘッダ
206 // 日付時刻をmSec精度で出力する。デフォルトはローカルタイム。
207 // 時刻は下記で取得している。
208 // std::chrono::system_clock::now()
209 // また、下記も出力する。
210 // 排他制御用Mutexのロックにかかった時間(mSec)
211 // ThreadId
212 // std::this_thread::get_id()
213 // operator<<にて文字列化。
214 // その際、5桁以上とし、空きは'_'で埋めている。
215 // (std::setfill('_'), std::setw(5))
216 //
217 // スレッド・セーフ性:安全
218 // LogStreamのインスタンスにて排他制御実施
219 //############################################################################
220 
221 // ***************************************************************************
222 // WeakData(ログ・ファイル・パス指定用)
223 // 特に設定用の定義が実体化されなければ初期値のまま
224 // 使い方
225 // 使用したいcppにて下記を定義する。
226 // 型 WeakData変数名;
227 // 下記で値を取り出す。
228 // THEOLIZER_INTERNAL_GET_WEAK_DATA(WeakData変数名, 型)
229 // そのヘッダ・ファイルにて下記宣言を行う。
230 // extern 型 WeakData変数名;
231 // 上書きしたいcppにて下記を定義する。
232 // THEOLIZER_INTERNAL_SET_WEAK_DATA(WeakData変数名, 型, 値);
233 //
234 // 注意事項
235 // tDataは組み込み型限定。
236 // 自動的に初期化される型は初期化タイミングを制御できないので
237 // 使えない。
238 // ***************************************************************************
239 
240 // ---------------------------------------------------------------------------
241 // 領域定義用
242 // 直接編集できないようにするため
243 // ---------------------------------------------------------------------------
244 
245 template<typename tData>
246 class WeakData
247 {
248 private:
249  template<typename tData2, WeakData<tData2>*> friend class AutoSet;
250  tData mData;
251  void set(const tData& iData)
252  {
253  mData=iData;
254  }
255  const tData& get() {return mData;}
256 
257 public:
258  WeakData()
259  {
260  static_assert(std::is_scalar<tData>::value,
261  "Please use tData is scalar type for WeekData.");
262  }
263 };
264 
265 // ---------------------------------------------------------------------------
266 // 設定用
267 // ---------------------------------------------------------------------------
268 
269 template<typename tData, WeakData<tData>* tWeakData>
270 class THEOLIZER_INTERNAL_DLL AutoSet
271 {
272  AutoSet()
273  {
274  tWeakData->set(tData());
275  }
276  ~AutoSet() { }
277 
278  static AutoSet& getInstance();
279 
280 public:
281  // コピー/ムーブ禁止(デストラクタ定義がないとis_trivially_copyableになる)
282  AutoSet(const AutoSet&) = delete;
283  AutoSet( AutoSet&&) = delete;
284  AutoSet& operator=(const AutoSet&) = delete;
285  AutoSet& operator=( AutoSet&&) = delete;
286 
287  // 設定
288  static int set(const tData& iData, char const* iFile, int iLineNo, int*)
289  {
290  getInstance();
291  if ((tWeakData->get() != tData())
292  && (tWeakData->get() != iData))
293  {
294  std::cout << "\n" << iFile << "(" << iLineNo << ")"
295  << " : Multiple setup the WeakData.\n";
296  exit(1);
297  }
298  tWeakData->set(iData);
299  return 0;
300  }
301 
302  // 返却
303  static tData const& get()
304  {
305  getInstance();
306  return tWeakData->get();
307  }
308 };
309 
310 // ---------------------------------------------------------------------------
311 // 使用するためのマクロ
312 //
313 // ライブラリ側(デフォルト値を設定する)
314 // WeakDataの定義
315 // cpp : WeakData<型> グローバル変数名;
316 // h : extern WeakData<型> グローバル変数名;
317 // 設定されているWeakDataの取出し
318 // cpp : 型 取出し先=THEOLIZER_INTERNAL_GET_WEAK_DATA(グローバル変数名, 型);
319 //
320 // ユーザ側(オプション指定を行う)
321 // cpp : THEOLIZER_INTERNAL_SET_WEAK_DATA(グローバル変数名, 型);
322 // ---------------------------------------------------------------------------
323 
324 #define THEOLIZER_INTERNAL_GET_WEAK_DATA(dWeakData, dType) \
325  theolizer::internal::AutoSet<dType, &dWeakData>::get()
326 
327 // &dUniqueをset()へ渡しているのはコンパイラの「未使用警告」を消すため
328 #define THEOLIZER_INTERNAL_SET_WEAK_DATA(dWeakData, dType, dData, dUnique) \
329  namespace \
330  { \
331  int dUnique=theolizer::internal::AutoSet<dType, &dWeakData>:: \
332  set(dData, THEOLIZER_INTERNAL_FILE, __LINE__, &dUnique); \
333  }
334 
335 #endif // THEOLIZER_INTERNAL_DOXYGEN
336 } // namespace internal
337 
338 // ***************************************************************************
339 // クラス本体
340 // ***************************************************************************
341 
342 //! 動作ログ用のクラス
343 class THEOLIZER_INTERNAL_DLL WorkingLog
344 {
345 //----------------------------------------------------------------------------
346 // 1行出力用ストリーム・クラス(LogStream)
347 // 1行出力のスレッド間排他制御も行う。
348 //----------------------------------------------------------------------------
349 
350 public:
351  //! ログ出力用のストリーム・クラス
352  class THEOLIZER_INTERNAL_DLL LogStream
353  {
354  private:
355  WorkingLog* mWorkingLog;
356 
357  // コンストラクタとデストラクタを対応させるため、コピー不可
358  LogStream(const LogStream&) = delete;
359  void operator =(const LogStream&) = delete;
360 
361  public:
362  //! 動作ログへの出力用コンストラクタ
363  explicit LogStream(WorkingLog* iWorkingLog);
364 
365  //! コピー・コンストラクタ
366  LogStream(LogStream&&);
367 
368  //! デストラクタ
369  ~LogStream() noexcept;
370 
371  //! 出力演算子
372  template<typename Type>
373  LogStream& operator<<(Type iObject)
374  {
375  mWorkingLog->getOStream() << iObject;
376  return *this;
377  }
378  };
379 
380 //----------------------------------------------------------------------------
381 // メンバー変数
382 //----------------------------------------------------------------------------
383 
384 private:
385  struct Impl;
386  std::unique_ptr<Impl> mImpl;
387  static std::string mErrorLogPath;
388  bool mIsUTC;
389 
390  std::ostream& getOStream();
391 
392 //----------------------------------------------------------------------------
393 // メンバー関数
394 //----------------------------------------------------------------------------
395 
396  // 排他制御を混乱させないため、コピー不可
397  WorkingLog(const WorkingLog&) = delete;
398  void operator =(const WorkingLog&) = delete;
399 
400  // スレッドセーフ化
401 public:
402  //! コンストラクタ
403  WorkingLog
404  (
405  const u8string& iPath, //!< ログ・ファイルのパス。
406  //!<(ファイル名には1つの%1%が必要。%1%はファイル番号に展開される。)
407  size_t iFileSize=1024*1024, //!< ログ・ファイル数
408  unsigned iFileCount=2 //!< 1ファイルのサイズ(バイト)
409  );
410  ~WorkingLog() noexcept;
411 
412  //! 行ヘッダの時刻を設定する(UTCタイム or ローカルタイム)
413  void setUTCTime(bool iIsUTC) {mIsUTC = iIsUTC;}
414 
415  //! ログ出力用ストリーム返却(有効な間LogStreamのインスタンスでロックする)
416  LogStream getLogStream();
417 
418  //! 現在時刻獲得(ログ・システムと同じ時間計測方法で獲得する)
419  static time_t getTime(bool iIsUTC=false);
420 
421 //----------------------------------------------------------------------------
422 // 行ヘッダ解析
423 //----------------------------------------------------------------------------
424 
425  //! 行ヘッダ情報
426  struct LineHeader
427  {
428  time_t mDateTime; //!< Mutex獲得直後の日付時刻(秒単位)
429  uint32_t mMilliseconds; //!< Mutex獲得直後の日付時刻のmSec
430  uint32_t mWaitedMicroseconds; //!< Mutex獲得に待った時間
431  std::string mThereadId; //!< ThreadId
432  };
433 
434  //! 行ヘッダを解析する
435  //!  行ヘッダを取り出せたら、iLineHeaderに返却し、trueが返る。
436  //!  その時、*iPosにはログ文字列の先頭Indexが返る。
437  static bool getLineHeader
438  (
439  std::string const& iLine,
440  LineHeader& iLineHeader,
441  size_t* iPos=nullptr
442  ) noexcept;
443 };
444 
445 //############################################################################
446 // エラー通知
447 //############################################################################
448 
449 // ***************************************************************************
450 // エラー付加情報
451 // ***************************************************************************
452 
453 class ErrorInfo;
454 
455 namespace internal
456 {
457 #ifndef THEOLIZER_INTERNAL_DOXYGEN
458 
459 struct THEOLIZER_INTERNAL_DLL BaseAdditionalInfo
460 {
461  BaseAdditionalInfo() { }
462 
463  // メッセージ取り出し
464  virtual u8string getString()=0;
465 
466  // エラー情報伝達
467  virtual void setError(ErrorInfo const& iErrorInfo, bool iConstructor)
468  {
469  }
470 };
471 
472 #endif // THEOLIZER_INTERNAL_DOXYGEN
473 } // namespace internal
474 
475 // ***************************************************************************
476 //! エラー種別
477 // ***************************************************************************
478 
479 enum class ErrorType
480 {
481  None=0, //!< エラー無し
482  Warning, //!< 警告
483  Error //!< エラー
484 };
485 
486 //! エラー種別をシンボル名で出力する
487 THEOLIZER_INTERNAL_DLL std::ostream& operator<<(std::ostream& iOStream, ErrorType iErrorType);
488 
489 // ***************************************************************************
490 //! エラー分類
491 // ***************************************************************************
492 
493 enum class ErrorKind
494 {
495  Unclassified=0, //!< 未分類
496  WrongUsing, //!< 使い方エラー
497 
498  // I/O動作エラー
499  IOError, //!< Read/Write時のI/Oエラー
500 
501  // デシリアイズ時のエラー
502  UnknownData, //!< 非対応シリアライズ・データ・フォーマット
503  UnknownVerson //!< 非対応バージョン
504 };
505 
506 //! エラー分類をシンボル名で出力する
507 THEOLIZER_INTERNAL_DLL std::ostream& operator<<(std::ostream& iOStream, ErrorKind iErrorKind);
508 
509 // ***************************************************************************
510 // エラー通知(例外 or getError())
511 // MinGW不具合対策
512 // thread_localのデストラクタが適切に動作しない不具合がある。
513 // https://sourceforge.net/p/mingw-w64/bugs/445/
514 // デストラクタを呼ばないで良いようstd::stringを使わず固定長とする。
515 // ***************************************************************************
516 
517 //! エラー情報
518 class THEOLIZER_INTERNAL_DLL ErrorInfo
519 {
520  friend class ErrorReporter;
521 
522  ErrorType mErrorType; // エラー種別
523  ErrorKind mErrorKind; // エラー分類
524 
525  // エラー検出位置
526  char const* mFileName; // ファイル名
527  unsigned mLineNo; // 行番号
528 
529 public:
530  //! デフォルト・コンストラクタ
532  mErrorType(ErrorType::None),
533  mErrorKind(ErrorKind::Unclassified),
534  mFileName(nullptr),
535  mLineNo(0),
536  mMessage(),
537  mAdditionalInfo()
538  { }
539 
540  //! メッセージ設定
541  void setMessage(u8string const& iMessage);
542  //! 追加情報設定
543  void setAdditionalInfo(u8string const& iAdditionalInfo);
544 
545  //! エラー種別コード返却
546  ErrorType getErrorType() const {return mErrorType;}
547  //! エラー分類コード返却
548  ErrorKind getErrorKind() const {return mErrorKind;}
549  //! エラーを検出したソース・ファイル名返却
550  char const* getFileName() const {return (mFileName)?mFileName:"<none>";}
551  //! エラーを検出したソース・ファイルの行番号返却
552  unsigned getLineNo() const {return mLineNo;}
553  //! メッセージ返却
554 #if defined(__MINGW32__)
555  u8string const getMessage() const { return mMessage; }
556 #else
557  u8string const& getMessage() const { return mMessage; }
558 #endif
559  //! 追加情報返却
560 #if defined(__MINGW32__)
561  u8string const getAdditionalInfo() const { return mAdditionalInfo; }
562 #else
563  u8string const& getAdditionalInfo() const { return mAdditionalInfo; }
564 #endif
565  //! 全エラー情報を含むエラー・メッセージ返却
566  std::string getString() const;
567 
568  //! エラーか警告ならtrue
569  operator bool() const { return mErrorType != ErrorType::None; }
570  //! エラーも警告もないならtrue
571  bool operator!() const { return mErrorType == ErrorType::None; }
572  //! エラーならtrue
573  bool isError() const
574  {
575  if (!*this)
576  return false;
577  return mErrorType != ErrorType::Warning;
578  }
579 
580 private:
581 #if defined(__MINGW32__)
582  char mMessage[256]; // エラー・メッセージ(固定長)
583  char mAdditionalInfo[256]; // 追加情報(固定長)
584 #else
585  u8string mMessage; // エラー・メッセージ
586  u8string mAdditionalInfo; // 追加情報
587 #endif
588 };
589 
590 //! エラーの内容を出力する
591 THEOLIZER_INTERNAL_DLL std::ostream& operator<<(std::ostream& iOStream, ErrorInfo iErrorInfo);
592 
593 // ***************************************************************************
594 // エラー・ログのファイル・パス指定(UTF-8)
595 //
596 // 内部構造:
597 // TheolizerLib.lib内にてweakシンボルとして定義している。
598 // ***************************************************************************
599 
600 namespace internal
601 {
602 #ifndef THEOLIZER_INTERNAL_DOXYGEN
603 THEOLIZER_INTERNAL_DLL extern WeakData<char const*> gErrorLogPath;
604 #endif // THEOLIZER_INTERNAL_DOXYGEN
605 } // namespace internal
606 
607 //! エラー・ログの有効化
608 #define THEOLIZER_ERRORLOG_FILE(dErrorLogName) \
609  THEOLIZER_INTERNAL_SET_WEAK_DATA(theolizer::internal::gErrorLogPath, \
610  char const*, dErrorLogName, ErrorLogPathDummy)
611 
612 // ***************************************************************************
613 // ErrorReporter内部で使うための宣言
614 // ***************************************************************************
615 
616 namespace internal
617 {
618 #ifndef THEOLIZER_INTERNAL_DOXYGEN
619 class Releasing;
620 class ApiBoundary;
621 void throwDeferred(u8string const&, ErrorKind, char const*, unsigned);
622 bool writeWarning(u8string const&, ErrorKind, char const*, unsigned) noexcept;
623 #endif // THEOLIZER_INTERNAL_DOXYGEN
624 } // namespace internal
625 
626 // ***************************************************************************
627 // エラー管理クラス(シングルトン)
628 // 遅延例外:
629 // リソース解放処理中なら、リソース解放完了まで遅延する。
630 // そうでない時は直ぐに投げる。
631 // ただし、既に例外が発行(mProcessing==true)されていたら、
632 // 多重例外を防ぐため投げない。
633 // ***************************************************************************
634 
635 //! エラー管理シングルトン
636 //!  スレッド毎に1つ存在する
637 class THEOLIZER_INTERNAL_DLL ErrorReporter
638 {
639  friend class internal::Releasing;
640  friend class internal::ApiBoundary;
641  friend void internal::throwDeferred(u8string const&, ErrorKind, char const*, unsigned);
642  friend bool internal::writeWarning(u8string const&,ErrorKind,char const*,unsigned) noexcept;
643 
644  unsigned mReleaseCount; // リソース開放処理中ネスト・カウント
645  bool mIsDeferred; // 例外保留
646  bool mProcessing; // 発生したエラー処理中
647  internal::BaseAdditionalInfo* mAdditionalInfo; // 付加情報提供クラス
648  bool mRegistered; // mAdditionalInfo登録済
649  ErrorInfo mErrorInfo; // エラー情報
650 
651  // コピー/ムーブ禁止
652  ErrorReporter(const ErrorReporter&) = delete;
653  ErrorReporter( ErrorReporter&&) = delete;
654  ErrorReporter& operator=(const ErrorReporter&) = delete;
655  ErrorReporter& operator=( ErrorReporter&&) = delete;
656 
657  // コンストラクタ
658  ErrorReporter() noexcept :
659  mReleaseCount(0),
660  mIsDeferred(false),
661  mProcessing(false),
662  mAdditionalInfo(nullptr),
663  mRegistered(false),
664  mErrorInfo()
665  { }
666 
667  // インスタンス生成
668  static ErrorReporter& getInstance();
669 
670  // エラー・ログ出力とエラー記録
671  bool writeErrorLog
672  (
673  u8string const& iMessage,
674  ErrorType iErrorType,
675  ErrorKind iErrorKind,
676  char const* iFileName,
677  unsigned iLineNo
678  );
679 
680  // 遅延例外の実装
681  void throwDeferredImpl
682  (
683  u8string const& iMessage,
684  ErrorKind iErrorKind,
685  char const* iFileName,
686  unsigned iLineNo
687  );
688 
689  // 警告通知の実装
690  bool writeWarningImpl
691  (
692  u8string const& iMessage,
693  ErrorKind iErrorKind,
694  char const* iFileName,
695  unsigned iLineNo
696  ) noexcept;
697 
698  // エラー・クリア
699  void clearError() noexcept;
700 
701 public:
702  //! エラー情報返却
703  static ErrorInfo const& getErrorInfo() noexcept
704  {
705  return getInstance().mErrorInfo;
706  }
707 
708  //! エラー発生ならtrue
709  static bool isError() noexcept
710  {
711  return getInstance().mErrorInfo.isError();
712  }
713 
714  //! エラー状態を解除する
715  static void resetError() noexcept
716  {
717  return getInstance().clearError();
718  }
719 };
720 
721 namespace internal
722 {
723 #ifndef THEOLIZER_INTERNAL_DOXYGEN
724 
725 //----------------------------------------------------------------------------
726 // private化するために中継
727 //----------------------------------------------------------------------------
728 
729 // 遅延例外
730 inline void throwDeferred
731 (
732  u8string const& iMessage,
734  char const* iFileName=nullptr,
735  unsigned iLineNo=0
736 )
737 {
738  ErrorReporter::getInstance().throwDeferredImpl(iMessage, iErrorKind, iFileName, iLineNo);
739 }
740 
741 // 警告メッセージを記録
742 // ログ・ファイルが指定されていたら、ログへ出力してtrue返却
743 inline bool writeWarning
744 (
745  u8string const& iMessage,
747  char const* iFileName=nullptr,
748  unsigned iLineNo=0
749 ) noexcept
750 {
751  return ErrorReporter::getInstance().writeWarningImpl(iMessage, iErrorKind, iFileName, iLineNo);
752 }
753 
754 // ***************************************************************************
755 // リソース解放処理中の保護と遅延例外の発行
756 // ***************************************************************************
757 
758 class Releasing
759 {
760 public:
761  Releasing() noexcept
762  {
763  ErrorReporter::getInstance().mReleaseCount++;
764  }
765  ~Releasing() noexcept(false)
766  {
767  auto&& aErrorReporter=ErrorReporter::getInstance();
768 
769  THEOLIZER_INTERNAL_ASSERT(aErrorReporter.mReleaseCount,
770  "mReleaseCount is zero at ~Releasing().");
771 
772  aErrorReporter.mReleaseCount--;
773 
774  // リソース解放が終わり、かつ、保留されていたら、例外を投げる
775  if ((aErrorReporter.mReleaseCount == 0) && (aErrorReporter.mIsDeferred))
776  {
777  aErrorReporter.mIsDeferred=false;
778  throw aErrorReporter.mErrorInfo;
779  }
780  }
781 };
782 
783 // ***************************************************************************
784 // APIの境界関数でこのインスタンスを生成する
785 // また、これはエラー追加情報管理領域をErrorReporterへ登録する
786 // すでに登録されていたら
787 // 生成時/開放時の両方で更新しない
788 // iConstructorについて
789 // 例外発行を禁止されたコンストラクタから呼ぶ場合に、trueとする。
790 // iAdditionalInfoは上記コンストラクタのクラスが保持する。
791 // ***************************************************************************
792 
793 class ApiBoundary
794 {
795  bool mRegistered;
796  bool mConstructor;
797 
798 public:
799  ApiBoundary(BaseAdditionalInfo* iAdditionalInfo, bool iConstructor=false) noexcept :
800  mRegistered(false), mConstructor(iConstructor)
801  {
802  auto&& aErrorReporter=ErrorReporter::getInstance();
803  if (aErrorReporter.mRegistered)
804  return;
805 
806  mRegistered=true;
807  aErrorReporter.resetError();
808  aErrorReporter.mAdditionalInfo=iAdditionalInfo;
809  aErrorReporter.mRegistered=true;
810  }
811  ~ApiBoundary() noexcept
812  {
813  auto&& aErrorReporter=ErrorReporter::getInstance();
814 
815  if (mRegistered)
816  {
817  if (aErrorReporter.mAdditionalInfo)
818  {
819  aErrorReporter.mAdditionalInfo->setError(aErrorReporter.mErrorInfo, mConstructor);
820  }
821  aErrorReporter.mRegistered=false;
822  aErrorReporter.mAdditionalInfo=nullptr;
823  aErrorReporter.mProcessing=false; // 例外処理中終了
824  aErrorReporter.mIsDeferred=false; // 念のため
825  }
826  }
827 };
828 
829 #endif // THEOLIZER_INTERNAL_DOXYGEN
830 // ***************************************************************************
831 // エラー管理用基底クラス
832 // ***************************************************************************
833 
834 //! エラー管理用クラス(シリアライザが継承する)
835 class THEOLIZER_INTERNAL_DLL ErrorBase
836 {
837 // ---<<< 発生したエラーの管理 >>>---
838 
839 protected:
840  bool mConstructorError; // コンストラクト実行中エラー
841 private:
842  ErrorInfo mErrorInfo; // エラー情報
843 
844  // エラー報告受領時の排他制御(ヘッダ依存回避のためpImpl)
845  // ErrorReporterはスレッド毎に存在し、ErrorReporterからエラーを受領するため
846  struct Impl;
847  std::unique_ptr<Impl> mImpl;
848 
849 protected:
850  ErrorBase() noexcept;
851  ~ErrorBase() noexcept;
852 
853  // エラー情報受領
854  void setError(ErrorInfo const& iErrorInfo, bool iConstructor) noexcept;
855 
856  // エラー・チェック(エラーが発生したまま呼び出したら例外)
857  void checkError();
858 
859 public:
860  //! エラー情報返却(@ref MemberFunctions 参照)
861  ErrorInfo const& getErrorInfo() const {return mErrorInfo;}
862 
863  //! エラー発生ならtrue(@ref MemberFunctions 参照)
864  bool isError()
865  {
866  return mErrorInfo.isError();
867 
868  }
869 
870  /*!
871  エラー状態を解除する(@ref MemberFunctions 参照)
872 
873  なお、例外不許可の場合、コンストラクト中にエラーが発生すると、エラー状態となる。
874  このコンストラクト中のエラーは解除できない。(解除しても動作できないため)
875  コンストラクト中にエラーになった場合、デストラクトすることのみ可能。
876  */
877  void resetError();
878 };
879 #ifndef THEOLIZER_INTERNAL_DOXYGEN
880 
881 // ***************************************************************************
882 // エラー報告マクロ
883 // エラー・ログがあれば、記録する
884 // ***************************************************************************
885 
886 #define THEOLIZER_INTERNAL_IO_ERROR(...) \
887  theolizer::internal::throwDeferred \
888  ( \
889  theolizer::print(__VA_ARGS__), \
890  theolizer::ErrorKind::IOError, \
891  THEOLIZER_INTERNAL_FILE, \
892  __LINE__ \
893  )
894 
895 #define THEOLIZER_INTERNAL_WRONG_USING(...) \
896  theolizer::internal::throwDeferred \
897  ( \
898  theolizer::print(__VA_ARGS__), \
899  theolizer::ErrorKind::WrongUsing, \
900  THEOLIZER_INTERNAL_FILE, \
901  __LINE__ \
902  )
903 
904 #define THEOLIZER_INTERNAL_DATA_ERROR(...) \
905  theolizer::internal::throwDeferred \
906  ( \
907  theolizer::print(__VA_ARGS__), \
908  theolizer::ErrorKind::UnknownData, \
909  THEOLIZER_INTERNAL_FILE, \
910  __LINE__ \
911  )
912 
913 #define THEOLIZER_INTERNAL_VERSION_ERROR(...) \
914  theolizer::internal::throwDeferred \
915  ( \
916  theolizer::print(__VA_ARGS__), \
917  theolizer::ErrorKind::UnknownVerson, \
918  THEOLIZER_INTERNAL_FILE, \
919  __LINE__ \
920  )
921 
922 // ---<<< 分類無し >>>---
923 
924 #define THEOLIZER_INTERNAL_ERROR(...) \
925  theolizer::internal::throwDeferred \
926  ( \
927  theolizer::print(__VA_ARGS__), \
928  theolizer::ErrorKind::Unclassified, \
929  THEOLIZER_INTERNAL_FILE, \
930  __LINE__ \
931  )
932 
933 #define THEOLIZER_INTERNAL_WARNING(...) \
934  theolizer::internal::writeWarning \
935  ( \
936  theolizer::print(__VA_ARGS__), \
937  theolizer::ErrorKind::Unclassified, \
938  THEOLIZER_INTERNAL_FILE, \
939  __LINE__ \
940  )
941 
942 #endif // THEOLIZER_INTERNAL_DOXYGEN
943 } // namespace internal
944 
945 //############################################################################
946 // End
947 //############################################################################
948 
949 } // namespace theolizer
950 
951 // ***************************************************************************
952 // 警告抑止解除
953 // ***************************************************************************
954 
955 #ifdef _MSC_VER
956  #pragma warning(pop)
957 #endif
958 
959 #endif // THEOLIZER_INTERNAL_REPORT_H
ErrorInfo const & getErrorInfo() const
エラー情報返却(3-1-2.メンバ関数 参照)
Definition: report.h:861
theolizer名前空間
Definition: base.h:53
非対応シリアライズ・データ・フォーマット
bool isError() const
エラーならtrue
Definition: report.h:573
エラー情報
Definition: report.h:518
非対応バージョン
ErrorType
エラー種別
Definition: report.h:479
unsigned getLineNo() const
エラーを検出したソース・ファイルの行番号返却
Definition: report.h:552
LogStream & operator<<(Type iObject)
出力演算子
Definition: report.h:373
static void resetError() noexcept
エラー状態を解除する
Definition: report.h:715
Unicode記録用文字列クラスu8string.
Definition: u8string.h:274
void setUTCTime(bool iIsUTC)
行ヘッダの時刻を設定する(UTCタイム or ローカルタイム)
Definition: report.h:413
uint32_t mWaitedMicroseconds
Mutex獲得に待った時間
Definition: report.h:430
std::string mThereadId
ThreadId.
Definition: report.h:431
行ヘッダ情報
Definition: report.h:426
uint32_t mMilliseconds
Mutex獲得直後の日付時刻のmSec.
Definition: report.h:429
ErrorType getErrorType() const
エラー種別コード返却
Definition: report.h:546
u8string const & getMessage() const
メッセージ返却
Definition: report.h:557
ErrorInfo()
デフォルト・コンストラクタ
Definition: report.h:531
u8string const & getAdditionalInfo() const
追加情報返却
Definition: report.h:563
Read/Write時のI/Oエラー
bool isError()
エラー発生ならtrue(3-1-2.メンバ関数 参照)
Definition: report.h:864
u8string print(u8string const &iFormat, tParams... iParams)
boost::formatのラッパ。
Definition: report.h:181
static ErrorInfo const & getErrorInfo() noexcept
エラー情報返却
Definition: report.h:703
char const * getFileName() const
エラーを検出したソース・ファイル名返却
Definition: report.h:550
エラー管理用クラス(シリアライザが継承する)
Definition: report.h:835
Unicode文字列用補助ツール群
ErrorKind getErrorKind() const
エラー分類コード返却
Definition: report.h:548
ログ出力用のストリーム・クラス
Definition: report.h:352
THEOLIZER_INTERNAL_DLL std::ostream & operator<<(std::ostream &iOStream, CheckMode iCheckMode)
CheckModeの表示用オーバーロード
static bool isError() noexcept
エラー発生ならtrue
Definition: report.h:709
ErrorKind
エラー分類
Definition: report.h:493
動作ログ用のクラス
Definition: report.h:343
bool operator!() const
エラーも警告もないならtrue
Definition: report.h:571
time_t mDateTime
Mutex獲得直後の日付時刻(秒単位)
Definition: report.h:428