From 8e3a6cd1b93cc9f505cdc52b16ddc11bfb1d8cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 13 Jul 2020 19:17:21 +0200 Subject: [PATCH] sarc: Add operator== (and !=) for oead::Sarc And add AreFilesEqual too. --- py/py_sarc.cpp | 2 ++ src/include/oead/sarc.h | 13 +++++++++++++ src/sarc.cpp | 15 +++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/py/py_sarc.cpp b/py/py_sarc.cpp index ed8d11d..2fdd554 100644 --- a/py/py_sarc.cpp +++ b/py/py_sarc.cpp @@ -29,6 +29,8 @@ void BindSarc(py::module& m) { py::class_ file_cl(m, "File"); cl.def(py::init>(), "data"_a, py::keep_alive<1, 2>()) + .def(py::self == py::self) + .def("are_files_equal", &Sarc::AreFilesEqual) .def("get_num_files", &Sarc::GetNumFiles) .def("get_data_offset", &Sarc::GetDataOffset) .def("get_endianness", &Sarc::GetEndianness) diff --git a/src/include/oead/sarc.h b/src/include/oead/sarc.h index 3104fca..0ede5cf 100644 --- a/src/include/oead/sarc.h +++ b/src/include/oead/sarc.h @@ -19,6 +19,7 @@ #pragma once +#include #include #include #include @@ -41,6 +42,12 @@ class Sarc { std::string_view name; /// File data (as a view). tcb::span data; + + bool operator==(const File& other) const { + return name == other.name && absl::c_equal(data, other.data); + } + + bool operator!=(const File& other) const { return !(*this == other); } }; /// File iterator. @@ -75,6 +82,12 @@ class Sarc { /// Guess the minimum data alignment for files that are stored in the archive. size_t GuessMinAlignment() const; + /// Returns true if and only if the raw archive data is identical. + bool operator==(const Sarc& other) const; + bool operator!=(const Sarc& other) const { return !(*this == other); } + + bool AreFilesEqual(const Sarc& other) const; + private: u16 m_num_files; u16 m_entries_offset; diff --git a/src/sarc.cpp b/src/sarc.cpp index 0ec9ed5..2c6e5dc 100644 --- a/src/sarc.cpp +++ b/src/sarc.cpp @@ -168,6 +168,21 @@ std::optional Sarc::GetFile(std::string_view name) const { return std::nullopt; } +bool Sarc::operator==(const Sarc& other) const { + return absl::c_equal(m_reader.span(), other.m_reader.span()); +} + +bool Sarc::AreFilesEqual(const Sarc& other) const { + if (GetNumFiles() != other.GetNumFiles()) + return false; + + for (const auto& [file1, file2] : easy_iterator::zip(GetFiles(), other.GetFiles())) { + if (file1 != file2) + return false; + } + return true; +} + static constexpr bool IsValidAlignment(size_t alignment) { return alignment != 0 && (alignment & (alignment - 1)) == 0; }