// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2025 IAS (ias@iasoft.dev) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include using namespace IACore; IAT_BEGIN_BLOCK(Core, RingBuffer) // 1. Basic Push Pop BOOL TestPushPop() { // Allocate raw memory for the ring buffer // ControlBlock (128 bytes) + Data std::vector memory(sizeof(RingBufferView::ControlBlock) + 1024); // Initialize as OWNER (Producer) RingBufferView producer(std::span(memory), TRUE); // Initialize as CONSUMER (Pointer to same memory) RingBufferView consumer(std::span(memory), FALSE); // Data to send String msg = "Hello RingBuffer"; BOOL pushed = producer.Push(1, {(const UINT8 *) msg.data(), msg.size()}); IAT_CHECK(pushed); // Read back RingBufferView::PacketHeader header; UINT8 readBuf[128]; INT32 bytesRead = consumer.Pop(header, std::span(readBuf, 128)); IAT_CHECK_EQ(header.ID, (UINT16) 1); IAT_CHECK_EQ(bytesRead, (INT32) msg.size()); String readMsg((char *) readBuf, bytesRead); IAT_CHECK_EQ(readMsg, msg); return TRUE; } // 2. Wrap Around (The hardest logic to get right) BOOL TestWrapAround() { // Small buffer to force wrapping quickly // Capacity will be 100 bytes std::vector memory(sizeof(RingBufferView::ControlBlock) + 100); RingBufferView rb(std::span(memory), TRUE); // Fill buffer to near end // Push 80 bytes std::vector junk(80, 0xFF); rb.Push(1, junk); // Pop them to advance READ cursor RingBufferView::PacketHeader header; UINT8 outBuf[100]; rb.Pop(header, outBuf); // Now READ and WRITE are near index 80. // Pushing 40 bytes should trigger a wrap-around (split write) std::vector wrapData(40, 0xAA); BOOL pushed = rb.Push(2, wrapData); IAT_CHECK(pushed); // Pop and verify integrity INT32 popSize = rb.Pop(header, outBuf); IAT_CHECK_EQ(popSize, 40); // Check if data is intact BOOL match = TRUE; for (int i = 0; i < 40; i++) { if (outBuf[i] != 0xAA) match = FALSE; } IAT_CHECK(match); return TRUE; } IAT_BEGIN_TEST_LIST() IAT_ADD_TEST(TestPushPop); IAT_ADD_TEST(TestWrapAround); IAT_END_TEST_LIST() IAT_END_BLOCK() IAT_REGISTER_ENTRY(Core, RingBuffer)