17 #ifndef DISTRHO_RING_BUFFER_HPP_INCLUDED 
   18 #define DISTRHO_RING_BUFFER_HPP_INCLUDED 
   20 #include "../DistrhoUtils.hpp" 
   94     static const uint32_t size = 4096;
 
   95     uint32_t head, tail, wrtn;
 
   96     bool     invalidateCommit;
 
  105     static const uint32_t size = 16384;
 
  106     uint32_t head, tail, wrtn;
 
  107     bool     invalidateCommit;
 
  116     static const uint32_t size = 65536;
 
  117     uint32_t head, tail, wrtn;
 
  118     bool     invalidateCommit;
 
  122 #ifdef DISTRHO_PROPER_CPP11_SUPPORT 
  123 # define HeapBuffer_INIT  {0, 0, 0, 0, false, nullptr} 
  124 # define StackBuffer_INIT {0, 0, 0, false, {0}} 
  126 # define HeapBuffer_INIT 
  127 # define StackBuffer_INIT 
  166 template <
class BufferStruct>
 
  178           errorWriting(
false) {}
 
  191     bool isDataAvailableForReading() 
const noexcept;
 
  196     bool isEmpty() 
const noexcept
 
  198         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr, 
false);
 
  200         return (buffer->buf == 
nullptr || buffer->head == buffer->tail);
 
  206     uint32_t getReadableDataSize() 
const noexcept
 
  208         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr, 0);
 
  210         const uint32_t wrap = buffer->head > buffer->tail ? 0 : buffer->size;
 
  212         return wrap + buffer->head - buffer->tail;
 
  218     uint32_t getWritableDataSize() 
const noexcept
 
  220         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr, 0);
 
  222         const uint32_t wrap = (buffer->tail > buffer->wrtn) ? 0 : buffer->size;
 
  224         return wrap + buffer->tail - buffer->wrtn;
 
  234     void clearData() noexcept
 
  236         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr,);
 
  241         buffer->invalidateCommit = 
false;
 
  243         std::memset(buffer->buf, 0, buffer->size);
 
  253     bool readBool() noexcept
 
  256         return tryRead(&b, 
sizeof(
bool)) ? b : 
false;
 
  263     uint8_t readByte() noexcept
 
  266         return tryRead(&B, 
sizeof(uint8_t)) ? B : 0;
 
  273     int16_t readShort() noexcept
 
  276         return tryRead(&s, 
sizeof(int16_t)) ? s : 0;
 
  283     uint16_t readUShort() noexcept
 
  286         return tryRead(&us, 
sizeof(uint16_t)) ? us : 0;
 
  293     int32_t readInt() noexcept
 
  296         return tryRead(&i, 
sizeof(int32_t)) ? i : 0;
 
  303     uint32_t readUInt() noexcept
 
  306         return tryRead(&ui, 
sizeof(int32_t)) ? ui : 0;
 
  313     int64_t readLong() noexcept
 
  316         return tryRead(&l, 
sizeof(int64_t)) ? l : 0;
 
  323     uint64_t readULong() noexcept
 
  326         return tryRead(&ul, 
sizeof(int64_t)) ? ul : 0;
 
  333     float readFloat() noexcept
 
  336         return tryRead(&f, 
sizeof(
float)) ? f : 0.0f;
 
  343     double readDouble() noexcept
 
  346         return tryRead(&d, 
sizeof(
double)) ? d : 0.0;
 
  358         DISTRHO_SAFE_ASSERT_RETURN(data != 
nullptr, 
false);
 
  359         DISTRHO_SAFE_ASSERT_RETURN(size > 0, 
false);
 
  361         if (tryRead(data, size))
 
  364         std::memset(data, 0, size);
 
  375     template <
typename T>
 
  378         if (tryRead(&type, 
sizeof(T)))
 
  381         std::memset(&type, 0, 
sizeof(T));
 
  391     bool writeBool(
const bool value) noexcept
 
  393         return tryWrite(&value, 
sizeof(
bool));
 
  399     bool writeByte(
const uint8_t value) noexcept
 
  401         return tryWrite(&value, 
sizeof(uint8_t));
 
  407     bool writeShort(
const int16_t value) noexcept
 
  409         return tryWrite(&value, 
sizeof(int16_t));
 
  415     bool writeUShort(
const uint16_t value) noexcept
 
  417         return tryWrite(&value, 
sizeof(uint16_t));
 
  423     bool writeInt(
const int32_t value) noexcept
 
  425         return tryWrite(&value, 
sizeof(int32_t));
 
  431     bool writeUInt(
const uint32_t value) noexcept
 
  433         return tryWrite(&value, 
sizeof(uint32_t));
 
  439     bool writeLong(
const int64_t value) noexcept
 
  441         return tryWrite(&value, 
sizeof(int64_t));
 
  447     bool writeULong(
const uint64_t value) noexcept
 
  449         return tryWrite(&value, 
sizeof(uint64_t));
 
  455     bool writeFloat(
const float value) noexcept
 
  457         return tryWrite(&value, 
sizeof(
float));
 
  463     bool writeDouble(
const double value) noexcept
 
  465         return tryWrite(&value, 
sizeof(
double));
 
  474         DISTRHO_SAFE_ASSERT_RETURN(data != 
nullptr, 
false);
 
  475         DISTRHO_SAFE_ASSERT_RETURN(size > 0, 
false);
 
  477         return tryWrite(data, size);
 
  484     template <
