/*-------------------------------------------------------------------------- Project: HorizonSDK File: rdt_SendBuffer.cpp 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-08-02#$ $Rev: 22422 $ $Author: hiratsu_daisuke $ *-------------------------------------------------------------------------*/ #include "stdafx.h" #include "rdt_SendBuffer.h" #include "Test.h" namespace { } // end of anonymous namespace namespace nn { namespace rdt { namespace CTR { ///< コンストラクタ SendBuffer::SendBuffer(void) :m_initialized(false) { } ///< デストラクタ SendBuffer::~SendBuffer(void) { Finalize(); } void SendBuffer::Initialize(void *pBuf, u16 bufSize) { ASSERT(pBuf!=NULL); ASSERT(bufSize > 0); if(m_initialized) { LOG("ReceiveWindow object is already initialized. Do nothing.\n"); } else { m_ringBuf.Initialize(pBuf, bufSize); m_readByte = 0; m_initialized = true; } } void SendBuffer::Finalize(void) { if(m_initialized) { m_initialized = false; m_ringBuf.Finalize(); } } /*! @brief データを追加します。 バッファの空きが不足しており、データを追加するのに充分な空きが無い場合には falseが返ります。 */ bool SendBuffer::Push(const void *pBuf, size_t len) { ASSERT(m_initialized); ASSERT(pBuf!=NULL); ASSERT(len > 0); bool ret = m_ringBuf.Push(pBuf, len); if(ret) { return true; } else { return false; } } size_t SendBuffer::Pull(void *pBuf, u32 *pSeq, size_t len) { ASSERT(m_initialized); ASSERT(pBuf!=NULL); ASSERT(pSeq!=NULL); ASSERT(len > 0); size_t ret = m_ringBuf.Read(pBuf, len); if(ret > 0) { m_ringBuf.Pop(ret); *pSeq = GetCurrentSequenceNumber(); m_readByte += ret; return ret; } else { return 0; } } bool SendBuffer::IsEmpty(void) const { ASSERT(m_initialized); return m_ringBuf.IsEmpty(); } u32 SendBuffer::GetInitialSequenceNumber(void) const { ASSERT(m_initialized); return m_initSeqNum; } u32 SendBuffer::GetCurrentSequenceNumber(void) const { ASSERT(m_initialized); return m_initSeqNum + 1 + m_readByte; } void SendBuffer::Clear(u32 initSeqNum) { m_ringBuf.Clear(); m_readByte = 0; m_initSeqNum = initSeqNum; } void SendBuffer::PrintDebugInfo(void) const { LOG("[SendBuffer] %u bytes read by Pull().\n", m_readByte); } #ifdef _WIN32 void SendBuffer::Test(void) { const u16 BUFSIZE = 8; u8 buf[BUFSIZE]; SendBuffer s; s.Initialize(buf, BUFSIZE); s.Clear(300); const u32 ISS = s.GetInitialSequenceNumber(); // 初期シーケンス番号 CU_ASSERT(s.IsEmpty()); CU_ASSERT(s.Push("ABC", 3)); CU_ASSERT(s.Push("DEFGH", 5)); CU_ASSERT(!s.IsEmpty()); CU_ASSERT(!s.Push("XYZ", 3)); char msg[256]; u32 seq = 0; CU_ASSERT(s.Pull(msg, &seq, 4)==4); CU_ASSERT(strncmp(msg, "ABCD", 4)==0); CU_ASSERT(seq==ISS+1); CU_ASSERT(!s.IsEmpty()); CU_ASSERT(s.Pull(msg, &seq, 5)==4); CU_ASSERT(strncmp(msg, "EFGH", 4)==0); CU_ASSERT(seq==ISS+1+4); CU_ASSERT(s.IsEmpty()); // 複数回呼んでも平気? s.Finalize(); s.Finalize(); } #endif // end of _WIN32 }}} // namespace nn::rdt::CTR