// 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; // ----------------------------------------------------------------------------- // Test Block Definition // ----------------------------------------------------------------------------- IAT_BEGIN_BLOCK(Core, BinaryStreamWriter) // ------------------------------------------------------------------------- // 1. Vector Mode (Dynamic Growth) // ------------------------------------------------------------------------- BOOL TestVectorGrowth() { std::vector buffer; // Start empty BinaryStreamWriter writer(buffer); // Write 1 Byte writer.Write(0xAA); IAT_CHECK_EQ(buffer.size(), (SIZE_T)1); IAT_CHECK_EQ(buffer[0], 0xAA); // Write 4 Bytes (UINT32) // 0xDDCCBBAA -> Little Endian: AA BB CC DD writer.Write(0xDDCCBBAA); IAT_CHECK_EQ(buffer.size(), (SIZE_T)5); // Verify Memory Layout IAT_CHECK_EQ(buffer[1], 0xAA); IAT_CHECK_EQ(buffer[2], 0xBB); IAT_CHECK_EQ(buffer[3], 0xCC); IAT_CHECK_EQ(buffer[4], 0xDD); return TRUE; } // ------------------------------------------------------------------------- // 2. Vector Mode (Appending to Existing Data) // ------------------------------------------------------------------------- BOOL TestVectorAppend() { // Vector starts with existing data std::vector buffer = { 0x01, 0x02 }; BinaryStreamWriter writer(buffer); // Should append to end, not overwrite 0x01 writer.Write(0x03); IAT_CHECK_EQ(buffer.size(), (SIZE_T)3); IAT_CHECK_EQ(buffer[0], 0x01); IAT_CHECK_EQ(buffer[2], 0x03); return TRUE; } // ------------------------------------------------------------------------- // 3. Fixed Mode (Span / No Allocation) // ------------------------------------------------------------------------- BOOL TestFixedBuffer() { UINT8 rawData[10]; // Initialize with zeros std::memset(rawData, 0, 10); BinaryStreamWriter writer(rawData); // Implicit conversion to span // Write UINT8 writer.Write(0xFF); IAT_CHECK_EQ(rawData[0], 0xFF); // Write UINT16 writer.Write(0x2211); IAT_CHECK_EQ(rawData[1], 0x11); IAT_CHECK_EQ(rawData[2], 0x22); // Verify we haven't touched the rest IAT_CHECK_EQ(rawData[3], 0x00); return TRUE; } // ------------------------------------------------------------------------- // 4. WriteBytes (Bulk Write) // ------------------------------------------------------------------------- BOOL TestWriteBytes() { std::vector buffer; BinaryStreamWriter writer(buffer); const char* msg = "IA"; writer.WriteBytes((PVOID)msg, 2); writer.Write(0x00); // Null term IAT_CHECK_EQ(buffer.size(), (SIZE_T)3); IAT_CHECK_EQ(buffer[0], 'I'); IAT_CHECK_EQ(buffer[1], 'A'); IAT_CHECK_EQ(buffer[2], 0x00); return TRUE; } // ------------------------------------------------------------------------- // 5. Random Access (WriteAt) // ------------------------------------------------------------------------- BOOL TestRandomAccess() { std::vector buffer; BinaryStreamWriter writer(buffer); // Fill with placeholders writer.Write(0xFFFFFFFF); writer.Write(0xFFFFFFFF); // Overwrite the first integer with 0x00000000 writer.WriteAt(0, 0); // Overwrite the byte at index 4 (start of second int) writer.WriteAt(4, 0xAA); IAT_CHECK_EQ(buffer[0], 0x00); IAT_CHECK_EQ(buffer[3], 0x00); IAT_CHECK_EQ(buffer[4], 0xAA); // Modified IAT_CHECK_EQ(buffer[5], 0xFF); // Unmodified return TRUE; } // ------------------------------------------------------------------------- // 6. Floating Point Writing // ------------------------------------------------------------------------- BOOL TestWriteFloat() { std::vector buffer; BinaryStreamWriter writer(buffer); FLOAT32 val = 1.234f; writer.Write(val); IAT_CHECK_EQ(buffer.size(), (SIZE_T)4); // Read it back via memcpy to verify FLOAT32 readBack; std::memcpy(&readBack, buffer.data(), 4); IAT_CHECK_APPROX(readBack, val); return TRUE; } // ------------------------------------------------------------------------- // 7. GetPtrAt (Pointer Arithmetic Check) // ------------------------------------------------------------------------- BOOL TestGetPtr() { std::vector buffer = { 0x10, 0x20, 0x30 }; BinaryStreamWriter writer(buffer); PUINT8 p1 = writer.GetPtrAt(1); IAT_CHECK(p1 != nullptr); IAT_CHECK_EQ(*p1, 0x20); // Bounds check (Valid boundary) PUINT8 pLast = writer.GetPtrAt(2); IAT_CHECK(pLast != nullptr); // Bounds check (Invalid) // Note: We don't test Panic here, but we check if it returns valid ptrs PUINT8 pInvalid = writer.GetPtrAt(3); IAT_CHECK(pInvalid == nullptr); return TRUE; } // ------------------------------------------------------------------------- // Registration // ------------------------------------------------------------------------- IAT_BEGIN_TEST_LIST() IAT_ADD_TEST(TestVectorGrowth); IAT_ADD_TEST(TestVectorAppend); IAT_ADD_TEST(TestFixedBuffer); IAT_ADD_TEST(TestWriteBytes); IAT_ADD_TEST(TestRandomAccess); IAT_ADD_TEST(TestWriteFloat); IAT_ADD_TEST(TestGetPtr); IAT_END_TEST_LIST() IAT_END_BLOCK() int main(int argc, char* argv[]) { UNUSED(argc); UNUSED(argv); // Define runner (StopOnFail=false, Verbose=true) ia::iatest::runner testRunner; // Run the BinaryReader block testRunner.testBlock(); return 0; }