1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: Result.h
4
5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 25607 $
14 *---------------------------------------------------------------------------*/
15
16 /*!
17 @file
18 @brief Result クラスの宣言
19
20 :include nn/Result.h
21 */
22
23 #ifndef NN_RESULT_H_
24 #define NN_RESULT_H_
25
26 #include <nn/types.h>
27 #include <nn/util/util_StaticAssert.h>
28
29 //-------------------------------------------------------------------
30 // for C / C++
31
32 /*!
33 @addtogroup nn_root
34 @{
35 */
36
37 /*!
38 @defgroup nn_Result_c Result (C)
39
40 @brief 処理の結果を示すnn::ResultのC インタフェースモジュールです。
41
42 @{
43 */
44
45
46 #ifdef __cplusplus
47 extern "C" {
48 #endif // ifdef __cplusplus
49
50 /*!
51 @brief 処理の結果を示す構造体です。C の API で使用します。
52 */
53 typedef struct nnResult
54 {
55 bit32 value;
56 }
57 nnResult;
58
59 #ifdef __cplusplus
60 }
61 #endif // ifdef __cplusplus
62
63 /*!
64 @}
65 */
66 /*!
67 @}
68 */
69
70
71 //-------------------------------------------------------------------
72 // for C++
73
74 #ifdef __cplusplus
75
76 namespace nn {
77
78 /*!
79 @brief 処理の結果を示すクラスです。
80 */
81
82 class Result{
83 private:
84 static const bit32 MASK_FAIL_BIT = 0x80000000u; // 最上位ビット
85
86 static const s32 SIZE_DESCRIPTION = 10;
87 static const s32 SIZE_MODULE = 8;
88 static const s32 SIZE_RESERVE = 3;
89 static const s32 SIZE_SUMMARY = 6;
90 static const s32 SIZE_LEVEL = 5;
91
92 static const s32 SHIFTS_DESCRIPTION = 0;
93 static const s32 SHIFTS_MODULE = SHIFTS_DESCRIPTION + SIZE_DESCRIPTION;
94 static const s32 SHIFTS_RESERVE = SHIFTS_MODULE + SIZE_MODULE;
95 static const s32 SHIFTS_SUMMARY = SHIFTS_RESERVE + SIZE_RESERVE;
96 static const s32 SHIFTS_LEVEL = SHIFTS_SUMMARY + SIZE_SUMMARY;
97 NN_STATIC_ASSERT( SHIFTS_LEVEL + SIZE_LEVEL == 32 );
98
99 static const bit32 MASK_NEGATIVE_LEVEL = (~0u) << SIZE_LEVEL;
100
101 #define NN_RESULT_H_MAKE_MASK(size, shift) (((~0u) >> (32 - (size))) << (shift))
102 #define NN_RESULT_H_MAKE_MASK_HELPER(c) \
103 static const bit32 MASK_ ## c = NN_RESULT_H_MAKE_MASK(SIZE_ ## c, SHIFTS_ ## c)
104 NN_RESULT_H_MAKE_MASK_HELPER(DESCRIPTION);
105 NN_RESULT_H_MAKE_MASK_HELPER(MODULE);
106 NN_RESULT_H_MAKE_MASK_HELPER(SUMMARY);
107 NN_RESULT_H_MAKE_MASK_HELPER(LEVEL);
108 #undef NN_RESULT_H_MAKE_MASK_HELPER
109 #undef NN_RESULT_H_MAKE_MASK
110
111 #define NN_RESULT_H_MAKE_MAX(size) ((~0u) >> (32 - (size)))
112 #define NN_RESULT_H_MAKE_MAX_HELPER(c) \
113 static const s32 MAX_ ## c = NN_RESULT_H_MAKE_MAX(SIZE_ ## c)
114 NN_RESULT_H_MAKE_MAX_HELPER(DESCRIPTION);
115 NN_RESULT_H_MAKE_MAX_HELPER(MODULE);
116 NN_RESULT_H_MAKE_MAX_HELPER(SUMMARY);
117 NN_RESULT_H_MAKE_MAX_HELPER(LEVEL);
118 #undef NN_RESULT_H_MAKE_MAX_HELPER
119 #undef NN_RESULT_H_MAKE_MAX
120
121 public:
122 /*!
123 * @brief エラーの重要度を示す列挙体です。
124 *
125 * Bug: 列挙体の定義は将来変更されます。
126 */
127 enum Level
128 {
129 //! 成功。追加情報あり。
130 LEVEL_INFO = 1,
131 //! 成功。追加情報なし。
132 LEVEL_SUCCESS = 0,
133 //! システムレベルの致命的なエラー。ソフトウェアでの復旧不可能。サポートセンター案内シーケンスへ移行。
134 LEVEL_FATAL = -1,
135 //! 予想されていないエラー。リセットシーケンスへ移行すべき。モジュールの再初期化で回復する見込みはないがリセットで回復する可能性がある。
136 LEVEL_RESET = -2,
137 //! モジュールの再初期化が必要なエラー。
138 LEVEL_REINIT = -3,
139 //! プログラミング上のエラー。指定された引数では内部状態によらず必ずエラーである。
140 LEVEL_USAGE = -4,
141 //! 通常のエラー。リトライできない。
142 LEVEL_PERMANENT = -5,
143 //! 一時的な失敗。同じ引数で即リトライできる。比較的少ないリトライ回数で成功する。
144 LEVEL_TEMPORARY = -6,
145 //! 予想された失敗。
146 LEVEL_STATUS = -7,
147 //! この値は使用されません。
148 LEVEL_END
149 };
150
151 /*!
152 * @brief エラーの概要を示す列挙体です。
153 *
154 * Bug: 列挙体の定義は将来変更されます。
155 */
156 enum Summary
157 {
158 SUMMARY_SUCCESS = 0,
159 SUMMARY_NOTHING_HAPPENED = 1,
160 SUMMARY_WOULD_BLOCK = 2,
161 SUMMARY_OUT_OF_RESOURCE = 3,
162 SUMMARY_NOT_FOUND = 4,
163 SUMMARY_INVALID_STATE = 5,
164 SUMMARY_NOT_SUPPORTED = 6,
165 SUMMARY_INVALID_ARGUMENT = 7,
166 SUMMARY_WRONG_ARGUMENT = 8,
167 SUMMARY_CANCELLED = 9,
168 SUMMARY_STATUS_CHANGED = 10,
169 SUMMARY_INTERNAL = 11,
170
171 SUMMARY_INVALID_RESULT_VALUE = MAX_SUMMARY
172 };
173
174 /*!
175 * @brief エラーが発生したモジュールを示す列挙体です。
176 *
177 * Bug: 列挙体の定義は将来変更されます。
178 */
179 enum Module
180 {
181 MODULE_COMMON = 0,
182 MODULE_NN_KERNEL = 1,
183 MODULE_NN_UTIL,
184 MODULE_NN_FILE_SERVER,
185 MODULE_NN_LOADER_SERVER,
186 MODULE_NN_TCB,
187 MODULE_NN_OS,
188 MODULE_NN_DBG,
189 MODULE_NN_DMNT,
190 MODULE_NN_PDN,
191 MODULE_NN_GX,
192 MODULE_NN_I2C,
193 MODULE_NN_GPIO,
194 MODULE_NN_DD,
195 MODULE_NN_CODEC,
196 MODULE_NN_SPI,
197 MODULE_NN_PXI,
198 MODULE_NN_FS,
199 MODULE_NN_DI,
200 MODULE_NN_HID,
201 MODULE_NN_CAMERA,
202 MODULE_NN_PI,
203 MODULE_NN_PM,
204 MODULE_NN_PMLOW,
205 MODULE_NN_FSI,
206 MODULE_NN_SRV,
207 MODULE_NN_NDM,
208 MODULE_NN_NWM,
209 MODULE_NN_SOCKET,
210 MODULE_NN_LDR,
211 MODULE_NN_ACC,
212 MODULE_NN_ROMFS,
213 MODULE_NN_AM,
214 MODULE_NN_HIO,
215 MODULE_NN_UPDATER,
216 MODULE_NN_MIC,
217 MODULE_NN_FND,
218 MODULE_NN_MP,
219 MODULE_NN_MPWL,
220 MODULE_NN_AC,
221 MODULE_NN_HTTP,
222 MODULE_NN_DSP,
223 MODULE_NN_SND,
224 MODULE_NN_DLP,
225 MODULE_NN_HIOLOW,
226 MODULE_NN_CSND,
227 MODULE_NN_SSL,
228 MODULE_NN_AMLOW,
229 MODULE_NN_NEX,
230 MODULE_NN_FRIENDS,
231 MODULE_NN_RDT,
232 MODULE_NN_APPLET,
233 MODULE_NN_NIM,
234 MODULE_NN_PTM,
235 MODULE_NN_MIDI,
236 MODULE_NN_MC,
237 MODULE_NN_SWC,
238 MODULE_NN_FATFS,
239 MODULE_NN_NGC,
240 MODULE_NN_CARD,
241 MODULE_NN_CARDNOR,
242 MODULE_NN_SDMC,
243 MODULE_NN_BOSS,
244 MODULE_NN_DBM,
245 MODULE_NN_CFG,
246 MODULE_NN_PS,
247 MODULE_NN_CEC,
248 MODULE_NN_IR,
249 MODULE_NN_UDS,
250 MODULE_NN_PL,
251 MODULE_NN_CUP,
252 MODULE_INVALID_RESULT_VALUE = MAX_MODULE
253 };
254
255 enum Description
256 {
257 DESCRIPTION_SUCCESS = 0,
258
259 DESCRIPTION_INVALID_SELECTION = MAX_DESCRIPTION - 23,
260 DESCRIPTION_TOO_LARGE = MAX_DESCRIPTION - 22,
261 DESCRIPTION_NOT_AUTHORIZED = MAX_DESCRIPTION - 21,
262 DESCRIPTION_ALREADY_DONE = MAX_DESCRIPTION - 20,
263 DESCRIPTION_INVALID_SIZE = MAX_DESCRIPTION - 19,
264 DESCRIPTION_INVALID_ENUM_VALUE = MAX_DESCRIPTION - 18,
265 DESCRIPTION_INVALID_COMBINATION = MAX_DESCRIPTION - 17,
266 DESCRIPTION_NO_DATA = MAX_DESCRIPTION - 16,
267 DESCRIPTION_BUSY = MAX_DESCRIPTION - 15,
268 DESCRIPTION_MISALIGNED_ADDRESS = MAX_DESCRIPTION - 14,
269 DESCRIPTION_MISALIGNED_SIZE = MAX_DESCRIPTION - 13,
270 DESCRIPTION_OUT_OF_MEMORY = MAX_DESCRIPTION - 12,
271 DESCRIPTION_NOT_IMPLEMENTED = MAX_DESCRIPTION - 11,
272 DESCRIPTION_INVALID_ADDRESS = MAX_DESCRIPTION - 10,
273 DESCRIPTION_INVALID_POINTER = MAX_DESCRIPTION - 9,
274 DESCRIPTION_INVALID_HANDLE = MAX_DESCRIPTION - 8,
275 DESCRIPTION_NOT_INITIALIZED = MAX_DESCRIPTION - 7,
276 DESCRIPTION_ALREADY_INITIALIZED = MAX_DESCRIPTION - 6,
277 DESCRIPTION_NOT_FOUND = MAX_DESCRIPTION - 5,
278 DESCRIPTION_CANCEL_REQUESTED = MAX_DESCRIPTION - 4,
279 DESCRIPTION_ALREADY_EXISTS = MAX_DESCRIPTION - 3,
280 DESCRIPTION_OUT_OF_RANGE = MAX_DESCRIPTION - 2,
281 DESCRIPTION_TIMEOUT = MAX_DESCRIPTION - 1,
282 DESCRIPTION_INVALID_RESULT_VALUE = MAX_DESCRIPTION - 0
283 };
284
285 private:
286
287 bit32 m_Code;
288
289 template <Result::Level TLevel, Result::Summary TSummary, Result::Module TModule, int TDescription> friend struct Const;
Result(bit32 code)290 explicit Result(bit32 code) : m_Code(code) {}
291
292 public:
Result()293 Result()
294 : m_Code( static_cast<bit32>(
295 ((static_cast<bit32>(LEVEL_USAGE) << SHIFTS_LEVEL) & MASK_LEVEL) |
296 ((SUMMARY_INVALID_RESULT_VALUE << SHIFTS_SUMMARY) & MASK_SUMMARY) |
297 ((MODULE_INVALID_RESULT_VALUE << SHIFTS_MODULE) & MASK_MODULE) |
298 ((DESCRIPTION_INVALID_RESULT_VALUE << SHIFTS_DESCRIPTION) & MASK_DESCRIPTION) ))
299 {
300 }
301
Result(Level level,Summary summary,Module module,int description)302 Result(Level level, Summary summary, Module module, int description)
303 : m_Code( static_cast<bit32>(
304 ((level << SHIFTS_LEVEL) & MASK_LEVEL) |
305 ((summary << SHIFTS_SUMMARY) & MASK_SUMMARY) |
306 ((module << SHIFTS_MODULE) & MASK_MODULE) |
307 ((description << SHIFTS_DESCRIPTION) & MASK_DESCRIPTION) ))
308 {
309 }
310
Result(nnResult result)311 Result(nnResult result) : m_Code(result.value) {}
312
313 /*!
314 * @brief 処理の結果が失敗なら true を、成功なら false を返します。
315 */
IsFailure()316 bool IsFailure() const
317 {
318 return (m_Code & MASK_FAIL_BIT) != 0;
319 }
320
321 /*!
322 * @brief 処理の結果が成功なら true を、失敗なら false を返します。
323 */
IsSuccess()324 bool IsSuccess() const
325 {
326 return !IsFailure();
327 }
328
329 /*!
330 * @brief エラーの深刻度を示す Level 列挙体を返します。
331 *
332 * Bug: 列挙体の定義は将来変更されます。現状では利用しないでください。
333 */
GetLevel()334 Level GetLevel() const
335 {
336 // TODO: プラットフォーム依存の算術シフトインライン関数を作ってそれを呼ぶべき
337 if(m_Code & MASK_FAIL_BIT)
338 {
339 return static_cast<Level>( GetCodeBits(MASK_LEVEL, SHIFTS_LEVEL) | MASK_NEGATIVE_LEVEL);
340 }
341 else
342 {
343 return static_cast<Level>( GetCodeBits(MASK_LEVEL, SHIFTS_LEVEL) );
344 }
345 }
346
347 /*!
348 * @brief エラーの概要を示す Summary 列挙体を返します。
349 *
350 * Bug: 列挙体の定義は将来変更されます。現状では利用しないでください。
351 */
GetSummary()352 Summary GetSummary() const
353 {
354 return static_cast<Summary>( GetCodeBits(MASK_SUMMARY, SHIFTS_SUMMARY) );
355 }
356
357 /*!
358 * @brief エラーが発生したモジュールを示す Module 列挙体を返します。
359 *
360 *
361 * Bug: 列挙体の定義は将来変更されます。現状では利用しないでください。
362 */
GetModule()363 Module GetModule() const
364 {
365 return static_cast<Module>( GetCodeBits(MASK_MODULE, SHIFTS_MODULE) );
366 }
367
GetDescription()368 int GetDescription() const
369 {
370 return static_cast<int>( GetCodeBits(MASK_DESCRIPTION, SHIFTS_DESCRIPTION) );
371 }
372
GetValue()373 bit32 GetValue() const { return m_Code; }
374
GetPrintableBits()375 bit32 GetPrintableBits() const { return m_Code; }
376
nnResult()377 operator nnResult() const
378 {
379 nnResult r = {m_Code};
380 return r;
381 }
382
383 bool operator ==(const Result& rhs) const { return this->m_Code == rhs.m_Code; }
384 bool operator !=(const Result& rhs) const { return this->m_Code != rhs.m_Code; }
385
386 template <Result::Level TLevel, Result::Summary TSummary, Result::Module TModule, int TDescription> struct Const;
387 template <Result::Level TLevel, Result::Summary TSummary, Result::Module TModule> struct Const_LSM;
388 template <Result::Level TLevel, Result::Module TModule> struct Const_LM;
389 template <Result::Level TLevel> struct Const_L;
390
391 private:
GetCodeBits(bit32 mask,s32 shift)392 bit32 GetCodeBits(bit32 mask, s32 shift) const
393 {
394 return ((m_Code & mask) >> shift);
395 }
396 };
397
398 template <Result::Level TLevel, Result::Summary TSummary, Result::Module TModule, int TDescription>
399 struct Result::Const : public Result
400 {
401 static const Result::Level Level = TLevel;
402 static const Result::Summary Summary = TSummary;
403 static const Result::Module Module = TModule;
404 static const int Description = TDescription;
405
406 static const bit32 Value = static_cast<bit32>(
407 ((static_cast<bit32>(TLevel) << SHIFTS_LEVEL) & MASK_LEVEL) |
408 ((TSummary << SHIFTS_SUMMARY) & MASK_SUMMARY) |
409 ((TModule << SHIFTS_MODULE) & MASK_MODULE) |
410 ((TDescription << SHIFTS_DESCRIPTION) & MASK_DESCRIPTION) );
411
ConstConst412 Const() : Result(Value) {}
413 };
414
415 template <Result::Level TLevel, Result::Summary TSummary, Result::Module TModule>
416 struct Result::Const_LSM : public Result
417 {
418 static const Result::Level Level = TLevel;
419 static const Result::Summary Summary = TSummary;
420 static const Result::Module Module = TModule;
421
422 template <int TDescription>
423 struct Const : public Result::Const<TLevel, TSummary, TModule, TDescription> {};
424
Const_LSMConst_LSM425 Const_LSM(int description) : Result(TLevel, TSummary, TModule, description) {}
426 };
427
428 template <Result::Level TLevel, Result::Module TModule>
429 struct Result::Const_LM : public Result
430 {
431 static const Result::Level Level = TLevel;
432 static const Result::Module Module = TModule;
433
434 template <Result::Summary TSummary, int TDescription>
435 struct Const : public Result::Const<TLevel, TSummary, TModule, TDescription> {};
436
Const_LMConst_LM437 Const_LM(Result::Summary summary, int description) : Result(TLevel, summary, TModule, description) {}
438 };
439
440 template <Result::Level TLevel>
441 struct Result::Const_L : public Result
442 {
443 static const Result::Level Level = TLevel;
444
445 template <Result::Summary TSummary, Result::Module TModule, int TDescription>
446 struct Const : public Result::Const<TLevel, TSummary, TModule, TDescription> {};
447
Const_LConst_L448 Const_L(Result::Summary summary, Result::Module module, int description) : Result(TLevel, summary, module, description) {}
449 };
450
451 #define NN_DEFINE_RESULT_CONST(name, level, summary, module, description) \
452 typedef ::nn::Result::Const<(level), (summary), (module), (description)> name
453
454 NN_DEFINE_RESULT_CONST(ResultSuccess, Result::LEVEL_SUCCESS, Result::SUMMARY_SUCCESS, Result::MODULE_COMMON, Result::DESCRIPTION_SUCCESS);
455
456 #define NN_DEFINE_RESULT_FUNC_LSM(name, level, summary, module) \
457 typedef ::nn::Result::Const_LSM<(level), (summary), (module)> name
458
459 #define NN_DEFINE_RESULT_CONST_LSM(name, f, description) \
460 typedef f::Const<(description)> name
461
462 #define NN_DEFINE_RESULT_FUNC_LM(name, level, module) \
463 typedef ::nn::Result::Const_LM<(level), (module)> name
464
465 #define NN_DEFINE_RESULT_CONST_LM(name, f, summary, description) \
466 typedef f::Const<(summary), (description)> name
467
468 #define NN_DEFINE_RESULT_FUNC_L(name, level) \
469 typedef ::nn::Result::Const_L<(level)> name
470
471 #define NN_DEFINE_RESULT_CONST_L(name, f, summary, module, description) \
472 typedef f::Const<(summary), (module), (description)> name
473
474 // 完全移行まではコメントアウト
475 //NN_DEFINE_RESULT_FUNC_L(MakeInfoResult, LEVEL_INFO);
476 //NN_DEFINE_RESULT_FUNC_L(MakeFatalResult, LEVEL_FATAL);
477 //NN_DEFINE_RESULT_FUNC_L(MakeResetResult, LEVEL_RESET);
478 //NN_DEFINE_RESULT_FUNC_L(MakeReInitResult, LEVEL_REINIT);
479 //NN_DEFINE_RESULT_FUNC_L(MakeUsageResult, LEVEL_USAGE);
480 //NN_DEFINE_RESULT_FUNC_L(MakePermanentResult, LEVEL_PERMANENT);
481 //NN_DEFINE_RESULT_FUNC_L(MakeTemporaryResult, LEVEL_TEMPORARY);
482 //NN_DEFINE_RESULT_FUNC_L(MakeStatusResult, LEVEL_STATUS);
483
MakeInfoResult(Result::Summary summary,Result::Module module,int description)484 inline Result MakeInfoResult(Result::Summary summary, Result::Module module, int description)
485 { return Result(Result::LEVEL_INFO, summary, module, description); }
MakeFatalResult(Result::Summary summary,Result::Module module,int description)486 inline Result MakeFatalResult(Result::Summary summary, Result::Module module, int description)
487 { return Result(Result::LEVEL_FATAL, summary, module, description); }
MakeResetResult(Result::Summary summary,Result::Module module,int description)488 inline Result MakeResetResult(Result::Summary summary, Result::Module module, int description)
489 { return Result(Result::LEVEL_RESET, summary, module, description); }
MakeReInitResult(Result::Summary summary,Result::Module module,int description)490 inline Result MakeReInitResult(Result::Summary summary, Result::Module module, int description)
491 { return Result(Result::LEVEL_REINIT, summary, module, description); }
MakeUsageResult(Result::Summary summary,Result::Module module,int description)492 inline Result MakeUsageResult(Result::Summary summary, Result::Module module, int description)
493 { return Result(Result::LEVEL_USAGE, summary, module, description); }
MakePermanentResult(Result::Summary summary,Result::Module module,int description)494 inline Result MakePermanentResult(Result::Summary summary, Result::Module module, int description)
495 { return Result(Result::LEVEL_PERMANENT, summary, module, description); }
MakeTemporaryResult(Result::Summary summary,Result::Module module,int description)496 inline Result MakeTemporaryResult(Result::Summary summary, Result::Module module, int description)
497 { return Result(Result::LEVEL_TEMPORARY, summary, module, description); }
MakeStatusResult(Result::Summary summary,Result::Module module,int description)498 inline Result MakeStatusResult(Result::Summary summary, Result::Module module, int description)
499 { return Result(Result::LEVEL_STATUS, summary, module, description); }
500
501 }
502
503
504 #endif // __cplusplus
505
506 #ifdef __cplusplus
507 extern "C" {
508 #endif
509
510 int nnResultFailureHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...);
511 int nnResultTFailureHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...);
512
513 int nnResultPanicHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...);
514 int nnResultTPanicHandler(nnResult result, const char* filename, int lineno, const char* fmt, ...);
515
516 nnResult nnMakeInvalidResult(void);
517
518 #ifdef __cplusplus
519 }
520 #endif
521
522 #endif /* NN_RESULT_H_ */
523