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