1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_ReceiveBuffer.cpp
4 
5   Copyright 2009 Nintendo.  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   $Date:: 2010-04-30#$
14   $Rev: 15289 $
15   $Author: hiratsu_daisuke $
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;  // 最新オクテットのシーケンス番号更新
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     // Initialize()関数では、サイズはu16でしか指定してできないから、
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 // 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)));  // 大きすぎるデータを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