# HG changeset patch # User Matti Hamalainen # Date 1518811639 -7200 # Node ID 179ffe97599c36e73a9cf543ce2a0d230b70d78e # Parent 7359170fbb7fdc346363975d76cb960cc7e12c82 Implement support for the "new" MD5 format of SLDB. diff -r 7359170fbb7f -r 179ffe97599c sidinfo.c --- a/sidinfo.c Fri Feb 16 21:24:28 2018 +0200 +++ b/sidinfo.c Fri Feb 16 22:07:19 2018 +0200 @@ -14,7 +14,7 @@ // Some constants #define SET_DEF_CHARSET "utf-8" -#define SET_SLDB_FILENAME "Songlengths.txt" +#define SET_SLDB_FILENAME "Songlengths.md5" enum @@ -94,7 +94,8 @@ // Option variables char *setHVSCPath = NULL, *setSLDBPath = NULL; -BOOL optParsable = FALSE, +BOOL setSLDBNewFormat = FALSE, + optParsable = FALSE, optNoNamePrefix = FALSE, optHexadecimal = FALSE, optOneLine = FALSE, @@ -892,7 +893,7 @@ } // Read PSID data - if (si_read_sid_file(inFile, &psid) != 0) + if (!si_read_sid_file(inFile, &psid, setSLDBNewFormat)) { THERR("Error reading %s\n", filename); goto error; @@ -1027,6 +1028,8 @@ goto err; } + setSLDBNewFormat = th_strrcasecmp(setSLDBPath, ".md5") != NULL; + err: th_io_close(inFile); } diff -r 7359170fbb7f -r 179ffe97599c sidlib.c --- a/sidlib.c Fri Feb 16 21:24:28 2018 +0200 +++ b/sidlib.c Fri Feb 16 22:07:19 2018 +0200 @@ -47,14 +47,12 @@ } -int si_read_sid_file(th_ioctx *ctx, PSIDHeader **ppsid) +static BOOL si_read_hash_data(th_ioctx *ctx, PSIDHeader *psid, + th_md5state_t *state, BOOL first) { - PSIDHeader *psid = NULL; - th_md5state_t state; - uint8_t tmp8, *data = NULL; - int index, ret = -1; + uint8_t *data = NULL; + BOOL ret = FALSE; size_t read; - BOOL first; if ((data = (uint8_t *) th_malloc(PSID_BUFFER_SIZE)) == NULL) { @@ -64,6 +62,52 @@ goto error; } + psid->dataSize = 0; + do + { + read = thfread(data, sizeof(uint8_t), PSID_BUFFER_SIZE, ctx); + psid->dataSize += read; + + // If load address is 0 in header and we have the first block, grab it + if (first && psid->loadAddress == 0) + { + if (read < 4) + { + th_io_error(ctx, THERR_FREAD, + "Error reading song data, unexpectedly small file.\n"); + goto error; + } + + // Grab the load address + psid->loadAddress = TH_LE16_TO_NATIVE(*(uint16_t *) data); + + // .. do not include the load address to the hash + th_md5_append(state, &data[2], read - 2); + first = FALSE; + } + else + if (read > 0) + { + // Append data "as is" + th_md5_append(state, data, read); + } + } while (read > 0 && !thfeof(ctx)); + + ret = TRUE; + +error: + th_free(data); + return ret; +} + + +BOOL si_read_sid_file(th_ioctx *ctx, PSIDHeader **ppsid, const BOOL newSLDB) +{ + PSIDHeader *psid = NULL; + th_md5state_t state; + BOOL ret = FALSE; + off_t hdrStart, hdrEnd; + if ((psid = *ppsid = th_malloc0(sizeof(PSIDHeader))) == NULL) { th_io_error(ctx, THERR_MALLOC, @@ -71,6 +115,8 @@ goto error; } + hdrStart = thftell(ctx); + // Read PSID header in if (!thfread_str(ctx, (uint8_t *) psid->magic, PSID_MAGIC_LEN) || !thfread_be16(ctx, &psid->version) || @@ -128,79 +174,66 @@ } } + hdrEnd = thftell(ctx); + // Initialize MD5-hash calculation th_md5_init(&state); - // Process actual data - psid->dataSize = 0; - first = TRUE; - do + if (newSLDB) + { + // New Songlengths.md5 style hash calculation: + // We just hash the whole file, so seek back to beginning .. + thfseek(ctx, hdrStart, SEEK_SET); + + if (!si_read_hash_data(ctx, psid, &state, FALSE)) + goto error; + + psid->dataSize -= hdrEnd - hdrStart; + } + else { - read = thfread(data, sizeof(uint8_t), PSID_BUFFER_SIZE, ctx); - psid->dataSize += read; + // "Old" Songlengths.txt style MD5 hash calculation + // We need to separately hash data etc. + if (!si_read_hash_data(ctx, psid, &state, TRUE)) + goto error; - // If load address is 0 in header and we have the first block, grab it - if (first && psid->loadAddress == 0) + // Append header data to hash + th_md5_append_le16(&state, psid->initAddress); + th_md5_append_le16(&state, psid->playAddress); + th_md5_append_le16(&state, psid->nSongs); + + // Append song speed data to hash + uint8_t tmp8 = psid->isRSID ? 60 : 0; + for (int index = 0; index < psid->nSongs && index < 32; index++) { - if (read < 4) - { - th_io_error(ctx, THERR_FREAD, - "Error reading song data, unexpectedly small file.\n"); - goto error; - } - - // Grab the load address - psid->loadAddress = TH_LE16_TO_NATIVE(*(uint16_t *) data); + if (psid->isRSID) + tmp8 = 60; + else + tmp8 = (psid->speed & (1 << index)) ? 60 : 0; - // .. do not include the load address to the hash - th_md5_append(&state, &data[2], read - 2); - first = FALSE; - } - else - if (read > 0) - { - // Append data "as is" - th_md5_append(&state, data, read); + th_md5_append(&state, &tmp8, sizeof(tmp8)); } - } while (read > 0 && !thfeof(ctx)); - // Append header data to hash - th_md5_append_le16(&state, psid->initAddress); - th_md5_append_le16(&state, psid->playAddress); - th_md5_append_le16(&state, psid->nSongs); + // Rest of songs (more than 32) + for (int index = 32; index < psid->nSongs; index++) + th_md5_append(&state, &tmp8, sizeof(tmp8)); - // Append song speed data to hash - tmp8 = psid->isRSID ? 60 : 0; - for (index = 0; index < psid->nSongs && index < 32; index++) - { - if (psid->isRSID) - tmp8 = 60; - else - tmp8 = (psid->speed & (1 << index)) ? 60 : 0; - - th_md5_append(&state, &tmp8, sizeof(tmp8)); - } - - // Rest of songs (more than 32) - for (index = 32; index < psid->nSongs; index++) - th_md5_append(&state, &tmp8, sizeof(tmp8)); - - // PSIDv2NG specific - if (psid->version >= 2) - { - // REFER TO SIDPLAY HEADERS FOR MORE INFORMATION - tmp8 = (psid->flags >> 2) & 3; - if (tmp8 == 2) - th_md5_append(&state, &tmp8, sizeof(tmp8)); + // PSIDv2NG specific + if (psid->version >= 2) + { + // REFER TO SIDPLAY HEADERS FOR MORE INFORMATION + tmp8 = (psid->flags >> 2) & 3; + if (tmp8 == 2) + th_md5_append(&state, &tmp8, sizeof(tmp8)); + } } // Calculate the hash th_md5_finish(&state, psid->hash); - ret = 0; + ret = TRUE; error: // Free buffer - th_free(data); return ret; } diff -r 7359170fbb7f -r 179ffe97599c sidlib.h --- a/sidlib.h Fri Feb 16 21:24:28 2018 +0200 +++ b/sidlib.h Fri Feb 16 22:07:19 2018 +0200 @@ -92,7 +92,7 @@ // // Functions // -int si_read_sid_file(th_ioctx *ctx, PSIDHeader **ppsid); +BOOL si_read_sid_file(th_ioctx *ctx, PSIDHeader **ppsid, const BOOL newSLDB); void si_free_sid_file(PSIDHeader *psid); const char * si_get_sid_clock_str(const int flags);