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