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:
Aaron Giles 2012-02-16 21:53:30 +00:00
parent a825e9730d
commit e055a551c1
10 changed files with 246 additions and 577 deletions

View File

@ -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 (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
record.set_actual(hashes);

View File

@ -1080,6 +1080,7 @@ void cli_frontend::listsoftware(const char *gamename)
drivlist.reset();
list_count = 0;
astring tempstr;
while (drivlist.next())
{
software_list_device_iterator iter(drivlist.config().root_device());
@ -1159,18 +1160,8 @@ void cli_frontend::listsoftware(const char *gamename)
/* dump checksum information only if there is a known dump */
hash_collection hashes(ROM_GETHASHDATA(rom));
if ( !hashes.flag(hash_collection::FLAG_NO_DUMP) )
{
astring tempstr;
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, " %s", hashes.attribute_string(tempstr) );
else
fprintf( out, " status=\"nodump\"" );
if (is_disk)
@ -1517,7 +1508,7 @@ void media_identifier::identify_file(const char *name)
// otherwise, get the hash collection for this CHD
hash_collection hashes;
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
int found = find_by_hash(hashes, chd.logical_bytes());

View File

@ -497,7 +497,8 @@ void device_image_interface::image_checkhash()
device_image_partialhash_func partialhash;
/* 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 */
/* TODO: use SHA1 in the CHD header as the hash */

View File

@ -250,10 +250,14 @@ emu_file::operator core_file &()
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
astring needed;
for (const char *scan = types; *scan != 0; scan++)
if (m_hashes.hash(*scan) == NULL)
if (already_have.chr(0, *scan) == -1)
needed.cat(*scan);
// if we need nothing, skip it

View File

@ -40,61 +40,10 @@
***************************************************************************/
#include "emu.h"
#include "zlib.h"
#include "sha1.h"
#include "hashing.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
//**************************************************************************
@ -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
//**************************************************************************
@ -328,17 +63,26 @@ void hash_sha1::end()
//-------------------------------------------------
hash_collection::hash_collection()
: m_has_crc32(false),
m_has_sha1(false),
m_creator(NULL)
{
}
hash_collection::hash_collection(const char *string)
: m_has_crc32(false),
m_has_sha1(false),
m_creator(NULL)
{
from_internal_string(string);
}
hash_collection::hash_collection(const hash_collection &src)
: m_has_crc32(false),
m_has_sha1(false),
m_creator(NULL)
{
copyfrom(src);
}
@ -350,6 +94,7 @@ hash_collection::hash_collection(const hash_collection &src)
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
{
// look for a mismatch in any hash; do not fail if one is missing
// match CRCs
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 (rhs_hash != NULL)
{
if (*hash != *rhs_hash)
if (m_crc32 != rhs.m_crc32)
return false;
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
@ -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
// a string
@ -412,26 +147,14 @@ hash_base *hash_collection::hash(char type) const
const char *hash_collection::hash_types(astring &buffer) const
{
buffer.reset();
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
buffer.cat(hash->id());
if (m_has_crc32)
buffer.cat(HASH_CRC);
if (m_has_sha1)
buffer.cat(HASH_SHA1);
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
// set of hashes and flags
@ -439,37 +162,10 @@ bool hash_collection::parse_errors() const
void hash_collection::reset()
{
m_hashlist.reset();
m_flags.reset();
}
//-------------------------------------------------
// 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);
m_has_crc32 = m_has_sha1 = false;
delete m_creator;
m_creator = NULL;
}
@ -478,27 +174,17 @@ hash_base *hash_collection::add_from_buffer(char type, const UINT8 *buffer, int
// 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
hash_base *existing = hash(type);
if (existing != NULL)
m_hashlist.remove(*existing);
// handle CRCs
if (type == HASH_CRC)
return m_has_crc32 = m_crc32.from_string(buffer, length);
// first allocate by ID
hash_base *newhash = alloc_by_id(type);
if (newhash == NULL)
return NULL;
// handle SHA1s
else if (type == HASH_SHA1)
return m_has_sha1 = m_sha1.from_string(buffer, length);
// then import
if (!newhash->from_string(buffer, length))
{
global_free(newhash);
return NULL;
}
// and append to our list
return &m_hashlist.append(*newhash);
return false;
}
@ -508,51 +194,22 @@ hash_base *hash_collection::add_from_string(char type, const char *buffer, int l
bool hash_collection::remove(char type)
{
// scan the list of hashes for a match
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
if (hash->id() == type)
bool result = false;
// handle CRCs
if (type == HASH_CRC)
{
m_hashlist.remove(*hash);
return true;
result = m_has_crc32;
m_has_crc32 = false;
}
// didn't find it
return false;
}
//-------------------------------------------------
// crc - return the CRC hash if present
//-------------------------------------------------
bool hash_collection::crc(UINT32 &result) const
// handle SHA1s
else if (type == HASH_SHA1)
{
// 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;
result = m_has_sha1;
m_has_sha1 = false;
}
//-------------------------------------------------
// 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));
return result;
}
@ -564,16 +221,19 @@ hash_base *hash_collection::add_crc(UINT32 crc)
const char *hash_collection::internal_string(astring &buffer) const
{
astring temp;
// output hashes first
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
buffer.cat(m_flags);
return buffer;
return buffer.cat(m_flags);
}
@ -584,15 +244,16 @@ const char *hash_collection::internal_string(astring &buffer) const
const char *hash_collection::macro_string(astring &buffer) const
{
astring temp;
// output hashes first
buffer.reset();
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
{
buffer.cat(temp.cpy(hash->name()).makeupper());
buffer.cat("(").cat(hash->string(temp)).cat(") ");
}
// 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))
@ -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
// 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
bool errors = false;
bool skip_digits = false;
while (ptr < stringend)
{
char c = *ptr++;
char lc = tolower(c);
char uc = toupper(c);
// 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 (hash != NULL)
{
if (!hash->from_string(ptr, stringend - ptr))
errors = true;
m_hashlist.append(*hash);
}
if (uc == HASH_CRC)
skip_digits = m_has_crc32 = m_crc32.from_string(ptr, stringend - ptr);
else if (uc == HASH_SHA1)
skip_digits = m_has_sha1 = m_sha1.from_string(ptr, stringend - ptr);
else
errors = true;
}
// 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;
}
// anything else is a flag
else
@ -656,26 +345,19 @@ bool hash_collection::from_internal_string(const char *string)
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
if (types == NULL)
{
m_hashlist.append(*alloc_by_id(HASH_CRC)).begin();
m_hashlist.append(*alloc_by_id(HASH_SHA1)).begin();
}
m_creator->m_doing_crc32 = m_creator->m_doing_sha1 = true;
// otherwise, just allocate the ones that are specified
else
{
for (const char *scan = types; *scan != 0; scan++)
{
// 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();
}
m_creator->m_doing_crc32 = (strchr(types, HASH_CRC) != NULL);
m_creator->m_doing_sha1 = (strchr(types, HASH_SHA1) != NULL);
}
}
@ -686,10 +368,13 @@ void hash_collection::begin(const char *types)
void hash_collection::buffer(const UINT8 *data, UINT32 length)
{
// buffer each hash appropriately
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
if (hash->in_progress())
hash->buffer(data, length);
assert(m_creator != NULL);
// append to each active hash
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()
{
// end each hash
for (hash_base *hash = m_hashlist.first(); hash != NULL; hash = hash->next())
if (hash->in_progress())
hash->end();
assert(m_creator != NULL);
// default to getting nothing
m_has_crc32 = m_has_sha1 = false;
// finish up the CRC32
if (m_creator->m_doing_crc32)
{
m_has_crc32 = true;
m_crc32 = m_creator->m_crc32_creator.finish();
}
//-------------------------------------------------
// alloc_by_id - based on the ID character,
// allocate a new hash
//-------------------------------------------------
hash_base *hash_collection::alloc_by_id(char id)
// finish up the SHA1
if (m_creator->m_doing_sha1)
{
switch (id)
{
case HASH_CRC: return global_alloc(hash_crc);
case HASH_SHA1: return global_alloc(hash_sha1);
default: return NULL;
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
m_flags = src.m_flags;
// rebuild the hashlist by copying from the source
m_hashlist.reset();
for (hash_base *hash = src.first(); hash != NULL; hash = hash->next())
add_from_buffer(hash->id(), hash->buffer(), hash->length());
// copy hashes
m_has_crc32 = src.m_has_crc32;
m_crc32 = src.m_crc32;
m_has_sha1 = src.m_has_sha1;
m_sha1 = src.m_sha1;
// don't copy creators
m_creator = NULL;
}

View File

@ -44,6 +44,8 @@
#ifndef __HASH_H__
#define __HASH_H__
#include "hashing.h"
//**************************************************************************
// 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
// a collection of the various supported hashes and flags
@ -147,24 +96,25 @@ public:
// getters
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;
bool parse_errors() const;
// hash manipulators
void reset();
hash_base *add_from_buffer(char type, const UINT8 *buffer, int bufflen);
hash_base *add_from_string(char type, const char *buffer, int length);
bool add_from_string(char type, const char *buffer, int length = -1);
bool remove(char type);
// CRC-specific helpers
bool crc(UINT32 &result) const;
hash_base *add_crc(UINT32 crc);
bool crc(UINT32 &result) const { result = m_crc32; return m_has_crc32; }
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
const char *internal_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);
// creation
@ -175,12 +125,24 @@ public:
private:
// internal helpers
static hash_base *alloc_by_id(char id);
void copyfrom(const hash_collection &src);
// internal state
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;
};

View File

@ -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
astring tempstr;
for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
fprintf(m_output, " %s=\"%s\"", hash->name(), hash->string(tempstr));
fprintf(m_output, " %s", hashes.attribute_string(tempstr));
}
else
fprintf(m_output, " status=\"nodump\"");
// append a region name
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
if (!is_disk)
fprintf(m_output, " offset=\"%x\"", offset);

View File

@ -455,7 +455,7 @@ static void dump_wrong_and_correct_checksums(rom_load_data *romdata, const hash_
astring tempstr;
romdata->errorstring.catprintf(" EXPECTED: %s\n", hashes.macro_string(tempstr));
romdata->errorstring.catprintf(" FOUND: %s\n", acthashes.macro_string(tempstr));
/*
// warn about any ill-formed hashes
for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
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->warnings++;
}
*/
}
@ -1228,7 +1229,7 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag,
/* get the header and extract the SHA1 */
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 */
if (hashes != acthashes)

View File

@ -38,6 +38,7 @@
***************************************************************************/
#include "hashing.h"
#include "zlib.h"
//**************************************************************************
@ -81,10 +82,12 @@ inline int char_to_hex(char c)
// 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
if (strlen(string) < 2 * sizeof(m_raw))
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
@ -104,7 +107,7 @@ bool sha1_t::from_string(const char *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();
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
//-------------------------------------------------
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
if (strlen(string) < 2 * sizeof(m_raw))
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
@ -144,7 +149,7 @@ bool md5_t::from_string(const char *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();
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
//-------------------------------------------------
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
if (strlen(string) < 2 * sizeof(m_raw))
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
@ -185,12 +192,23 @@ bool crc32_t::from_string(const char *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);
}
//-------------------------------------------------
// 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
@ -200,10 +218,12 @@ const char *crc32_t::as_string(astring &buffer)
// 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
if (strlen(string) < 2 * sizeof(m_raw))
if (length == -1)
length = strlen(string);
if (length < 2 * sizeof(m_raw))
return false;
// iterate through our raw buffer
@ -223,7 +243,7 @@ bool crc16_t::from_string(const char *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);
}

View File

@ -44,7 +44,7 @@
#include "osdcore.h"
#include "astring.h"
#include "zlib.h"
//#include "zlib.h"
#include "md5.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; }
operator UINT8 *() { return m_raw; }
const char *as_string(astring &buffer);
bool from_string(const char *string);
bool from_string(const char *string, int length = -1);
const char *as_string(astring &buffer) const;
UINT8 m_raw[20];
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; }
operator UINT8 *() { return m_raw; }
const char *as_string(astring &buffer);
bool from_string(const char *string);
bool from_string(const char *string, int length = -1);
const char *as_string(astring &buffer) const;
UINT8 m_raw[16];
static const md5_t null;
};
@ -161,9 +161,11 @@ protected:
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; }
crc32_t &operator=(const UINT32 crc) { m_raw = crc; return *this; }
operator UINT32() const { return m_raw; }
const char *as_string(astring &buffer);
bool from_string(const char *string);
bool from_string(const char *string, int length = -1);
const char *as_string(astring &buffer) const;
UINT32 m_raw;
static const crc32_t null;
};
@ -179,7 +181,7 @@ public:
void reset() { m_accum.m_raw = 0; }
// 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
crc32_t finish() { return m_accum; }
@ -205,9 +207,11 @@ protected:
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; }
crc16_t &operator=(const UINT16 crc) { m_raw = crc; return *this; }
operator UINT16() const { return m_raw; }
const char *as_string(astring &buffer);
bool from_string(const char *string);
bool from_string(const char *string, int length = -1);
const char *as_string(astring &buffer) const;
UINT16 m_raw;
static const crc16_t null;
};