1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Discovering that there is such a thing as P81 — a ZX81 file without the name omitted — added support for it. Extended FileHolder while I was here to retain the file name and be able to supply its extension, as my quick-fix test-the-last-character approach to o/p/80/81 discrimination stops working with p81 thrown into the mix and this feels like the correct factoring.

This commit is contained in:
Thomas Harte 2017-07-22 16:02:25 -04:00
parent 4dec9716c4
commit 6633537fb8
5 changed files with 38 additions and 27 deletions

View File

@ -184,6 +184,7 @@
<array>
<string>p</string>
<string>81</string>
<string>p81</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>cassette</string>

View File

@ -104,7 +104,8 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
Format("dsk", disks, Disk::OricMFMDSK, TargetPlatform::Oric) // DSK
Format("g64", disks, Disk::G64, TargetPlatform::Commodore) // G64
Format("o", tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // O
Format("p", tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // O
Format("p", tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // P
Format("p81", tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // P81
// PRG
if(!strcmp(lowercase_extension, "prg"))

View File

@ -12,26 +12,22 @@
using namespace Storage;
FileHolder::~FileHolder()
{
FileHolder::~FileHolder() {
if(file_) fclose(file_);
}
FileHolder::FileHolder(const char *file_name) : file_(nullptr)
{
stat(file_name, &file_stats_);
FileHolder::FileHolder(const std::string &file_name) : file_(nullptr), name_(file_name) {
stat(file_name.c_str(), &file_stats_);
is_read_only_ = false;
file_ = fopen(file_name, "rb+");
if(!file_)
{
file_ = fopen(file_name.c_str(), "rb+");
if(!file_) {
is_read_only_ = true;
file_ = fopen(file_name, "rb");
file_ = fopen(file_name.c_str(), "rb");
}
if(!file_) throw ErrorCantOpen;
}
bool FileHolder::check_signature(const char *signature, size_t length)
{
bool FileHolder::check_signature(const char *signature, size_t length) {
if(!length) length = strlen(signature)+1;
// read and check the file signature
@ -41,8 +37,7 @@ bool FileHolder::check_signature(const char *signature, size_t length)
return true;
}
uint32_t FileHolder::fgetc32le()
{
uint32_t FileHolder::fgetc32le() {
uint32_t result = (uint32_t)fgetc(file_);
result |= (uint32_t)(fgetc(file_) << 8);
result |= (uint32_t)(fgetc(file_) << 16);
@ -51,8 +46,7 @@ uint32_t FileHolder::fgetc32le()
return result;
}
uint32_t FileHolder::fgetc24le()
{
uint32_t FileHolder::fgetc24le() {
uint32_t result = (uint32_t)fgetc(file_);
result |= (uint32_t)(fgetc(file_) << 8);
result |= (uint32_t)(fgetc(file_) << 16);
@ -60,16 +54,14 @@ uint32_t FileHolder::fgetc24le()
return result;
}
uint16_t FileHolder::fgetc16le()
{
uint16_t FileHolder::fgetc16le() {
uint16_t result = (uint16_t)fgetc(file_);
result |= (uint16_t)(fgetc(file_) << 8);
return result;
}
uint32_t FileHolder::fgetc32be()
{
uint32_t FileHolder::fgetc32be() {
uint32_t result = (uint32_t)(fgetc(file_) << 24);
result |= (uint32_t)(fgetc(file_) << 16);
result |= (uint32_t)(fgetc(file_) << 8);
@ -78,16 +70,14 @@ uint32_t FileHolder::fgetc32be()
return result;
}
uint16_t FileHolder::fgetc16be()
{
uint16_t FileHolder::fgetc16be() {
uint16_t result = (uint16_t)(fgetc(file_) << 8);
result |= (uint16_t)fgetc(file_);
return result;
}
void FileHolder::ensure_file_is_at_least_length(long length)
{
void FileHolder::ensure_file_is_at_least_length(long length) {
fseek(file_, 0, SEEK_END);
long bytes_to_write = length - ftell(file_);
if(bytes_to_write > 0)
@ -98,3 +88,13 @@ void FileHolder::ensure_file_is_at_least_length(long length)
delete[] empty;
}
}
std::string FileHolder::extension() {
size_t pointer = name_.size() - 1;
while(pointer > 0 && name_[pointer] != '.') pointer--;
if(name_[pointer] == '.') pointer++;
std::string extension = name_.substr(pointer);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
return extension;
}

View File

@ -12,6 +12,7 @@
#include <sys/stat.h>
#include <cstdio>
#include <cstdint>
#include <string>
namespace Storage {
@ -24,7 +25,7 @@ class FileHolder {
virtual ~FileHolder();
protected:
FileHolder(const char *file_name);
FileHolder(const std::string &file_name);
/*!
Reads @c length bytes from the file and compares them to the first
@ -65,6 +66,12 @@ class FileHolder {
*/
uint16_t fgetc16be();
/*!
Determines and returns the file extension everything from the final character
back to the first dot. The string is converted to lowercase before being returned.
*/
std::string extension();
/*!
Ensures the file is at least @c length bytes long, appending 0s until it is
if necessary.
@ -117,6 +124,8 @@ class FileHolder {
FILE *file_;
struct stat file_stats_;
bool is_read_only_;
const std::string name_;
};
}

View File

@ -19,8 +19,8 @@ ZX80O81P::ZX80O81P(const char *file_name) :
fread(data_.data(), 1, (size_t)file_stats_.st_size, file_);
// If it's a ZX81 file, prepend a file name.
char type = (char)tolower(file_name[strlen(file_name) - 1]);
if(type == 'p' || type == '1') {
std::string type = extension();
if(type == "p" || type == "81") {
// TODO, maybe: prefix a proper file name; this is leaving the file nameless.
data_.insert(data_.begin(), 0x80);
}