1 /*--------------------------------------------------------------------------
2 Project: HorizonSDK
3 File: rdt_ReceiveBuffer.cpp
4 Copyright 2009 Nintendo. All rights reserved.
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10 $Date:: 2010-04-30#$
11 $Rev: 15289 $
12 $Author: hiratsu_daisuke $
13 *-------------------------------------------------------------------------
14
15
16 */
17
18 #include "stdafx.h"
19
20 #include "rdt_ReceiveBuffer.h"
21
22 #include "Test.h"
23
24 #include "rdt_Utility.h"
25
26
27 namespace
28 {
29
30 } // End of anonymous namespace
31
32 namespace nn { namespace rdt { namespace CTR {
33
34 //
ReceiveBuffer(void)35 ReceiveBuffer::ReceiveBuffer(void)
36 :m_initialized(false)
37 {
38 }
39
40
41 //
~ReceiveBuffer(void)42 ReceiveBuffer::~ReceiveBuffer(void)
43 {
44 Finalize();
45 }
46
47
48
Initialize(void * pBuf,u16 bufSize)49 void ReceiveBuffer::Initialize(void *pBuf, u16 bufSize)
50 {
51 ASSERT(pBuf!=NULL);
52 ASSERT(bufSize > 0);
53
54 if(m_initialized)
55 {
56 LOG("ReceiveBuffer object is already initialized.\n");
57 }
58 else
59 {
60 m_ringBuf.Initialize(pBuf, bufSize);
61 Clear();
62 m_initialized = true;
63 }
64 }
65
66
Finalize(void)67 void ReceiveBuffer::Finalize(void)
68 {
69 if(m_initialized)
70 {
71 m_initialized = false;
72 m_ringBuf.Finalize();
73 }
74 }
75
76
SetInitialSequenceNumber(u32 num)77 void ReceiveBuffer::SetInitialSequenceNumber(u32 num)
78 {
79 m_initSeqNum = num;
80 m_latestSeqNum = num;
81 }
82
83
Pop(size_t n)84 void ReceiveBuffer::Pop(size_t n)
85 {
86 ASSERT(m_initialized);
87
88 ASSERT(n >= 0);
89 m_ringBuf.Pop(n);
90 }
91
92
Push(const void * pBuf,size_t len)93 bool ReceiveBuffer::Push(const void *pBuf, size_t len)
94 {
95 ASSERT(m_initialized);
96 ASSERT(pBuf!=NULL);
97 ASSERT(len > 0);
98
99 bool ret = m_ringBuf.Push(pBuf, len);
100 if(ret)
101 {
102 m_latestSeqNum += len; // Newest octet sequence number update
103 }
104 return ret;
105 }
106
107
Read(void * pBuf,size_t len)108 size_t ReceiveBuffer::Read(void *pBuf, size_t len)
109 {
110 ASSERT(m_initialized);
111 ASSERT(pBuf!=NULL);
112 ASSERT(len > 0);
113
114 return m_ringBuf.Read(pBuf, len);
115 }
116
117
GetLatestSequenceNumber(void) const118 u32 ReceiveBuffer::GetLatestSequenceNumber(void) const
119 {
120 ASSERT(m_initialized);
121
122 return m_latestSeqNum;
123 }
124
125
GetRestSize(void) const126 size_t ReceiveBuffer::GetRestSize(void) const
127 {
128 ASSERT(m_initialized);
129
130 size_t ret = m_ringBuf.GetRestSize();
131
132 // With the Initialize function, the size can only be specified with u16, so it is odd if the size is out of this range.
133 //
134 ASSERT((0 <= ret) && (ret <= USHRT_MAX));
135
136 return ret;
137 }
138
139
Clear(void)140 void ReceiveBuffer::Clear(void)
141 {
142 m_ringBuf.Clear();
143 m_initSeqNum = 0;
144 m_latestSeqNum = 0;
145 }
146
147
IsEmpty(void) const148 bool ReceiveBuffer::IsEmpty(void) const
149 {
150 return m_ringBuf.IsEmpty();
151 }
152
153
PrintDebugInfo(void) const154 void ReceiveBuffer::PrintDebugInfo(void) const
155 {
156 if(m_initialized)
157 {
158 LOG("Initialized.\n");
159 LOG("Initial sequecne number: %u\n", m_initSeqNum);
160 LOG("Latest octet sequence nubmer: %u\n", m_latestSeqNum);
161 }
162 else
163 {
164 LOG("Not initialized.\n");
165 }
166 }
167
168
169 #ifdef _WIN32
170 // Single unit test with CUnit
Test(void)171 void ReceiveBuffer::Test(void)
172 {
173 ReceiveBuffer w;
174
175 const int BUFSIZE = 4096;
176 u8 windowBuf[BUFSIZE];
177 const u32 SEQ_NUM = 100;
178
179 w.Initialize(windowBuf, BUFSIZE);
180 w.SetInitialSequenceNumber(SEQ_NUM);
181 CU_ASSERT(w.GetRestSize()==BUFSIZE);
182 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM);
183
184 char buf[BUFSIZE*2];
185 CU_ASSERT(!w.Push(buf, sizeof(buf))); // Should fail because the data is too large to Push.
186
187 CU_ASSERT(w.Push("Hello", 5));
188 CU_ASSERT(w.Read(buf, 5)==5);
189 CU_ASSERT(strncmp(buf, "Hello", 5)==0);
190 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM+5);
191 CU_ASSERT(w.GetRestSize()==BUFSIZE-5);
192
193 w.Pop(3);
194 CU_ASSERT(w.GetRestSize()==BUFSIZE-2);
195 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM+5);
196 CU_ASSERT(w.Read(buf, 5)==2);
197
198 CU_ASSERT(w.Push("ading", 5));
199 CU_ASSERT(w.GetRestSize()==BUFSIZE-7);
200 CU_ASSERT(w.Read(buf, 100)==7);
201 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM+10);
202 }
203 #endif // end of _WIN32
204
205 }}} // namespace nn::rdt::CTR
206