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