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:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user