diff --git a/lib/globals.h b/lib/globals.h index 65313240..c764f25e 100644 --- a/lib/globals.h +++ b/lib/globals.h @@ -22,7 +22,7 @@ extern void hexdumpForSrp16(std::ostream& stream, const Bytes& bytes); class Error { public: - ~Error() + [[ noreturn ]] ~Error() { std::cerr << "Error: " << _stream.str() << std::endl; exit(1); diff --git a/lib/imagereader/imagereader.cc b/lib/imagereader/imagereader.cc index 4fe62777..c0a1ede7 100644 --- a/lib/imagereader/imagereader.cc +++ b/lib/imagereader/imagereader.cc @@ -7,6 +7,13 @@ #include "imagereader/imagereader.h" #include "fmt/format.h" +std::map ImageReader::formats = +{ + {".adf", ImageReader::createImgImageReader}, + {".d81", ImageReader::createImgImageReader}, + {".img", ImageReader::createImgImageReader}, +}; + static bool ends_with(const std::string& value, const std::string& ending) { if (ending.size() > value.size()) @@ -14,15 +21,29 @@ static bool ends_with(const std::string& value, const std::string& ending) return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } -std::unique_ptr ImageReader::create(const ImageSpec& spec) +ImageReader::Constructor ImageReader::findConstructor(const ImageSpec& spec) { const auto& filename = spec.filename; - if (ends_with(filename, ".img") || ends_with(filename, ".adf")) - return createImgImageReader(spec); + for (const auto& e : formats) + { + if (ends_with(filename, e.first)) + return e.second; + } - Error() << "unrecognised image filename extension"; - return std::unique_ptr(); + return NULL; +} + +std::unique_ptr ImageReader::create(const ImageSpec& spec) +{ + verifyImageSpec(spec); + return findConstructor(spec)(spec); +} + +void ImageReader::verifyImageSpec(const ImageSpec& spec) +{ + if (!findConstructor(spec)) + Error() << "unrecognised image filename extension"; } ImageReader::ImageReader(const ImageSpec& spec): diff --git a/lib/imagereader/imagereader.h b/lib/imagereader/imagereader.h index 5b74544e..2c1fbeaa 100644 --- a/lib/imagereader/imagereader.h +++ b/lib/imagereader/imagereader.h @@ -12,10 +12,21 @@ public: public: static std::unique_ptr create(const ImageSpec& spec); + static void verifyImageSpec(const ImageSpec& spec); private: + typedef + std::function< + std::unique_ptr(const ImageSpec& spec) + > + Constructor; + + static std::map formats; + static std::unique_ptr createImgImageReader(const ImageSpec& spec); + static Constructor findConstructor(const ImageSpec& spec); + public: virtual SectorSet readImage() = 0; diff --git a/lib/imagewriter/imagewriter.cc b/lib/imagewriter/imagewriter.cc index 101d2f5d..4f91f2ea 100644 --- a/lib/imagewriter/imagewriter.cc +++ b/lib/imagewriter/imagewriter.cc @@ -7,6 +7,15 @@ #include "imagewriter/imagewriter.h" #include "fmt/format.h" +std::map ImageWriter::formats = +{ + {".adf", ImageWriter::createImgImageWriter}, + {".d64", ImageWriter::createD64ImageWriter}, + {".d81", ImageWriter::createImgImageWriter}, + {".img", ImageWriter::createImgImageWriter}, + {".ldbs", ImageWriter::createLDBSImageWriter}, +}; + static bool ends_with(const std::string& value, const std::string& ending) { if (ending.size() > value.size()) @@ -14,19 +23,29 @@ static bool ends_with(const std::string& value, const std::string& ending) return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } -std::unique_ptr ImageWriter::create(const SectorSet& sectors, const ImageSpec& spec) +ImageWriter::Constructor ImageWriter::findConstructor(const ImageSpec& spec) { const auto& filename = spec.filename; - if (ends_with(filename, ".img") || ends_with(filename, ".adf")) - return createImgImageWriter(sectors, spec); - else if (ends_with(filename, ".ldbs")) - return createLDBSImageWriter(sectors, spec); - else if (ends_with(filename, ".d64")) - return createD64ImageWriter(sectors, spec); + for (const auto& e : formats) + { + if (ends_with(filename, e.first)) + return e.second; + } - Error() << "unrecognised image filename extension"; - return std::unique_ptr(); + return NULL; +} + +std::unique_ptr ImageWriter::create(const SectorSet& sectors, const ImageSpec& spec) +{ + verifyImageSpec(spec); + return findConstructor(spec)(sectors, spec); +} + +void ImageWriter::verifyImageSpec(const ImageSpec& spec) +{ + if (!findConstructor(spec)) + Error() << "unrecognised image filename extension"; } ImageWriter::ImageWriter(const SectorSet& sectors, const ImageSpec& spec): diff --git a/lib/imagewriter/imagewriter.h b/lib/imagewriter/imagewriter.h index 74b416b6..d2940666 100644 --- a/lib/imagewriter/imagewriter.h +++ b/lib/imagewriter/imagewriter.h @@ -12,8 +12,17 @@ public: public: static std::unique_ptr create(const SectorSet& sectors, const ImageSpec& spec); + static void verifyImageSpec(const ImageSpec& filename); private: + typedef + std::function< + std::unique_ptr(const SectorSet& sectors, const ImageSpec& spec) + > + Constructor; + + static std::map formats; + static std::unique_ptr createImgImageWriter( const SectorSet& sectors, const ImageSpec& spec); static std::unique_ptr createLDBSImageWriter( @@ -21,6 +30,8 @@ private: static std::unique_ptr createD64ImageWriter( const SectorSet& sectors, const ImageSpec& spec); + static Constructor findConstructor(const ImageSpec& spec); + public: virtual void adjustGeometry(); void printMap(); diff --git a/lib/reader.cc b/lib/reader.cc index 86bccba6..ffc61695 100644 --- a/lib/reader.cc +++ b/lib/reader.cc @@ -14,6 +14,7 @@ #include "bytes.h" #include "decoders/rawbits.h" #include "track.h" +#include "imagewriter/imagewriter.h" #include "fmt/format.h" FlagGroup readerFlags { &hardwareFluxSourceFlags, &fluxmapReaderFlags }; @@ -153,7 +154,8 @@ static void replace_sector(std::unique_ptr& replacing, Sector& replaceme void readDiskCommand(AbstractDecoder& decoder) { const ImageSpec outputSpec(output); - + ImageWriter::verifyImageSpec(outputSpec); + bool failures = false; SectorSet allSectors; auto tracks = readTracks();