1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_RingBuffer.h
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 #ifndef NN_RDT_RINGBUFFER_H_
21 #define NN_RDT_RINGBUFFER_H_
22 
23 #include "rdt_Utility.h"
24 
25 
26 namespace nn { namespace rdt { namespace CTR {
27 
28 /*!
29     @brief これはリングバッファを表現するクラスです。
30 */
31 class RingBuffer{
32 public:
33 /*!
34     @brief 引数無しコンストラクタ。
35 */
36     RingBuffer(void);
37 
38 /*!
39     @brief 引数付きコンストラクタ。
40 */
41     RingBuffer(void *pBuf, size_t len);
42 
43 /*!
44     @brief 解放します。
45 */
46    ~RingBuffer(void);
47 
48 /*!
49     @brief 初期化します。引数無しコンストラクタでオブジェクトを構築した場合は、
50     必ずこの関数を呼び出してから、他の関数を呼び出すようにして下さい。
51 */
52     void Initialize(void *pBuf, size_t len);
53 
54 /*!
55     @brief 解放処理です。明示的に呼ばなくても、デストラクタで暗黙的に呼ばれます。
56 */
57     void Finalize(void);
58 
59 
60     // データ列の先頭からnバイトを除去します。
61     // データ列の長さよりも大きな数値が指定された場合は、データの全てが除去されます。
62     void Pop(size_t n);
63 
64     // 既存のデータ列の後ろに、pBufで示されるnバイトのデータ列を付け足します。
65     // バッファが不足しており、与えられたデータ列を書き込めない場合にfalseを返します。
66     bool Push(const void *pBuf, size_t n);
67 
68     // データを(保持されているデータ列の先頭から)最大nバイト読み出します。
69     // このとき、バッファからデータ列は除去されません。
70     // 返値は、実際に読み出すことのできたバイト数です。
71     // 読み出すデータが存在しなかった場合にはゼロが返ります。
72     size_t Read(void *pBuf, size_t n) const;
73 
74     // データ列の先頭からoffsetバイトだけずれた位置から、最大nバイト読み出します。
75     // このとき、バッファからデータ列は除去されません。
76     // 返値は、実際に読み出すことのできたバイト数です。
77     // 読み出すデータが存在しなかった場合にはゼロが返ります。
78     size_t Read(void *pBuf, size_t n, size_t offset) const;
79 
80     // データ列がカラかどうかの判定をします。
IsEmpty(void)81     bool IsEmpty(void) const { ASSERT(m_initialized); return m_dataLength==0; }
82 
83     // データ列をカラにします。
Clear(void)84     void Clear(void) { ASSERT(m_initialized); m_pHeadData = getHeadOfBuffer(); m_dataLength = 0; }
85 
86     // 現時点で保持されているデータ列の長さ(バイト数)を返します。
GetDataSize(void)87     size_t GetDataSize(void) const { ASSERT(m_initialized); return m_dataLength; }
88 
89     // このバッファの大きさ(バイト数)を返します。
GetBufferSize(void)90     size_t GetBufferSize(void) const { ASSERT(m_initialized); return m_bufLength; }
91 
92     // 現時点で書き込み可能なバイト数(すなわち、空きサイズ)を返します。
GetRestSize(void)93     size_t GetRestSize(void) const { ASSERT(m_initialized); return GetBufferSize() - GetDataSize(); }
94 
95 /*!
96     @brief CUnitを用いた単体テストです。
97 */
98     static void Test(void);
99 
100 
101 private:
102 /*!
103     @brief コピーコンストラクタは封印します。
104 */
105     RingBuffer           (const RingBuffer&);
106 
107 /*!
108     @brief 代入演算子は封印します。
109 */
110     RingBuffer& operator=(const RingBuffer&);
111 
112     // バッファの先頭アドレスを返します。
getHeadOfBuffer(void)113     u8* getHeadOfBuffer(void) const { return m_pHeadBuffer; }
114 
115     // バッファの最後+1のアドレスを返します。
getEndOfBuffer(void)116     u8* getEndOfBuffer(void) const { return m_pHeadBuffer + m_bufLength; }
117 
118     // 次にデータを書き込むべき場所のアドレスを返します。
119     u8* getEndOfData(void) const;
120 
121     // Read()の下請け関数。
122     size_t read(void *pBuf, size_t n, size_t offset) const;
123 
124     // デバッグ目的。与えられたポインタは、バッファの中を指しているか?
isValidAddress(u8 * p)125     bool isValidAddress(u8 *p) const { return (getHeadOfBuffer() <= p) && (p < getEndOfBuffer()); }
126 
127     u8    *m_pHeadBuffer; // バッファの先頭を指します。
128     size_t m_bufLength;   // バッファの長さ。
129     u8    *m_pHeadData;   // (意味のある)データの先頭を指すポインタです。
130                           // この位置からデータを読み出すことができます。
131     size_t m_dataLength;  // 現在、保持されているデータ列の長さ。
132     bool   m_initialized; // オブジェクトは初期化済み?
133 
134     u8     m_padding[3];  // パディング
135 };
136 
137 }}} // namespace nn::rdt::CTR
138 
139 #endif  // end of NN_RDT_RINGBUFFER_H_
140