*第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")