From f4db4c3a7302909889993c00d0c8755d1a5115da Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 4 Jun 2021 18:54:50 -0400 Subject: [PATCH] Implements ROM::Request::validate. It now also validates ROM sizes, so can no longer take a const Map. --- Machines/AmstradCPC/AmstradCPC.cpp | 2 +- Machines/Apple/Macintosh/Macintosh.cpp | 2 +- Machines/Atari/ST/AtariST.cpp | 2 +- Machines/ColecoVision/ColecoVision.cpp | 2 +- Machines/Electron/Electron.cpp | 2 +- Machines/MSX/MSX.cpp | 2 +- Machines/MasterSystem/MasterSystem.cpp | 3 +- Machines/Oric/Oric.cpp | 2 +- Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 2 +- Machines/Utility/ROMCatalogue.cpp | 37 +++++++++++++++++-- Machines/Utility/ROMCatalogue.hpp | 5 ++- .../xcschemes/Clock Signal Kiosk.xcscheme | 2 +- 12 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 2ea18fa22..f7a4db3e5 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -811,7 +811,7 @@ template class ConcreteMachine: } // Fetch and verify the ROMs. - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index c6e22f276..4903055f3 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -123,7 +123,7 @@ template class ConcreteMachin // Grab a copy of the ROM and convert it into big-endian data. ROM::Request request(rom_name); - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/Atari/ST/AtariST.cpp b/Machines/Atari/ST/AtariST.cpp index ee3d31817..e3c656f58 100644 --- a/Machines/Atari/ST/AtariST.cpp +++ b/Machines/Atari/ST/AtariST.cpp @@ -76,7 +76,7 @@ class ConcreteMachine: constexpr ROM::Name rom_name = ROM::Name::AtariSTTOS100; ROM::Request request(rom_name); - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/ColecoVision/ColecoVision.cpp b/Machines/ColecoVision/ColecoVision.cpp index c798bc1a7..922229554 100644 --- a/Machines/ColecoVision/ColecoVision.cpp +++ b/Machines/ColecoVision/ColecoVision.cpp @@ -129,7 +129,7 @@ class ConcreteMachine: constexpr ROM::Name rom_name = ROM::Name::ColecoVisionBIOS; const ROM::Request request(rom_name); - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 8b9e09316..7590d8dc6 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -82,7 +82,7 @@ template class ConcreteMachine: if(target.has_ap6_rom) { request = request && ::ROM::Request(::ROM::Name::PRESAdvancedPlus6); } - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 542d905c9..69c05a350 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -219,7 +219,7 @@ class ConcreteMachine: request = bios_request; } - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index 25d07e234..5b81fbfc8 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -143,7 +143,8 @@ class ConcreteMachine: const bool is_japanese = target.region == Target::Region::Japan; const ROM::Name bios_name = is_japanese ? ROM::Name::MasterSystemJapaneseBIOS : ROM::Name::MasterSystemWesternBIOS; ROM::Request request(bios_name, true); - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); + request.validate(roms); const auto rom = roms.find(bios_name); if(rom == roms.end()) { diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 1011bf69e..49d16c7f5 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -330,7 +330,7 @@ template class ConcreteMachine: // TODO: possibly accept the +3 ROM in multiple parts? } const auto request = ROM::Request(rom_name); - const auto roms = rom_fetcher(request); + auto roms = rom_fetcher(request); if(!request.validate(roms)) { throw ROMMachine::Error::MissingROMs; } diff --git a/Machines/Utility/ROMCatalogue.cpp b/Machines/Utility/ROMCatalogue.cpp index 1122b2900..e38a8d4f9 100644 --- a/Machines/Utility/ROMCatalogue.cpp +++ b/Machines/Utility/ROMCatalogue.cpp @@ -28,9 +28,8 @@ Request Request::operator ||(const Request &rhs) { return *this; } -bool Request::validate(const Map &) const { - /* TODO. */ - return true; +bool Request::validate(Map &map) const { + return node.validate(map); } std::vector Request::all_descriptions() const { @@ -50,6 +49,38 @@ void Request::Node::add_descriptions(std::vector &result) const { } } +bool Request::Node::validate(Map &map) const { + // Leaf nodes are easy: check that the named ROM is present, + // unless it's optional, in which case it is always valid. + // + // If it is present, make sure it's the proper size. + if(type == Type::One) { + auto rom = map.find(name); + if(rom == map.end()) { + return is_optional; + } + + const Description description(name); + rom->second.resize(description.size); + + return true; + } + + // This is a collection node then. Check for both any or all + // simultaneously, since all nodes will need to be visited + // regardless of any/all in order to ensure proper sizing. + bool has_all = true; + bool has_any = false; + + for(const auto &child: children) { + const bool is_valid = child.validate(map); + has_all &= is_valid; + has_any |= is_valid; + } + + return (type == Type::Any && has_any) || (type == Type::All && has_all); +} + std::optional Description::from_crc(uint32_t crc32) { for(int name = 1; name <= SpectrumPlus3; name++) { const Description candidate = Description(ROM::Name(name)); diff --git a/Machines/Utility/ROMCatalogue.hpp b/Machines/Utility/ROMCatalogue.hpp index 9af771f3e..ec69124c7 100644 --- a/Machines/Utility/ROMCatalogue.hpp +++ b/Machines/Utility/ROMCatalogue.hpp @@ -156,7 +156,9 @@ struct Request { /// Inspects the ROMMap to ensure that it satisfies this @c Request. /// @c returns @c true if the request is satisfied; @c false otherwise. - bool validate(const Map &) const; + /// + /// All ROMs in the map will be resized to their idiomatic sizes. + bool validate(Map &) const; std::vector all_descriptions() const; @@ -174,6 +176,7 @@ struct Request { std::vector children; void add_descriptions(std::vector &) const; + bool validate(Map &) const; }; Node node; }; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme index 6bf363373..02b9d9828 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme @@ -106,7 +106,7 @@ + isEnabled = "YES">