1 /*--------------------------------------------------------------------------
2 Project: HorizonSDK
3 File: rdt_Utility.h
4
5 Copyright 2009 Nintendo. 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 $Date:: 2010-10-19#$
14 $Rev: 28318 $
15 $Author: hiratsu_daisuke $
16 *-------------------------------------------------------------------------*/
17
18 #include "stdafx.h"
19
20 #ifndef NN_RDT_UTILITY_H_
21 #define NN_RDT_UTILITY_H_
22
23
24 #ifdef _WIN32
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include "types.h"
28 #include <time.h>
29 #else
30 #include <nn/types.h>
31 #endif
32
33 #include <nn/rdt/CTR/rdt_Misc.h>
34
35 /*!
36 @brief これは、便利な関数(ユーティリティ関数)をまとめたものです。
37 */
38
39 #ifdef _WIN32
40 #define PRINTF printf
41 #else
42 #define PRINTF NN_LOG
43 #endif
44
45
infinite_loop(void)46 inline void infinite_loop(void)
47 {
48 while(1)
49 {
50 }
51 }
52
53
54 #define WARNING(exp) (void) ((exp) || (nn::rdt::CTR::GetLogLevel()==nn::rdt::CTR::LOG_LEVEL_NONE) || \
55 (PRINTF("WARNING: %s line: %d\n", __FILE__, __LINE__), \
56 0))
57
58
59 #define WARNINGMSG(exp, ...) (void) ((exp) || (nn::rdt::CTR::GetLogLevel()==nn::rdt::CTR::LOG_LEVEL_NONE) || \
60 (PRINTF("WARNING: %s line: %d ", __FILE__, __LINE__), \
61 PRINTF(__VA_ARGS__), \
62 PRINTF("\n"), \
63 0))
64
65 #define PANIC(...) (void) (PRINTF("PANIC: %s line: %d ", __FILE__, __LINE__), \
66 PRINTF(__VA_ARGS__), \
67 PRINTF("\n"), \
68 infinite_loop()/*abort()*/)
69
70 #define ASSERT(exp) (void) ((exp) || \
71 (PRINTF("ASSERT: %s line: %d\n", __FILE__, __LINE__), \
72 infinite_loop() /*abort()*/, \
73 0))
74
75
76
77 #define ASSERTMSG(exp, ...) (void) ((exp) || \
78 (PRINTF("ASSERTMSG: %s line: %d ", __FILE__, __LINE__), \
79 PRINTF(__VA_ARGS__), \
80 PRINTF("\n"), \
81 infinite_loop() /*abort()*/, \
82 0))
83
84 #define LOG(...) if(nn::rdt::CTR::GetLogLevel()==nn::rdt::CTR::LOG_LEVEL_ALL)(void) (PRINTF(__VA_ARGS__))
85
86 #define VERBOSE(...) (void)(0)
87
88
89 #ifdef _WIN32
90 #define ALIGN_ASSERT(exp, align) ASSERTMSG( ((uptr)(exp)) % (align) == 0, "%s must be %d byte aligned.", #exp, align )
91 #elif defined(NN_PLATFORM_CTR)
92 #define ALIGN_ASSERT(exp, align) NN_ALIGN_ASSERT(exp, align)
93 #endif
94
95 //#define alignof(type) ((int)offsetof(struct { char top; type bot; }, bot))
96 template <class T>
97 class Align{
98 public:
Align(void)99 Align(void)
100 {
101 struct S{
102 char top; // 1バイトの変数が欲しいだけ。
103 T t;
104 };
105
106 LOG("offset: %d\n", offsetof(S, t));
107 }
108 };
109
110
111 namespace nn { namespace rdt { namespace CTR {
112
113 // 先行宣言
114 class Sender;
115 class Receiver;
116
117 // ネットワークの準備/後始末を行います。
118 // データ通信ができる状況にまでもっていくことが目的です。
119 void SetupNetwork (void);
120 void CleanupNetwork(void);
121
122 // インスタンスの作成・削除。Create()系関数で返されたポインタをDestroy()して下さい。
123 Sender* CreateSender (u16 port, void *pSendBuf, u16 sendBufSize);
124 void DestroySender (Sender *s);
125
126 Receiver* CreateReceiver (u16 port, void *pRecvBuf, u16 recvBufSize);
127 void DestroyReceiver(Receiver *r);
128
129 // スレッドの休眠。Windows環境とCTR環境の違いを内部実装で吸収している。
130 void SleepCurrentThread(s32 msec);
131
132
133 // バッファへのポインタがNULLポインタだったときに使う。
MakeNullPointerResult(void)134 inline nn::Result MakeNullPointerResult(void)
135 {
136 return MakeUsageResult(
137 Result::SUMMARY_INVALID_ARGUMENT,
138 Result::MODULE_NN_RDT,
139 Result::DESCRIPTION_INVALID_POINTER);
140 }
141
142
143 // バッファの長さを表す引数がゼロだったときに使う。
MakeZeroSizeResult(void)144 inline nn::Result MakeZeroSizeResult(void)
145 {
146 return MakeUsageResult(
147 Result::SUMMARY_INVALID_ARGUMENT,
148 Result::MODULE_NN_RDT,
149 Result::DESCRIPTION_INVALID_SIZE);
150 }
151
152
153 // 関数を呼ぶべきステートではなかったときに使う。
MakeInvalidState(void)154 inline nn::Result MakeInvalidState(void)
155 {
156 return MakeStatusResult(
157 Result::SUMMARY_INVALID_STATE,
158 Result::MODULE_NN_RDT,
159 Result::DESCRIPTION_INVALID_RESULT_VALUE); // TORIAEZU。この値は適切ではない気がするが…。
160 }
161
162
163 // 未実装の関数の返値…。
MakeNotImplemented(void)164 inline nn::Result MakeNotImplemented(void)
165 {
166 return MakeFatalResult(
167 Result::SUMMARY_INTERNAL,
168 Result::MODULE_NN_RDT,
169 Result::DESCRIPTION_NOT_IMPLEMENTED);
170 }
171
172
173 // リソース確保に失敗
MakeResourceAllocationFailure(void)174 inline nn::Result MakeResourceAllocationFailure(void)
175 {
176 return MakeStatusResult(
177 Result::SUMMARY_OUT_OF_RESOURCE,
178 Result::MODULE_NN_RDT,
179 Result::DESCRIPTION_OUT_OF_MEMORY); // TORIAEZU。メモリ以外のリソースが不足していた場合のDESCRIPTIONが欲しい…。
180 }
181
182
183 // 初期化済み状態の時に初期化しようとしたケースで返される。
MakeAlreadyInitialized(void)184 inline nn::Result MakeAlreadyInitialized(void)
185 {
186 return MakeInfoResult(
187 Result::SUMMARY_NOTHING_HAPPENED,
188 Result::MODULE_NN_RDT,
189 Result::DESCRIPTION_ALREADY_INITIALIZED);
190 }
191
192
193 // リモートからRSTを受け取ったときに、ユーザーにそれを伝えるためのエラーコード。
MakeResetReceived(void)194 inline nn::Result MakeResetReceived(void)
195 {
196 return MakeReInitResult(
197 Result::SUMMARY_CANCELLED, // TORIAEZU。
198 Result::MODULE_NN_RDT,
199 Result::DESCRIPTION_CANCEL_REQUESTED); // TORIAEZU。
200 }
201
202
203 // 接続が失われたときのエラー。
MakeDisconnected(void)204 inline nn::Result MakeDisconnected(void)
205 {
206 return MakeReInitResult(
207 Result::SUMMARY_OUT_OF_RESOURCE,
208 Result::MODULE_NN_RDT,
209 Result::DESCRIPTION_NOT_FOUND); // TORIAEZU。
210 }
211
212
213 // 受信セグメントが無かった(まだ到着していない)場合。
MakeNoData(void)214 inline nn::Result MakeNoData(void)
215 {
216 return MakeTemporaryResult(
217 Result::SUMMARY_NOT_FOUND,
218 Result::MODULE_NN_RDT,
219 Result::DESCRIPTION_NO_DATA);
220 }
221
222
223 // やや引っかかるところはあるが、エラーを宣告するほどではない時に使う。
MakeNothingHappened(void)224 inline nn::Result MakeNothingHappened(void)
225 {
226 return MakeInfoResult(
227 Result::SUMMARY_NOTHING_HAPPENED,
228 Result::MODULE_NN_RDT,
229 Result::DESCRIPTION_SUCCESS);
230 }
231
232 #ifdef _WIN32
233 // サーバー側のソケットのセットアップ、クリーンアップを実行する。Windows専用。
234 // 内部でlisten(), accept()などの処理を実行し、データを送受信できる状態にまで
235 // 持って行く。
236 SOCKET SetupServerSide(u16 port);
237 void CleanupServerSide(SOCKET sock);
238
239 // クライアント側のソケットのセットアップ、クリーンアップを実行する。
240 // 内部ではconnect()等の処理を実行し、データを送受信できる状態にまで
241 // 持って行く。
242 SOCKET SetupClientSide(u16 port);
243 void CleanupClientSide(SOCKET sock);
244
245 // 利用可能なポート番号を返す。
246 u16 GetAvailablePort(void);
247
248 // ミリセカンド型。
249 typedef clock_t MSEC_T;
250 MSEC_T GetCurrentTimeAsMillisecond(void);
251
252 #else
253 template <class T>
min(T a,T b)254 T min(T a, T b)
255 {
256 return a < b ? a : b;
257 }
258
259 template <class T>
max(T a,T b)260 T max(T a, T b)
261 {
262 return a > b ? a : b;
263 }
264
265
266 // ミリセカンド型。
267 typedef s64 MSEC_T;
268 MSEC_T GetCurrentTimeAsMillisecond(void);
269
270
271 void PrintResultCode(nn::Result r);
272
273 #endif // end of _WIN32
274
275
276 // この関数を呼び出した時点で、どれだけスタックが食いつぶされているかを得る。
277 void stackChecker(void);
278
279
280 }}} // namespace nn::rdt::CTR
281
282 #endif // end of NN_RDT_UTILITY_H_
283