159class RingBufferControl
167 RingBufferControl() noexcept
170 errorWriting(
false) {}
175 virtual ~RingBufferControl()
noexcept {}
183 bool isDataAvailableForReading()
const noexcept;
188 bool isEmpty()
const noexcept
190 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,
false);
192 return (buffer->buf ==
nullptr || buffer->head == buffer->tail);
198 uint32_t getSize()
const noexcept
200 return buffer !=
nullptr ? buffer->size : 0;
206 uint32_t getReadableDataSize()
const noexcept
208 DAF_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 DAF_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 - 1;
234 void clearData()
noexcept
236 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,);
241 buffer->invalidateCommit =
false;
243 std::memset(buffer->buf, 0, buffer->size);
250 void flush()
noexcept
252 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,);
254 buffer->head = buffer->tail = buffer->wrtn = 0;
255 buffer->invalidateCommit =
false;
257 errorWriting =
false;
267 bool readBool()
noexcept
270 return tryRead(&b,
sizeof(
bool)) ? b :
false;
277 uint8_t readByte()
noexcept
280 return tryRead(&B,
sizeof(uint8_t)) ? B : 0;
287 int16_t readShort()
noexcept
290 return tryRead(&s,
sizeof(int16_t)) ? s : 0;
297 uint16_t readUShort()
noexcept
300 return tryRead(&us,
sizeof(uint16_t)) ? us : 0;
307 int32_t readInt()
noexcept
310 return tryRead(&i,
sizeof(int32_t)) ? i : 0;
317 uint32_t readUInt()
noexcept
320 return tryRead(&ui,
sizeof(int32_t)) ? ui : 0;
327 int64_t readLong()
noexcept
330 return tryRead(&l,
sizeof(int64_t)) ? l : 0;
337 uint64_t readULong()
noexcept
340 return tryRead(&ul,
sizeof(int64_t)) ? ul : 0;
347 float readFloat()
noexcept
350 return tryRead(&f,
sizeof(
float)) ? f : 0.0f;
357 double readDouble()
noexcept
360 return tryRead(&d,
sizeof(
double)) ? d : 0.0;
372 DAF_SAFE_ASSERT_RETURN(data !=
nullptr,
false);
373 DAF_SAFE_ASSERT_RETURN(size > 0,
false);
375 if (tryRead(data, size))
378 std::memset(data, 0, size);
389 template <
typename T>
392 if (tryRead(&type,
sizeof(T)))
395 std::memset(&type, 0,
sizeof(T));
406 uint32_t peekUInt() const noexcept
409 return tryPeek(&ui,
sizeof(int32_t)) ? ui : 0;
419 template <
typename T>
422 if (tryPeek(&type,
sizeof(T)))
425 std::memset(&type, 0,
sizeof(T));
435 bool writeBool(
const bool value)
noexcept
437 return tryWrite(&value,
sizeof(
bool));
443 bool writeByte(
const uint8_t value)
noexcept
445 return tryWrite(&value,
sizeof(uint8_t));
451 bool writeShort(
const int16_t value)
noexcept
453 return tryWrite(&value,
sizeof(int16_t));
459 bool writeUShort(
const uint16_t value)
noexcept
461 return tryWrite(&value,
sizeof(uint16_t));
467 bool writeInt(
const int32_t value)
noexcept
469 return tryWrite(&value,
sizeof(int32_t));
475 bool writeUInt(
const uint32_t value)
noexcept
477 return tryWrite(&value,
sizeof(uint32_t));
483 bool writeLong(
const int64_t value)
noexcept
485 return tryWrite(&value,
sizeof(int64_t));
491 bool writeULong(
const uint64_t value)
noexcept
493 return tryWrite(&value,
sizeof(uint64_t));
499 bool writeFloat(
const float value)
noexcept
501 return tryWrite(&value,
sizeof(
float));
507 bool writeDouble(
const double value)
noexcept
509 return tryWrite(&value,
sizeof(
double));
518 DAF_SAFE_ASSERT_RETURN(data !=
nullptr,
false);
519 DAF_SAFE_ASSERT_RETURN(size > 0,
false);
521 return tryWrite(data, size);
528 template <
typename T>
531 return tryWrite(&type,
sizeof(T));
542 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,
false);
544 if (buffer->invalidateCommit)
546 buffer->wrtn = buffer->head;
547 buffer->invalidateCommit =
false;
552 if (debugMsg !=
nullptr) {
553 DAF_CUSTOM_SAFE_ASSERT_RETURN(debugMsg, buffer->head != buffer->wrtn,
false);
555 DAF_SAFE_ASSERT_RETURN(buffer->head != buffer->wrtn,
false);
559 buffer->head = buffer->wrtn;
560 errorWriting =
false;
569 void setRingBuffer(BufferStruct*
const ringBuf,
const bool clearRingBufferData)
noexcept
571 DAF_SAFE_ASSERT_RETURN(buffer != ringBuf,);
575 if (clearRingBufferData && ringBuf !=
nullptr)
583 bool tryRead(
void*
const buf,
const uint32_t size)
noexcept
585 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,
false);
586 #if defined(__clang__)
587 #pragma clang diagnostic push
588 #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
590 DAF_SAFE_ASSERT_RETURN(buffer->buf !=
nullptr,
false);
591 #if defined(__clang__)
592 #pragma clang diagnostic pop
594 DAF_SAFE_ASSERT_RETURN(buf !=
nullptr,
false);
595 DAF_SAFE_ASSERT_RETURN(size > 0,
false);
596 DAF_SAFE_ASSERT_RETURN(size < buffer->size,
false);
599 if (buffer->head == buffer->tail)
602 uint8_t*
const bytebuf =
static_cast<uint8_t*
>(buf);
604 const uint32_t head = buffer->head;
605 const uint32_t tail = buffer->tail;
606 const uint32_t wrap = head > tail ? 0 : buffer->size;
608 if (size > wrap + head - tail)
613 d_stderr2(
"RingBuffer::tryRead(%p, %lu): failed, not enough space", buf, (ulong)size);
618 uint32_t readto = tail + size;
620 if (readto > buffer->size)
622 readto -= buffer->size;
626 std::memcpy(bytebuf, buffer->buf + tail, 1);
630 const uint32_t firstpart = buffer->size - tail;
631 std::memcpy(bytebuf, buffer->buf + tail, firstpart);
632 std::memcpy(bytebuf + firstpart, buffer->buf, readto);
637 std::memcpy(bytebuf, buffer->buf + tail, size);
639 if (readto == buffer->size)
643 buffer->tail = readto;
644 errorReading =
false;
649 bool tryPeek(
void*
const buf,
const uint32_t size)
const noexcept
651 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,
false);
652 #if defined(__clang__)
653 #pragma clang diagnostic push
654 #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
656 DAF_SAFE_ASSERT_RETURN(buffer->buf !=
nullptr,
false);
657 #if defined(__clang__)
658 #pragma clang diagnostic pop
660 DAF_SAFE_ASSERT_RETURN(buf !=
nullptr,
false);
661 DAF_SAFE_ASSERT_RETURN(size > 0,
false);
662 DAF_SAFE_ASSERT_RETURN(size < buffer->size,
false);
665 if (buffer->head == buffer->tail)
668 uint8_t*
const bytebuf =
static_cast<uint8_t*
>(buf);
670 const uint32_t head = buffer->head;
671 const uint32_t tail = buffer->tail;
672 const uint32_t wrap = head > tail ? 0 : buffer->size;
674 if (size > wrap + head - tail)
677 uint32_t readto = tail + size;
679 if (readto > buffer->size)
681 readto -= buffer->size;
685 std::memcpy(bytebuf, buffer->buf + tail, 1);
689 const uint32_t firstpart = buffer->size - tail;
690 std::memcpy(bytebuf, buffer->buf + tail, firstpart);
691 std::memcpy(bytebuf + firstpart, buffer->buf, readto);
696 std::memcpy(bytebuf, buffer->buf + tail, size);
698 if (readto == buffer->size)
706 bool tryWrite(
const void*
const buf,
const uint32_t size)
noexcept
708 DAF_SAFE_ASSERT_RETURN(buffer !=
nullptr,
false);
709 DAF_SAFE_ASSERT_RETURN(buf !=
nullptr,
false);
710 DAF_SAFE_ASSERT_RETURN(size > 0,
false);
711 DAF_SAFE_ASSERT_UINT2_RETURN(size < buffer->size, size, buffer->size,
false);
713 const uint8_t*
const bytebuf =
static_cast<const uint8_t*
>(buf);
715 const uint32_t tail = buffer->tail;
716 const uint32_t wrtn = buffer->wrtn;
717 const uint32_t wrap = tail > wrtn ? 0 : buffer->size;
719 if (size >= wrap + tail - wrtn)
724 d_stderr2(
"RingBuffer::tryWrite(%p, %lu): failed, not enough space", buf, (ulong)size);
726 buffer->invalidateCommit =
true;
730 uint32_t writeto = wrtn + size;
732 if (writeto > buffer->size)
734 writeto -= buffer->size;
738 std::memcpy(buffer->buf, bytebuf, 1);
742 const uint32_t firstpart = buffer->size - wrtn;
743 std::memcpy(buffer->buf + wrtn, bytebuf, firstpart);
744 std::memcpy(buffer->buf, bytebuf + firstpart, writeto);
749 std::memcpy(buffer->buf + wrtn, bytebuf, size);
751 if (writeto == buffer->size)
755 buffer->wrtn = writeto;
761 BufferStruct* buffer;
769 DAF_PREVENT_VIRTUAL_HEAP_ALLOCATION
770 DAF_DECLARE_NON_COPYABLE(RingBufferControl)