commit a05231b01dd2376f9cf80019e4e6c00e716647e1
parent fac31729ed450a7c530e83e0feecf46d6562b5fd
Author: falkTX <falktx@falktx.com>
Date: Fri, 3 May 2024 21:37:13 +0200
Add a few ringbuffer peek methods
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
1 file changed, 89 insertions(+), 2 deletions(-)
diff --git a/distrho/extra/RingBuffer.hpp b/distrho/extra/RingBuffer.hpp
@@ -405,6 +405,36 @@ public:
}
// -------------------------------------------------------------------
+ // peek operations (returns a value without advancing read position)
+
+ /*
+ * Peek for an unsigned 32-bit integer.
+ * Returns 0 if reading fails.
+ */
+ uint32_t peekUInt() const noexcept
+ {
+ uint32_t ui = 0;
+ return tryPeek(&ui, sizeof(int32_t)) ? ui : 0;
+ }
+
+ /*!
+ * Peek for a custom data type specified by the template typename used,
+ * with size being automatically deduced by the compiler (through the use of sizeof).
+ *
+ * Returns true if peeking succeeds.
+ * In case of failure, @a type value is automatically cleared by its deduced size.
+ */
+ template <typename T>
+ bool peekCustomType(T& type) const noexcept
+ {
+ if (tryPeek(&type, sizeof(T)))
+ return true;
+
+ std::memset(&type, 0, sizeof(T));
+ return false;
+ }
+
+ // -------------------------------------------------------------------
// write operations
/*
@@ -601,7 +631,7 @@ protected:
}
else
{
- const uint32_t firstpart(buffer->size - tail);
+ const uint32_t firstpart = buffer->size - tail;
std::memcpy(bytebuf, buffer->buf + tail, firstpart);
std::memcpy(bytebuf + firstpart, buffer->buf, readto);
}
@@ -619,6 +649,63 @@ protected:
return true;
}
+ /** @internal try reading from the buffer, can fail. */
+ bool tryPeek(void* const buf, const uint32_t size) const noexcept
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(buffer != nullptr, false);
+ #if defined(__clang__)
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
+ #endif
+ DISTRHO_SAFE_ASSERT_RETURN(buffer->buf != nullptr, false);
+ #if defined(__clang__)
+ #pragma clang diagnostic pop
+ #endif
+ DISTRHO_SAFE_ASSERT_RETURN(buf != nullptr, false);
+ DISTRHO_SAFE_ASSERT_RETURN(size > 0, false);
+ DISTRHO_SAFE_ASSERT_RETURN(size < buffer->size, false);
+
+ // empty
+ if (buffer->head == buffer->tail)
+ return false;
+
+ uint8_t* const bytebuf = static_cast<uint8_t*>(buf);
+
+ const uint32_t head = buffer->head;
+ const uint32_t tail = buffer->tail;
+ const uint32_t wrap = head > tail ? 0 : buffer->size;
+
+ if (size > wrap + head - tail)
+ return false;
+
+ uint32_t readto = tail + size;
+
+ if (readto > buffer->size)
+ {
+ readto -= buffer->size;
+
+ if (size == 1)
+ {
+ std::memcpy(bytebuf, buffer->buf + tail, 1);
+ }
+ else
+ {
+ const uint32_t firstpart = buffer->size - tail;
+ std::memcpy(bytebuf, buffer->buf + tail, firstpart);
+ std::memcpy(bytebuf + firstpart, buffer->buf, readto);
+ }
+ }
+ else
+ {
+ std::memcpy(bytebuf, buffer->buf + tail, size);
+
+ if (readto == buffer->size)
+ readto = 0;
+ }
+
+ return true;
+ }
+
/** @internal try writing to the buffer, can fail. */
bool tryWrite(const void* const buf, const uint32_t size) noexcept
{
@@ -656,7 +743,7 @@ protected:
}
else
{
- const uint32_t firstpart(buffer->size - wrtn);
+ const uint32_t firstpart = buffer->size - wrtn;
std::memcpy(buffer->buf + wrtn, bytebuf, firstpart);
std::memcpy(buffer->buf, bytebuf + firstpart, writeto);
}