typename T>
 
  487         return tryWrite(&type, 
sizeof(T));
 
  498         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr, 
false);
 
  500         if (buffer->invalidateCommit)
 
  502             buffer->wrtn = buffer->head;
 
  503             buffer->invalidateCommit = 
false;
 
  508         DISTRHO_SAFE_ASSERT_RETURN(buffer->head != buffer->wrtn, 
false);
 
  511         buffer->head = buffer->wrtn;
 
  512         errorWriting = 
false;
 
  521     void setRingBuffer(BufferStruct* 
const ringBuf, 
const bool clearRingBufferData) noexcept
 
  523         DISTRHO_SAFE_ASSERT_RETURN(buffer != ringBuf,);
 
  527         if (clearRingBufferData && ringBuf != 
nullptr)
 
  535     bool tryRead(
void* 
const buf, 
const uint32_t size) noexcept
 
  537         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr, 
false);
 
  538         #if defined(__clang__) 
  539         # pragma clang diagnostic push 
  540         # pragma clang diagnostic ignored "-Wtautological-pointer-compare" 
  542         DISTRHO_SAFE_ASSERT_RETURN(buffer->buf != 
nullptr, 
false);
 
  543         #if defined(__clang__) 
  544         # pragma clang diagnostic pop 
  546         DISTRHO_SAFE_ASSERT_RETURN(buf != 
nullptr, 
false);
 
  547         DISTRHO_SAFE_ASSERT_RETURN(size > 0, 
false);
 
  548         DISTRHO_SAFE_ASSERT_RETURN(size < buffer->size, 
false);
 
  551         if (buffer->head == buffer->tail)
 
  554         uint8_t* 
const bytebuf(
static_cast<uint8_t*
>(buf));
 
  556         const uint32_t head(buffer->head);
 
  557         const uint32_t tail(buffer->tail);
 
  558         const uint32_t wrap((head > tail) ? 0 : buffer->size);
 
  560         if (size > wrap + head - tail)
 
  565                 d_stderr2(
"RingBuffer::tryRead(%p, %lu): failed, not enough space", buf, (ulong)size);
 
  570         uint32_t readto(tail + size);
 
  572         if (readto > buffer->size)
 
  574             readto -= buffer->size;
 
  578                 std::memcpy(bytebuf, buffer->buf + tail, 1);
 
  582                 const uint32_t firstpart(buffer->size - tail);
 
  583                 std::memcpy(bytebuf, buffer->buf + tail, firstpart);
 
  584                 std::memcpy(bytebuf + firstpart, buffer->buf, readto);
 
  589             std::memcpy(bytebuf, buffer->buf + tail, size);
 
  591             if (readto == buffer->size)
 
  595         buffer->tail = readto;
 
  596         errorReading = 
false;
 
  601     bool tryWrite(
const void* 
const buf, 
const uint32_t size) noexcept
 
  603         DISTRHO_SAFE_ASSERT_RETURN(buffer != 
nullptr, 
false);
 
  604         DISTRHO_SAFE_ASSERT_RETURN(buf != 
nullptr, 
false);
 
  605         DISTRHO_SAFE_ASSERT_RETURN(size > 0, 
false);
 
  606         DISTRHO_SAFE_ASSERT_UINT2_RETURN(size < buffer->size, size, buffer->size, 
false);
 
  608         const uint8_t* 
const bytebuf(
static_cast<const uint8_t*
>(buf));
 
  610         const uint32_t tail(buffer->tail);
 
  611         const uint32_t wrtn(buffer->wrtn);
 
  612         const uint32_t wrap((tail > wrtn) ? 0 : buffer->size);
 
  614         if (size >= wrap + tail - wrtn)
 
  619                 d_stderr2(
"RingBuffer::tryWrite(%p, %lu): failed, not enough space", buf, (ulong)size);
 
  621             buffer->invalidateCommit = 
