52 lines
1.7 KiB
C++
52 lines
1.7 KiB
C++
// RingBuffer.cpp
|
|
#include "RingBuffer.h"
|
|
|
|
RingBuffer::RingBuffer(size_t size) :
|
|
buffer(size), head(0), tail(0), capacity(size), isFull(false) {}
|
|
|
|
bool RingBuffer::push(const uint8_t* data, size_t size) {
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
size_t bytesToWrite = size;
|
|
while (bytesToWrite > 0) {
|
|
size_t spaceAvailable = (tail >= head) ? capacity - (tail - head) : head - tail;
|
|
if (isFull) {
|
|
notFull.wait(lock, [this]() { return !isFull; });
|
|
}
|
|
size_t bytesToWriteNow = std::min(bytesToWrite, spaceAvailable);
|
|
std::memcpy(&buffer[tail], data, bytesToWriteNow);
|
|
tail = (tail + bytesToWriteNow) % capacity;
|
|
if (tail == head) {
|
|
isFull = true;
|
|
}
|
|
data += bytesToWriteNow;
|
|
bytesToWrite -= bytesToWriteNow;
|
|
notEmpty.notify_one();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool RingBuffer::pop(uint8_t* outBuffer, size_t& size) {
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
notEmpty.wait(lock, [this]() { return head != tail || isFull; });
|
|
size_t bytesAvailable = (tail >= head) ? tail - head : capacity - (head - tail);
|
|
size_t bytesToRead = std::min(size, bytesAvailable);
|
|
std::memcpy(outBuffer, &buffer[head], bytesToRead);
|
|
head = (head + bytesToRead) % capacity;
|
|
if (head == tail) {
|
|
isFull = false;
|
|
}
|
|
size = bytesToRead;
|
|
notFull.notify_one();
|
|
return bytesAvailable > 0;
|
|
}
|
|
|
|
bool RingBuffer::empty() const {
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
return !isFull && head == tail;
|
|
}
|
|
|
|
bool RingBuffer::full() const {
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
return isFull;
|
|
}
|