/*-------------------------------------------------------------------------- Project: HorizonSDK File: rdt_Utility.h Copyright 2009 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2010-07-20#$ $Rev: 21498 $ $Author: hiratsu_daisuke $ *-------------------------------------------------------------------------*/ #include "stdafx.h" #ifndef NN_RDT_UTILITY_H_ #define NN_RDT_UTILITY_H_ #ifdef _WIN32 #include #include #include "types.h" #include #else #include #endif /*! @brief これは、便利な関数(ユーティリティ関数)をまとめたものです。 */ #ifdef _WIN32 #define PRINTF printf #else #define PRINTF NN_LOG #endif inline void infinite_loop(void) { while(1) { } } #define WARNING(exp) (void) ((exp) || \ (PRINTF("WARNING: %s line: %d\n", __FILE__, __LINE__), \ 0)) #define WARNINGMSG(exp, ...) (void) ((exp) || \ (PRINTF("WARNING: %s line: %d ", __FILE__, __LINE__), \ PRINTF(__VA_ARGS__), \ PRINTF("\n"), \ 0)) #define PANIC(...) (void) (PRINTF("PANIC: %s line: %d ", __FILE__, __LINE__), \ PRINTF(__VA_ARGS__), \ PRINTF("\n"), \ infinite_loop()/*abort()*/) #define ASSERT(exp) (void) ((exp) || \ (PRINTF("ASSERT: %s line: %d\n", __FILE__, __LINE__), \ infinite_loop() /*abort()*/, \ 0)) #define ASSERTMSG(exp, ...) (void) ((exp) || \ (PRINTF("ASSERTMSG: %s line: %d ", __FILE__, __LINE__), \ PRINTF(__VA_ARGS__), \ PRINTF("\n"), \ infinite_loop() /*abort()*/, \ 0)) #define LOG(...) (void) (PRINTF(__VA_ARGS__)) #define VERBOSE(...) (void)(0) #ifdef _WIN32 #define ALIGN_ASSERT(exp, align) ASSERTMSG( ((uptr)(exp)) % (align) == 0, "%s must be %d byte aligned.", #exp, align ) #elif defined(NN_PLATFORM_CTR) #define ALIGN_ASSERT(exp, align) NN_ALIGN_ASSERT(exp, align) #endif //#define alignof(type) ((int)offsetof(struct { char top; type bot; }, bot)) template class Align{ public: Align(void) { struct S{ char top; // 1バイトの変数が欲しいだけ。 T t; }; LOG("offset: %d\n", offsetof(S, t)); } }; namespace nn { namespace rdt { namespace CTR { // 先行宣言 class Sender; class Receiver; // ネットワークの準備/後始末を行います。 // データ通信ができる状況にまでもっていくことが目的です。 void SetupNetwork (void); void CleanupNetwork(void); // インスタンスの作成・削除。Create()系関数で返されたポインタをDestroy()して下さい。 Sender* CreateSender (u16 port, void *pSendBuf, u16 sendBufSize); void DestroySender (Sender *s); Receiver* CreateReceiver (u16 port, void *pRecvBuf, u16 recvBufSize); void DestroyReceiver(Receiver *r); // スレッドの休眠。Windows環境とCTR環境の違いを内部実装で吸収している。 void SleepCurrentThread(s32 msec); // バッファへのポインタがNULLポインタだったときに使う。 inline nn::Result MakeNullPointerResult(void) { return MakeUsageResult( Result::SUMMARY_INVALID_ARGUMENT, Result::MODULE_NN_RDT, Result::DESCRIPTION_INVALID_POINTER); } // バッファの長さを表す引数がゼロだったときに使う。 inline nn::Result MakeZeroSizeResult(void) { return MakeUsageResult( Result::SUMMARY_INVALID_ARGUMENT, Result::MODULE_NN_RDT, Result::DESCRIPTION_INVALID_SIZE); } // 関数を呼ぶべきステートではなかったときに使う。 inline nn::Result MakeInvalidState(void) { return MakeStatusResult( Result::SUMMARY_INVALID_STATE, Result::MODULE_NN_RDT, Result::DESCRIPTION_INVALID_RESULT_VALUE); // TORIAEZU。この値は適切ではない気がするが…。 } // 未実装の関数の返値…。 inline nn::Result MakeNotImplemented(void) { return MakeFatalResult( Result::SUMMARY_INTERNAL, Result::MODULE_NN_RDT, Result::DESCRIPTION_NOT_IMPLEMENTED); } // リソース確保に失敗 inline nn::Result MakeResourceAllocationFailure(void) { return MakeStatusResult( Result::SUMMARY_OUT_OF_RESOURCE, Result::MODULE_NN_RDT, Result::DESCRIPTION_OUT_OF_MEMORY); // TORIAEZU。メモリ以外のリソースが不足していた場合のDESCRIPTIONが欲しい…。 } // 初期化済み状態の時に初期化しようとしたケースで返される。 inline nn::Result MakeAlreadyInitialized(void) { return MakeInfoResult( Result::SUMMARY_NOTHING_HAPPENED, Result::MODULE_NN_RDT, Result::DESCRIPTION_ALREADY_INITIALIZED); } // リモートからRSTを受け取ったときに、ユーザーにそれを伝えるためのエラーコード。 inline nn::Result MakeResetReceived(void) { return MakeReInitResult( Result::SUMMARY_CANCELLED, // TORIAEZU。 Result::MODULE_NN_RDT, Result::DESCRIPTION_CANCEL_REQUESTED); // TORIAEZU。 } // 接続が失われたときのエラー。 inline nn::Result MakeDisconnected(void) { return MakeReInitResult( Result::SUMMARY_OUT_OF_RESOURCE, Result::MODULE_NN_RDT, Result::DESCRIPTION_NOT_FOUND); // TORIAEZU。 } // 受信セグメントが無かった(まだ到着していない)場合。 inline nn::Result MakeNoData(void) { return MakeTemporaryResult( Result::SUMMARY_NOT_FOUND, Result::MODULE_NN_RDT, Result::DESCRIPTION_NO_DATA); } // やや引っかかるところはあるが、エラーを宣告するほどではない時に使う。 inline nn::Result MakeNothingHappened(void) { return MakeInfoResult( Result::SUMMARY_NOTHING_HAPPENED, Result::MODULE_NN_RDT, Result::DESCRIPTION_SUCCESS); } #ifdef _WIN32 // サーバー側のソケットのセットアップ、クリーンアップを実行する。Windows専用。 // 内部でlisten(), accept()などの処理を実行し、データを送受信できる状態にまで // 持って行く。 SOCKET SetupServerSide(u16 port); void CleanupServerSide(SOCKET sock); // クライアント側のソケットのセットアップ、クリーンアップを実行する。 // 内部ではconnect()等の処理を実行し、データを送受信できる状態にまで // 持って行く。 SOCKET SetupClientSide(u16 port); void CleanupClientSide(SOCKET sock); // 利用可能なポート番号を返す。 u16 GetAvailablePort(void); // ミリセカンド型。 typedef clock_t MSEC_T; MSEC_T GetCurrentTimeAsMillisecond(void); #else template T min(T a, T b) { return a < b ? a : b; } template T max(T a, T b) { return a > b ? a : b; } // ミリセカンド型。 typedef s64 MSEC_T; MSEC_T GetCurrentTimeAsMillisecond(void); void PrintResultCode(nn::Result r); #endif // end of _WIN32 // この関数を呼び出した時点で、どれだけスタックが食いつぶされているかを得る。 void stackChecker(void); }}} // namespace nn::rdt::CTR #endif // end of NN_RDT_UTILITY_H_