/*---------------------------------------------------------------------------* Project: Horizon File: Result.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 25607 $ *---------------------------------------------------------------------------*/ /*! @file @brief Result クラスの宣言 :include nn/Result.h */ #ifndef NN_RESULT_H_ #define NN_RESULT_H_ #include #include //------------------------------------------------------------------- // for C / C++ /*! @addtogroup nn_root @{ */ /*! @defgroup nn_Result_c Result (C) @brief 処理の結果を示すnn::ResultのC インタフェースモジュールです。 @{ */ #ifdef __cplusplus extern "C" { #endif // ifdef __cplusplus /*! @brief 処理の結果を示す構造体です。C の API で使用します。 */ typedef struct nnResult { bit32 value; } nnResult; #ifdef __cplusplus } #endif // ifdef __cplusplus /*! @} */ /*! @} */ //------------------------------------------------------------------- // for C++ #ifdef __cplusplus namespace nn { /*! @brief 処理の結果を示すクラスです。 */ class Result{ private: static const bit32 MASK_FAIL_BIT = 0x80000000u; // 最上位ビット static const s32 SIZE_DESCRIPTION = 10; static const s32 SIZE_MODULE = 8; static const s32 SIZE_RESERVE = 3; static const s32 SIZE_SUMMARY = 6; static const s32 SIZE_LEVEL = 5; static const s32 SHIFTS_DESCRIPTION = 0; static const s32 SHIFTS_MODULE = SHIFTS_DESCRIPTION + SIZE_DESCRIPTION; static const s32 SHIFTS_RESERVE = SHIFTS_MODULE + SIZE_MODULE; static const s32 SHIFTS_SUMMARY = SHIFTS_RESERVE + SIZE_RESERVE; static const s32 SHIFTS_LEVEL = SHIFTS_SUMMARY + SIZE_SUMMARY; NN_STATIC_ASSERT( SHIFTS_LEVEL + SIZE_LEVEL == 32 ); static const bit32 MASK_NEGATIVE_LEVEL = (~0u) << SIZE_LEVEL; #define NN_RESULT_H_MAKE_MASK(size, shift) (((~0u) >> (32 - (size))) << (shift)) #define NN_RESULT_H_MAKE_MASK_HELPER(c) \ static const bit32 MASK_ ## c = NN_RESULT_H_MAKE_MASK(SIZE_ ## c, SHIFTS_ ## c) NN_RESULT_H_MAKE_MASK_HELPER(DESCRIPTION); NN_RESULT_H_MAKE_MASK_HELPER(MODULE); NN_RESULT_H_MAKE_MASK_HELPER(SUMMARY); NN_RESULT_H_MAKE_MASK_HELPER(LEVEL); #undef NN_RESULT_H_MAKE_MASK_HELPER #undef NN_RESULT_H_MAKE_MASK #define NN_RESULT_H_MAKE_MAX(size) ((~0u) >> (32 - (size))) #define NN_RESULT_H_MAKE_MAX_HELPER(c) \ static const s32 MAX_ ## c = NN_RESULT_H_MAKE_MAX(SIZE_ ## c) NN_RESULT_H_MAKE_MAX_HELPER(DESCRIPTION); NN_RESULT_H_MAKE_MAX_HELPER(MODULE); NN_RESULT_H_MAKE_MAX_HELPER(SUMMARY); NN_RESULT_H_MAKE_MAX_HELPER(LEVEL); #undef NN_RESULT_H_MAKE_MAX_HELPER #undef NN_RESULT_H_MAKE_MAX public: /*! * @brief エラーの重要度を示す列挙体です。 * * Bug: 列挙体の定義は将来変更されます。 */ enum Level { //! 成功。追加情報あり。 LEVEL_INFO = 1, //! 成功。追加情報なし。 LEVEL_SUCCESS = 0, //! システムレベルの致命的なエラー。ソフトウェアでの復旧不可能。サポートセンター案内シーケンスへ移行。 LEVEL_FATAL = -1, //! 予想されていないエラー。リセットシーケンスへ移行すべき。モジュールの再初期化で回復する見込みはないがリセットで回復する可能性がある。 LEVEL_RESET = -2, //! モジュールの再初期化が必要なエラー。 LEVEL_REINIT = -3, //! プログラミング上のエラー。指定された引数では内部状態によらず必ずエラーである。 LEVEL_USAGE = -4, //! 通常のエラー。リトライできない。 LEVEL_PERMANENT = -5, //! 一時的な失敗。同じ引数で即リトライできる。比較的少ないリトライ回数で成功する。 LEVEL_TEMPORARY = -6, //! 予想された失敗。 LEVEL_STATUS = -7, //! この値は使用されません。 LEVEL_END }; /*! * @brief エラーの概要を示す列挙体です。 * * Bug: 列挙体の定義は将来変更されます。 */ enum Summary { SUMMARY_SUCCESS = 0, SUMMARY_NOTHING_HAPPENED = 1, SUMMARY_WOULD_BLOCK = 2, SUMMARY_OUT_OF_RESOURCE = 3, SUMMARY_NOT_FOUND = 4, SUMMARY_INVALID_STATE = 5, SUMMARY_NOT_SUPPORTED = 6, SUMMARY_INVALID_ARGUMENT = 7, SUMMARY_WRONG_ARGUMENT = 8, SUMMARY_CANCELLED = 9, SUMMARY_STATUS_CHANGED = 10, SUMMARY_INTERNAL = 11, SUMMARY_INVALID_RESULT_VALUE = MAX_SUMMARY }; /*! * @brief エラーが発生したモジュールを示す列挙体です。 * * Bug: 列挙体の定義は将来変更されます。 */ enum Module { MODULE_COMMON = 0, MODULE_NN_KERNEL = 1, MODULE_NN_UTIL, MODULE_NN_FILE_SERVER, MODULE_NN_LOADER_SERVER, MODULE_NN_TCB, MODULE_NN_OS, MODULE_NN_DBG, MODULE_NN_DMNT, MODULE_NN_PDN, MODULE_NN_GX, MODULE_NN_I2C, MODULE_NN_GPIO, MODULE_NN_DD, MODULE_NN_CODEC, MODULE_NN_SPI, MODULE_NN_PXI, MODULE_NN_FS, MODULE_NN_DI, MODULE_NN_HID, MODULE_NN_CAMERA, MODULE_NN_PI, MODULE_NN_PM, MODULE_NN_PMLOW, MODULE_NN_FSI, MODULE_NN_SRV, MODULE_NN_NDM, MODULE_NN_NWM, MODULE_NN_SOCKET, MODULE_NN_LDR, MODULE_NN_ACC, MODULE_NN_ROMFS, MODULE_NN_AM, MODULE_NN_HIO, MODULE_NN_UPDATER, MODULE_NN_MIC, MODULE_NN_FND, MODULE_NN_MP, MODULE_NN_MPWL, MODULE_NN_AC, MODULE_NN_HTTP, MODULE_NN_DSP, MODULE_NN_SND, MODULE_NN_DLP, MODULE_NN_HIOLOW, MODULE_NN_CSND, MODULE_NN_SSL, MODULE_NN_AMLOW, MODULE_NN_NEX, MODULE_NN_FRIENDS, MODULE_NN_RDT, MODULE_NN_APPLET, MODULE_NN_NIM, MODULE_NN_PTM, MODULE_NN_MIDI, MODULE_NN_MC, MODULE_NN_SWC, MODULE_NN_FATFS, MODULE_NN_NGC, MODULE_NN_CARD, MODULE_NN_CARDNOR, MODULE_NN_SDMC, MODULE_NN_BOSS, MODULE_NN_DBM, MODULE_NN_CFG, MODULE_NN_PS, MODULE_NN_CEC, MODULE_NN_IR, MODULE_NN_UDS, MODULE_NN_PL, MODULE_NN_CUP, MODULE_INVALID_RESULT_VALUE = MAX_MODULE }; enum Description { DESCRIPTION_SUCCESS = 0, DESCRIPTION_INVALID_SELECTION = MAX_DESCRIPTION - 23, DESCRIPTION_TOO_LARGE = MAX_DESCRIPTION - 22, DESCRIPTION_NOT_AUTHORIZED = MAX_DESCRIPTION - 21, DESCRIPTION_ALREADY_DONE = MAX_DESCRIPTION - 20, DESCRIPTION_INVALID_SIZE = MAX_DESCRIPTION - 19, DESCRIPTION_INVALID_ENUM_VALUE = MAX_DESCRIPTION - 18, DESCRIPTION_INVALID_COMBINATION = MAX_DESCRIPTION - 17, DESCRIPTION_NO_DATA = MAX_DESCRIPTION - 16, DESCRIPTION_BUSY = MAX_DESCRIPTION - 15, DESCRIPTION_MISALIGNED_ADDRESS = MAX_DESCRIPTION - 14, DESCRIPTION_MISALIGNED_SIZE = MAX_DESCRIPTION - 13, DESCRIPTION_OUT_OF_MEMORY = MAX_DESCRIPTION - 12, DESCRIPTION_NOT_IMPLEMENTED = MAX_DESCRIPTION - 11, DESCRIPTION_INVALID_ADDRESS = MAX_DESCRIPTION - 10, DESCRIPTION_INVALID_POINTER = MAX_DESCRIPTION - 9, DESCRIPTION_INVALID_HANDLE = MAX_DESCRIPTION - 8, DESCRIPTION_NOT_INITIALIZED = MAX_DESCRIPTION - 7, DESCRIPTION_ALREADY_INITIALIZED = MAX_DESCRIPTION - 6, DESCRIPTION_NOT_FOUND = MAX_DESCRIPTION - 5, DESCRIPTION_CANCEL_REQUESTED = MAX_DESCRIPTION - 4, DESCRIPTION_ALREADY_EXISTS = MAX_DESCRIPTION - 3, DESCRIPTION_OUT_OF_RANGE = MAX_DESCRIPTION - 2, DESCRIPTION_TIMEOUT = MAX_DESCRIPTION - 1, DESCRIPTION_INVALID_RESULT_VALUE = MAX_DESCRIPTION - 0 }; private: bit32 m_Code; template friend struct Const; explicit Result(bit32 code) : m_Code(code) {} public: Result() : m_Code( static_cast( ((static_cast(LEVEL_USAGE) << SHIFTS_LEVEL) & MASK_LEVEL) | ((SUMMARY_INVALID_RESULT_VALUE << SHIFTS_SUMMARY) & MASK_SUMMARY) | ((MODULE_INVALID_RESULT_VALUE << SHIFTS_MODULE) & MASK_MODULE) | ((DESCRIPTION_INVALID_RESULT_VALUE << SHIFTS_DESCRIPTION) & MASK_DESCRIPTION) )) { } Result(Level level, Summary summary, Module module, int description) : m_Code( static_cast( ((level << SHIFTS_LEVEL) & MASK_LEVEL) | ((summary << SHIFTS_SUMMARY) & MASK_SUMMARY) | ((module << SHIFTS_MODULE) & MASK_MODULE) | ((description << SHIFTS_DESCRIPTION) & MASK_DESCRIPTION) )) { } Result(nnResult result) : m_Code(result.value) {} /*! * @brief 処理の結果が失敗なら true を、成功なら false を返します。 */ bool IsFailure() const { return (m_Code & MASK_FAIL_BIT) != 0; } /*! * @brief 処理の結果が成功なら true を、失敗なら false を返します。 */ bool IsSuccess() const { return !IsFailure(); } /*! * @brief エラーの深刻度を示す Level 列挙体を返します。 * * Bug: 列挙体の定義は将来変更されます。現状では利用しないでください。 */ Level GetLevel() const { // TODO: プラットフォーム依存の算術シフトインライン関数を作ってそれを呼ぶべき if(m_Code & MASK_FAIL_BIT) { return static_cast( GetCodeBits(MASK_LEVEL, SHIFTS_LEVEL) | MASK_NEGATIVE_LEVEL); } else { return static_cast( GetCodeBits(MASK_LEVEL, SHIFTS_LEVEL) ); } } /*! * @brief エラーの概要を示す Summary 列挙体を返します。 * * Bug: 列挙体の定義は将来変更されます。現状では利用しないでください。 */ Summary GetSummary() const { return static_cast( GetCodeBits(MASK_SUMMARY, SHIFTS_SUMMARY) ); } /*! * @brief エラーが発生したモジュールを示す Module 列挙体を返します。 * * * Bug: 列挙体の定義は将来変更されます。現状では利用しないでください。 */ Module GetModule() const { return static_cast( GetCodeBits(MASK_MODULE, SHIFTS_MODULE) ); } int GetDescription() const { return static_cast( GetCodeBits(MASK_DESCRIPTION, SHIFTS_DESCRIPTION) ); } bit32 GetValue() const { return m_Code; } bit32 GetPrintableBits() const { return m_Code; } operator nnResult() const { nnResult r = {m_Code}; return r; } bool operator ==(const Result& rhs) const { return this->m_Code == rhs.m_Code; } bool operator !=(const Result& rhs) const { return this->m_Code != rhs.m_Code; } template struct Const; template struct Const_LSM; template struct Const_LM; template struct Const_L; private: bit32 GetCodeBits(bit32 mask, s32 shift) const { return ((m_Code & mask) >> shift); } }; template struct Result::Const : public Result { static const Result::Level Level = TLevel; static const Result::Summary Summary = TSummary; static const Result::Module Module = TModule; static const int Description = TDescription; static const bit32 Value = static_cast( ((static_cast(TLevel) << SHIFTS_LEVEL) & MASK_LEVEL) | ((TSummary << SHIFTS_SUMMARY) & MASK_SUMMARY) | ((TModule << SHIFTS_MODULE) & MASK_MODULE) | ((TDescription << SHIFTS_DESCRIPTION) & MASK_DESCRIPTION) ); Const() : Result(Value) {} }; template struct Result::Const_LSM : public Result { static const Result::Level Level = TLevel; static const Result::Summary Summary = TSummary; static const Result::Module Module = TModule; template struct Const : public Result::Const {}; Const_LSM(int description) : Result(TLevel, TSummary, TModule, description) {} }; template struct Result::Const_LM : public Result { static const Result::Level Level = TLevel; static const Result::Module Module = TModule; template struct Const : public Result::Const {}; Const_LM(Result::Summary summary, int description) : Result(TLevel, summary, TModule, description) {} }; template struct Result::Const_L : public Result { static const Result::Level Level = TLevel; template struct Const : public Result::Const {}; Const_L(Result::Summary summary, Result::Module module, int description) : Result(TLevel, summary, module, description) {} }; #define NN_DEFINE_RESULT_CONST(name, level, summary, module, description) \ typedef ::nn::Result::Const<(level), (summary), (module), (description)> name NN_DEFINE_RESULT_CONST(ResultSuccess, Result::LEVEL_SUCCESS, Result::SUMMARY_SUCCESS, Result::MODULE_COMMON, Result::DESCRIPTION_SUCCESS); #define NN_DEFINE_RESULT_FUNC_LSM(name, level, summary, module) \ typedef ::nn::Result::Const_LSM<(level), (summary), (module)> name #define NN_DEFINE_RESULT_CONST_LSM(name, f, description) \ typedef f::Const<(description)> name #define NN_DEFINE_RESULT_FUNC_LM(name, level, module) \ typedef ::nn::Result::Const_LM<(level), (module)> name #define NN_DEFINE_RESULT_CONST_LM(name, f, summary, description) \ typedef f::Const<(summary), (description)> name #define NN_DEFINE_RESULT_FUNC_L(name, level) \ typedef ::nn::Result::Const_L<(level)> name #define NN_DEFINE_RESULT_CONST_L(name, f, summary, module, description) \ typedef f::Const<(summary), (module), (description)> name // 完全移行まではコメントアウト //NN_DEFINE_RESULT_FUNC_L(MakeInfoResult, LEVEL_INFO); //NN_DEFINE_RESULT_FUNC_L(MakeFatalResult, LEVEL_FATAL); //NN_DEFINE_RESULT_FUNC_L(MakeResetResult, LEVEL_RESET); //NN_DEFINE_RESULT_FUNC_L(MakeReInitResult, LEVEL_REINIT); //NN_DEFINE_RESULT_FUNC_L(MakeUsageResult, LEVEL_USAGE); //NN_DEFINE_RESULT_FUNC_L(MakePermanentResult, LEVEL_PERMANENT); //NN_DEFINE_RESULT_FUNC_L(MakeTemporaryResult, LEVEL_TEMPORARY); //NN_DEFINE_RESULT_FUNC_L(MakeStatusResult, LEVEL_STATUS); inline Result MakeInfoResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_INFO, summary, module, description); } inline Result MakeFatalResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_FATAL, summary, module, description); } inline Result MakeResetResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_RESET, summary, module, description); } inline Result MakeReInitResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_REINIT, summary, module, description); } inline Result MakeUsageResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_USAGE, summary, module, description); } inline Result MakePermanentResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_PERMANENT, summary, module, description); } inline Result MakeTemporaryResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_TEMPORARY, summary, module, description); } inline Result MakeStatusResult(Result::Summary summary, Result::Module module, int description) { return Result(Result::LEVEL_STATUS, summary, module, description); } } #endif // __cplusplus #ifdef __cplusplus extern "C" { #endif int nnResultFailureHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...); int nnResultTFailureHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...); int nnResultPanicHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...); int nnResultTPanicHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...); nnResult nnMakeInvalidResult(void); #ifdef __cplusplus } #endif #endif /* NN_RESULT_H_ */