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