]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
enhance: Add Bytes::erase
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 23 Oct 2025 08:13:24 +0000 (10:13 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 25 Oct 2025 10:03:27 +0000 (12:03 +0200)
src/ccache/util/bytes.cpp
src/ccache/util/bytes.hpp
unittest/test_util_bytes.cpp

index 7524d991e113612aee163d2dbd0cbbd7e4e36725..b3e01fee3e27b0e6ae0cac7e7bb7d536276bc34a 100644 (file)
@@ -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
index c103ed22a4309a1a1c7d6ee2c692980490d5afb5..327e0c6e0f0d10b729d594c9afe1eb3cc8988e05 100644 (file)
@@ -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<const uint8_t> 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<uint8_t[]> m_data;
   size_t m_size = 0;
index cb564c88453151b5fe283456d4ee0446cd586bb1..11c6927e75443ba8e3ecc0fd737783395920d0c0 100644 (file)
@@ -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")