1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-11-25 20:18:01 +00:00

Distinguish when to include the trailing NULL.

This commit is contained in:
Thomas Harte
2025-08-28 21:53:52 -04:00
parent 91831200d6
commit 095be3072b
20 changed files with 45 additions and 39 deletions

View File

@@ -13,7 +13,7 @@
using namespace Storage::Cartridge;
PRG::PRG(const std::string &file_name) {
Storage::FileHolder file(file_name.c_str(), FileHolder::FileMode::Read);
Storage::FileHolder file(file_name.c_str(), FileMode::Read);
const auto loading_address = file.get_le<uint16_t>();
if(loading_address != 0xa000) {

View File

@@ -27,7 +27,7 @@ Disk2MG::DiskOrMassStorageDevice Disk2MG::open(const std::string &file_name) {
FileHolder file(file_name);
// Check the signature.
if(!file.check_signature("2IMG")) throw Error::InvalidFormat;
if(!file.check_signature<SignatureType::String>("2IMG")) throw Error::InvalidFormat;
// Grab the creator, potential to fix the data size momentarily.
const auto creator = file.read(4);

View File

@@ -23,10 +23,10 @@ CPCDSK::CPCDSK(const std::string &file_name) :
FileHolder file(file_name);
is_read_only_ = file.is_known_read_only();
if(!file.check_signature("MV - CPC")) {
if(!file.check_signature<SignatureType::String>("MV - CPC")) {
is_extended_ = true;
file.seek(0, Whence::SET);
if(!file.check_signature("EXTENDED"))
if(!file.check_signature<SignatureType::String>("EXTENDED"))
throw Error::InvalidFormat;
}
@@ -276,7 +276,7 @@ void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::uni
}
// Rewrite the entire disk image, in extended form.
Storage::FileHolder output(file_name_, Storage::FileHolder::FileMode::Rewrite);
Storage::FileHolder output(file_name_, Storage::FileMode::Rewrite);
output.write(reinterpret_cast<const uint8_t *>("EXTENDED CPC DSK File\r\nDisk-Info\r\n"), 34);
output.write(reinterpret_cast<const uint8_t *>("Clock Signal "), 14);
output.put(uint8_t(head_position_count_));

View File

@@ -19,7 +19,7 @@ using namespace Storage::Disk;
G64::G64(const std::string &file_name) :
file_(file_name) {
// read and check the file signature
if(!file_.check_signature("GCR-1541")) throw Error::InvalidFormat;
if(!file_.check_signature<SignatureType::String>("GCR-1541")) throw Error::InvalidFormat;
// check the version number
int version = file_.get();

View File

@@ -15,7 +15,7 @@ using namespace Storage::Disk;
HFE::HFE(const std::string &file_name) :
file_(file_name) {
if(!file_.check_signature("HXCPICFE")) throw Error::InvalidFormat;
if(!file_.check_signature<SignatureType::String>("HXCPICFE")) throw Error::InvalidFormat;
if(file_.get()) throw Error::UnknownVersion;
track_count_ = file_.get();

View File

@@ -21,7 +21,7 @@ using namespace Storage::Disk;
IMD::IMD(const std::string &file_name) : file_(file_name) {
// Check for signature.
if(!file_.check_signature("IMD")) {
if(!file_.check_signature<SignatureType::String>("IMD")) {
throw Error::InvalidFormat;
}

View File

@@ -18,7 +18,7 @@ using namespace Storage::Disk;
OricMFMDSK::OricMFMDSK(const std::string &file_name) :
file_(file_name) {
if(!file_.check_signature("MFM_DISK"))
if(!file_.check_signature<SignatureType::String>("MFM_DISK"))
throw Error::InvalidFormat;
head_count_ = file_.get_le<uint32_t>();

View File

@@ -391,7 +391,7 @@ private:
STX::STX(const std::string &file_name) : file_(file_name) {
// Require that this be a version 3 Pasti.
if(!file_.check_signature("RSY\0")) throw Error::InvalidFormat;
if(!file_.check_signature<SignatureType::Binary>("RSY")) throw Error::InvalidFormat;
if(file_.get_le<uint16_t>() != 3) throw Error::InvalidFormat;
// Skip: tool used, 2 reserved bytes.

View File

@@ -33,9 +33,9 @@ WOZ::WOZ(const std::string &file_name) :
char(0xff), 0x0a, 0x0d, 0x0a
};
const bool isWoz1 = file_.check_signature(signature1);
const bool isWoz1 = file_.check_signature<SignatureType::Binary>(signature1);
file_.seek(0, Whence::SET);
const bool isWoz2 = file_.check_signature(signature2);
const bool isWoz2 = file_.check_signature<SignatureType::Binary>(signature2);
if(!isWoz1 && !isWoz2) throw Error::InvalidFormat;
type_ = isWoz2 ? Type::WOZ2 : Type::WOZ1;

View File

@@ -25,18 +25,23 @@ enum class Whence: int {
END = SEEK_END,
};
enum class SignatureType {
String,
Binary,
};
enum class FileMode {
ReadWrite,
Read,
Rewrite
};
class FileHolder final {
public:
enum class Error {
CantOpen = -1
};
enum class FileMode {
ReadWrite,
Read,
Rewrite
};
~FileHolder();
/*!
@@ -70,7 +75,7 @@ public:
Optionally limits itself to only @c size bytes.
*/
template <typename IntT, size_t size = sizeof(IntT)>
void put_be(IntT value) {
void put_be(const IntT value) {
auto shift = size * 8;
while(shift) {
shift -= 8;
@@ -161,9 +166,10 @@ public:
@returns @c true if the bytes read match the signature; @c false otherwise.
*/
template <size_t size>
template <SignatureType type, size_t size>
bool check_signature(const char (&signature)[size]) {
constexpr auto signature_length = size - 1;
// Discard C-style trailing NULL if this is a string compare.
constexpr auto signature_length = size - (type == SignatureType::String ? 1 : 0);
std::array<uint8_t, size> stored_signature;
if(read(stored_signature) != size) {
@@ -215,7 +221,7 @@ private:
};
inline std::vector<uint8_t> contents_of(const std::string &file_name) {
FileHolder file(file_name, FileHolder::FileMode::Read);
FileHolder file(file_name, FileMode::Read);
return file.read(size_t(file.stats().st_size));
}

View File

@@ -21,7 +21,7 @@ VHD::VHD(const std::string &file_name) : file_(file_name) {
default: throw std::exception();
}
if(!file_.check_signature("conectix")) {
if(!file_.check_signature<SignatureType::String>("conectix")) {
throw std::exception();
}

View File

@@ -37,7 +37,7 @@ std::unique_ptr<Analyser::Static::Target> SZX::load(const std::string &file_name
result->state = std::unique_ptr<Reflection::Struct>(state);
// Check signature and major version number.
if(!file.check_signature("ZXST")) {
if(!file.check_signature<SignatureType::String>("ZXST")) {
return nullptr;
}
const uint8_t major_version = file.get();

View File

@@ -60,7 +60,7 @@ const auto ascii_signature = signature<0xea>;
}
CAS::CAS(const std::string &file_name) {
Storage::FileHolder file(file_name, FileHolder::FileMode::Read);
Storage::FileHolder file(file_name, FileMode::Read);
enum class Mode {
Seeking,

View File

@@ -15,11 +15,11 @@
using namespace Storage::Tape;
CSW::CSW(const std::string &file_name) {
Storage::FileHolder file(file_name, FileHolder::FileMode::Read);
Storage::FileHolder file(file_name, FileMode::Read);
if(file.stats().st_size < 0x20) throw ErrorNotCSW;
// Check signature.
if(!file.check_signature("Compressed Square Wave")) {
if(!file.check_signature<SignatureType::String>("Compressed Square Wave")) {
throw ErrorNotCSW;
}

View File

@@ -15,9 +15,9 @@ using namespace Storage::Tape;
CommodoreTAP::CommodoreTAP(const std::string &file_name) : file_name_(file_name) {
Storage::FileHolder file(file_name);
const bool is_c64 = file.check_signature("C64-TAPE-RAW");
const bool is_c64 = file.check_signature<SignatureType::String>("C64-TAPE-RAW");
file.seek(0, Whence::SET);
const bool is_c16 = file.check_signature("C16-TAPE-RAW");
const bool is_c16 = file.check_signature<SignatureType::String>("C16-TAPE-RAW");
if(!is_c64 && !is_c16) {
throw ErrorNotCommodoreTAP;
}
@@ -60,7 +60,7 @@ CommodoreTAP::Serialiser::Serialiser(
Pulse initial,
bool half_waves,
bool updated_layout) :
file_(file_name, FileHolder::FileMode::Read),
file_(file_name, FileMode::Read),
current_pulse_(initial),
half_waves_(half_waves),
updated_layout_(updated_layout)

View File

@@ -13,7 +13,7 @@
using namespace Storage::Tape;
OricTAP::OricTAP(const std::string &file_name) : file_name_(file_name) {
Storage::FileHolder file(file_name, FileHolder::FileMode::Read);
Storage::FileHolder file(file_name, FileMode::Read);
// Check for a sequence of at least three 0x16s followed by a 0x24.
while(true) {
@@ -34,7 +34,7 @@ std::unique_ptr<FormatSerialiser> OricTAP::format_serialiser() const {
return std::make_unique<Serialiser>(file_name_);
}
OricTAP::Serialiser::Serialiser(const std::string &file_name) : file_(file_name, FileHolder::FileMode::Read) {
OricTAP::Serialiser::Serialiser(const std::string &file_name) : file_(file_name, FileMode::Read) {
reset();
}

View File

@@ -22,10 +22,10 @@ Log::Logger<Log::Source::TZX> logger;
}
TZX::TZX(const std::string &file_name) : file_name_(file_name) {
Storage::FileHolder file(file_name, FileHolder::FileMode::Read);
Storage::FileHolder file(file_name, FileMode::Read);
// Check for signature followed by a 0x1a
if(!file.check_signature("ZXTape!")) throw ErrorNotTZX;
if(!file.check_signature<SignatureType::String>("ZXTape!")) throw ErrorNotTZX;
if(file.get() != 0x1a) throw ErrorNotTZX;
// Get version number
@@ -40,7 +40,7 @@ std::unique_ptr<FormatSerialiser> TZX::format_serialiser() const {
return std::make_unique<Serialiser>(file_name_);
}
TZX::Serialiser::Serialiser(const std::string &file_name) : file_(file_name, FileHolder::FileMode::Read) {
TZX::Serialiser::Serialiser(const std::string &file_name) : file_(file_name, FileMode::Read) {
reset();
}

View File

@@ -49,7 +49,7 @@
using namespace Storage::Tape;
PRG::PRG(const std::string &file_name) : file_name_(file_name) {
FileHolder file(file_name, FileHolder::FileMode::Read);
FileHolder file(file_name, FileMode::Read);
// There's really no way to validate other than that if this file is larger than 64kb,
// of if load address + length > 65536 then it's broken.
@@ -68,7 +68,7 @@ std::unique_ptr<FormatSerialiser> PRG::format_serialiser() const {
}
PRG::Serialiser::Serialiser(const std::string &file_name, uint16_t load_address, uint16_t length) :
file_(file_name, FileHolder::FileMode::Read),
file_(file_name, FileMode::Read),
load_address_(load_address),
length_(length),
timings_(false)

View File

@@ -12,7 +12,7 @@
using namespace Storage::Tape;
ZX80O81P::ZX80O81P(const std::string &file_name) {
Storage::FileHolder file(file_name, FileHolder::FileMode::Read);
Storage::FileHolder file(file_name, FileMode::Read);
// Grab file contents.
data_ = file.read(size_t(file.stats().st_size));

View File

@@ -40,7 +40,7 @@ std::unique_ptr<FormatSerialiser> ZXSpectrumTAP::format_serialiser() const {
return std::make_unique<Serialiser>(file_name_);
}
ZXSpectrumTAP::Serialiser::Serialiser(const std::string &file_name) : file_(file_name, FileHolder::FileMode::Read) {
ZXSpectrumTAP::Serialiser::Serialiser(const std::string &file_name) : file_(file_name, FileMode::Read) {
read_next_block();
}