mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Refactor the way image extensions are handled to be generally cleaner. Add
support for validating ImageSpecs before we actually want to read/write an image, so as to allow us to check the extension *before* wasting time reading a disk. Make .d81 an alias of .img.
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
| @@ -7,6 +7,13 @@ | ||||
| #include "imagereader/imagereader.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| std::map<std::string, ImageReader::Constructor> 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> 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<ImageReader>(); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| std::unique_ptr<ImageReader> 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): | ||||
|   | ||||
| @@ -12,10 +12,21 @@ public: | ||||
|  | ||||
| public: | ||||
|     static std::unique_ptr<ImageReader> create(const ImageSpec& spec); | ||||
| 	static void verifyImageSpec(const ImageSpec& spec); | ||||
|  | ||||
| private: | ||||
| 	typedef  | ||||
| 		std::function< | ||||
| 			std::unique_ptr<ImageReader>(const ImageSpec& spec) | ||||
| 		> | ||||
| 		Constructor; | ||||
|  | ||||
| 	static std::map<std::string, Constructor> formats; | ||||
|  | ||||
|     static std::unique_ptr<ImageReader> createImgImageReader(const ImageSpec& spec); | ||||
|  | ||||
| 	static Constructor findConstructor(const ImageSpec& spec); | ||||
|  | ||||
| public: | ||||
| 	virtual SectorSet readImage() = 0; | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,15 @@ | ||||
| #include "imagewriter/imagewriter.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| std::map<std::string, ImageWriter::Constructor> 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> 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<ImageWriter>(); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| std::unique_ptr<ImageWriter> 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): | ||||
|   | ||||
| @@ -12,8 +12,17 @@ public: | ||||
|  | ||||
| public: | ||||
|     static std::unique_ptr<ImageWriter> create(const SectorSet& sectors, const ImageSpec& spec); | ||||
| 	static void verifyImageSpec(const ImageSpec& filename); | ||||
|  | ||||
| private: | ||||
| 	typedef  | ||||
| 		std::function< | ||||
| 			std::unique_ptr<ImageWriter>(const SectorSet& sectors, const ImageSpec& spec) | ||||
| 		> | ||||
| 		Constructor; | ||||
|  | ||||
| 	static std::map<std::string, Constructor> formats; | ||||
|  | ||||
|     static std::unique_ptr<ImageWriter> createImgImageWriter( | ||||
| 		const SectorSet& sectors, const ImageSpec& spec); | ||||
|     static std::unique_ptr<ImageWriter> createLDBSImageWriter( | ||||
| @@ -21,6 +30,8 @@ private: | ||||
|     static std::unique_ptr<ImageWriter> createD64ImageWriter( | ||||
| 		const SectorSet& sectors, const ImageSpec& spec); | ||||
|  | ||||
| 	static Constructor findConstructor(const ImageSpec& spec); | ||||
|  | ||||
| public: | ||||
| 	virtual void adjustGeometry(); | ||||
| 	void printMap(); | ||||
|   | ||||
| @@ -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<Sector>& replacing, Sector& replaceme | ||||
| void readDiskCommand(AbstractDecoder& decoder) | ||||
| { | ||||
| 	const ImageSpec outputSpec(output); | ||||
|  | ||||
| 	ImageWriter::verifyImageSpec(outputSpec); | ||||
|          | ||||
| 	bool failures = false; | ||||
| 	SectorSet allSectors; | ||||
| 	auto tracks = readTracks(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user