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