31 virtual void execute(
const vector<TclObject>& tokens,
33 virtual string help(
const vector<string>& tokens)
const;
49 : romDBSHA1(romDBSHA1_)
50 , unknownTypes(unknownTypes_)
120 unsigned unknownLevel;
132 if (tag ==
"softwaredb") {
135 throw MSXException(
"Expected <softwaredb> as root tag.");
139 if (tag ==
"software") {
154 if (tag ==
"system") {
156 }
else if (tag ==
"title") {
158 }
else if (tag ==
"company") {
160 }
else if (tag ==
"year") {
162 }
else if (tag ==
"country") {
164 }
else if (tag ==
"remark") {
166 }
else if (tag ==
"genmsxid") {
168 }
else if (tag ==
"dump") {
169 dumps.resize(dumps.size() + 1);
171 dumps.back().origValue =
false;
178 if (tag ==
"original") {
179 dumps.back().origValue =
false;
181 }
else if (tag ==
"megarom") {
185 }
else if (tag ==
"rom") {
196 }
else if (tag ==
"start") {
198 }
else if (tag ==
"remark") {
200 }
else if (tag ==
"hash") {
246 if (unknownLevel)
return;
250 if (name ==
"value") {
255 if (name ==
"algo") {
283 static void joinRemarks(
string& result,
string_ref extra)
285 if (extra.
empty())
return;
286 if (!result.empty()) result +=
'\n';
287 result.append(extra.
data(), extra.
size());
292 if (unknownLevel)
return;
311 genMSXid =
stoi(text);
319 dumps.back().origData =
text;
328 if (algo ==
"sha1") {
329 dumps.back().hash =
Sha1Sum(text);
334 joinRemarks(remarks, text);
338 joinRemarks(dumps.back().remarks,
text);
353 void DBParser::addEntries()
355 if (!system.
empty() && (system !=
"MSX")) {
360 for (
auto& d : dumps) {
361 if (!sums.insert(d.hash).second) {
363 "duplicate softwaredb entry SHA1: " +
368 auto& ptr = romDBSHA1[d.hash];
376 joinRemarks(r, d.remarks);
378 ptr = make_unique<RomInfo>(
379 title, year, company, country,
380 d.origValue, d.origData, r, d.type,
419 if (dumps.back().hash.empty()) {
431 if (t ==
"Mirrored") {
432 if (
const char*
start = parseStart(startVal)) {
433 memcpy(buf, t.
data(), 8);
434 memcpy(buf + 8,
start, 4);
437 }
else if (t ==
"Normal") {
438 if (
const char*
start = parseStart(startVal)) {
439 memcpy(buf, t.
data(), 6);
440 memcpy(buf + 6,
start, 4);
448 dumps.back().type = romType;
472 auto pos1 = text.
find(
" SYSTEM \"");
474 auto t = text.
substr(pos1 + 9);
475 auto pos2 = t.
find(
'"');
477 systemID = t.
substr(0, pos2);
480 static void parseDB(
CliComm& cliComm,
const string& filename,
484 auto size = file.getSize();
486 file.read(buf.data(),
size);
489 DBParser handler(romDBSHA1, unknownTypes, cliComm);
490 rapidsax::parse<rapidsax::trimWhitespace>(handler, buf.data());
492 if (handler.getSystemID() !=
"softwaredb1.dtd") {
494 "Missing or wrong systemID.\n"
495 "You're probably using an old incompatible file format.",
502 commandController.getOpenMSXInfoCommand(), *this))
507 for (
auto& p : paths) {
510 parseDB(cliComm, filename, romDBSHA1, unknownTypes);
513 "Rom database parsing failed: " << e.
what());
521 if (romDBSHA1.empty()) {
523 "Couldn't load software database.\n"
524 "This may cause incorrect ROM mapper types to be used.");
526 if (!unknownTypes.
empty()) {
528 output <<
"Unknown mapper types in software database: ";
529 for (
auto& p : unknownTypes) {
530 output << p.first() <<
" (" << p.second <<
"x); ";
542 auto it = romDBSHA1.find(sha1sum);
543 return (it == romDBSHA1.end()) ?
nullptr : it->second.get();
551 :
InfoTopic(openMSXInfoCommand,
"software")
552 , romDatabase(romDatabase_)
559 if (tokens.size() != 3) {
568 "Software with sha1sum " + sha1sum.
toString() +
" not found");
593 return "Returns information about the software "
594 "given its sha1sum, in a paired list.";