1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: rdt_ReceiveBuffer.cpp
4
5 Copyright (C)2009-2012 Nintendo Co., Ltd. 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 $Rev: 46347 $
14 *---------------------------------------------------------------------------*/
15
16 #include "stdafx.h"
17
18 #include "rdt_ReceiveBuffer.h"
19
20 #include "Test.h"
21
22 #include "rdt_Utility.h"
23
24
25 namespace
26 {
27
28 } // End of anonymous namespace
29
30 namespace nn { namespace rdt { namespace CTR {
31
32 //
ReceiveBuffer(void)33 ReceiveBuffer::ReceiveBuffer(void)
34 :m_initialized(false)
35 {
36 }
37
38
39 //
~ReceiveBuffer(void)40 ReceiveBuffer::~ReceiveBuffer(void)
41 {
42 Finalize();
43 }
44
45
46
Initialize(void * pBuf,u16 bufSize)47 void ReceiveBuffer::Initialize(void *pBuf, u16 bufSize)
48 {
49 ASSERT(pBuf!=NULL);
50 ASSERT(bufSize > 0);
51
52 if(m_initialized)
53 {
54 LOG("ReceiveBuffer object is already initialized.\n");
55 }
56 else
57 {
58 m_ringBuf.Initialize(pBuf, bufSize);
59 Clear();
60 m_initialized = true;
61 }
62 }
63
64
Finalize(void)65 void ReceiveBuffer::Finalize(void)
66 {
67 if(m_initialized)
68 {
69 m_initialized = false;
70 m_ringBuf.Finalize();
71 }
72 }
73
74
SetInitialSequenceNumber(u32 num)75 void ReceiveBuffer::SetInitialSequenceNumber(u32 num)
76 {
77 m_initSeqNum = num;
78 m_latestSeqNum = num;
79 }
80
81
Pop(size_t n)82 void ReceiveBuffer::Pop(size_t n)
83 {
84 ASSERT(m_initialized);
85
86 ASSERT(n >= 0);
87 m_ringBuf.Pop(n);
88 }
89
90
Push(const void * pBuf,size_t len)91 bool ReceiveBuffer::Push(const void *pBuf, size_t len)
92 {
93 ASSERT(m_initialized);
94 ASSERT(pBuf!=NULL);
95 ASSERT(len > 0);
96
97 bool ret = m_ringBuf.Push(pBuf, len);
98 if(ret)
99 {
100 m_latestSeqNum += len; // Update most recent octet sequence number
101 }
102 return ret;
103 }
104
105
Read(void * pBuf,size_t len)106 size_t ReceiveBuffer::Read(void *pBuf, size_t len)
107 {
108 ASSERT(m_initialized);
109 ASSERT(pBuf!=NULL);
110 ASSERT(len > 0);
111
112 return m_ringBuf.Read(pBuf, len);
113 }
114
115
GetLatestSequenceNumber(void) const116 u32 ReceiveBuffer::GetLatestSequenceNumber(void) const
117 {
118 ASSERT(m_initialized);
119
120 return m_latestSeqNum;
121 }
122
123
GetRestSize(void) const124 size_t ReceiveBuffer::GetRestSize(void) const
125 {
126 ASSERT(m_initialized);
127
128 size_t ret = m_ringBuf.GetRestSize();
129
130 // With the Initialize function, because the size can be specified only as u16, it would be odd if it did not fit within this range.
131 //
132 ASSERT((0 <= ret) && (ret <= USHRT_MAX));
133
134 return ret;
135 }
136
137
Clear(void)138 void ReceiveBuffer::Clear(void)
139 {
140 m_ringBuf.Clear();
141 m_initSeqNum = 0;
142 m_latestSeqNum = 0;
143 }
144
145
IsEmpty(void) const146 bool ReceiveBuffer::IsEmpty(void) const
147 {
148 return m_ringBuf.IsEmpty();
149 }
150
151
PrintDebugInfo(void) const152 void ReceiveBuffer::PrintDebugInfo(void) const
153 {
154 if(m_initialized)
155 {
156 LOG("Initialized.\n");
157 LOG("Initial sequecne number: %u\n", m_initSeqNum);
158 LOG("Latest octet sequence nubmer: %u\n", m_latestSeqNum);
159 }
160 else
161 {
162 LOG("Not initialized.\n");
163 }
164 }
165
166
167 #ifdef _WIN32
168 // Standalone test with CUnit.
Test(void)169 void ReceiveBuffer::Test(void)
170 {
171 ReceiveBuffer w;
172
173 const int BUFSIZE = 4096;
174 u8 windowBuf[BUFSIZE];
175 const u32 SEQ_NUM = 100;
176
177 w.Initialize(windowBuf, BUFSIZE);
178 w.SetInitialSequenceNumber(SEQ_NUM);
179 CU_ASSERT(w.GetRestSize()==BUFSIZE);
180 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM);
181
182 char buf[BUFSIZE*2];
183 CU_ASSERT(!w.Push(buf, sizeof(buf))); // Should fail because trying to Push too much data.
184
185 CU_ASSERT(w.Push("Hello", 5));
186 CU_ASSERT(w.Read(buf, 5)==5);
187 CU_ASSERT(strncmp(buf, "Hello", 5)==0);
188 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM+5);
189 CU_ASSERT(w.GetRestSize()==BUFSIZE-5);
190
191 w.Pop(3);
192 CU_ASSERT(w.GetRestSize()==BUFSIZE-2);
193 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM+5);
194 CU_ASSERT(w.Read(buf, 5)==2);
195
196 CU_ASSERT(w.Push("ading", 5));
197 CU_ASSERT(w.GetRestSize()==BUFSIZE-7);
198 CU_ASSERT(w.Read(buf, 100)==7);
199 CU_ASSERT(w.GetLatestSequenceNumber()==SEQ_NUM+10);
200 }
201 #endif // end of _WIN32
202
203 }}} // namespace nn::rdt::CTR
204