// 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, BinaryStreamReader) // ------------------------------------------------------------------------- // 1. Basic Primitive Reading (UINT8) // ------------------------------------------------------------------------- BOOL TestReadUint8() { UINT8 data[] = { 0xAA, 0xBB, 0xCC }; BinaryStreamReader reader(data); // Read First Byte auto val1 = reader.Read(); IAT_CHECK(val1.has_value()); IAT_CHECK_EQ(*val1, 0xAA); IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)1); // Read Second Byte auto val2 = reader.Read(); IAT_CHECK_EQ(*val2, 0xBB); return TRUE; } // ------------------------------------------------------------------------- // 2. Multi-byte Reading (Endianness check) // ------------------------------------------------------------------------- BOOL TestReadMultiByte() { // 0x04030201 in Little Endian memory layout UINT8 data[] = { 0x01, 0x02, 0x03, 0x04 }; BinaryStreamReader reader(data); auto val = reader.Read(); IAT_CHECK(val.has_value()); // Assuming standard x86/ARM Little Endian for this test // If your engine supports Big Endian, you'd check architecture here IAT_CHECK_EQ(*val, (UINT32)0x04030201); IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)4); IAT_CHECK(reader.IsEOF()); return TRUE; } // ------------------------------------------------------------------------- // 3. Floating Point (Approx check) // ------------------------------------------------------------------------- BOOL TestReadFloat() { FLOAT32 pi = 3.14159f; // Bit-cast float to bytes for setup UINT8 data[4]; std::memcpy(data, &pi, 4); BinaryStreamReader reader(data); auto val = reader.Read(); IAT_CHECK(val.has_value()); IAT_CHECK_APPROX(*val, pi); return TRUE; } // ------------------------------------------------------------------------- // 4. String Reading // ------------------------------------------------------------------------- BOOL TestReadString() { const char* raw = "HelloIA"; BinaryStreamReader reader(std::span((const UINT8*)raw, 7)); // Read "Hello" (5 bytes) auto str = reader.ReadString(5); IAT_CHECK(str.has_value()); IAT_CHECK_EQ(*str, String("Hello")); IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)5); // Read remaining "IA" auto str2 = reader.ReadString(2); IAT_CHECK_EQ(*str2, String("IA")); return TRUE; } // ------------------------------------------------------------------------- // 5. Batch Buffer Reading // ------------------------------------------------------------------------- BOOL TestReadBuffer() { UINT8 src[] = { 1, 2, 3, 4, 5 }; UINT8 dst[3] = { 0 }; BinaryStreamReader reader(src); // Read 3 bytes into dst auto res = reader.Read(dst, 3); IAT_CHECK(res.has_value()); // Verify dst content IAT_CHECK_EQ(dst[0], 1); IAT_CHECK_EQ(dst[1], 2); IAT_CHECK_EQ(dst[2], 3); // Verify cursor IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)3); return TRUE; } // ------------------------------------------------------------------------- // 6. Navigation (Seek, Skip, Remaining) // ------------------------------------------------------------------------- BOOL TestNavigation() { UINT8 data[10] = { 0 }; // Zero init BinaryStreamReader reader(data); IAT_CHECK_EQ(reader.Remaining(), (SIZE_T)10); // Skip reader.Skip(5); IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)5); IAT_CHECK_EQ(reader.Remaining(), (SIZE_T)5); // Skip clamping reader.Skip(100); // Should clamp to 10 IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)10); IAT_CHECK(reader.IsEOF()); // Seek reader.Seek(2); IAT_CHECK_EQ(reader.Cursor(), (SIZE_T)2); IAT_CHECK_EQ(reader.Remaining(), (SIZE_T)8); IAT_CHECK_NOT(reader.IsEOF()); return TRUE; } // ------------------------------------------------------------------------- // 7. Error Handling (EOF Protection) // ------------------------------------------------------------------------- BOOL TestBoundaryChecks() { UINT8 data[] = { 0x00, 0x00 }; BinaryStreamReader reader(data); // Valid read UNUSED(reader.Read()); IAT_CHECK(reader.IsEOF()); // Invalid Read Primitive auto val = reader.Read(); IAT_CHECK_NOT(val.has_value()); // Should be unexpected // Invalid Read String auto str = reader.ReadString(1); IAT_CHECK_NOT(str.has_value()); // Invalid Batch Read UINT8 buf[1]; auto batch = reader.Read(buf, 1); IAT_CHECK_NOT(batch.has_value()); return TRUE; } // ------------------------------------------------------------------------- // Registration // ------------------------------------------------------------------------- IAT_BEGIN_TEST_LIST() IAT_ADD_TEST(TestReadUint8); IAT_ADD_TEST(TestReadMultiByte); IAT_ADD_TEST(TestReadFloat); IAT_ADD_TEST(TestReadString); IAT_ADD_TEST(TestReadBuffer); IAT_ADD_TEST(TestNavigation); IAT_ADD_TEST(TestBoundaryChecks); 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 BinaryStreamReader block testRunner.testBlock(); return 0; }