diff --git a/Source/Core/Common/Hash.cpp b/Source/Core/Common/Hash.cpp index 692745cb0a..62b56bc82c 100644 --- a/Source/Core/Common/Hash.cpp +++ b/Source/Core/Common/Hash.cpp @@ -534,11 +534,25 @@ void SetHash64Function() u32 ComputeCRC32(std::string_view data) { - const Bytef* buf = reinterpret_cast(data.data()); - uInt len = static_cast(data.size()); + return ComputeCRC32(reinterpret_cast(data.data()), static_cast(data.size())); +} + +u32 ComputeCRC32(const u8* ptr, u32 length) +{ + return UpdateCRC32(StartCRC32(), ptr, length); +} + +u32 StartCRC32() +{ + return crc32(0L, Z_NULL, 0); +} + +u32 UpdateCRC32(u32 crc, const u8* ptr, u32 length) +{ + static_assert(std::is_same_v); + static_assert(std::is_same_v); // Use zlib's crc32 implementation to compute the hash - u32 hash = crc32(0L, Z_NULL, 0); - hash = crc32(hash, buf, len); - return hash; + // crc32_z (which takes a size_t) would be better, but it isn't available on Android + return crc32(crc, ptr, length); } } // namespace Common diff --git a/Source/Core/Common/Hash.h b/Source/Core/Common/Hash.h index c346c343e4..c742ed0b64 100644 --- a/Source/Core/Common/Hash.h +++ b/Source/Core/Common/Hash.h @@ -17,4 +17,7 @@ u64 GetHash64(const u8* src, u32 len, u32 samples); void SetHash64Function(); u32 ComputeCRC32(std::string_view data); +u32 ComputeCRC32(const u8* ptr, u32 length); +u32 StartCRC32(); +u32 UpdateCRC32(u32 crc, const u8* ptr, u32 length); } // namespace Common diff --git a/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp b/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp index 72c5eab82b..7b4f0be1a3 100644 --- a/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/MotionPlus.cpp @@ -8,10 +8,10 @@ #include #include -#include #include "Common/BitUtils.h" #include "Common/ChunkFile.h" +#include "Common/Hash.h" #include "Common/Logging/Log.h" #include "Common/MathUtil.h" #include "Common/MsgHandler.h" @@ -146,9 +146,9 @@ void MotionPlus::Reset() void MotionPlus::CalibrationData::UpdateChecksum() { // Checksum is crc32 of all data other than the checksum itself. - auto crc_result = crc32(0, Z_NULL, 0); - crc_result = crc32(crc_result, reinterpret_cast(this), 0xe); - crc_result = crc32(crc_result, reinterpret_cast(this) + 0x10, 0xe); + u32 crc_result = Common::StartCRC32(); + crc_result = Common::UpdateCRC32(crc_result, reinterpret_cast(this), 0xe); + crc_result = Common::UpdateCRC32(crc_result, reinterpret_cast(this) + 0x10, 0xe); crc32_lsb = u16(crc_result); crc32_msb = u16(crc_result >> 16); diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index a31243c006..0a17864290 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -16,13 +16,13 @@ #include #include #include -#include #include "Common/Align.h" #include "Common/Assert.h" #include "Common/CommonPaths.h" #include "Common/CommonTypes.h" #include "Common/FileUtil.h" +#include "Common/Hash.h" #include "Common/HttpRequest.h" #include "Common/IOFile.h" #include "Common/Logging/Log.h" @@ -1041,7 +1041,7 @@ void VolumeVerifier::SetUpHashing() [](const GroupToVerify& a, const GroupToVerify& b) { return a.offset < b.offset; }); if (m_hashes_to_calculate.crc32) - m_crc32_context = crc32(0, nullptr, 0); + m_crc32_context = Common::StartCRC32(); if (m_hashes_to_calculate.md5) { @@ -1171,9 +1171,8 @@ void VolumeVerifier::Process() if (m_hashes_to_calculate.crc32) { m_crc32_future = std::async(std::launch::async, [this, byte_increment] { - // It would be nice to use crc32_z here instead of crc32, but it isn't available on Android m_crc32_context = - crc32(m_crc32_context, m_data.data(), static_cast(byte_increment)); + Common::UpdateCRC32(m_crc32_context, m_data.data(), static_cast(byte_increment)); }); } diff --git a/Source/Core/DiscIO/VolumeVerifier.h b/Source/Core/DiscIO/VolumeVerifier.h index 6e573880ac..1a38f610b9 100644 --- a/Source/Core/DiscIO/VolumeVerifier.h +++ b/Source/Core/DiscIO/VolumeVerifier.h @@ -172,7 +172,7 @@ private: Hashes m_hashes_to_calculate{}; bool m_calculating_any_hash = false; - unsigned long m_crc32_context = 0; + u32 m_crc32_context = 0; mbedtls_md5_context m_md5_context{}; mbedtls_sha1_context m_sha1_context{}; diff --git a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h index a397431e3d..aca2176e6d 100644 --- a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h +++ b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h @@ -7,9 +7,8 @@ #include #include -#include - #include "Common/CommonTypes.h" +#include "Common/Hash.h" namespace ciface::DualShockUDPClient::Proto { @@ -217,11 +216,6 @@ struct FromClient }; } // namespace MessageType -static inline u32 CRC32(const void* buffer, unsigned length) -{ - return crc32(crc32(0L, Z_NULL, 0), static_cast(buffer), length); -} - template struct Message { @@ -236,7 +230,11 @@ struct Message m_message.message_type = MsgType::TYPE; } - void Finish() { m_message.header.crc32 = CRC32(&m_message, sizeof(m_message)); } + void Finish() + { + m_message.header.crc32 = + Common::ComputeCRC32(reinterpret_cast(&m_message), sizeof(m_message)); + } template std::optional CheckAndCastTo() @@ -244,7 +242,8 @@ struct Message const u32 crc32_in_header = m_message.header.crc32; // zero out the crc32 in the packet once we got it since that's whats needed for calculation m_message.header.crc32 = 0; - const u32 crc32_calculated = CRC32(&m_message, sizeof(ToMsgType)); + const u32 crc32_calculated = + Common::ComputeCRC32(reinterpret_cast(&m_message), sizeof(ToMsgType)); if (crc32_in_header != crc32_calculated) { NOTICE_LOG_FMT(