diff options
author | 2021-08-22 09:06:15 +1000 | |
---|---|---|
committer | 2021-08-22 09:06:15 +1000 | |
commit | e8bbea1fc6e94e14768509d322f6c624403ffb36 (patch) | |
tree | 74dd1606a900d83de8aecff17a6737af4113308d /src/tools/romcmp.cpp | |
parent | e319bde5fc3696d7f48f62b15b6366c4377fe5d1 (diff) |
formats, osd, util: Started refactoring file I/O stuff. (#8456)
Added more modern generic I/O interfaces with implementation backed by stdio, osd_file and core_file, replacing io_generic. Also replaced core_file's build-in zlib compression with a filter.
unzip.cpp, un7z.cpp: Added option to supply abstract I/O interface rather than filename.
Converted osd_file, core_file, archive_file, chd_file and device_image_interface to use std::error_condition rather than their own error enums.
Allow mounting TI-99 RPK from inside archives.
Diffstat (limited to 'src/tools/romcmp.cpp')
-rw-r--r-- | src/tools/romcmp.cpp | 743 |
1 files changed, 365 insertions, 378 deletions
diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp index 4862f74a769..b65889c70a1 100644 --- a/src/tools/romcmp.cpp +++ b/src/tools/romcmp.cpp @@ -8,25 +8,20 @@ ***************************************************************************/ +#include "hash.h" +#include "path.h" #include "unzip.h" + #include "osdfile.h" #include "osdcomm.h" -#include "hash.h" #include <cstdarg> #include <cstdlib> +#include <memory> #define MAX_FILES 1000 -#ifndef MAX_FILENAME_LEN -#define MAX_FILENAME_LEN 255 -#endif - -#ifndef PATH_DELIM -#define PATH_DELIM '/' -#endif - /* compare modes when one file is twice as long as the other */ @@ -105,382 +100,383 @@ static void compatiblemodes(int mode,int *start,int *end) struct fileinfo { - char name[MAX_FILENAME_LEN+1]; + std::string name; int size; - unsigned char *buf; /* file is read in here */ + std::unique_ptr<unsigned char []> buf; // file is read in here int listed; -}; - -static fileinfo files[2][MAX_FILES]; -static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES]; -static bool is_ascii_char(int ch) -{ - return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t'); -} - -static void checkintegrity(const fileinfo *file, int side, bool all_hashes) -{ - if (file->buf == nullptr) return; - - if (all_hashes) + static constexpr bool is_ascii_char(int ch) { - util::crc32_creator crc32; - util::sha1_creator sha1; - util::sum16_creator sum16; - crc32.append(file->buf, file->size); - sha1.append(file->buf, file->size); - sum16.append(file->buf, file->size); - printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", file->size, - crc32.finish().as_string().c_str(), sha1.finish().as_string().c_str(), sum16.finish().as_string().c_str()); - side = 0; + return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t'); } - /* check for bad data lines */ - unsigned mask0 = 0x0000; - unsigned mask1 = 0xffff; - bool is_ascii = true; - for (unsigned i = 0; i < file->size; i += 2) + void checkintegrity(int side, bool all_hashes) const { - is_ascii = is_ascii && is_ascii_char(file->buf[i]); - mask0 |= file->buf[i] << 8; - mask1 &= (file->buf[i] << 8) | 0x00ff; - if (i < file->size - 1) + if (!buf) + return; + + if (all_hashes) { - is_ascii = is_ascii && is_ascii_char(file->buf[i+1]); - mask0 |= file->buf[i+1]; - mask1 &= file->buf[i+1] | 0xff00; + util::crc32_creator crc32; + util::sha1_creator sha1; + util::sum16_creator sum16; + crc32.append(buf.get(), size); + sha1.append(buf.get(), size); + sum16.append(buf.get(), size); + printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n", + (side & 1) ? name.c_str() : "", + (side & 2) ? name.c_str() : "", + size, + crc32.finish().as_string().c_str(), + sha1.finish().as_string().c_str(), + sum16.finish().as_string().c_str()); + side = 0; } - if (mask0 == 0xffff && mask1 == 0x0000) break; - } - - if (is_ascii && mask0 == 0x7f7f && mask1 == 0) - { - printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - return; - } - if (mask0 != 0xffff || mask1 != 0x0000) - { - int fixedmask; - int bits; + // check for bad data lines + unsigned mask0 = 0x0000; + unsigned mask1 = 0xffff; - fixedmask = (~mask0 | mask1) & 0xffff; + bool is_ascii = true; + for (unsigned i = 0; i < size; i += 2) + { + is_ascii = is_ascii && is_ascii_char(buf[i]); + mask0 |= buf[i] << 8; + mask1 &= (buf[i] << 8) | 0x00ff; + if (i < size - 1) + { + is_ascii = is_ascii && is_ascii_char(buf[i+1]); + mask0 |= buf[i+1]; + mask1 &= buf[i+1] | 0xff00; + } + if (mask0 == 0xffff && mask1 == 0x0000) break; + } - if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff)) - bits = 8; - else bits = 16; + if (is_ascii && mask0 == 0x7f7f && mask1 == 0) + { + printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + return; + } - printf("%-23s %-23s FIXED BITS (", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - for (int i = 0; i < bits; i++) + if (mask0 != 0xffff || mask1 != 0x0000) { - if (~mask0 & 0x8000) printf("0"); - else if (mask1 & 0x8000) printf("1"); - else printf("x"); + int fixedmask; + int bits; - mask0 <<= 1; - mask1 <<= 1; - } - printf(")\n"); + fixedmask = (~mask0 | mask1) & 0xffff; - /* if the file contains a fixed value, we don't need to do the other */ - /* validity checks */ - if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00) - return; - } + if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff)) + bits = 8; + else bits = 16; - unsigned addrbit = 1; - unsigned addrmirror = 0; - while (addrbit <= file->size/2) - { - unsigned i = 0; - for (i = 0; i < file->size; i++) + printf("%-23s %-23s FIXED BITS (", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + for (int i = 0; i < bits; i++) + { + if (~mask0 & 0x8000) printf("0"); + else if (mask1 & 0x8000) printf("1"); + else printf("x"); + + mask0 <<= 1; + mask1 <<= 1; + } + printf(")\n"); + + /* if the file contains a fixed value, we don't need to do the other */ + /* validity checks */ + if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00) + return; + } + + unsigned addrbit = 1; + unsigned addrmirror = 0; + while (addrbit <= size/2) { - if ((i ^ addrbit) < file->size && file->buf[i] != file->buf[i ^ addrbit]) break; + unsigned i = 0; + for (i = 0; i < size; i++) + { + if ((i ^ addrbit) < size && buf[i] != buf[i ^ addrbit]) break; + } + + if (i == size) + addrmirror |= addrbit; + + addrbit <<= 1; } - if (i == file->size) - addrmirror |= addrbit; + if (addrmirror != 0) + { + if (addrmirror == size/2) + { + printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + util::hash_collection hash; + hash.begin(); + hash.buffer(buf.get(), size / 2); + hash.end(); + printf("%-23s %-23s %s\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "", hash.attribute_string().c_str()); + } + else + { + printf("%-23s %-23s BADADDR", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + for (int i = 0; i < 24; i++) + { + if (size <= (1<<(23-i))) printf(" "); + else if (addrmirror & 0x800000) printf("-"); + else printf("x"); + addrmirror <<= 1; + } + printf("\n"); + } + return; + } - addrbit <<= 1; - } + unsigned sizemask = 1; + while (sizemask < size - 1) + sizemask = (sizemask << 1) | 1; - if (addrmirror != 0) - { - if (addrmirror == file->size/2) + mask0 = 0x000000; + mask1 = sizemask; + for (unsigned i = 0; i < size; i++) { - printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - util::hash_collection hash; - hash.begin(); - hash.buffer(file->buf, file->size / 2); - hash.end(); - printf("%-23s %-23s %s\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", hash.attribute_string().c_str()); + if (buf[i] != 0xff) + { + mask0 |= i; + mask1 &= i; + if (mask0 == sizemask && mask1 == 0x00) break; + } } - else + + if (mask0 != sizemask || mask1 != 0x00) { - printf("%-23s %-23s BADADDR", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); + printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); for (int i = 0; i < 24; i++) { - if (file->size <= (1<<(23-i))) printf(" "); - else if (addrmirror & 0x800000) printf("-"); + if (size <= (1<<(23-i))) printf(" "); + else if (~mask0 & 0x800000) printf("1"); + else if (mask1 & 0x800000) printf("0"); else printf("x"); - addrmirror <<= 1; + mask0 <<= 1; + mask1 <<= 1; } - printf("\n"); + printf(" = 0xFF\n"); + + return; } - return; - } - unsigned sizemask = 1; - while (sizemask < file->size - 1) - sizemask = (sizemask << 1) | 1; - mask0 = 0x000000; - mask1 = sizemask; - for (unsigned i = 0; i < file->size; i++) - { - if (file->buf[i] != 0xff) + mask0 = 0x000000; + mask1 = sizemask; + for (unsigned i = 0; i < size; i++) { - mask0 |= i; - mask1 &= i; - if (mask0 == sizemask && mask1 == 0x00) break; + if (buf[i] != 0x00) + { + mask0 |= i; + mask1 &= i; + if (mask0 == sizemask && mask1 == 0x00) break; + } } - } - if (mask0 != sizemask || mask1 != 0x00) - { - printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - for (int i = 0; i < 24; i++) + if (mask0 != sizemask || mask1 != 0x00) { - if (file->size <= (1<<(23-i))) printf(" "); - else if (~mask0 & 0x800000) printf("1"); - else if (mask1 & 0x800000) printf("0"); - else printf("x"); - mask0 <<= 1; - mask1 <<= 1; - } - printf(" = 0xFF\n"); - - return; - } + printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + for (int i = 0; i < 24; i++) + { + if (size <= (1<<(23-i))) printf(" "); + else if ((mask0 & 0x800000) == 0) printf("1"); + else if (mask1 & 0x800000) printf("0"); + else printf("x"); + mask0 <<= 1; + mask1 <<= 1; + } + printf(" = 0x00\n"); + return; + } - mask0 = 0x000000; - mask1 = sizemask; - for (unsigned i = 0; i < file->size; i++) - { - if (file->buf[i] != 0x00) + mask0 = 0xff; + for (unsigned i = 0; i < size/4 && mask0 != 0x00; i++) { - mask0 |= i; - mask1 &= i; - if (mask0 == sizemask && mask1 == 0x00) break; + if (buf[ 2*i ] != 0x00) mask0 &= ~0x01; + if (buf[ 2*i ] != 0xff) mask0 &= ~0x02; + if (buf[ 2*i+1] != 0x00) mask0 &= ~0x04; + if (buf[ 2*i+1] != 0xff) mask0 &= ~0x08; + if (buf[size/2 + 2*i ] != 0x00) mask0 &= ~0x10; + if (buf[size/2 + 2*i ] != 0xff) mask0 &= ~0x20; + if (buf[size/2 + 2*i+1] != 0x00) mask0 &= ~0x40; + if (buf[size/2 + 2*i+1] != 0xff) mask0 &= ~0x80; } + + if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); + if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : ""); } - if (mask0 != sizemask || mask1 != 0x00) + int usedbytes(int mode) const { - printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - for (int i = 0; i < 24; i++) + switch (mode) { - if (file->size <= (1<<(23-i))) printf(" "); - else if ((mask0 & 0x800000) == 0) printf("1"); - else if (mask1 & 0x800000) printf("0"); - else printf("x"); - mask0 <<= 1; - mask1 <<= 1; + case MODE_A: + case MODE_NIB1: + case MODE_NIB2: + return size; + case MODE_12: + case MODE_22: + case MODE_E: + case MODE_O: + return size / 2; + case MODE_14: + case MODE_24: + case MODE_34: + case MODE_44: + case MODE_E12: + case MODE_O12: + case MODE_E22: + case MODE_O22: + return size / 4; + default: + return 0; } - printf(" = 0x00\n"); - - return; } - mask0 = 0xff; - for (unsigned i = 0; i < file->size/4 && mask0 != 0x00; i++) + void basemultmask(int mode, int &base, int &mult, int &mask) const { - if (file->buf[ 2*i ] != 0x00) mask0 &= ~0x01; - if (file->buf[ 2*i ] != 0xff) mask0 &= ~0x02; - if (file->buf[ 2*i+1] != 0x00) mask0 &= ~0x04; - if (file->buf[ 2*i+1] != 0xff) mask0 &= ~0x08; - if (file->buf[file->size/2 + 2*i ] != 0x00) mask0 &= ~0x10; - if (file->buf[file->size/2 + 2*i ] != 0xff) mask0 &= ~0x20; - if (file->buf[file->size/2 + 2*i+1] != 0x00) mask0 &= ~0x40; - if (file->buf[file->size/2 + 2*i+1] != 0xff) mask0 &= ~0x80; - } + mult = 1; + if (mode >= MODE_E) + mult = 2; - if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); - if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : ""); -} - - -static int usedbytes(const fileinfo *file,int mode) -{ - switch (mode) - { - case MODE_A: - case MODE_NIB1: - case MODE_NIB2: - return file->size; - case MODE_12: - case MODE_22: - case MODE_E: - case MODE_O: - return file->size / 2; - case MODE_14: - case MODE_24: - case MODE_34: - case MODE_44: - case MODE_E12: - case MODE_O12: - case MODE_E22: - case MODE_O22: - return file->size / 4; - default: - return 0; + switch (mode) + { + case MODE_A: + case MODE_12: + case MODE_14: + case MODE_E: + case MODE_E12: + base = 0; mask = 0xff; break; + case MODE_NIB1: + base = 0; mask = 0x0f; break; + case MODE_NIB2: + base = 0; mask = 0xf0; break; + case MODE_O: + case MODE_O12: + base = 1; mask = 0xff; break; + case MODE_22: + case MODE_E22: + base = size / 2; mask = 0xff; break; + case MODE_O22: + base = 1 + size / 2; mask = 0xff; break; + case MODE_24: + base = size / 4; mask = 0xff; break; + case MODE_34: + base = 2*size / 4; mask = 0xff; break; + case MODE_44: + base = 3*size / 4; mask = 0xff; break; + } } -} - -static void basemultmask(const fileinfo *file,int mode,int *base,int *mult,int *mask) -{ - *mult = 1; - if (mode >= MODE_E) *mult = 2; - switch (mode) + float compare(const fileinfo &file2, int mode1, int mode2) const { - case MODE_A: - case MODE_12: - case MODE_14: - case MODE_E: - case MODE_E12: - *base = 0; *mask = 0xff; break; - case MODE_NIB1: - *base = 0; *mask = 0x0f; break; - case MODE_NIB2: - *base = 0; *mask = 0xf0; break; - case MODE_O: - case MODE_O12: - *base = 1; *mask = 0xff; break; - case MODE_22: - case MODE_E22: - *base = file->size / 2; *mask = 0xff; break; - case MODE_O22: - *base = 1 + file->size / 2; *mask = 0xff; break; - case MODE_24: - *base = file->size / 4; *mask = 0xff; break; - case MODE_34: - *base = 2*file->size / 4; *mask = 0xff; break; - case MODE_44: - *base = 3*file->size / 4; *mask = 0xff; break; - } -} - -static float filecompare(const fileinfo *file1,const fileinfo *file2,int mode1,int mode2) -{ - int i; - int match = 0; - int size1,size2; - int base1=0,base2=0,mult1=0,mult2=0,mask1=0,mask2=0; + if (!buf || !file2.buf) + return 0.0; + int const size1 = usedbytes(mode1); + int const size2 = file2.usedbytes(mode2); - if (file1->buf == nullptr || file2->buf == nullptr) return 0.0; + if (size1 != size2) + return 0.0; - size1 = usedbytes(file1,mode1); - size2 = usedbytes(file2,mode2); + int base1=0, base2=0, mult1=0, mult2=0, mask1=0, mask2=0; + basemultmask(mode1, base1, mult1, mask1); + file2.basemultmask(mode2, base2, mult2, mask2); - if (size1 != size2) return 0.0; - - basemultmask(file1,mode1,&base1,&mult1,&mask1); - basemultmask(file2,mode2,&base2,&mult2,&mask2); - - if (mask1 == mask2) - { - if (mask1 == 0xff) - { - /* normal compare */ - for (i = 0;i < size1;i++) - if (file1->buf[base1 + mult1 * i] == file2->buf[base2 + mult2 * i]) match++; - } - else + int match = 0; + if (mask1 == mask2) { - /* nibble compare, abort if other half is not empty */ - for (i = 0;i < size1;i++) + if (mask1 == 0xff) + { + // normal compare + for (int i = 0; i < size1; i++) + if (buf[base1 + mult1 * i] == file2.buf[base2 + mult2 * i]) match++; + } + else { - if (((file1->buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) && - (file1->buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) || - ((file2->buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) && - (file2->buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2))) + // nibble compare, abort if other half is not empty + for (int i = 0; i < size1; i++) { - match = 0; - break; + if (((buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) && + (buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) || + ((file2.buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) && + (file2.buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2))) + { + match = 0; + break; + } + if ((buf[base1 + mult1 * i] & mask1) == (file2.buf[base2 + mult2 * i] & mask2)) match++; } - if ((file1->buf[base1 + mult1 * i] & mask1) == (file2->buf[base2 + mult2 * i] & mask2)) match++; } } - } - return (float)match / size1; -} + return float(match) / size1; + } + void readfile(const char *path) + { + std::string fullname(path ? path : ""); + util::path_append(fullname, name); -static void readfile(const char *path,fileinfo *file) -{ - osd_file::error filerr; - uint64_t filesize; - uint32_t actual; - char fullname[256]; - osd_file::ptr f; + buf.reset(new (std::nothrow) unsigned char [size]); + if (!buf) + { + printf("%s: out of memory!\n", name.c_str()); + return; + } - if (path) - { - char delim[2] = { PATH_DELIM, '\0' }; - strcpy(fullname,path); - strcat(fullname,delim); - } - else fullname[0] = 0; - strcat(fullname,file->name); + std::error_condition filerr; + osd_file::ptr f; + uint64_t filesize; - if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr) - { - printf("%s: out of memory!\n",file->name); - return; - } + filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize); + if (filerr) + { + printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str()); + return; + } - filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize); - if (filerr != osd_file::error::NONE) - { - printf("%s: error %d\n", fullname, int(filerr)); - return; + uint32_t actual; + filerr = f->read(buf.get(), 0, size, actual); + if (filerr) + { + printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str()); + return; + } } - filerr = f->read(file->buf, 0, file->size, actual); - if (filerr != osd_file::error::NONE) + void free() { - printf("%s: error %d\n", fullname, int(filerr)); - return; + buf.reset(); } -} - +}; -static void freefile(fileinfo *file) -{ - free(file->buf); - file->buf = nullptr; -} +static fileinfo files[2][MAX_FILES]; +static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES]; -static void printname(const fileinfo *file1,const fileinfo *file2,float score,int mode1,int mode2) +static void printname(const fileinfo *file1, const fileinfo *file2, float score, int mode1, int mode2) { - printf("%-12s %s %-12s %s ",file1 ? file1->name : "",modenames[mode1],file2 ? file2->name : "",modenames[mode2]); + printf( + "%-12s %s %-12s %s ", + file1 ? file1->name.c_str() : "", + modenames[mode1], + file2 ? file2->name.c_str() : "", + modenames[mode2]); if (score == 0.0f) printf("NO MATCH\n"); else if (score == 1.0f) printf("IDENTICAL\n"); - else printf("%3.6f%%\n",(double) (score*100)); + else printf("%3.6f%%\n", double(score*100)); } @@ -496,24 +492,23 @@ static int load_files(int i, int *found, const char *path) while ((d = dir->read()) != nullptr) { const char *d_name = d->name; - char buf[255+1]; + const std::string buf(util::path_concat(path, d_name)); // FIXME: is this even used for anything? - sprintf(buf, "%s%c%s", path, PATH_DELIM, d_name); if (d->type == osd::directory::entry::entry_type::FILE) { uint64_t size = d->size; while (size && (size & 1) == 0) size >>= 1; //if (size & ~1) - // printf("%-23s %-23s ignored (not a ROM)\n",i ? "" : d_name,i ? d_name : ""); + // printf("%-23s %-23s ignored (not a ROM)\n", i ? "" : d_name, i ? d_name : ""); //else { - strcpy(files[i][found[i]].name,d_name); + files[i][found[i]].name = d_name; files[i][found[i]].size = d->size; - readfile(path,&files[i][found[i]]); + files[i][found[i]].readfile(path); files[i][found[i]].listed = 0; if (found[i] >= MAX_FILES) { - printf("%s: max of %d files exceeded\n",path,MAX_FILES); + printf("%s: max of %d files exceeded\n", path, MAX_FILES); break; } found[i]++; @@ -522,15 +517,13 @@ static int load_files(int i, int *found, const char *path) } dir.reset(); } - - /* if not, try to open as a ZIP file */ else { + /* if not, try to open as a ZIP file */ util::archive_file::ptr zip; /* wasn't a directory, so try to open it as a zip file */ - if ((util::archive_file::open_zip(path, zip) != util::archive_file::error::NONE) && - (util::archive_file::open_7z(path, zip) != util::archive_file::error::NONE)) + if (util::archive_file::open_zip(path, zip) && util::archive_file::open_7z(path, zip)) { printf("Error, cannot open zip file '%s' !\n", path); return 1; @@ -552,26 +545,26 @@ static int load_files(int i, int *found, const char *path) } else { - fileinfo *file = &files[i][found[i]]; + fileinfo &file = files[i][found[i]]; const char *delim = strrchr(zip->current_name().c_str(), '/'); if (delim) - strcpy (file->name,delim+1); + file.name = delim + 1; else - strcpy(file->name,zip->current_name().c_str()); - file->size = zip->current_uncompressed_length(); - if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr) - printf("%s: out of memory!\n",file->name); + file.name = zip->current_name(); + file.size = zip->current_uncompressed_length(); + file.buf.reset(new (std::nothrow) unsigned char [file.size]); + if (!file.buf) + { + printf("%s: out of memory!\n", file.name.c_str()); + } else { - if (zip->decompress(file->buf, file->size) != util::archive_file::error::NONE) - { - free(file->buf); - file->buf = nullptr; - } + if (zip->decompress(file.buf.get(), file.size)) + file.free(); } - file->listed = 0; + file.listed = 0; if (found[i] >= MAX_FILES) { printf("%s: max of %d files exceeded\n",path,MAX_FILES); @@ -612,13 +605,8 @@ int CLIB_DECL main(int argc,char *argv[]) } { - int found[2]; - int i,j,mode1,mode2; - int besti,bestj; - - - found[0] = found[1] = 0; - for (i = 0;i < 2;i++) + int found[2] = { 0, 0 }; + for (int i = 0; i < 2; i++) { if (argc > i+1) { @@ -633,26 +621,26 @@ int CLIB_DECL main(int argc,char *argv[]) else printf("%d files\n",found[0]); - for (i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { - for (j = 0; j < found[i]; j++) + for (int j = 0; j < found[i]; j++) { - checkintegrity(&files[i][j], 1 << i, all_hashes); + files[i][j].checkintegrity(1 << i, all_hashes); } } if (argc < 3) { - /* find duplicates in one dir */ - for (i = 0;i < found[0];i++) + // find duplicates in one dir + for (int i = 0;i < found[0];i++) { - for (j = i+1;j < found[0];j++) + for (int j = i+1;j < found[0];j++) { - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - if (filecompare(&files[0][i],&files[0][j],mode1,mode2) == 1.0f) + if (files[0][i].compare(files[0][j],mode1,mode2) == 1.0f) printname(&files[0][i],&files[0][j],1.0,mode1,mode2); } } @@ -661,40 +649,38 @@ int CLIB_DECL main(int argc,char *argv[]) } else { - /* compare two dirs */ - for (i = 0;i < found[0];i++) + // compare two dirs + for (int i = 0;i < found[0];i++) { - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { fprintf(stderr,"%2d%%\r",100*(i*found[1]+j)/(found[0]*found[1])); - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - matchscore[i][j][mode1][mode2] = filecompare(&files[0][i],&files[1][j],mode1,mode2); + matchscore[i][j][mode1][mode2] = files[0][i].compare(files[1][j],mode1,mode2); } } } } fprintf(stderr," \r"); + int besti; do { - float bestscore; - int bestmode1,bestmode2; - besti = -1; - bestj = -1; - bestscore = 0.0; - bestmode1 = bestmode2 = -1; + int bestj = -1; + float bestscore = 0.0; + int bestmode1 = -1, bestmode2 = -1; - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { if (matchscore[i][j][mode1][mode2] > bestscore || (matchscore[i][j][mode1][mode2] == 1.0f && mode2 == 0 && bestmode2 > 0)) @@ -721,17 +707,17 @@ int CLIB_DECL main(int argc,char *argv[]) matchscore[besti][bestj][bestmode1][bestmode2] = 0.0; /* remove all matches using the same sections with a worse score */ - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { if (matchscore[besti][j][bestmode1][mode2] < bestscore) matchscore[besti][j][bestmode1][mode2] = 0.0; } } - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { if (matchscore[i][bestj][mode1][bestmode2] < bestscore) matchscore[i][bestj][mode1][bestmode2] = 0.0; @@ -740,49 +726,50 @@ int CLIB_DECL main(int argc,char *argv[]) /* remove all matches using incompatible sections */ compatiblemodes(bestmode1,&start,&end); - for (j = 0;j < found[1];j++) + for (int j = 0;j < found[1];j++) { - for (mode2 = 0;mode2 < total_modes;mode2++) + for (int mode2 = 0;mode2 < total_modes;mode2++) { - for (mode1 = 0;mode1 < start;mode1++) + for (int mode1 = 0;mode1 < start;mode1++) matchscore[besti][j][mode1][mode2] = 0.0; - for (mode1 = end+1;mode1 < total_modes;mode1++) + for (int mode1 = end+1;mode1 < total_modes;mode1++) matchscore[besti][j][mode1][mode2] = 0.0; } } compatiblemodes(bestmode2,&start,&end); - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - for (mode1 = 0;mode1 < total_modes;mode1++) + for (int mode1 = 0;mode1 < total_modes;mode1++) { - for (mode2 = 0;mode2 < start;mode2++) + for (int mode2 = 0;mode2 < start;mode2++) matchscore[i][bestj][mode1][mode2] = 0.0; - for (mode2 = end+1;mode2 < total_modes;mode2++) + for (int mode2 = end+1;mode2 < total_modes;mode2++) matchscore[i][bestj][mode1][mode2] = 0.0; } } } - } while (besti != -1); + } + while (besti != -1); - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { if (files[0][i].listed == 0) printname(&files[0][i],nullptr,0.0,0,0); } - for (i = 0;i < found[1];i++) + for (int i = 0;i < found[1];i++) { if (files[1][i].listed == 0) printname(nullptr,&files[1][i],0.0,0,0); } } - for (i = 0;i < found[0];i++) + for (int i = 0;i < found[0];i++) { - freefile(&files[0][i]); + files[0][i].free(); } - for (i = 0;i < found[1];i++) + for (int i = 0;i < found[1];i++) { - freefile(&files[1][i]); + files[1][i].free(); } } |