hash.cpp, hashing.cpp: Change string processing to use std::string_view parameters; add sum16 type

This commit is contained in:
AJR 2021-01-01 12:16:05 -05:00
parent c296bd9729
commit 21fd983545
6 changed files with 160 additions and 45 deletions

View File

@ -1661,7 +1661,7 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re
actual_hashes.compute(contents.get(), length, util::hash_collection::HASH_TYPES_CRC_SHA1);
util::hash_collection expected_hashes;
expected_hashes.add_from_string(util::hash_collection::HASH_SHA1, sha1, strlen(sha1));
expected_hashes.add_from_string(util::hash_collection::HASH_SHA1, sha1);
if (actual_hashes != expected_hashes) throw rpk_exception(RPK_INVALID_FILE_REF, "SHA1 check failed");
}

View File

@ -559,7 +559,7 @@ void software_list_device::internal_validity_check(validity_checker &valid)
// make sure the hash is valid
util::hash_collection hashes;
if (!hashes.from_internal_string(romp->hashdata().c_str()))
if (!hashes.from_internal_string(romp->hashdata()))
osd_printf_error("%s: %s part %s ROM '%s' has invalid hash string '%s'\n", filename(), shortname, part.name(), romp->name(), romp->hashdata());
}

View File

@ -148,15 +148,15 @@ void hash_collection::reset()
// from a string
//-------------------------------------------------
bool hash_collection::add_from_string(char type, const char *buffer, int length)
bool hash_collection::add_from_string(char type, std::string_view string)
{
// handle CRCs
if (type == HASH_CRC)
return m_has_crc32 = m_crc32.from_string(buffer, length);
return m_has_crc32 = m_crc32.from_string(string);
// handle SHA1s
else if (type == HASH_SHA1)
return m_has_sha1 = m_sha1.from_string(buffer, length);
return m_has_sha1 = m_sha1.from_string(string);
return false;
}
@ -273,24 +273,19 @@ std::string hash_collection::attribute_string() const
// compact string to set of hashes and flags
//-------------------------------------------------
bool hash_collection::from_internal_string(const char *string)
bool hash_collection::from_internal_string(std::string_view string)
{
assert(string != nullptr);
// start fresh
reset();
// determine the end of the string
const char *stringend = string + strlen(string);
const char *ptr = string;
// loop until we hit it
// loop until we hit the end of the string
bool errors = false;
int skip_digits = 0;
while (ptr < stringend)
while (!string.empty())
{
char c = *ptr++;
char c = string[0];
char uc = toupper(c);
string.remove_prefix(1);
// non-hex alpha values specify a hash type
if (uc >= 'G' && uc <= 'Z')
@ -299,13 +294,13 @@ bool hash_collection::from_internal_string(const char *string)
if (uc == HASH_CRC)
{
m_has_crc32 = true;
errors = !m_crc32.from_string(ptr, stringend - ptr);
errors = !m_crc32.from_string(string);
skip_digits = 2 * sizeof(crc32_t);
}
else if (uc == HASH_SHA1)
{
m_has_sha1 = true;
errors = !m_sha1.from_string(ptr, stringend - ptr);
errors = !m_sha1.from_string(string);
skip_digits = 2 * sizeof(sha1_t);
}
else

View File

@ -71,7 +71,7 @@ public:
// hash manipulators
void reset();
bool add_from_string(char type, const char *buffer, int length = -1);
bool add_from_string(char type, std::string_view string);
bool remove(char type);
// CRC-specific helpers
@ -86,7 +86,7 @@ public:
std::string internal_string() const;
std::string macro_string() const;
std::string attribute_string() const;
bool from_internal_string(const char *string);
bool from_internal_string(std::string_view string);
// creation
void begin(const char *types = nullptr);

View File

@ -115,6 +115,7 @@ const crc16_t crc16_t::null = { 0 };
const crc32_t crc32_t::null = { 0 };
const md5_t md5_t::null = { { 0 } };
const sha1_t sha1_t::null = { { 0 } };
const sum16_t sum16_t::null = { 0 };
@ -126,23 +127,22 @@ const sha1_t sha1_t::null = { { 0 } };
// from_string - convert from a string
//-------------------------------------------------
bool sha1_t::from_string(const char *string, int length)
bool sha1_t::from_string(std::string_view string)
{
// must be at least long enough to hold everything
memset(m_raw, 0, sizeof(m_raw));
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
if (string.length() < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
for (auto & elem : m_raw)
{
int upper = char_to_hex(*string++);
int lower = char_to_hex(*string++);
int upper = char_to_hex(string[0]);
int lower = char_to_hex(string[1]);
if (upper == -1 || lower == -1)
return false;
elem = (upper << 4) | lower;
string.remove_prefix(2);
}
return true;
}
@ -245,23 +245,22 @@ sha1_t sha1_creator::finish()
// from_string - convert from a string
//-------------------------------------------------
bool md5_t::from_string(const char *string, int length)
bool md5_t::from_string(std::string_view string)
{
// must be at least long enough to hold everything
memset(m_raw, 0, sizeof(m_raw));
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
if (string.length() < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
for (auto & elem : m_raw)
{
int upper = char_to_hex(*string++);
int lower = char_to_hex(*string++);
int upper = char_to_hex(string[0]);
int lower = char_to_hex(string[1]);
if (upper == -1 || lower == -1)
return false;
elem = (upper << 4) | lower;
string.remove_prefix(2);
}
return true;
}
@ -291,23 +290,22 @@ std::string md5_t::as_string() const
// from_string - convert from a string
//-------------------------------------------------
bool crc32_t::from_string(const char *string, int length)
bool crc32_t::from_string(std::string_view string)
{
// must be at least long enough to hold everything
m_raw = 0;
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
if (string.length() < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
m_raw = 0;
for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++)
{
int nibble = char_to_hex(*string++);
int nibble = char_to_hex(string[0]);
if (nibble == -1)
return false;
m_raw = (m_raw << 4) | nibble;
string.remove_prefix(1);
}
return true;
}
@ -343,23 +341,22 @@ void crc32_creator::append(const void *data, uint32_t length)
// from_string - convert from a string
//-------------------------------------------------
bool crc16_t::from_string(const char *string, int length)
bool crc16_t::from_string(std::string_view string)
{
// must be at least long enough to hold everything
m_raw = 0;
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
if (string.length() < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
m_raw = 0;
for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++)
{
int nibble = char_to_hex(*string++);
int nibble = char_to_hex(string[0]);
if (nibble == -1)
return false;
m_raw = (m_raw << 4) | nibble;
string.remove_prefix(1);
}
return true;
}
@ -437,4 +434,71 @@ void crc16_creator::append(const void *data, uint32_t length)
m_accum.m_raw = crc;
}
//**************************************************************************
// SUM-16 HELPERS
//**************************************************************************
//-------------------------------------------------
// from_string - convert from a string
//-------------------------------------------------
bool sum16_t::from_string(std::string_view string)
{
// must be at least long enough to hold everything
m_raw = 0;
if (string.length() < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
m_raw = 0;
for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++)
{
int nibble = char_to_hex(string[0]);
if (nibble == -1)
return false;
m_raw = (m_raw << 4) | nibble;
string.remove_prefix(1);
}
return true;
}
/**
* @fn std::string sum16_t::as_string() const
*
* @brief -------------------------------------------------
* as_string - convert to a string
* -------------------------------------------------.
*
* @return a std::string.
*/
std::string sum16_t::as_string() const
{
return string_format("%04x", m_raw);
}
/**
* @fn void sum16_creator::append(const void *data, uint32_t length)
*
* @brief -------------------------------------------------
* append - sum a block of data, appending to the currently-accumulated value
* -------------------------------------------------.
*
* @param data The data.
* @param length The length.
*/
void sum16_creator::append(const void *data, uint32_t length)
{
const auto *src = reinterpret_cast<const uint8_t *>(data);
// fetch the current value into a local and rip through the source data
uint16_t sum = m_accum.m_raw;
while (length-- != 0)
sum += *src++;
m_accum.m_raw = sum;
}
} // namespace util

View File

@ -19,6 +19,7 @@
#include <array>
#include <functional>
#include <string>
#include <string_view>
namespace util {
@ -36,7 +37,7 @@ struct sha1_t
bool operator==(const sha1_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) == 0; }
bool operator!=(const sha1_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; }
operator uint8_t *() { return m_raw; }
bool from_string(const char *string, int length = -1);
bool from_string(std::string_view string);
std::string as_string() const;
uint8_t m_raw[20];
static const sha1_t null;
@ -82,7 +83,7 @@ struct md5_t
bool operator==(const md5_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) == 0; }
bool operator!=(const md5_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; }
operator uint8_t *() { return m_raw; }
bool from_string(const char *string, int length = -1);
bool from_string(std::string_view string);
std::string as_string() const;
uint8_t m_raw[16];
static const md5_t null;
@ -141,7 +142,7 @@ struct crc32_t
constexpr operator uint32_t() const { return m_raw; }
bool from_string(const char *string, int length = -1);
bool from_string(std::string_view string);
std::string as_string() const;
uint32_t m_raw;
@ -197,7 +198,7 @@ struct crc16_t
constexpr operator uint16_t() const { return m_raw; }
bool from_string(const char *string, int length = -1);
bool from_string(std::string_view string);
std::string as_string() const;
uint16_t m_raw;
@ -235,6 +236,61 @@ protected:
};
// ======================> SUM-16
// final digest
struct sum16_t
{
sum16_t() { }
constexpr sum16_t(const sum16_t &rhs) = default;
constexpr sum16_t(const uint16_t sum) : m_raw(sum) { }
constexpr bool operator==(const sum16_t &rhs) const { return m_raw == rhs.m_raw; }
constexpr bool operator!=(const sum16_t &rhs) const { return m_raw != rhs.m_raw; }
sum16_t &operator=(const sum16_t &rhs) = default;
sum16_t &operator=(const uint16_t sum) { m_raw = sum; return *this; }
constexpr operator uint16_t() const { return m_raw; }
bool from_string(std::string_view string);
std::string as_string() const;
uint16_t m_raw;
static const sum16_t null;
};
// creation helper
class sum16_creator
{
public:
// construction/destruction
sum16_creator() { reset(); }
// reset
void reset() { m_accum.m_raw = 0; }
// append data
void append(const void *data, uint32_t length);
// finalize and compute the final digest
sum16_t finish() { return m_accum; }
// static wrapper to just get the digest from a block
static sum16_t simple(const void *data, uint32_t length)
{
sum16_creator creator;
creator.append(data, length);
return creator.finish();
}
protected:
// internal state
sum16_t m_accum; // internal accumulator
};
} // namespace util
namespace std {