true;
 
  625         uint32_t writeto(wrtn + size);
 
  627         if (writeto > buffer->size)
 
  629             writeto -= buffer->size;
 
  633                 std::memcpy(buffer->buf, bytebuf, 1);
 
  637                 const uint32_t firstpart(buffer->size - wrtn);
 
  638                 std::memcpy(buffer->buf + wrtn, bytebuf, firstpart);
 
  639                 std::memcpy(buffer->buf, bytebuf + firstpart, writeto);
 
  644             std::memcpy(buffer->buf + wrtn, bytebuf, size);
 
  646             if (writeto == buffer->size)
 
  650         buffer->wrtn = writeto;
 
  656     BufferStruct* buffer;
 
  664     DISTRHO_PREVENT_VIRTUAL_HEAP_ALLOCATION
 
  668 template <
class BufferStruct>
 
  671     return (buffer != 
nullptr && buffer->head != buffer->tail);
 
  677     return (buffer != 
nullptr && buffer->buf != 
nullptr && buffer->head != buffer->tail);
 
  693         : heapBuffer(HeapBuffer_INIT)
 
  695 #ifndef DISTRHO_PROPER_CPP11_SUPPORT 
  696         std::memset(&heapBuffer, 0, 
sizeof(heapBuffer));
 
  703         if (heapBuffer.
buf == 
nullptr)
 
  706         delete[] heapBuffer.
buf;
 
  707         heapBuffer.
buf = 
nullptr;
 
  713         DISTRHO_SAFE_ASSERT_RETURN(heapBuffer.
buf == 
nullptr, 
false);
 
  714         DISTRHO_SAFE_ASSERT_RETURN(size > 0,  
false);
 
  719             heapBuffer.
buf = 
new uint8_t[p2size];
 
  720         } DISTRHO_SAFE_EXCEPTION_RETURN(
"HeapRingBuffer::createBuffer", 
false);
 
  722         heapBuffer.
size = p2size;
 
  723         setRingBuffer(&heapBuffer, 
true);
 
  730         DISTRHO_SAFE_ASSERT_RETURN(heapBuffer.
buf != 
nullptr,);
 
  732         setRingBuffer(
nullptr, 
false);
 
  734         delete[] heapBuffer.
buf;
 
  735         heapBuffer.
buf  = 
nullptr;
 
  741         DISTRHO_SAFE_ASSERT_RETURN(other.heapBuffer.
size == heapBuffer.
size,);
 
  743         std::memcpy(&heapBuffer, &other.heapBuffer, 
sizeof(
HeapBuffer) - 
sizeof(uint8_t*));
 
  744         std::memcpy(heapBuffer.
buf, other.heapBuffer.
buf, 
sizeof(uint8_t) * heapBuffer.
size);
 
  752     DISTRHO_PREVENT_VIRTUAL_HEAP_ALLOCATION
 
  768         : stackBuffer(StackBuffer_INIT)
 
  770 #ifndef DISTRHO_PROPER_CPP11_SUPPORT 
  771         std::memset(&stackBuffer, 0, 
sizeof(stackBuffer));
 
  773         setRingBuffer(&stackBuffer, 
true);
 
  780     DISTRHO_PREVENT_VIRTUAL_HEAP_ALLOCATION
 
Definition: RingBuffer.hpp:689
 
HeapRingBuffer() noexcept
Definition: RingBuffer.hpp:692
 
void deleteBuffer() noexcept
Definition: RingBuffer.hpp:728
 
bool createBuffer(const uint32_t size) noexcept
Definition: RingBuffer.hpp:711
 
~HeapRingBuffer() noexcept override
Definition: RingBuffer.hpp:701
 
Definition: RingBuffer.hpp:168
 
bool writeCustomType(const T &type) noexcept
Definition: RingBuffer.hpp:485
 
bool writeCustomData(const void *const data, const uint32_t size) noexcept
Definition: RingBuffer.hpp:472
 
bool readCustomType(T &type) noexcept
Definition: RingBuffer.hpp:376
 
bool readCustomData(void *const data, const uint32_t size) noexcept
Definition: RingBuffer.hpp:356
 
bool commitWrite() noexcept
Definition: RingBuffer.hpp:496
 
Definition: RingBuffer.hpp:764
 
SmallStackRingBuffer() noexcept
Definition: RingBuffer.hpp:767
 
static uint32_t d_nextPowerOf2(uint32_t size) noexcept
Definition: DistrhoUtils.hpp:298
 
#define END_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:834
 
#define START_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:828
 
static void d_stderr2(const char *const fmt,...) noexcept
Definition: DistrhoUtils.hpp:161
 
Definition: RingBuffer.hpp:104
 
Definition: RingBuffer.hpp:49
 
bool invalidateCommit
Definition: RingBuffer.hpp:80
 
uint32_t wrtn
Definition: RingBuffer.hpp:74
 
uint32_t head
Definition: RingBuffer.hpp:60
 
uint32_t size
Definition: RingBuffer.hpp:54
 
uint32_t tail
Definition: RingBuffer.hpp:67
 
uint8_t * buf
Definition: RingBuffer.hpp:86
 
Definition: RingBuffer.hpp:115
 
Definition: RingBuffer.hpp:93