1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: rdt_SendBuffer.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_SendBuffer.h"
19
20 #include "Test.h"
21
22
23 namespace
24 {
25
26 } // End of anonymous namespace
27
28 namespace nn { namespace rdt { namespace CTR {
29
30 //
SendBuffer(void)31 SendBuffer::SendBuffer(void)
32 :m_initialized(false)
33 {
34 }
35
36
37 //
~SendBuffer(void)38 SendBuffer::~SendBuffer(void)
39 {
40 Finalize();
41 }
42
43
Initialize(void * pBuf,u16 bufSize)44 void SendBuffer::Initialize(void *pBuf, u16 bufSize)
45 {
46 ASSERT(pBuf!=NULL);
47 ASSERT(bufSize > 0);
48
49 if(m_initialized)
50 {
51 LOG("ReceiveWindow object is already initialized. Do nothing.\n");
52 }
53 else
54 {
55 m_ringBuf.Initialize(pBuf, bufSize);
56 m_readByte = 0;
57 m_initialized = true;
58 }
59 }
60
61
Finalize(void)62 void SendBuffer::Finalize(void)
63 {
64 if(m_initialized)
65 {
66 m_initialized = false;
67 m_ringBuf.Finalize();
68 }
69 }
70
71 /* Please see man pages for details
72
73
74
75 */
Push(const void * pBuf,size_t len)76 bool SendBuffer::Push(const void *pBuf, size_t len)
77 {
78 ASSERT(m_initialized);
79 ASSERT(pBuf!=NULL);
80 ASSERT(len > 0);
81
82 bool ret = m_ringBuf.Push(pBuf, len);
83 if(ret)
84 {
85 return true;
86 }
87 else
88 {
89 return false;
90 }
91 }
92
93
Pull(void * pBuf,u32 * pSeq,size_t len)94 size_t SendBuffer::Pull(void *pBuf, u32 *pSeq, size_t len)
95 {
96 ASSERT(m_initialized);
97 ASSERT(pBuf!=NULL);
98 ASSERT(pSeq!=NULL);
99 ASSERT(len > 0);
100
101 size_t ret = m_ringBuf.Read(pBuf, len);
102 if(ret > 0)
103 {
104 m_ringBuf.Pop(ret);
105 *pSeq = GetCurrentSequenceNumber();
106 m_readByte += ret;
107 return ret;
108 }
109 else
110 {
111 return 0;
112 }
113 }
114
115
IsEmpty(void) const116 bool SendBuffer::IsEmpty(void) const
117 {
118 ASSERT(m_initialized);
119
120 return m_ringBuf.IsEmpty();
121 }
122
123
GetInitialSequenceNumber(void) const124 u32 SendBuffer::GetInitialSequenceNumber(void) const
125 {
126 ASSERT(m_initialized);
127
128 return m_initSeqNum;
129 }
130
131
GetCurrentSequenceNumber(void) const132 u32 SendBuffer::GetCurrentSequenceNumber(void) const
133 {
134 ASSERT(m_initialized);
135
136 return m_initSeqNum + 1 + m_readByte;
137 }
138
139
Clear(u32 initSeqNum)140 void SendBuffer::Clear(u32 initSeqNum)
141 {
142 m_ringBuf.Clear();
143 m_readByte = 0;
144 m_initSeqNum = initSeqNum;
145 }
146
147
PrintDebugInfo(void) const148 void SendBuffer::PrintDebugInfo(void) const
149 {
150 LOG("[SendBuffer] %u bytes read by Pull().\n", m_readByte);
151 }
152
153
154 #ifdef _WIN32
Test(void)155 void SendBuffer::Test(void)
156 {
157 const u16 BUFSIZE = 8;
158 u8 buf[BUFSIZE];
159
160 SendBuffer s;
161 s.Initialize(buf, BUFSIZE);
162 s.Clear(300);
163
164 const u32 ISS = s.GetInitialSequenceNumber(); // Initial sequence number
165
166 CU_ASSERT(s.IsEmpty());
167 CU_ASSERT(s.Push("ABC", 3));
168 CU_ASSERT(s.Push("DEFGH", 5));
169 CU_ASSERT(!s.IsEmpty());
170 CU_ASSERT(!s.Push("XYZ", 3));
171
172 char msg[256];
173 u32 seq = 0;
174 CU_ASSERT(s.Pull(msg, &seq, 4)==4);
175 CU_ASSERT(strncmp(msg, "ABCD", 4)==0);
176 CU_ASSERT(seq==ISS+1);
177 CU_ASSERT(!s.IsEmpty());
178 CU_ASSERT(s.Pull(msg, &seq, 5)==4);
179 CU_ASSERT(strncmp(msg, "EFGH", 4)==0);
180 CU_ASSERT(seq==ISS+1+4);
181 CU_ASSERT(s.IsEmpty());
182
183 // OK to call multiple times?
184 s.Finalize();
185 s.Finalize();
186 }
187 #endif // end of _WIN32
188
189
190 }}} // namespace nn::rdt::CTR
191