1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_SendBuffer.cpp
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-08-02#$
14   $Rev: 22422 $
15   $Author: hiratsu_daisuke $
16  *-------------------------------------------------------------------------*/
17 
18 #include "stdafx.h"
19 
20 #include "rdt_SendBuffer.h"
21 
22 #include "Test.h"
23 
24 
25 namespace
26 {
27 
28 }  // end of anonymous namespace
29 
30 namespace nn { namespace rdt { namespace CTR {
31 
32 ///< コンストラクタ
SendBuffer(void)33 SendBuffer::SendBuffer(void)
34      :m_initialized(false)
35 {
36 }
37 
38 
39 ///< デストラクタ
~SendBuffer(void)40 SendBuffer::~SendBuffer(void)
41 {
42     Finalize();
43 }
44 
45 
Initialize(void * pBuf,u16 bufSize)46 void SendBuffer::Initialize(void *pBuf, u16 bufSize)
47 {
48     ASSERT(pBuf!=NULL);
49     ASSERT(bufSize > 0);
50 
51     if(m_initialized)
52     {
53         LOG("ReceiveWindow object is already initialized.  Do nothing.\n");
54     }
55     else
56     {
57         m_ringBuf.Initialize(pBuf, bufSize);
58         m_readByte     = 0;
59         m_initialized  = true;
60     }
61 }
62 
63 
Finalize(void)64 void SendBuffer::Finalize(void)
65 {
66     if(m_initialized)
67     {
68         m_initialized = false;
69         m_ringBuf.Finalize();
70     }
71 }
72 
73 /*!
74     @brief データを追加します。
75     バッファの空きが不足しており、データを追加するのに充分な空きが無い場合には
76     falseが返ります。
77  */
Push(const void * pBuf,size_t len)78 bool SendBuffer::Push(const void *pBuf, size_t len)
79 {
80     ASSERT(m_initialized);
81     ASSERT(pBuf!=NULL);
82     ASSERT(len > 0);
83 
84     bool ret = m_ringBuf.Push(pBuf, len);
85     if(ret)
86     {
87         return true;
88     }
89     else
90     {
91         return false;
92     }
93 }
94 
95 
Pull(void * pBuf,u32 * pSeq,size_t len)96 size_t SendBuffer::Pull(void *pBuf, u32 *pSeq, size_t len)
97 {
98     ASSERT(m_initialized);
99     ASSERT(pBuf!=NULL);
100     ASSERT(pSeq!=NULL);
101     ASSERT(len > 0);
102 
103     size_t ret = m_ringBuf.Read(pBuf, len);
104     if(ret > 0)
105     {
106         m_ringBuf.Pop(ret);
107         *pSeq = GetCurrentSequenceNumber();
108         m_readByte += ret;
109         return ret;
110     }
111     else
112     {
113         return 0;
114     }
115 }
116 
117 
IsEmpty(void) const118 bool SendBuffer::IsEmpty(void) const
119 {
120     ASSERT(m_initialized);
121 
122     return m_ringBuf.IsEmpty();
123 }
124 
125 
GetInitialSequenceNumber(void) const126 u32 SendBuffer::GetInitialSequenceNumber(void) const
127 {
128     ASSERT(m_initialized);
129 
130     return m_initSeqNum;
131 }
132 
133 
GetCurrentSequenceNumber(void) const134 u32 SendBuffer::GetCurrentSequenceNumber(void) const
135 {
136     ASSERT(m_initialized);
137 
138     return m_initSeqNum + 1 + m_readByte;
139 }
140 
141 
Clear(u32 initSeqNum)142 void SendBuffer::Clear(u32 initSeqNum)
143 {
144     m_ringBuf.Clear();
145     m_readByte   = 0;
146     m_initSeqNum = initSeqNum;
147 }
148 
149 
PrintDebugInfo(void) const150 void SendBuffer::PrintDebugInfo(void) const
151 {
152     LOG("[SendBuffer] %u bytes read by Pull().\n", m_readByte);
153 }
154 
155 
156 #ifdef _WIN32
Test(void)157 void SendBuffer::Test(void)
158 {
159     const u16 BUFSIZE = 8;
160     u8 buf[BUFSIZE];
161 
162     SendBuffer s;
163     s.Initialize(buf, BUFSIZE);
164     s.Clear(300);
165 
166     const u32 ISS = s.GetInitialSequenceNumber();  // 初期シーケンス番号
167 
168     CU_ASSERT(s.IsEmpty());
169     CU_ASSERT(s.Push("ABC", 3));
170     CU_ASSERT(s.Push("DEFGH", 5));
171     CU_ASSERT(!s.IsEmpty());
172     CU_ASSERT(!s.Push("XYZ", 3));
173 
174     char msg[256];
175     u32 seq = 0;
176     CU_ASSERT(s.Pull(msg, &seq, 4)==4);
177     CU_ASSERT(strncmp(msg, "ABCD", 4)==0);
178     CU_ASSERT(seq==ISS+1);
179     CU_ASSERT(!s.IsEmpty());
180     CU_ASSERT(s.Pull(msg, &seq, 5)==4);
181     CU_ASSERT(strncmp(msg, "EFGH", 4)==0);
182     CU_ASSERT(seq==ISS+1+4);
183     CU_ASSERT(s.IsEmpty());
184 
185     // 複数回呼んでも平気?
186     s.Finalize();
187     s.Finalize();
188 }
189 #endif  // end of _WIN32
190 
191 
192 }}} // namespace nn::rdt::CTR
193