diff --git a/AK/Array.h b/AK/Array.h index 372d1f73f5..6ed6db42a7 100644 --- a/AK/Array.h +++ b/AK/Array.h @@ -63,6 +63,9 @@ struct Array { constexpr const T& operator[](size_t index) const { return __data[index]; } constexpr T& operator[](size_t index) { return __data[index]; } + template + constexpr bool operator==(const Array& other) const { return span() == other.span(); } + using ConstIterator = SimpleIterator; using Iterator = SimpleIterator; diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index c7341d025d..29c51ce43c 100644 --- a/AK/ByteBuffer.h +++ b/AK/ByteBuffer.h @@ -71,6 +71,9 @@ public: Bytes bytes() { return { data(), size() }; } ReadonlyBytes bytes() const { return { data(), size() }; } + Span span() { return { data(), size() }; } + Span span() const { return { data(), size() }; } + u8* offset_pointer(int offset) { return m_data + offset; } const u8* offset_pointer(int offset) const { return m_data + offset; } @@ -159,6 +162,9 @@ public: Bytes bytes() { return m_impl ? m_impl->bytes() : nullptr; } ReadonlyBytes bytes() const { return m_impl ? m_impl->bytes() : nullptr; } + Span span() { return m_impl ? m_impl->span() : nullptr; } + Span span() const { return m_impl ? m_impl->span() : nullptr; } + u8* offset_pointer(int offset) { return m_impl ? m_impl->offset_pointer(offset) : nullptr; } const u8* offset_pointer(int offset) const { return m_impl ? m_impl->offset_pointer(offset) : nullptr; } diff --git a/AK/Tests/TestMemoryStream.cpp b/AK/Tests/TestMemoryStream.cpp index 3331296c51..f9b763df38 100644 --- a/AK/Tests/TestMemoryStream.cpp +++ b/AK/Tests/TestMemoryStream.cpp @@ -27,22 +27,8 @@ #include #include -#include #include -static bool compare(ReadonlyBytes lhs, ReadonlyBytes rhs) -{ - if (lhs.size() != rhs.size()) - return false; - - for (size_t idx = 0; idx < lhs.size(); ++idx) { - if (lhs[idx] != rhs[idx]) - return false; - } - - return true; -} - TEST_CASE(read_an_integer) { u32 expected = 0x01020304, actual; @@ -97,39 +83,41 @@ TEST_CASE(recoverable_error) TEST_CASE(chain_stream_operator) { - u8 expected[] { 0, 1, 2, 3 }, actual[4]; + const Array expected { 0, 1, 2, 3 }; + Array actual; - InputMemoryStream stream { { expected, sizeof(expected) } }; + InputMemoryStream stream { expected }; stream >> actual[0] >> actual[1] >> actual[2] >> actual[3]; EXPECT(!stream.has_any_error() && stream.eof()); - EXPECT(compare({ expected, sizeof(expected) }, { actual, sizeof(actual) })); + EXPECT_EQ(expected, actual); } TEST_CASE(seeking_slicing_offset) { - u8 input[] { 0, 1, 2, 3, 4, 5, 6, 7 }, - expected0[] { 0, 1, 2, 3 }, - expected1[] { 4, 5, 6, 7 }, - expected2[] { 1, 2, 3, 4 }, - actual0[4], actual1[4], actual2[4]; + const Array input { 0, 1, 2, 3, 4, 5, 6, 7 }; + const Array expected0 { 0, 1, 2, 3 }; + const Array expected1 { 4, 5, 6, 7 }; + const Array expected2 { 1, 2, 3, 4 }; - InputMemoryStream stream { { input, sizeof(input) } }; + Array actual0, actual1, actual2; - stream >> Bytes { actual0, sizeof(actual0) }; + InputMemoryStream stream { input }; + + stream >> actual0; EXPECT(!stream.has_any_error() && !stream.eof()); - EXPECT(compare({ expected0, sizeof(expected0) }, { actual0, sizeof(actual0) })); + EXPECT_EQ(expected0, actual0); stream.seek(4); - stream >> Bytes { actual1, sizeof(actual1) }; + stream >> actual1; EXPECT(!stream.has_any_error() && stream.eof()); - EXPECT(compare({ expected1, sizeof(expected1) }, { actual1, sizeof(actual1) })); + EXPECT_EQ(expected1, actual1); stream.seek(1); - stream >> Bytes { actual2, sizeof(actual2) }; + stream >> actual2; EXPECT(!stream.has_any_error() && !stream.eof()); - EXPECT(compare({ expected2, sizeof(expected2) }, { actual2, sizeof(actual2) })); + EXPECT_EQ(expected2, actual2); } TEST_CASE(duplex_simple) @@ -172,8 +160,8 @@ TEST_CASE(duplex_large_buffer) TEST_CASE(read_endian_values) { - const u8 input[] { 0, 1, 2, 3, 4, 5, 6, 7 }; - InputMemoryStream stream { { input, sizeof(input) } }; + const Array input { 0, 1, 2, 3, 4, 5, 6, 7 }; + InputMemoryStream stream { input }; LittleEndian value1; BigEndian value2; @@ -185,13 +173,13 @@ TEST_CASE(read_endian_values) TEST_CASE(write_endian_values) { - const u8 expected[] { 4, 3, 2, 1, 1, 2, 3, 4 }; + const Array expected { 4, 3, 2, 1, 1, 2, 3, 4 }; DuplexMemoryStream stream; stream << LittleEndian { 0x01020304 } << BigEndian { 0x01020304 }; EXPECT_EQ(stream.size(), 8u); - EXPECT(compare({ expected, sizeof(expected) }, stream.copy_into_contiguous_buffer())); + EXPECT(expected.span() == stream.copy_into_contiguous_buffer().span()); } TEST_CASE(new_output_memory_stream) @@ -250,10 +238,7 @@ TEST_CASE(offset_calculation_error_regression) stream.discard_or_error(sizeof(int)); stream.read(output); - EXPECT(compare(input, output)); - - AK::dump_bytes(input); - AK::dump_bytes(output); + EXPECT_EQ(input, output); } TEST_MAIN(MemoryStream) diff --git a/Userland/test-compress.cpp b/Userland/test-compress.cpp index 08150f2cec..7e1dbb0d63 100644 --- a/Userland/test-compress.cpp +++ b/Userland/test-compress.cpp @@ -32,19 +32,6 @@ #include #include -static bool compare(ReadonlyBytes lhs, ReadonlyBytes rhs) -{ - if (lhs.size() != rhs.size()) - return false; - - for (size_t idx = 0; idx < lhs.size(); ++idx) { - if (lhs[idx] != rhs[idx]) - return false; - } - - return true; -} - TEST_CASE(canonical_code_simple) { const Array code { @@ -98,7 +85,7 @@ TEST_CASE(deflate_decompress_compressed_block) const u8 uncompressed[] = "This is a simple text file :)"; const auto decompressed = Compress::DeflateDecompressor::decompress_all(compressed); - EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.value().bytes())); + EXPECT(decompressed.value().bytes() == ReadonlyBytes({ uncompressed, sizeof(uncompressed) - 1 })); } TEST_CASE(deflate_decompress_uncompressed_block) @@ -111,7 +98,7 @@ TEST_CASE(deflate_decompress_uncompressed_block) const u8 uncompressed[] = "Hello, World!"; const auto decompressed = Compress::DeflateDecompressor::decompress_all(compressed); - EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.value().bytes())); + EXPECT(decompressed.value().bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 })); } TEST_CASE(deflate_decompress_multiple_blocks) @@ -128,7 +115,7 @@ TEST_CASE(deflate_decompress_multiple_blocks) const u8 uncompressed[] = "The first block is uncompressed and the second block is compressed."; const auto decompressed = Compress::DeflateDecompressor::decompress_all(compressed); - EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.value().bytes())); + EXPECT(decompressed.value().bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 })); } TEST_CASE(deflate_decompress_zeroes) @@ -141,7 +128,7 @@ TEST_CASE(deflate_decompress_zeroes) const Array uncompressed { 0 }; const auto decompressed = Compress::DeflateDecompressor::decompress_all(compressed); - EXPECT(compare(uncompressed, decompressed.value().bytes())); + EXPECT(uncompressed == decompressed.value().bytes()); } TEST_CASE(zlib_decompress_simple) @@ -156,7 +143,7 @@ TEST_CASE(zlib_decompress_simple) const u8 uncompressed[] = "This is a simple text file :)"; const auto decompressed = Compress::Zlib::decompress_all(compressed); - EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.value().bytes())); + EXPECT(decompressed.value().bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 })); } TEST_CASE(gzip_decompress_simple) @@ -170,7 +157,7 @@ TEST_CASE(gzip_decompress_simple) const u8 uncompressed[] = "word1 abc word2"; const auto decompressed = Compress::GzipDecompressor::decompress_all(compressed); - EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.value().bytes())); + EXPECT(decompressed.value().bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 })); } TEST_CASE(gzip_decompress_multiple_members) @@ -186,7 +173,7 @@ TEST_CASE(gzip_decompress_multiple_members) const u8 uncompressed[] = "abcabcabcabc"; const auto decompressed = Compress::GzipDecompressor::decompress_all(compressed); - EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.value().bytes())); + EXPECT(decompressed.value().bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 })); } TEST_CASE(gzip_decompress_zeroes) @@ -211,7 +198,7 @@ TEST_CASE(gzip_decompress_zeroes) const Array uncompressed = { 0 }; const auto decompressed = Compress::GzipDecompressor::decompress_all(compressed); - EXPECT(compare(uncompressed, decompressed.value().bytes())); + EXPECT(uncompressed == decompressed.value().bytes()); } TEST_CASE(gzip_decompress_repeat_around_buffer) @@ -231,7 +218,7 @@ TEST_CASE(gzip_decompress_repeat_around_buffer) uncompressed.span().slice(0x7f00, 0x0100).fill(1); const auto decompressed = Compress::GzipDecompressor::decompress_all(compressed); - EXPECT(compare(uncompressed, decompressed.value().bytes())); + EXPECT(uncompressed == decompressed.value().bytes()); } TEST_MAIN(Compress)