From 20c814a4dd90cbb4debb65c01eb9161ebac42c73 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 1 May 2021 21:10:46 -0400 Subject: [PATCH] Factors out boilerplate around full-device sector images. --- .../Clock Signal.xcodeproj/project.pbxproj | 2 + Storage/MassStorage/Formats/DAT.cpp | 33 +++--------- Storage/MassStorage/Formats/DAT.hpp | 14 +---- Storage/MassStorage/Formats/RawSectorDump.hpp | 53 +++++++++++++++++++ 4 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 Storage/MassStorage/Formats/RawSectorDump.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 2fc24652f..e32353f5f 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1524,6 +1524,7 @@ 4B9378E322A199C600973513 /* Audio.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Audio.hpp; sourceTree = ""; }; 4B95FA9C1F11893B0008E395 /* ZX8081OptionsPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZX8081OptionsPanel.swift; sourceTree = ""; }; 4B961408222760E0001A7BF2 /* Screenshot.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Screenshot.hpp; sourceTree = ""; }; + 4B96F7CB263E30B00092AEE1 /* RawSectorDump.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RawSectorDump.hpp; sourceTree = ""; }; 4B98A05C1FFAD3F600ADF63B /* CSROMFetcher.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CSROMFetcher.hpp; sourceTree = ""; }; 4B98A05D1FFAD3F600ADF63B /* CSROMFetcher.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CSROMFetcher.mm; sourceTree = ""; }; 4B98A0601FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MSXStaticAnalyserTests.mm; sourceTree = ""; }; @@ -2973,6 +2974,7 @@ 4B74CF802312FA9C00500CE8 /* HFV.cpp */, 4BE8EB6425C750B50040BC40 /* DAT.cpp */, 4BE8EB6525C750B50040BC40 /* DAT.hpp */, + 4B96F7CB263E30B00092AEE1 /* RawSectorDump.hpp */, ); path = Formats; sourceTree = ""; diff --git a/Storage/MassStorage/Formats/DAT.cpp b/Storage/MassStorage/Formats/DAT.cpp index ceb00c7ab..d5853dfd6 100644 --- a/Storage/MassStorage/Formats/DAT.cpp +++ b/Storage/MassStorage/Formats/DAT.cpp @@ -10,32 +10,13 @@ using namespace Storage::MassStorage; -DAT::DAT(const std::string &file_name) : file_(file_name) { - // Is the file a multiple of 256 bytes in size? - const auto file_size = file_.stats().st_size; - if(file_size & 255) throw std::exception(); - - // Does it contain the 'Hugo' signature? - file_.seek(0x201, SEEK_SET); - if(!file_.check_signature("Hugo")) { +DAT::DAT(const std::string &file_name) : RawSectorDump(file_name) { + // Does the third sector contain the 'Hugo' signature? + const auto sector3 = get_block(2); + if(sector3.size() != 256) { + throw std::exception(); + } + if(sector3[1] != 'H' || sector3[2] != 'u' || sector3[3] != 'g' || sector3[4] != 'o') { throw std::exception(); } } - -size_t DAT::get_block_size() { - return 256; -} - -size_t DAT::get_number_of_blocks() { - return size_t(file_.stats().st_size) / 256; -} - -std::vector DAT::get_block(size_t address) { - file_.seek(long(address * 256), SEEK_SET); - return file_.read(256); -} - -void DAT::set_block(size_t address, const std::vector &contents) { - file_.seek(long(address * 256), SEEK_SET); - file_.write(contents); -} diff --git a/Storage/MassStorage/Formats/DAT.hpp b/Storage/MassStorage/Formats/DAT.hpp index 7ec0350e4..a47a537c5 100644 --- a/Storage/MassStorage/Formats/DAT.hpp +++ b/Storage/MassStorage/Formats/DAT.hpp @@ -9,8 +9,7 @@ #ifndef MassStorage_DAT_hpp #define MassStorage_DAT_hpp -#include "../MassStorageDevice.hpp" -#include "../../FileHolder.hpp" +#include "RawSectorDump.hpp" namespace Storage { namespace MassStorage { @@ -20,18 +19,9 @@ namespace MassStorage { sector dump of an ADFS volume. It will be validated for an ADFS catalogue and communicate in 256-byte blocks. */ -class DAT: public MassStorageDevice { +class DAT: public RawSectorDump<256> { public: DAT(const std::string &file_name); - - private: - FileHolder file_; - - /* MassStorageDevices overrides. */ - size_t get_block_size() final; - size_t get_number_of_blocks() final; - std::vector get_block(size_t address) final; - void set_block(size_t address, const std::vector &) final; }; } diff --git a/Storage/MassStorage/Formats/RawSectorDump.hpp b/Storage/MassStorage/Formats/RawSectorDump.hpp new file mode 100644 index 000000000..b75340459 --- /dev/null +++ b/Storage/MassStorage/Formats/RawSectorDump.hpp @@ -0,0 +1,53 @@ +// +// RawSectorDump.hpp +// Clock Signal +// +// Created by Thomas Harte on 01/05/2021. +// Copyright © 2021 Thomas Harte. All rights reserved. +// + +#ifndef RawSectorDump_h +#define RawSectorDump_h + +#include "../MassStorageDevice.hpp" +#include "../../FileHolder.hpp" + +namespace Storage { +namespace MassStorage { + +template class RawSectorDump: public MassStorageDevice { + public: + RawSectorDump(const std::string &file_name) : file_(file_name) { + // Is the file a multiple of sector_size bytes in size? + const auto file_size = size_t(file_.stats().st_size); + if(file_size % sector_size) throw std::exception(); + } + + /* MassStorageDevices overrides. */ + size_t get_block_size() final { + return sector_size; + } + + size_t get_number_of_blocks() final { + return size_t(file_.stats().st_size) / sector_size; + } + + std::vector get_block(size_t address) final { + file_.seek(long(address * sector_size), SEEK_SET); + return file_.read(sector_size); + } + + void set_block(size_t address, const std::vector &contents) final { + assert(contents.size() == sector_size); + file_.seek(long(address * sector_size), SEEK_SET); + file_.write(contents); + } + + private: + FileHolder file_; +}; + +} +} + +#endif /* RawSectorDump_h */