From 9d3b65ba5cdaa6285292301ec89a37fec3f10e58 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Thu, 23 Oct 2025 10:13:24 +0200 Subject: [PATCH] enhance: Add Bytes::erase --- src/ccache/util/bytes.cpp | 21 ++++++++ src/ccache/util/bytes.hpp | 3 ++ unittest/test_util_bytes.cpp | 92 ++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/src/ccache/util/bytes.cpp b/src/ccache/util/bytes.cpp index 7524d991..b3e01fee 100644 --- a/src/ccache/util/bytes.cpp +++ b/src/ccache/util/bytes.cpp @@ -131,4 +131,25 @@ Bytes::resize(size_t size) noexcept m_size = size; } +void +Bytes::erase(const uint8_t* pos, const size_t size) noexcept +{ + if (size == 0) { + return; + } + const size_t offset = pos - m_data.get(); + if (offset + size < m_size) { + std::memmove(m_data.get() + offset, + m_data.get() + offset + size, + m_size - offset - size); + } + m_size -= size; +} + +void +Bytes::erase(const uint8_t* first, const uint8_t* last) noexcept +{ + erase(first, last - first); +} + } // namespace util diff --git a/src/ccache/util/bytes.hpp b/src/ccache/util/bytes.hpp index c103ed22..327e0c6e 100644 --- a/src/ccache/util/bytes.hpp +++ b/src/ccache/util/bytes.hpp @@ -86,6 +86,9 @@ public: void insert(const uint8_t* pos, const char* data, size_t size) noexcept; void insert(const uint8_t* pos, nonstd::span data) noexcept; + void erase(const uint8_t* pos, const size_t size) noexcept; + void erase(const uint8_t* first, const uint8_t* last) noexcept; + private: std::unique_ptr m_data; size_t m_size = 0; diff --git a/unittest/test_util_bytes.cpp b/unittest/test_util_bytes.cpp index cb564c88..11c6927e 100644 --- a/unittest/test_util_bytes.cpp +++ b/unittest/test_util_bytes.cpp @@ -397,6 +397,98 @@ TEST_CASE("Basics") CHECK(bytes2[1] == 'b'); CHECK(bytes2[2] == 'c'); } + + SUBCASE("Erase with pos and size") + { + Bytes bytes2("abcdef", 6); + + // Erase from beginning + bytes2.erase(bytes2.begin(), 2); + REQUIRE(bytes2.size() == 4); + CHECK(bytes2[0] == 'c'); + CHECK(bytes2[1] == 'd'); + CHECK(bytes2[2] == 'e'); + CHECK(bytes2[3] == 'f'); + + // Erase from middle + bytes2.erase(bytes2.begin() + 1, 2); + REQUIRE(bytes2.size() == 2); + CHECK(bytes2[0] == 'c'); + CHECK(bytes2[1] == 'f'); + + // Erase from end + bytes2.erase(bytes2.begin() + 1, 1); + REQUIRE(bytes2.size() == 1); + CHECK(bytes2[0] == 'c'); + + // Erase remaining + bytes2.erase(bytes2.begin(), 1); + REQUIRE(bytes2.size() == 0); + CHECK(bytes2.empty()); + } + + SUBCASE("Erase with first and last") + { + Bytes bytes2("0123456789", 10); + + // Erase from beginning + bytes2.erase(bytes2.begin(), bytes2.begin() + 3); + REQUIRE(bytes2.size() == 7); + CHECK(bytes2[0] == '3'); + CHECK(bytes2[1] == '4'); + CHECK(bytes2[6] == '9'); + + // Erase from middle + bytes2.erase(bytes2.begin() + 2, bytes2.begin() + 5); + REQUIRE(bytes2.size() == 4); + CHECK(bytes2[0] == '3'); + CHECK(bytes2[1] == '4'); + CHECK(bytes2[2] == '8'); + CHECK(bytes2[3] == '9'); + + // Erase from end + bytes2.erase(bytes2.begin() + 2, bytes2.end()); + REQUIRE(bytes2.size() == 2); + CHECK(bytes2[0] == '3'); + CHECK(bytes2[1] == '4'); + + // Erase all + bytes2.erase(bytes2.begin(), bytes2.end()); + REQUIRE(bytes2.size() == 0); + CHECK(bytes2.empty()); + } + + SUBCASE("Erase zero bytes") + { + Bytes bytes2("abc", 3); + const uint8_t* orig_data = bytes2.data(); + + // Erase zero with pos and size + bytes2.erase(bytes2.begin(), size_t(0)); + REQUIRE(bytes2.size() == 3); + CHECK(bytes2.data() == orig_data); + CHECK(bytes2[0] == 'a'); + CHECK(bytes2[1] == 'b'); + CHECK(bytes2[2] == 'c'); + + // Erase zero with first and last + bytes2.erase(bytes2.begin(), bytes2.begin()); + REQUIRE(bytes2.size() == 3); + CHECK(bytes2.data() == orig_data); + CHECK(bytes2[0] == 'a'); + CHECK(bytes2[1] == 'b'); + CHECK(bytes2[2] == 'c'); + } + + SUBCASE("Erase single byte") + { + Bytes bytes2("xyz", 3); + + bytes2.erase(bytes2.begin() + 1, bytes2.begin() + 2); + REQUIRE(bytes2.size() == 2); + CHECK(bytes2[0] == 'x'); + CHECK(bytes2[1] == 'z'); + } } TEST_CASE("Conversion to span") -- 2.47.3