<commit_before>//
//  CPCDSK.cpp
//  Clock Signal
//
//  Created by <NAME> on 05/08/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

#include "CPCDSK.hpp"

#include "../Encodings/MFM.hpp"

using namespace Storage::Disk;

CPCDSK::CPCDSK(const char *file_name) :
	Storage::FileHolder(file_name), is_extended_(false) {
	if(!check_signature("MV - CPC", 8)) {
		is_extended_ = true;
		fseek(file_, 0, SEEK_SET);
		if(!check_signature("EXTENDED", 8))
			throw ErrorNotCPCDSK;
	}

	// Don't really care about about the creator; skip.
	fseek(file_, 0x30, SEEK_SET);
	head_position_count_ = (unsigned int)fgetc(file_);
	head_count_ = (unsigned int)fgetc(file_);

	if(is_extended_) {
		// Skip two unused bytes and grab the track size table.
		fseek(file_, 2, SEEK_CUR);
		for(unsigned int c = 0; c < head_position_count_ * head_count_; c++) {
			track_sizes_.push_back((size_t)(fgetc(file_) << 8));
		}
	} else {
		size_of_a_track_ = fgetc16le();
	}
}

unsigned int CPCDSK::get_head_position_count() {
	return head_position_count_;
}

unsigned int CPCDSK::get_head_count() {
	return head_count_;
}

bool CPCDSK::get_is_read_only() {
	// TODO: allow writing.
	return true;
}

std::shared_ptr<Track> CPCDSK::get_uncached_track_at_position(unsigned int head, unsigned int position) {
	// Given that thesea are interleaved images, determine which track, chronologically, is being requested.
	unsigned int chronological_track = (position * head_count_) + head;

	// All DSK images reserve 0x100 bytes for their headers.
	long file_offset = 0x100;
	if(is_extended_) {
		// Tracks are a variable size in the original DSK file format; sum the lengths
		// of all tracks prior to the interesting one to get a file offset.
		unsigned int t = 0;
		while(t < chronological_track && t < track_sizes_.size()) {
			file_offset += track_sizes_[t];
			t++;
		}
	} else {
		// Tracks are a fixed size in the original DSK file format.
		file_offset += size_of_a_track_ * chronological_track;
	}

	// Find the track, and skip the unused part of track information.
	fseek(file_, file_offset + 16, SEEK_SET);

	// Grab the track information.<commit_msg>Flagged as not read-only, at least for now, to allow 8272 writing tests definitively to function.<commit_after>//
//  CPCDSK.cpp
//  Clock Signal
//
//  Created by <NAME> on 05/08/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

#include "CPCDSK.hpp"

#include "../Encodings/MFM.hpp"

using namespace Storage::Disk;

CPCDSK::CPCDSK(const char *file_name) :
	Storage::FileHolder(file_name), is_extended_(false) {
	if(!check_signature("MV - CPC", 8)) {
		is_extended_ = true;
		fseek(file_, 0, SEEK_SET);
		if(!check_signature("EXTENDED", 8))
			throw ErrorNotCPCDSK;
	}

	// Don't really care about about the creator; skip.
	fseek(file_, 0x30, SEEK_SET);
	head_position_count_ = (unsigned int)fgetc(file_);
	head_count_ = (unsigned int)fgetc(file_);

	if(is_extended_) {
		// Skip two unused bytes and grab the track size table.
		fseek(file_, 2, SEEK_CUR);
		for(unsigned int c = 0; c < head_position_count_ * head_count_; c++) {
			track_sizes_.push_back((size_t)(fgetc(file_) << 8));
		}
	} else {
		size_of_a_track_ = fgetc16le();
	}
}

unsigned int CPCDSK::get_head_position_count() {
	return head_position_count_;
}

unsigned int CPCDSK::get_head_count() {
	return head_count_;
}

bool CPCDSK::get_is_read_only() {
	// TODO: allow writing.
	return false;
}

std::shared_ptr<Track> CPCDSK::get_uncached_track_at_position(unsigned int head, unsigned int position) {
	// Given that thesea are interleaved images, determine which track, chronologically, is being requested.
	unsigned int chronological_track = (position * head_count_) + head;

	// All DSK images reserve 0x100 bytes for their headers.
	long file_offset = 0x100;
	if(is_extended_) {
		// Tracks are a variable size in the original DSK file format; sum the lengths
		// of all tracks prior to the interesting one to get a file offset.
		unsigned int t = 0;
		while(t < chronological_track && t < track_sizes_.size()) {
			file_offset += track_sizes_[t];
			t++;
		}
	} else {
		// Tracks are a fixed size in the original DSK file format.
		file_offset += size_of_a_track_ * chronological_track;
	}

	// Find the track, and skip the unused part of track information.
	fseek(file_, file_offset + 16, SEEK_SET);

	// Grab the track information.
{'fraction_non_alphanumeric': 0.11721443346357159, 'fraction_numerical': 0.016547920018386578, 'mean_word_length': 4.156398104265403, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '794287', 'n_tokens_mistral': 1651, 'n_tokens_neox': 1499, 'n_words': 438}