- 追加された行はこの色です。
- 削除された行はこの色です。
*第17回目 リングバッファ [#s8a194f6]
C++でRingBufferクラスを作ってみた
**RingBufferクラスメンバ [#k57c551d]
***bool Create(size_t size); [#e6ee2701]
リングバッファ作成
***void Release(void); [#e744562a]
リングバッファリリース
***void Reset(void); [#pf2ef909]
リングバッファの内容を消す
***size_t GetReadableSize(void) const; [#a5014acc]
格納されているデータのサイズ取得
***bool Read(void* buffer, size_t size); [#z711ea4b]
データ読み込み
***size_t GetWritableSize(void) const; [#yf4d818c]
書き込みできるバッファの最大サイズ取得
***bool Write(const void* buffer, size_t size); [#dedf73dc]
データ書き込み
***size_t GetBufferSize(void) const; [#h8218cd6]
バッファのサイズ取得
**使用例 [#h59ab125]
#include "ringbuffer.hpp"
int main(int argc, char* argv[])
{
char data1[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
char data2[] = {'A', 'B', 'C', 'D'};
char temp[15];
RingBuffer ringbuffer;
size_t size;
bool result;
result = ringbuffer.Create(15); // 15バイトのリングバッファ作成
size = ringbuffer.GetWritableSize();
result = ringbuffer.Write(data1, sizeof(data1));
size = ringbuffer.GetWritableSize();
result = ringbuffer.Write(data2, sizeof(data2));
result = ringbuffer.Read(temp, 3);
result = ringbuffer.Read(temp, 2);
result = ringbuffer.Write(data2, sizeof(data2));
size = ringbuffer.GetReadableSize();
result = ringbuffer.Read(temp, size);
ringbuffer.Release(); // リングバッファ消去
return 0;
}
**プログラムソース [#u8aee38c]
***ringbuffer.hpp [#a0be9aab]
#ifndef RINGBUFFER_HPP
#define RINGBUFFER_HPP
class RingBuffer
{
public:
RingBuffer(void);
~RingBuffer(void);
bool Create(size_t size);
void Release(void);
void Reset(void);
size_t GetReadableSize(void) const;
bool Read(void* buffer, size_t size);
size_t GetWritableSize(void) const;
bool Write(const void* buffer, size_t size);
size_t GetBufferSize(void) const;
private:
char* buffer;
size_t buffersize;
size_t readpointer;
size_t writepointer;
bool empty;
private:
RingBuffer(RingBuffer&);
RingBuffer& operator = (RingBuffer&);
};
#endif
***ringbuffer.cpp [#mf92a371]
#include <string.h>
#include "ringbuffer.hpp"
RingBuffer::RingBuffer(void)
:buffer(NULL), buffersize(0), readpointer(0), writepointer(0), empty(true)
{
}
RingBuffer::~RingBuffer(void)
{
Release();
}
bool RingBuffer::Create(size_t size)
{
Release();
if(size == 0)
{
return false;
}
buffer = new char[size];
buffersize = size;
return true;
}
void RingBuffer::Release(void)
{
if(buffersize)
{
delete [] buffer;
buffer = NULL;
}
buffersize = 0;
readpointer = 0;
writepointer = 0;
empty = true;
}
void RingBuffer::Reset(void)
{
readpointer = 0;
writepointer = 0;
empty = true;
}
size_t RingBuffer::GetReadableSize(void) const
{
if(empty)
{
return 0;
}
size_t size;
if(readpointer < writepointer)
{
size = writepointer - readpointer;
}
else if(readpointer > writepointer)
{
size = buffersize - readpointer + writepointer;
}
else
{
size = buffersize;
}
return size;
}
bool RingBuffer::Read(void* buffer, size_t size)
{
if(buffer == NULL)
{
return false;
}
size_t readablesize;
readablesize = GetReadableSize();
if(size > readablesize)
{
return false;
}
if(size == readablesize)
{
empty = true;
}
if(readpointer < writepointer)
{
memcpy(buffer, &this->buffer[readpointer], size);
}
else
{
size_t copysize;
char* copybuffer;
copybuffer = static_cast<char*>(buffer);
copysize = buffersize - readpointer;
if(size < copysize)
{
copysize = size;
}
memcpy(copybuffer, &this->buffer[readpointer], copysize);
copybuffer += copysize;
copysize = size - copysize;
if(copysize != 0)
{
memcpy(copybuffer, this->buffer, copysize);
}
}
readpointer = (readpointer + size) % buffersize;
return true;
}
size_t RingBuffer::GetWritableSize(void) const
{
size_t size;
if(writepointer < readpointer)
{
size = readpointer - writepointer;
}
else if(writepointer > readpointer)
{
size = buffersize - writepointer + readpointer;
}
else if(empty)
{
size = buffersize;
}
else
{
size = 0;
}
return size;
}
bool RingBuffer::Write(const void* buffer, size_t size)
{
if(buffer == NULL)
{
return false;
}
if(size <= 0)
{
return false;
}
size_t writablesize;
writablesize = GetWritableSize();
if(writepointer < readpointer)
{
memcpy(&this->buffer[writepointer], buffer, size);
}
else
{
size_t copysize;
const char* copybuffer;
copybuffer = reinterpret_cast<const char*>(buffer);
copysize = buffersize - writepointer;
if(size < copysize)
{
copysize = size;
}
memcpy(&this->buffer[writepointer], copybuffer, copysize);
copybuffer += copysize;
copysize = size - copysize;
if(copysize != 0)
{
memcpy(this->buffer, copybuffer, copysize);
}
}
writepointer = (writepointer + size) % buffersize;
empty = false;
return true;
}
size_t RingBuffer::GetBufferSize(void) const
{
return this->buffersize;
}
[[前に戻る>プログラミング]]