MythTV  master
rom_metadata.cpp
Go to the documentation of this file.
1 #include "config.h"
2 #include "rom_metadata.h"
3 
4 #include <QFile>
5 
6 #include <mythcontext.h>
7 
8 #include "zlib.h"
9 #include MINIZIP_UNZIP_H
10 #undef Z_NULL
11 #define Z_NULL nullptr
12 
13 static int calcOffset(const QString& GameType, uLong filesize) {
14  int result = 0;
15 
16  if (GameType == "NES")
17  {
18  result = 16;
19  }
20  else if (GameType == "SNES")
21  {
22  uLong rom_size = (filesize / 0x2000) * 0x2000;
23 
24  if (rom_size < filesize)
25  result = filesize - rom_size;
26  }
27  else if (GameType == "PCE")
28  {
29  if (filesize & 0x0FFF)
30  result = filesize & 0x0FFF;
31 
32  }
33 
34  return result;
35 }
36 
37 static QString crcStr(uLong crc)
38 {
39  QString tmpcrc("");
40 
41  tmpcrc = QString("%1").arg( crc, 0, 16 );
42  if (tmpcrc == "0")
43  tmpcrc = "";
44  else
45  tmpcrc = tmpcrc.rightJustified(8, '0');
46 
47  return tmpcrc;
48 }
49 
50 // Return the crc32 info for this rom. (ripped mostly from the old neshandler.cpp source)
51 QString crcinfo(const QString& romname, const QString& GameType, QString *key, RomDBMap *romDB)
52 {
53  // Get CRC of file
54  std::array<char,32768> block {};
55  uLong crc = crc32(0, Z_NULL, 0);
56  QString crcRes;
57  unz_file_info file_info {};
58 
59  int blocksize = 8192;
60 #if 0
61  LOG(VB_GENERAL, LOG_DEBUG,
62  QString("crcinfo : %1 : %2 :").arg(romname).arg(GameType));
63 #endif
64 
65  unzFile zf = unzOpen(qPrintable(romname));
66  if (zf != nullptr)
67  {
68  for (int FoundFile = unzGoToFirstFile(zf); FoundFile == UNZ_OK;
69  FoundFile = unzGoToNextFile(zf))
70  {
71  if (unzOpenCurrentFile(zf) == UNZ_OK)
72  {
73  std::string filename_inzip(256,'\0');
74  unzGetCurrentFileInfo(zf,&file_info,filename_inzip.data(),filename_inzip.size(),nullptr,0,nullptr,0);
75 
76  int offset = calcOffset(GameType, file_info.uncompressed_size);
77 
78  if (offset > 0)
79  unzReadCurrentFile(zf, block.data(), offset);
80 
81  // Get CRC of rom data
82  int count = 0;
83  while ((count = unzReadCurrentFile(zf, block.data(), blocksize)) > 0)
84  {
85  crc = crc32(crc, (Bytef *)block.data(), (uInt)count);
86  }
87  crcRes = crcStr(crc);
88  *key = QString("%1:%2")
89  .arg(crcRes)
90  .arg(filename_inzip.data());
91 
92  if (romDB->contains(*key))
93  {
94  unzCloseCurrentFile(zf);
95  break;
96  }
97 
98  unzCloseCurrentFile(zf);
99  }
100  }
101  unzClose(zf);
102  }
103  else
104  {
105  QFile f(romname);
106 
107  if (f.open(QIODevice::ReadOnly))
108  {
109  int offset = calcOffset(GameType, f.size());
110 
111  if (offset > 0)
112  f.read(block.data(), offset);
113 
114  // Get CRC of rom data
115  qint64 count = 0;
116  while ((count = f.read(block.data(), blocksize)) > 0)
117  {
118  crc = crc32(crc, (Bytef *)block.data(), (uInt)count);
119  }
120 
121  crcRes = crcStr(crc);
122  *key = QString("%1:").arg(crcRes);
123  f.close();
124  }
125  }
126 
127  return crcRes;
128 }
129 
arg
arg(title).arg(filename).arg(doDelete))
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
f
QTextStream t & f
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:606
calcOffset
static int calcOffset(const QString &GameType, uLong filesize)
Definition: rom_metadata.cpp:13
crcStr
static QString crcStr(uLong crc)
Definition: rom_metadata.cpp:37
crcinfo
QString crcinfo(const QString &romname, const QString &GameType, QString *key, RomDBMap *romDB)
Definition: rom_metadata.cpp:51
RomDBMap
QMap< QString, RomData > RomDBMap
Definition: rom_metadata.h:47
Z_NULL
#define Z_NULL
Definition: rom_metadata.cpp:11
mythcontext.h
GameType
Definition: gamesettings.cpp:252
crc32
static uint32_t crc32(const unsigned char *data, int len)
Definition: dsmcc.cpp:612
rom_metadata.h