summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2012-02-16 21:53:30 +0000
committer Aaron Giles <aaron@aarongiles.com>2012-02-16 21:53:30 +0000
commite055a551c19a2f5e67472faaf16e1131fa36a6ce (patch)
treec610667dbedc663684ee2e763f1942c056c108db /src
parenta825e9730d32de2f78a6ebdd39e5956898ca150e (diff)
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. ;)
Diffstat (limited to 'src')
-rw-r--r--src/emu/audit.c2
-rw-r--r--src/emu/clifront.c19
-rw-r--r--src/emu/diimage.c3
-rw-r--r--src/emu/fileio.c6
-rw-r--r--src/emu/hash.c625
-rw-r--r--src/emu/hash.h86
-rw-r--r--src/emu/info.c11
-rw-r--r--src/emu/romload.c5
-rw-r--r--src/lib/util/hashing.c44
-rw-r--r--src/lib/util/hashing.h24
10 files changed, 247 insertions, 578 deletions
diff --git a/src/emu/audit.c b/src/emu/audit.c
index 42e2ed77060..d1a07aea607 100644
--- a/src/emu/audit.c
+++ b/src/emu/audit.c
@@ -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);
diff --git a/src/emu/clifront.c b/src/emu/clifront.c
index f9f17ee09a3..582af2d84fc 100644
--- a/src/emu/clifront.c
+++ b/src/emu/clifront.c
@@ -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());
@@ -1158,19 +1159,9 @@ 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) )
+ 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());
diff --git a/src/emu/diimage.c b/src/emu/diimage.c
index 8f4f949a7f1..bf5f4a3cb5a 100644
--- a/src/emu/diimage.c
+++ b/src/emu/diimage.c
@@ -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 */
diff --git a/src/emu/fileio.c b/src/emu/fileio.c
index d5fbf122043..ab0b361f560 100644
--- a/src/emu/fileio.c
+++ b/src/emu/fileio.c
@@ -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
diff --git a/src/emu/hash.c b/src/emu/hash.c
index d50395b2f74..ef03418ef50 100644
--- a/src/emu/hash.c
+++ b/src/emu/hash.c
@@ -40,62 +40,11 @@
***************************************************************************/
#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
//**************************************************************************
@@ -106,220 +55,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)
- return false;
- matches++;
- }
+ 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
@@ -391,20 +140,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,8 +147,10 @@ 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;
}
@@ -423,53 +160,12 @@ const char *hash_collection::hash_types(astring &buffer) const
// 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
-//-------------------------------------------------
-
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);
-
- // first allocate by ID
- hash_base *newhash = alloc_by_id(type);
- if (newhash == NULL)
- return NULL;
-
- // then import
- if (!newhash->from_string(buffer, length))
- {
- global_free(newhash);
- return NULL;
- }
+ // handle CRCs
+ if (type == HASH_CRC)
+ return m_has_crc32 = m_crc32.from_string(buffer, length);
+
+ // handle SHA1s
+ else if (type == HASH_SHA1)
+ return m_has_sha1 = m_sha1.from_string(buffer, length);
- // 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)
- {
- m_hashlist.remove(*hash);
- return true;
- }
-
- // didn't find it
- return false;
-}
-
-
-//-------------------------------------------------
-// crc - return the CRC hash if present
-//-------------------------------------------------
-
-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));
+ bool result = false;
+
+ // handle CRCs
+ if (type == HASH_CRC)
+ {
+ result = m_has_crc32;
+ m_has_crc32 = false;
+ }
+
+ // handle SHA1s
+ else if (type == HASH_SHA1)
+ {
+ result = m_has_sha1;
+ m_has_sha1 = false;
+ }
+ 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))
@@ -604,6 +265,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'))
- errors = true;
+ 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();
-}
-
-
-//-------------------------------------------------
-// alloc_by_id - based on the ID character,
-// allocate a new hash
-//-------------------------------------------------
-
-hash_base *hash_collection::alloc_by_id(char id)
-{
- switch (id)
+ 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)
{
- case HASH_CRC: return global_alloc(hash_crc);
- case HASH_SHA1: return global_alloc(hash_sha1);
- default: return NULL;
+ m_has_crc32 = true;
+ m_crc32 = m_creator->m_crc32_creator.finish();
}
+
+ // 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;
}
@@ -731,9 +418,13 @@ 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;
}
diff --git a/src/emu/hash.h b/src/emu/hash.h
index 04c25853856..e12aa4ce974 100644
--- a/src/emu/hash.h
+++ b/src/emu/hash.h
@@ -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;
};
diff --git a/src/emu/info.c b/src/emu/info.c
index 8ef8c3c7f33..462dc594c0c 100644
--- a/src/emu/info.c
+++ b/src/emu/info.c
@@ -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);
diff --git a/src/emu/romload.c b/src/emu/romload.c
index 85351c74b8d..b8173ef9485 100644
--- a/src/emu/romload.c
+++ b/src/emu/romload.c
@@ -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)
diff --git a/src/lib/util/hashing.c b/src/lib/util/hashing.c
index 97afb184156..866cec8fc0d 100644
--- a/src/lib/util/hashing.c
+++ b/src/lib/util/hashing.c
@@ -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);
}
diff --git a/src/lib/util/hashing.h b/src/lib/util/hashing.h
index 8bb59b9c5cc..08aeec5ac60 100644
--- a/src/lib/util/hashing.h
+++ b/src/lib/util/hashing.h
@@ -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;
};