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