Remove redundant hashing code, use hashing.h instead.
Remove overabstraction in hash.h; it's ok to hard code the two types of hashes we have. Even adding another one would not be very difficult. ;)
This commit is contained in:
parent
a825e9730d
commit
e055a551c1
@ -446,7 +446,7 @@ audit_record *media_auditor::audit_one_disk(const rom_entry *rom)
|
|||||||
|
|
||||||
// if there's a SHA1 hash, add them to the output hash
|
// if there's a SHA1 hash, add them to the output hash
|
||||||
if (source.sha1() != sha1_t::null)
|
if (source.sha1() != sha1_t::null)
|
||||||
hashes.add_from_buffer(hash_collection::HASH_SHA1, source.sha1().m_raw, sizeof(source.sha1().m_raw));
|
hashes.add_sha1(source.sha1());
|
||||||
|
|
||||||
// update the actual values
|
// update the actual values
|
||||||
record.set_actual(hashes);
|
record.set_actual(hashes);
|
||||||
|
@ -1080,6 +1080,7 @@ void cli_frontend::listsoftware(const char *gamename)
|
|||||||
|
|
||||||
drivlist.reset();
|
drivlist.reset();
|
||||||
list_count = 0;
|
list_count = 0;
|
||||||
|
astring tempstr;
|
||||||
while (drivlist.next())
|
while (drivlist.next())
|
||||||
{
|
{
|
||||||
software_list_device_iterator iter(drivlist.config().root_device());
|
software_list_device_iterator iter(drivlist.config().root_device());
|
||||||
@ -1158,19 +1159,9 @@ void cli_frontend::listsoftware(const char *gamename)
|
|||||||
|
|
||||||
/* dump checksum information only if there is a known dump */
|
/* dump checksum information only if there is a known dump */
|
||||||
hash_collection hashes(ROM_GETHASHDATA(rom));
|
hash_collection hashes(ROM_GETHASHDATA(rom));
|
||||||
if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
|
if ( !hashes.flag(hash_collection::FLAG_NO_DUMP) )
|
||||||
{
|
fprintf( out, " %s", hashes.attribute_string(tempstr) );
|
||||||
astring tempstr;
|
else
|
||||||
for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
|
|
||||||
fprintf(out, " %s=\"%s\"", hash->name(), hash->string(tempstr));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_disk)
|
|
||||||
fprintf( out, " offset=\"0x%x\"", ROM_GETOFFSET(rom) );
|
|
||||||
|
|
||||||
if ( hashes.flag(hash_collection::FLAG_BAD_DUMP) )
|
|
||||||
fprintf( out, " status=\"baddump\"" );
|
|
||||||
if ( hashes.flag(hash_collection::FLAG_NO_DUMP) )
|
|
||||||
fprintf( out, " status=\"nodump\"" );
|
fprintf( out, " status=\"nodump\"" );
|
||||||
|
|
||||||
if (is_disk)
|
if (is_disk)
|
||||||
@ -1517,7 +1508,7 @@ void media_identifier::identify_file(const char *name)
|
|||||||
// otherwise, get the hash collection for this CHD
|
// otherwise, get the hash collection for this CHD
|
||||||
hash_collection hashes;
|
hash_collection hashes;
|
||||||
if (chd.sha1() != sha1_t::null)
|
if (chd.sha1() != sha1_t::null)
|
||||||
hashes.add_from_buffer(hash_collection::HASH_SHA1, chd.sha1().m_raw, sizeof(chd.sha1().m_raw));
|
hashes.add_sha1(chd.sha1());
|
||||||
|
|
||||||
// determine whether this file exists
|
// determine whether this file exists
|
||||||
int found = find_by_hash(hashes, chd.logical_bytes());
|
int found = find_by_hash(hashes, chd.logical_bytes());
|
||||||
|
@ -497,7 +497,8 @@ void device_image_interface::image_checkhash()
|
|||||||
device_image_partialhash_func partialhash;
|
device_image_partialhash_func partialhash;
|
||||||
|
|
||||||
/* only calculate CRC if it hasn't been calculated, and the open_mode is read only */
|
/* only calculate CRC if it hasn't been calculated, and the open_mode is read only */
|
||||||
if (m_hash.first() == NULL && m_readonly && !m_created)
|
UINT32 crcval;
|
||||||
|
if (!m_hash.crc(crcval) && m_readonly && !m_created)
|
||||||
{
|
{
|
||||||
/* do not cause a linear read of 600 megs please */
|
/* do not cause a linear read of 600 megs please */
|
||||||
/* TODO: use SHA1 in the CHD header as the hash */
|
/* TODO: use SHA1 in the CHD header as the hash */
|
||||||
|
@ -250,10 +250,14 @@ emu_file::operator core_file &()
|
|||||||
|
|
||||||
hash_collection &emu_file::hashes(const char *types)
|
hash_collection &emu_file::hashes(const char *types)
|
||||||
{
|
{
|
||||||
|
// determine the hashes we already have
|
||||||
|
astring already_have;
|
||||||
|
m_hashes.hash_types(already_have);
|
||||||
|
|
||||||
// determine which hashes we need
|
// determine which hashes we need
|
||||||
astring needed;
|
astring needed;
|
||||||
for (const char *scan = types; *scan != 0; scan++)
|
for (const char *scan = types; *scan != 0; scan++)
|
||||||
if (m_hashes.hash(*scan) == NULL)
|
if (already_have.chr(0, *scan) == -1)
|
||||||
needed.cat(*scan);
|
needed.cat(*scan);
|
||||||
|
|
||||||
// if we need nothing, skip it
|
// if we need nothing, skip it
|
||||||
|
601
src/emu/hash.c
601
src/emu/hash.c
@ -40,61 +40,10 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "zlib.h"
|
#include "hashing.h"
|
||||||
#include "sha1.h"
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// TYPE DEFINITIONS
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
// ======================> hash_crc
|
|
||||||
|
|
||||||
// CRC-32 hash implementation
|
|
||||||
class hash_crc : public hash_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// construction/destruction
|
|
||||||
hash_crc();
|
|
||||||
|
|
||||||
// operators
|
|
||||||
operator UINT32() const { return (m_buffer[0] << 24) | (m_buffer[1] << 16) | (m_buffer[2] << 8) | m_buffer[3]; }
|
|
||||||
|
|
||||||
// creation
|
|
||||||
virtual void begin();
|
|
||||||
virtual void buffer(const UINT8 *data, UINT32 length);
|
|
||||||
virtual void end();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// internal state
|
|
||||||
UINT8 m_buffer[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======================> hash_sha1
|
|
||||||
|
|
||||||
// SHA1 hash implementation
|
|
||||||
class hash_sha1 : public hash_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// construction/destruction
|
|
||||||
hash_sha1();
|
|
||||||
|
|
||||||
// creation
|
|
||||||
virtual void begin();
|
|
||||||
virtual void buffer(const UINT8 *data, UINT32 length);
|
|
||||||
virtual void end();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// internal state
|
|
||||||
UINT8 m_buffer[20];
|
|
||||||
struct sha1_ctx m_context;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// GLOBAL VARIABLES
|
// GLOBAL VARIABLES
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -105,220 +54,6 @@ const char *hash_collection::HASH_TYPES_ALL = "RS";
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// HASH BASE
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// hash_base - constructor
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_base::hash_base(char id, const char *name, UINT8 length, UINT8 *bufptr)
|
|
||||||
: m_next(NULL),
|
|
||||||
m_name(name),
|
|
||||||
m_in_progress(false),
|
|
||||||
m_parse_error(false),
|
|
||||||
m_id(id),
|
|
||||||
m_length(length),
|
|
||||||
m_bufptr(bufptr)
|
|
||||||
{
|
|
||||||
memset(m_bufptr, 0, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// fromhex - convert a character to a hex value
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
int hash_base::fromhex(char c)
|
|
||||||
{
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
return c - '0';
|
|
||||||
else if (c >= 'A' && c <= 'F')
|
|
||||||
return c - 'A' + 10;
|
|
||||||
else if (c >= 'a' && c <= 'f')
|
|
||||||
return (c - 'a' + 10);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// from_buffer - copy a raw buffer into the
|
|
||||||
// current hash
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
bool hash_base::from_buffer(const UINT8 *buffer, int buflen)
|
|
||||||
{
|
|
||||||
// fail if we're too small
|
|
||||||
if (buflen < m_length)
|
|
||||||
return false;
|
|
||||||
memcpy(m_bufptr, buffer, m_length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// string - output a string for the current hash
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
const char *hash_base::string(astring &buffer)
|
|
||||||
{
|
|
||||||
buffer.reset();
|
|
||||||
for (int index = 0; index < m_length; index++)
|
|
||||||
buffer.catprintf("%02x", m_bufptr[index]);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// from_string - parse a string into the current
|
|
||||||
// hash
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
bool hash_base::from_string(const char *&string, int length)
|
|
||||||
{
|
|
||||||
// reset the error and our buffer
|
|
||||||
m_parse_error = false;
|
|
||||||
memset(m_bufptr, 0, m_length);
|
|
||||||
|
|
||||||
// special case for idiom HASH(1) to map to a dummy (0) hash
|
|
||||||
if (string[0] == '1' && fromhex(string[1]) == -1)
|
|
||||||
{
|
|
||||||
string++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fail if we're too short
|
|
||||||
if (length < 2 * m_length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// loop over bytes
|
|
||||||
for (int index = 0; index < m_length; index++)
|
|
||||||
{
|
|
||||||
// parse the upper digit
|
|
||||||
int upper = fromhex(string[0]);
|
|
||||||
if (upper == -1)
|
|
||||||
{
|
|
||||||
m_parse_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the lower digit
|
|
||||||
int lower = fromhex(string[1]);
|
|
||||||
if (lower == -1)
|
|
||||||
{
|
|
||||||
m_parse_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the byte and advance
|
|
||||||
m_bufptr[index] = (upper << 4) | lower;
|
|
||||||
string += 2;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// HASH CRC
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// hash_crc - constructor
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_crc::hash_crc()
|
|
||||||
: hash_base(hash_collection::HASH_CRC, "crc", sizeof(m_buffer), m_buffer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// begin - initialize state for hash computation
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void hash_crc::begin()
|
|
||||||
{
|
|
||||||
m_in_progress = true;
|
|
||||||
memset(m_buffer, 0, sizeof(m_buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// buffer - hash a buffer's worth of data
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void hash_crc::buffer(const UINT8 *data, UINT32 length)
|
|
||||||
{
|
|
||||||
UINT32 crc = crc32(*this, data, length);
|
|
||||||
m_buffer[0] = crc >> 24;
|
|
||||||
m_buffer[1] = crc >> 16;
|
|
||||||
m_buffer[2] = crc >> 8;
|
|
||||||
m_buffer[3] = crc >> 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// end - finish hash computation
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void hash_crc::end()
|
|
||||||
{
|
|
||||||
m_in_progress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// HASH SHA1
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// hash_sha1 - constructor
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_sha1::hash_sha1()
|
|
||||||
: hash_base(hash_collection::HASH_SHA1, "sha1", sizeof(m_buffer), m_buffer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// begin - initialize state for hash computation
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void hash_sha1::begin()
|
|
||||||
{
|
|
||||||
m_in_progress = true;
|
|
||||||
sha1_init(&m_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// buffer - hash a buffer's worth of data
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void hash_sha1::buffer(const UINT8 *data, UINT32 length)
|
|
||||||
{
|
|
||||||
sha1_update(&m_context, length, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// end - finish hash computation
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void hash_sha1::end()
|
|
||||||
{
|
|
||||||
sha1_final(&m_context);
|
|
||||||
sha1_digest(&m_context, sizeof(m_buffer), m_buffer);
|
|
||||||
m_in_progress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// HASH COLLECTION
|
// HASH COLLECTION
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -328,17 +63,26 @@ void hash_sha1::end()
|
|||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
hash_collection::hash_collection()
|
hash_collection::hash_collection()
|
||||||
|
: m_has_crc32(false),
|
||||||
|
m_has_sha1(false),
|
||||||
|
m_creator(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hash_collection::hash_collection(const char *string)
|
hash_collection::hash_collection(const char *string)
|
||||||
|
: m_has_crc32(false),
|
||||||
|
m_has_sha1(false),
|
||||||
|
m_creator(NULL)
|
||||||
{
|
{
|
||||||
from_internal_string(string);
|
from_internal_string(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hash_collection::hash_collection(const hash_collection &src)
|
hash_collection::hash_collection(const hash_collection &src)
|
||||||
|
: m_has_crc32(false),
|
||||||
|
m_has_sha1(false),
|
||||||
|
m_creator(NULL)
|
||||||
{
|
{
|
||||||
copyfrom(src);
|
copyfrom(src);
|
||||||
}
|
}
|
||||||
@ -350,6 +94,7 @@ hash_collection::hash_collection(const hash_collection &src)
|
|||||||
|
|
||||||
hash_collection::~hash_collection()
|
hash_collection::~hash_collection()
|
||||||
{
|
{
|
||||||
|
delete m_creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -372,17 +117,21 @@ hash_collection &hash_collection::operator=(const hash_collection &src)
|
|||||||
|
|
||||||
bool hash_collection::operator==(const hash_collection &rhs) const
|
bool hash_collection::operator==(const hash_collection &rhs) const
|
||||||
{
|
{
|
||||||
// look for a mismatch in any hash; do not fail if one is missing
|
// match CRCs
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
if (m_has_crc32 && rhs.m_has_crc32)
|
||||||
{
|
{
|
||||||
hash_base *rhs_hash = rhs.hash(hash->id());
|
if (m_crc32 != rhs.m_crc32)
|
||||||
if (rhs_hash != NULL)
|
|
||||||
{
|
|
||||||
if (*hash != *rhs_hash)
|
|
||||||
return false;
|
return false;
|
||||||
matches++;
|
matches++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// match SHA1s
|
||||||
|
if (m_has_sha1 && rhs.m_has_sha1)
|
||||||
|
{
|
||||||
|
if (m_sha1 != rhs.m_sha1)
|
||||||
|
return false;
|
||||||
|
matches++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if all shared hashes match, return true
|
// if all shared hashes match, return true
|
||||||
@ -390,20 +139,6 @@ bool hash_collection::operator==(const hash_collection &rhs) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// hash - return a hash of the given type
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_base *hash_collection::hash(char type) const
|
|
||||||
{
|
|
||||||
// look for a mismatch in any hash; do not fail if one is missing
|
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
if (hash->id() == type)
|
|
||||||
return hash;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// hash_types - return a list of hash types as
|
// hash_types - return a list of hash types as
|
||||||
// a string
|
// a string
|
||||||
@ -412,26 +147,14 @@ hash_base *hash_collection::hash(char type) const
|
|||||||
const char *hash_collection::hash_types(astring &buffer) const
|
const char *hash_collection::hash_types(astring &buffer) const
|
||||||
{
|
{
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
if (m_has_crc32)
|
||||||
buffer.cat(hash->id());
|
buffer.cat(HASH_CRC);
|
||||||
|
if (m_has_sha1)
|
||||||
|
buffer.cat(HASH_SHA1);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// reset - reset the hash collection to an empty
|
|
||||||
// set of hashes and flags
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
bool hash_collection::parse_errors() const
|
|
||||||
{
|
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
if (hash->parse_error())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// reset - reset the hash collection to an empty
|
// reset - reset the hash collection to an empty
|
||||||
// set of hashes and flags
|
// set of hashes and flags
|
||||||
@ -439,37 +162,10 @@ bool hash_collection::parse_errors() const
|
|||||||
|
|
||||||
void hash_collection::reset()
|
void hash_collection::reset()
|
||||||
{
|
{
|
||||||
m_hashlist.reset();
|
|
||||||
m_flags.reset();
|
m_flags.reset();
|
||||||
}
|
m_has_crc32 = m_has_sha1 = false;
|
||||||
|
delete m_creator;
|
||||||
|
m_creator = NULL;
|
||||||
//-------------------------------------------------
|
|
||||||
// add_from_buffer - add a new hash, importing
|
|
||||||
// from a buffer
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_base *hash_collection::add_from_buffer(char type, const UINT8 *buffer, int bufflen)
|
|
||||||
{
|
|
||||||
// nuke any existing hash with the same ID
|
|
||||||
hash_base *existing = hash(type);
|
|
||||||
if (existing != NULL)
|
|
||||||
m_hashlist.remove(*existing);
|
|
||||||
|
|
||||||
// first allocate by ID
|
|
||||||
hash_base *newhash = alloc_by_id(type);
|
|
||||||
if (newhash == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// then import
|
|
||||||
if (!newhash->from_buffer(buffer, bufflen))
|
|
||||||
{
|
|
||||||
global_free(newhash);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and append to our list
|
|
||||||
return &m_hashlist.append(*newhash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -478,27 +174,17 @@ hash_base *hash_collection::add_from_buffer(char type, const UINT8 *buffer, int
|
|||||||
// from a string
|
// from a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
hash_base *hash_collection::add_from_string(char type, const char *buffer, int length)
|
bool hash_collection::add_from_string(char type, const char *buffer, int length)
|
||||||
{
|
{
|
||||||
// nuke any existing hash with the same ID
|
// handle CRCs
|
||||||
hash_base *existing = hash(type);
|
if (type == HASH_CRC)
|
||||||
if (existing != NULL)
|
return m_has_crc32 = m_crc32.from_string(buffer, length);
|
||||||
m_hashlist.remove(*existing);
|
|
||||||
|
|
||||||
// first allocate by ID
|
// handle SHA1s
|
||||||
hash_base *newhash = alloc_by_id(type);
|
else if (type == HASH_SHA1)
|
||||||
if (newhash == NULL)
|
return m_has_sha1 = m_sha1.from_string(buffer, length);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// then import
|
return false;
|
||||||
if (!newhash->from_string(buffer, length))
|
|
||||||
{
|
|
||||||
global_free(newhash);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and append to our list
|
|
||||||
return &m_hashlist.append(*newhash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -508,51 +194,22 @@ hash_base *hash_collection::add_from_string(char type, const char *buffer, int l
|
|||||||
|
|
||||||
bool hash_collection::remove(char type)
|
bool hash_collection::remove(char type)
|
||||||
{
|
{
|
||||||
// scan the list of hashes for a match
|
bool result = false;
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
if (hash->id() == type)
|
// handle CRCs
|
||||||
|
if (type == HASH_CRC)
|
||||||
{
|
{
|
||||||
m_hashlist.remove(*hash);
|
result = m_has_crc32;
|
||||||
return true;
|
m_has_crc32 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// didn't find it
|
// handle SHA1s
|
||||||
return false;
|
else if (type == HASH_SHA1)
|
||||||
}
|
{
|
||||||
|
result = m_has_sha1;
|
||||||
|
m_has_sha1 = false;
|
||||||
//-------------------------------------------------
|
}
|
||||||
// crc - return the CRC hash if present
|
return result;
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
bool hash_collection::crc(UINT32 &result) const
|
|
||||||
{
|
|
||||||
// attempt to find the CRC hash; if we fail, return false
|
|
||||||
hash_base *crchash = hash(HASH_CRC);
|
|
||||||
if (crchash == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// downcast to a hash_crc and convert to a UINT32
|
|
||||||
result = *downcast<const hash_crc *>(crchash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// add_crc - add a CRC hash
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_base *hash_collection::add_crc(UINT32 crc)
|
|
||||||
{
|
|
||||||
// expand to a buffer
|
|
||||||
UINT8 buffer[4];
|
|
||||||
buffer[0] = crc >> 24;
|
|
||||||
buffer[1] = crc >> 16;
|
|
||||||
buffer[2] = crc >> 8;
|
|
||||||
buffer[3] = crc >> 0;
|
|
||||||
|
|
||||||
// add it the standard way
|
|
||||||
return add_from_buffer(HASH_CRC, buffer, sizeof(buffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -564,16 +221,19 @@ hash_base *hash_collection::add_crc(UINT32 crc)
|
|||||||
|
|
||||||
const char *hash_collection::internal_string(astring &buffer) const
|
const char *hash_collection::internal_string(astring &buffer) const
|
||||||
{
|
{
|
||||||
astring temp;
|
|
||||||
|
|
||||||
// output hashes first
|
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
buffer.cat(hash->id()).cat(hash->string(temp));
|
// handle CRCs
|
||||||
|
astring temp;
|
||||||
|
if (m_has_crc32)
|
||||||
|
buffer.cat(HASH_CRC).cat(m_crc32.as_string(temp));
|
||||||
|
|
||||||
|
// handle SHA1s
|
||||||
|
if (m_has_sha1)
|
||||||
|
buffer.cat(HASH_SHA1).cat(m_sha1.as_string(temp));
|
||||||
|
|
||||||
// append flags
|
// append flags
|
||||||
buffer.cat(m_flags);
|
return buffer.cat(m_flags);
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -584,15 +244,16 @@ const char *hash_collection::internal_string(astring &buffer) const
|
|||||||
|
|
||||||
const char *hash_collection::macro_string(astring &buffer) const
|
const char *hash_collection::macro_string(astring &buffer) const
|
||||||
{
|
{
|
||||||
astring temp;
|
|
||||||
|
|
||||||
// output hashes first
|
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
{
|
// handle CRCs
|
||||||
buffer.cat(temp.cpy(hash->name()).makeupper());
|
astring temp;
|
||||||
buffer.cat("(").cat(hash->string(temp)).cat(") ");
|
if (m_has_crc32)
|
||||||
}
|
buffer.cat("CRC(").cat(m_crc32.as_string(temp)).cat(" )");
|
||||||
|
|
||||||
|
// handle SHA1s
|
||||||
|
if (m_has_sha1)
|
||||||
|
buffer.cat("SHA1(").cat(m_sha1.as_string(temp)).cat(" )");
|
||||||
|
|
||||||
// append flags
|
// append flags
|
||||||
if (flag(FLAG_NO_DUMP))
|
if (flag(FLAG_NO_DUMP))
|
||||||
@ -603,6 +264,33 @@ const char *hash_collection::macro_string(astring &buffer) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// attribute_string - convert set of hashes and
|
||||||
|
// flags to a string in XML attribute format
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
const char *hash_collection::attribute_string(astring &buffer) const
|
||||||
|
{
|
||||||
|
buffer.reset();
|
||||||
|
|
||||||
|
// handle CRCs
|
||||||
|
astring temp;
|
||||||
|
if (m_has_crc32)
|
||||||
|
buffer.cat("crc=\"").cat(m_crc32.as_string(temp)).cat("\" ");
|
||||||
|
|
||||||
|
// handle SHA1s
|
||||||
|
if (m_has_sha1)
|
||||||
|
buffer.cat("sha1=\"").cat(m_sha1.as_string(temp)).cat("\" ");
|
||||||
|
|
||||||
|
// append flags
|
||||||
|
if (flag(FLAG_NO_DUMP))
|
||||||
|
buffer.cat("status=\"nodump\"" );
|
||||||
|
if (flag(FLAG_BAD_DUMP))
|
||||||
|
buffer.cat("status=\"baddump\"" );
|
||||||
|
return buffer.trimspace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// from_internal_string - convert an internal
|
// from_internal_string - convert an internal
|
||||||
// compact string to set of hashes and flags
|
// compact string to set of hashes and flags
|
||||||
@ -619,28 +307,29 @@ bool hash_collection::from_internal_string(const char *string)
|
|||||||
|
|
||||||
// loop until we hit it
|
// loop until we hit it
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
bool skip_digits = false;
|
||||||
while (ptr < stringend)
|
while (ptr < stringend)
|
||||||
{
|
{
|
||||||
char c = *ptr++;
|
char c = *ptr++;
|
||||||
char lc = tolower(c);
|
char uc = toupper(c);
|
||||||
|
|
||||||
// non-hex alpha values specify a hash type
|
// non-hex alpha values specify a hash type
|
||||||
if (lc >= 'g' && lc <= 'z')
|
if (uc >= 'G' && uc <= 'Z')
|
||||||
{
|
{
|
||||||
hash_base *hash = alloc_by_id(c);
|
if (uc == HASH_CRC)
|
||||||
if (hash != NULL)
|
skip_digits = m_has_crc32 = m_crc32.from_string(ptr, stringend - ptr);
|
||||||
{
|
else if (uc == HASH_SHA1)
|
||||||
if (!hash->from_string(ptr, stringend - ptr))
|
skip_digits = m_has_sha1 = m_sha1.from_string(ptr, stringend - ptr);
|
||||||
errors = true;
|
|
||||||
m_hashlist.append(*hash);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
errors = true;
|
errors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hex values are ignored, though unexpected
|
// hex values are ignored, though unexpected
|
||||||
else if ((lc >= '0' && lc <= '9') || (lc >= 'a' && lc <= 'f'))
|
else if ((uc >= '0' && uc <= '9') || (uc >= 'A' && uc <= 'F'))
|
||||||
|
{
|
||||||
|
if (!skip_digits)
|
||||||
errors = true;
|
errors = true;
|
||||||
|
}
|
||||||
|
|
||||||
// anything else is a flag
|
// anything else is a flag
|
||||||
else
|
else
|
||||||
@ -656,26 +345,19 @@ bool hash_collection::from_internal_string(const char *string)
|
|||||||
|
|
||||||
void hash_collection::begin(const char *types)
|
void hash_collection::begin(const char *types)
|
||||||
{
|
{
|
||||||
|
// nuke previous creator and make a new one
|
||||||
|
delete m_creator;
|
||||||
|
m_creator = new hash_creator;
|
||||||
|
|
||||||
// by default use all types
|
// by default use all types
|
||||||
if (types == NULL)
|
if (types == NULL)
|
||||||
{
|
m_creator->m_doing_crc32 = m_creator->m_doing_sha1 = true;
|
||||||
m_hashlist.append(*alloc_by_id(HASH_CRC)).begin();
|
|
||||||
m_hashlist.append(*alloc_by_id(HASH_SHA1)).begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, just allocate the ones that are specified
|
// otherwise, just allocate the ones that are specified
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const char *scan = types; *scan != 0; scan++)
|
m_creator->m_doing_crc32 = (strchr(types, HASH_CRC) != NULL);
|
||||||
{
|
m_creator->m_doing_sha1 = (strchr(types, HASH_SHA1) != NULL);
|
||||||
// nuke any existing hash of this type
|
|
||||||
hash_base *existing = hash(*scan);
|
|
||||||
if (existing != NULL)
|
|
||||||
m_hashlist.remove(*existing);
|
|
||||||
|
|
||||||
// append a new one
|
|
||||||
m_hashlist.append(*alloc_by_id(*scan)).begin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,10 +368,13 @@ void hash_collection::begin(const char *types)
|
|||||||
|
|
||||||
void hash_collection::buffer(const UINT8 *data, UINT32 length)
|
void hash_collection::buffer(const UINT8 *data, UINT32 length)
|
||||||
{
|
{
|
||||||
// buffer each hash appropriately
|
assert(m_creator != NULL);
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
if (hash->in_progress())
|
// append to each active hash
|
||||||
hash->buffer(data, length);
|
if (m_creator->m_doing_crc32)
|
||||||
|
m_creator->m_crc32_creator.append(data, length);
|
||||||
|
if (m_creator->m_doing_sha1)
|
||||||
|
m_creator->m_sha1_creator.append(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -699,26 +384,28 @@ void hash_collection::buffer(const UINT8 *data, UINT32 length)
|
|||||||
|
|
||||||
void hash_collection::end()
|
void hash_collection::end()
|
||||||
{
|
{
|
||||||
// end each hash
|
assert(m_creator != NULL);
|
||||||
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
|
|
||||||
if (hash->in_progress())
|
|
||||||
hash->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// default to getting nothing
|
||||||
|
m_has_crc32 = m_has_sha1 = false;
|
||||||
|
|
||||||
//-------------------------------------------------
|
// finish up the CRC32
|
||||||
// alloc_by_id - based on the ID character,
|
if (m_creator->m_doing_crc32)
|
||||||
// allocate a new hash
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
hash_base *hash_collection::alloc_by_id(char id)
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
{
|
||||||
case HASH_CRC: return global_alloc(hash_crc);
|
m_has_crc32 = true;
|
||||||
case HASH_SHA1: return global_alloc(hash_sha1);
|
m_crc32 = m_creator->m_crc32_creator.finish();
|
||||||
default: return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// finish up the SHA1
|
||||||
|
if (m_creator->m_doing_sha1)
|
||||||
|
{
|
||||||
|
m_has_sha1 = true;
|
||||||
|
m_sha1 = m_creator->m_sha1_creator.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// nuke the creator
|
||||||
|
delete m_creator;
|
||||||
|
m_creator = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -732,8 +419,12 @@ void hash_collection::copyfrom(const hash_collection &src)
|
|||||||
// copy flags directly
|
// copy flags directly
|
||||||
m_flags = src.m_flags;
|
m_flags = src.m_flags;
|
||||||
|
|
||||||
// rebuild the hashlist by copying from the source
|
// copy hashes
|
||||||
m_hashlist.reset();
|
m_has_crc32 = src.m_has_crc32;
|
||||||
for (hash_base *hash = src.first(); hash != NULL; hash = hash->next())
|
m_crc32 = src.m_crc32;
|
||||||
add_from_buffer(hash->id(), hash->buffer(), hash->length());
|
m_has_sha1 = src.m_has_sha1;
|
||||||
|
m_sha1 = src.m_sha1;
|
||||||
|
|
||||||
|
// don't copy creators
|
||||||
|
m_creator = NULL;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
#ifndef __HASH_H__
|
#ifndef __HASH_H__
|
||||||
#define __HASH_H__
|
#define __HASH_H__
|
||||||
|
|
||||||
|
#include "hashing.h"
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// MACROS
|
// MACROS
|
||||||
@ -62,59 +64,6 @@
|
|||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
|
|
||||||
// ======================> hash_base
|
|
||||||
|
|
||||||
// base class for all hash types, which does most of the heavy lifting
|
|
||||||
class hash_base
|
|
||||||
{
|
|
||||||
friend class simple_list<hash_base>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// construction/destruction
|
|
||||||
hash_base(char id, const char *name, UINT8 length, UINT8 *bufptr);
|
|
||||||
virtual ~hash_base() { }
|
|
||||||
|
|
||||||
// operators
|
|
||||||
bool operator==(const hash_base &rhs) const { return (m_length == rhs.m_length && memcmp(m_bufptr, rhs.m_bufptr, m_length) == 0); }
|
|
||||||
bool operator!=(const hash_base &rhs) const { return (m_length != rhs.m_length || memcmp(m_bufptr, rhs.m_bufptr, m_length) != 0); }
|
|
||||||
|
|
||||||
// getters
|
|
||||||
hash_base *next() const { return m_next; }
|
|
||||||
char id() const { return m_id; }
|
|
||||||
const char *name() const { return m_name; }
|
|
||||||
int length() const { return m_length; }
|
|
||||||
bool in_progress() const { return m_in_progress; }
|
|
||||||
bool parse_error() const { return m_parse_error; }
|
|
||||||
UINT8 byte(int index) const { return (index >= 0 && index < m_length) ? m_bufptr[index] : 0; }
|
|
||||||
|
|
||||||
// buffer conversion
|
|
||||||
const UINT8 *buffer() { return m_bufptr; }
|
|
||||||
bool from_buffer(const UINT8 *buffer, int buflen);
|
|
||||||
|
|
||||||
// string conversion
|
|
||||||
const char *string(astring &buffer);
|
|
||||||
bool from_string(const char *&string, int length);
|
|
||||||
|
|
||||||
// creation
|
|
||||||
virtual void begin() = 0;
|
|
||||||
virtual void buffer(const UINT8 *data, UINT32 length) = 0;
|
|
||||||
virtual void end() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// internal helpers
|
|
||||||
int fromhex(char c);
|
|
||||||
|
|
||||||
// internal state
|
|
||||||
hash_base * m_next;
|
|
||||||
const char * m_name;
|
|
||||||
bool m_in_progress;
|
|
||||||
bool m_parse_error;
|
|
||||||
char m_id;
|
|
||||||
UINT8 m_length;
|
|
||||||
UINT8 * m_bufptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ======================> hash_collection
|
// ======================> hash_collection
|
||||||
|
|
||||||
// a collection of the various supported hashes and flags
|
// a collection of the various supported hashes and flags
|
||||||
@ -147,24 +96,25 @@ public:
|
|||||||
|
|
||||||
// getters
|
// getters
|
||||||
bool flag(char flag) const { return (m_flags.chr(0, flag) != -1); }
|
bool flag(char flag) const { return (m_flags.chr(0, flag) != -1); }
|
||||||
hash_base *hash(char type) const;
|
|
||||||
hash_base *first() const { return m_hashlist.first(); }
|
|
||||||
const char *hash_types(astring &buffer) const;
|
const char *hash_types(astring &buffer) const;
|
||||||
bool parse_errors() const;
|
|
||||||
|
|
||||||
// hash manipulators
|
// hash manipulators
|
||||||
void reset();
|
void reset();
|
||||||
hash_base *add_from_buffer(char type, const UINT8 *buffer, int bufflen);
|
bool add_from_string(char type, const char *buffer, int length = -1);
|
||||||
hash_base *add_from_string(char type, const char *buffer, int length);
|
|
||||||
bool remove(char type);
|
bool remove(char type);
|
||||||
|
|
||||||
// CRC-specific helpers
|
// CRC-specific helpers
|
||||||
bool crc(UINT32 &result) const;
|
bool crc(UINT32 &result) const { result = m_crc32; return m_has_crc32; }
|
||||||
hash_base *add_crc(UINT32 crc);
|
void add_crc(UINT32 crc) { m_crc32 = crc; m_has_crc32 = true; }
|
||||||
|
|
||||||
|
// SHA1-specific helpers
|
||||||
|
bool sha1(sha1_t &result) const { result = m_sha1; return m_has_sha1; }
|
||||||
|
void add_sha1(sha1_t sha1) { m_has_sha1 = true; m_sha1 = sha1; }
|
||||||
|
|
||||||
// string conversion
|
// string conversion
|
||||||
const char *internal_string(astring &buffer) const;
|
const char *internal_string(astring &buffer) const;
|
||||||
const char *macro_string(astring &buffer) const;
|
const char *macro_string(astring &buffer) const;
|
||||||
|
const char *attribute_string(astring &buffer) const;
|
||||||
bool from_internal_string(const char *string);
|
bool from_internal_string(const char *string);
|
||||||
|
|
||||||
// creation
|
// creation
|
||||||
@ -175,12 +125,24 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// internal helpers
|
// internal helpers
|
||||||
static hash_base *alloc_by_id(char id);
|
|
||||||
void copyfrom(const hash_collection &src);
|
void copyfrom(const hash_collection &src);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
astring m_flags;
|
astring m_flags;
|
||||||
simple_list<hash_base> m_hashlist;
|
bool m_has_crc32;
|
||||||
|
crc32_t m_crc32;
|
||||||
|
bool m_has_sha1;
|
||||||
|
sha1_t m_sha1;
|
||||||
|
|
||||||
|
// creators
|
||||||
|
struct hash_creator
|
||||||
|
{
|
||||||
|
bool m_doing_crc32;
|
||||||
|
crc32_creator m_crc32_creator;
|
||||||
|
bool m_doing_sha1;
|
||||||
|
sha1_creator m_sha1_creator;
|
||||||
|
};
|
||||||
|
hash_creator * m_creator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -524,19 +524,14 @@ void info_xml_creator::output_rom(const rom_source *source)
|
|||||||
{
|
{
|
||||||
// iterate over hash function types and print m_output their values
|
// iterate over hash function types and print m_output their values
|
||||||
astring tempstr;
|
astring tempstr;
|
||||||
for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
|
fprintf(m_output, " %s", hashes.attribute_string(tempstr));
|
||||||
fprintf(m_output, " %s=\"%s\"", hash->name(), hash->string(tempstr));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
fprintf(m_output, " status=\"nodump\"");
|
||||||
|
|
||||||
// append a region name
|
// append a region name
|
||||||
fprintf(m_output, " region=\"%s\"", ROMREGION_GETTAG(region));
|
fprintf(m_output, " region=\"%s\"", ROMREGION_GETTAG(region));
|
||||||
|
|
||||||
// add nodump/baddump flags
|
|
||||||
if (hashes.flag(hash_collection::FLAG_NO_DUMP))
|
|
||||||
fprintf(m_output, " status=\"nodump\"");
|
|
||||||
if (hashes.flag(hash_collection::FLAG_BAD_DUMP))
|
|
||||||
fprintf(m_output, " status=\"baddump\"");
|
|
||||||
|
|
||||||
// for non-disk entries, print offset
|
// for non-disk entries, print offset
|
||||||
if (!is_disk)
|
if (!is_disk)
|
||||||
fprintf(m_output, " offset=\"%x\"", offset);
|
fprintf(m_output, " offset=\"%x\"", offset);
|
||||||
|
@ -455,7 +455,7 @@ static void dump_wrong_and_correct_checksums(rom_load_data *romdata, const hash_
|
|||||||
astring tempstr;
|
astring tempstr;
|
||||||
romdata->errorstring.catprintf(" EXPECTED: %s\n", hashes.macro_string(tempstr));
|
romdata->errorstring.catprintf(" EXPECTED: %s\n", hashes.macro_string(tempstr));
|
||||||
romdata->errorstring.catprintf(" FOUND: %s\n", acthashes.macro_string(tempstr));
|
romdata->errorstring.catprintf(" FOUND: %s\n", acthashes.macro_string(tempstr));
|
||||||
|
/*
|
||||||
// warn about any ill-formed hashes
|
// warn about any ill-formed hashes
|
||||||
for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
|
for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
|
||||||
if (hash->parse_error())
|
if (hash->parse_error())
|
||||||
@ -463,6 +463,7 @@ static void dump_wrong_and_correct_checksums(rom_load_data *romdata, const hash_
|
|||||||
romdata->errorstring.catprintf("\tInvalid %s checksum treated as 0 (check leading zeros)\n", hash->name());
|
romdata->errorstring.catprintf("\tInvalid %s checksum treated as 0 (check leading zeros)\n", hash->name());
|
||||||
romdata->warnings++;
|
romdata->warnings++;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1228,7 +1229,7 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag,
|
|||||||
|
|
||||||
/* get the header and extract the SHA1 */
|
/* get the header and extract the SHA1 */
|
||||||
hash_collection acthashes;
|
hash_collection acthashes;
|
||||||
acthashes.add_from_buffer(hash_collection::HASH_SHA1, chd->orig_chd().sha1().m_raw, sizeof(chd->orig_chd().sha1().m_raw));
|
acthashes.add_sha1(chd->orig_chd().sha1());
|
||||||
|
|
||||||
/* verify the hash */
|
/* verify the hash */
|
||||||
if (hashes != acthashes)
|
if (hashes != acthashes)
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "hashing.h"
|
#include "hashing.h"
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -81,10 +82,12 @@ inline int char_to_hex(char c)
|
|||||||
// from_string - convert from a string
|
// from_string - convert from a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool sha1_t::from_string(const char *string)
|
bool sha1_t::from_string(const char *string, int length)
|
||||||
{
|
{
|
||||||
// must be at least long enough to hold everything
|
// must be at least long enough to hold everything
|
||||||
if (strlen(string) < 2 * sizeof(m_raw))
|
if (length == -1)
|
||||||
|
length = strlen(string);
|
||||||
|
if (length < 2 * sizeof(m_raw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// iterate through our raw buffer
|
// iterate through our raw buffer
|
||||||
@ -104,7 +107,7 @@ bool sha1_t::from_string(const char *string)
|
|||||||
// as_string - convert to a string
|
// as_string - convert to a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
const char *sha1_t::as_string(astring &buffer)
|
const char *sha1_t::as_string(astring &buffer) const
|
||||||
{
|
{
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
for (int i = 0; i < ARRAY_LENGTH(m_raw); i++)
|
for (int i = 0; i < ARRAY_LENGTH(m_raw); i++)
|
||||||
@ -121,10 +124,12 @@ const char *sha1_t::as_string(astring &buffer)
|
|||||||
// from_string - convert from a string
|
// from_string - convert from a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool md5_t::from_string(const char *string)
|
bool md5_t::from_string(const char *string, int length)
|
||||||
{
|
{
|
||||||
// must be at least long enough to hold everything
|
// must be at least long enough to hold everything
|
||||||
if (strlen(string) < 2 * sizeof(m_raw))
|
if (length == -1)
|
||||||
|
length = strlen(string);
|
||||||
|
if (length < 2 * sizeof(m_raw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// iterate through our raw buffer
|
// iterate through our raw buffer
|
||||||
@ -144,7 +149,7 @@ bool md5_t::from_string(const char *string)
|
|||||||
// as_string - convert to a string
|
// as_string - convert to a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
const char *md5_t::as_string(astring &buffer)
|
const char *md5_t::as_string(astring &buffer) const
|
||||||
{
|
{
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
for (int i = 0; i < ARRAY_LENGTH(m_raw); i++)
|
for (int i = 0; i < ARRAY_LENGTH(m_raw); i++)
|
||||||
@ -162,10 +167,12 @@ const char *md5_t::as_string(astring &buffer)
|
|||||||
// from_string - convert from a string
|
// from_string - convert from a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool crc32_t::from_string(const char *string)
|
bool crc32_t::from_string(const char *string, int length)
|
||||||
{
|
{
|
||||||
// must be at least long enough to hold everything
|
// must be at least long enough to hold everything
|
||||||
if (strlen(string) < 2 * sizeof(m_raw))
|
if (length == -1)
|
||||||
|
length = strlen(string);
|
||||||
|
if (length < 2 * sizeof(m_raw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// iterate through our raw buffer
|
// iterate through our raw buffer
|
||||||
@ -185,12 +192,23 @@ bool crc32_t::from_string(const char *string)
|
|||||||
// as_string - convert to a string
|
// as_string - convert to a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
const char *crc32_t::as_string(astring &buffer)
|
const char *crc32_t::as_string(astring &buffer) const
|
||||||
{
|
{
|
||||||
return buffer.format("%08x", m_raw);
|
return buffer.format("%08x", m_raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// append - hash a block of data, appending to
|
||||||
|
// the currently-accumulated value
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void crc32_creator::append(const void *data, UINT32 length)
|
||||||
|
{
|
||||||
|
m_accum.m_raw = crc32(m_accum, reinterpret_cast<const Bytef *>(data), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// CRC-16 HELPERS
|
// CRC-16 HELPERS
|
||||||
@ -200,10 +218,12 @@ const char *crc32_t::as_string(astring &buffer)
|
|||||||
// from_string - convert from a string
|
// from_string - convert from a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool crc16_t::from_string(const char *string)
|
bool crc16_t::from_string(const char *string, int length)
|
||||||
{
|
{
|
||||||
// must be at least long enough to hold everything
|
// must be at least long enough to hold everything
|
||||||
if (strlen(string) < 2 * sizeof(m_raw))
|
if (length == -1)
|
||||||
|
length = strlen(string);
|
||||||
|
if (length < 2 * sizeof(m_raw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// iterate through our raw buffer
|
// iterate through our raw buffer
|
||||||
@ -223,7 +243,7 @@ bool crc16_t::from_string(const char *string)
|
|||||||
// as_string - convert to a string
|
// as_string - convert to a string
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
const char *crc16_t::as_string(astring &buffer)
|
const char *crc16_t::as_string(astring &buffer) const
|
||||||
{
|
{
|
||||||
return buffer.format("%04x", m_raw);
|
return buffer.format("%04x", m_raw);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
#include "osdcore.h"
|
#include "osdcore.h"
|
||||||
#include "astring.h"
|
#include "astring.h"
|
||||||
#include "zlib.h"
|
//#include "zlib.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
|
|
||||||
@ -62,8 +62,8 @@ 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; }
|
||||||
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 *() { return m_raw; }
|
operator UINT8 *() { return m_raw; }
|
||||||
const char *as_string(astring &buffer);
|
bool from_string(const char *string, int length = -1);
|
||||||
bool from_string(const char *string);
|
const char *as_string(astring &buffer) const;
|
||||||
UINT8 m_raw[20];
|
UINT8 m_raw[20];
|
||||||
static const sha1_t null;
|
static const sha1_t null;
|
||||||
};
|
};
|
||||||
@ -113,8 +113,8 @@ 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; }
|
||||||
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 *() { return m_raw; }
|
operator UINT8 *() { return m_raw; }
|
||||||
const char *as_string(astring &buffer);
|
bool from_string(const char *string, int length = -1);
|
||||||
bool from_string(const char *string);
|
const char *as_string(astring &buffer) const;
|
||||||
UINT8 m_raw[16];
|
UINT8 m_raw[16];
|
||||||
static const md5_t null;
|
static const md5_t null;
|
||||||
};
|
};
|
||||||
@ -161,9 +161,11 @@ protected:
|
|||||||
struct crc32_t
|
struct crc32_t
|
||||||
{
|
{
|
||||||
bool operator==(const crc32_t &rhs) const { return m_raw == rhs.m_raw; }
|
bool operator==(const crc32_t &rhs) const { return m_raw == rhs.m_raw; }
|
||||||
|
bool operator!=(const crc32_t &rhs) const { return m_raw != rhs.m_raw; }
|
||||||
|
crc32_t &operator=(const UINT32 crc) { m_raw = crc; return *this; }
|
||||||
operator UINT32() const { return m_raw; }
|
operator UINT32() const { return m_raw; }
|
||||||
const char *as_string(astring &buffer);
|
bool from_string(const char *string, int length = -1);
|
||||||
bool from_string(const char *string);
|
const char *as_string(astring &buffer) const;
|
||||||
UINT32 m_raw;
|
UINT32 m_raw;
|
||||||
static const crc32_t null;
|
static const crc32_t null;
|
||||||
};
|
};
|
||||||
@ -179,7 +181,7 @@ public:
|
|||||||
void reset() { m_accum.m_raw = 0; }
|
void reset() { m_accum.m_raw = 0; }
|
||||||
|
|
||||||
// append data
|
// append data
|
||||||
void append(const void *data, UINT32 length) { m_accum.m_raw = crc32(m_accum, reinterpret_cast<const Bytef *>(data), length); }
|
void append(const void *data, UINT32 length);
|
||||||
|
|
||||||
// finalize and compute the final digest
|
// finalize and compute the final digest
|
||||||
crc32_t finish() { return m_accum; }
|
crc32_t finish() { return m_accum; }
|
||||||
@ -205,9 +207,11 @@ protected:
|
|||||||
struct crc16_t
|
struct crc16_t
|
||||||
{
|
{
|
||||||
bool operator==(const crc16_t &rhs) const { return m_raw == rhs.m_raw; }
|
bool operator==(const crc16_t &rhs) const { return m_raw == rhs.m_raw; }
|
||||||
|
bool operator!=(const crc16_t &rhs) const { return m_raw != rhs.m_raw; }
|
||||||
|
crc16_t &operator=(const UINT16 crc) { m_raw = crc; return *this; }
|
||||||
operator UINT16() const { return m_raw; }
|
operator UINT16() const { return m_raw; }
|
||||||
const char *as_string(astring &buffer);
|
bool from_string(const char *string, int length = -1);
|
||||||
bool from_string(const char *string);
|
const char *as_string(astring &buffer) const;
|
||||||
UINT16 m_raw;
|
UINT16 m_raw;
|
||||||
static const crc16_t null;
|
static const crc16_t null;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user