*第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 <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;
 }
[[前に戻る>プログラミング]]
#author("2018-06-18T16:05:41+09:00","default:kuran","kuran")

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS