第17回目 リングバッファ

C++でRingBufferクラスを作ってみた

RingBufferクラスメンバ

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;

バッファのサイズ取得

使用例

#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;
}

プログラムソース

ringbuffer.hpp

#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

#include <string.h>
#include <stdlib.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 = static_cast<char*>(malloc(size));
	buffersize = size;
	return true;
}

void RingBuffer::Release(void)
{
	if(buffersize)
	{
		free(buffer);
	}
	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;
}

前に戻る?


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS