1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-09 15:39:08 +00:00

Eliminate use of std::shared_ptr at DiskImage and below.

This commit is contained in:
Thomas Harte 2024-12-08 21:26:03 -05:00
parent aecd7f9283
commit 657960e7d0
38 changed files with 114 additions and 100 deletions

View File

@ -50,12 +50,12 @@ public:
@returns the @c Track at @c position underneath @c head if there are any detectable events there;
returns @c nullptr otherwise.
*/
virtual std::shared_ptr<Track> get_track_at_position(Track::Address address) = 0;
virtual std::unique_ptr<Track> track_at_position(Track::Address address) = 0;
/*!
Replaces the Tracks indicated by the map, that maps from physical address to track content.
*/
virtual void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &) {}
virtual void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &) {}
/*!
Communicates that it is likely to be a while before any more tracks are written.
@ -72,6 +72,12 @@ public:
This can avoid some degree of work when disk images offer sub-head-position precision.
*/
virtual bool tracks_differ(Track::Address lhs, Track::Address rhs) { return lhs != rhs; }
/*!
Maps from an address to its canonical form; this provides a means for images that duplicate the same
track at different addresses to declare as much.
*/
virtual Track::Address canonical_address(Track::Address address) { return address; }
};
class DiskImageHolderBase: public Disk {

View File

@ -22,10 +22,10 @@ template <typename T> void DiskImageHolder<T>::flush_tracks() {
if(!unwritten_tracks_.empty()) {
if(!update_queue_) update_queue_ = std::make_unique<Concurrency::AsyncTaskQueue<true>>();
using TrackMap = std::map<Track::Address, std::shared_ptr<Track>>;
std::shared_ptr<TrackMap> track_copies(new TrackMap);
using TrackMap = std::map<Track::Address, std::unique_ptr<Track>>;
auto track_copies = std::make_shared<TrackMap>();
for(const auto &address : unwritten_tracks_) {
track_copies->insert({address, std::shared_ptr<Track>(cached_tracks_[address]->clone())});
track_copies->insert({address, std::unique_ptr<Track>(cached_tracks_[address]->clone())});
}
unwritten_tracks_.clear();
@ -46,12 +46,13 @@ template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_po
if(address.head >= get_head_count()) return nullptr;
if(address.position >= get_maximum_head_position()) return nullptr;
auto cached_track = cached_tracks_.find(address);
const auto canonical_address = disk_image_.canonical_address(address);
auto cached_track = cached_tracks_.find(canonical_address);
if(cached_track != cached_tracks_.end()) return cached_track->second;
std::shared_ptr<Track> track = disk_image_.get_track_at_position(address);
std::shared_ptr<Track> track = disk_image_.track_at_position(canonical_address);
if(!track) return nullptr;
cached_tracks_[address] = track;
cached_tracks_[canonical_address] = track;
return track;
}

View File

@ -124,7 +124,7 @@ int AmigaADF::get_head_count() {
return 2;
}
std::shared_ptr<Track> AmigaADF::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> AmigaADF::track_at_position(Track::Address address) {
using namespace Storage::Encodings;
// Create an MFM encoder.
@ -179,7 +179,7 @@ std::shared_ptr<Track> AmigaADF::get_track_at_position(Track::Address address) {
encoder->add_byte(0xff);
}
return std::make_shared<Storage::Disk::PCMTrack>(std::move(encoded_segment));
return std::make_unique<Storage::Disk::PCMTrack>(std::move(encoded_segment));
}
long AmigaADF::get_file_offset_for_position(Track::Address address) {

View File

@ -31,7 +31,7 @@ public:
// implemented to satisfy @c Disk
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<Track> get_track_at_position(Track::Address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -61,7 +61,7 @@ size_t AppleDSK::logical_sector_for_physical_sector(size_t physical) {
return (physical * (is_prodos_ ? 8 : 7)) % 15;
}
std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> AppleDSK::track_at_position(Track::Address address) {
std::vector<uint8_t> track_data;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
@ -93,10 +93,10 @@ std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
const size_t offset_in_fifths = size_t(address.position.as_int() % 5);
segment.rotate_right(offset_in_fifths * segment.data.size() / 5);
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
void AppleDSK::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void AppleDSK::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
for(const auto &pair: tracks) {
// Decode the track.

View File

@ -31,8 +31,8 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
std::shared_ptr<Track> get_track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &) final;
bool get_is_read_only() final;
private:

View File

@ -198,7 +198,7 @@ std::size_t CPCDSK::index_for_track(::Storage::Disk::Track::Address address) {
return size_t((address.position.as_int() * head_count_) + address.head);
}
std::shared_ptr<Track> CPCDSK::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> CPCDSK::track_at_position(::Storage::Disk::Track::Address address) {
// Given that thesea are interleaved images, determine which track, chronologically, is being requested.
const std::size_t chronological_track = index_for_track(address);
@ -221,7 +221,7 @@ std::shared_ptr<Track> CPCDSK::get_track_at_position(::Storage::Disk::Track::Add
track->filler_byte);
}
void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::shared_ptr<::Storage::Disk::Track>> &tracks) {
void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::unique_ptr<::Storage::Disk::Track>> &tracks) {
// Patch changed tracks into the disk image.
for(auto &pair: tracks) {
// Assume MFM for now; with extensions DSK can contain FM tracks.

View File

@ -34,8 +34,8 @@ public:
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
bool get_is_read_only() final;
void set_tracks(const std::map<::Storage::Disk::Track::Address, std::shared_ptr<::Storage::Disk::Track>> &tracks) final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &) final;
std::unique_ptr<::Storage::Disk::Track> track_at_position(::Storage::Disk::Track::Address) final;
private:
struct Track {

View File

@ -38,7 +38,7 @@ HeadPosition D64::get_maximum_head_position() {
return HeadPosition(number_of_tracks_);
}
std::shared_ptr<Track> D64::get_track_at_position(const Track::Address address) {
std::unique_ptr<Track> D64::track_at_position(const Track::Address address) {
// Figure out where this track starts on the disk.
int offset_to_track = 0;
int tracks_to_traverse = address.position.as_int();
@ -135,5 +135,5 @@ std::shared_ptr<Track> D64::get_track_at_position(const Track::Address address)
Encodings::CommodoreGCR::encode_block(&sector_data[target_data_offset], end_of_data);
}
return std::make_shared<PCMTrack>(PCMSegment(data));
return std::make_unique<PCMTrack>(PCMSegment(data));
}

View File

@ -27,7 +27,7 @@ public:
D64(const std::string &file_name);
HeadPosition get_maximum_head_position() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -79,7 +79,7 @@ long DMK::get_file_offset_for_position(Track::Address address) {
return (address.head*head_count_ + address.position.as_int()) * track_length_ + 16;
}
std::shared_ptr<::Storage::Disk::Track> DMK::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<::Storage::Disk::Track> DMK::track_at_position(::Storage::Disk::Track::Address address) {
file_.seek(get_file_offset_for_position(address), SEEK_SET);
// Read the IDAM table.
@ -179,5 +179,5 @@ std::shared_ptr<::Storage::Disk::Track> DMK::get_track_at_position(::Storage::Di
idam_pointer++;
}
return std::make_shared<PCMTrack>(segments);
return std::make_unique<PCMTrack>(segments);
}

View File

@ -33,7 +33,7 @@ public:
int get_head_count() final;
bool get_is_read_only() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
FileHolder file_;

View File

@ -36,9 +36,7 @@ HeadPosition G64::get_maximum_head_position() {
return HeadPosition(number_of_tracks_ > 84 ? number_of_tracks_ : 84, 2);
}
std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
std::shared_ptr<Track> resulting_track;
std::unique_ptr<Track> G64::track_at_position(Track::Address address) {
// seek to this track's entry in the track table
file_.seek(long((address.position.as_half() * 4) + 0xc), SEEK_SET);
@ -93,7 +91,7 @@ std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
}
}
resulting_track = std::make_shared<PCMTrack>(std::move(segments));
return std::make_unique<PCMTrack>(std::move(segments));
} else {
PCMSegment segment(
Encodings::CommodoreGCR::length_of_a_bit_in_time_zone(unsigned(speed_zone_offset)),
@ -101,11 +99,9 @@ std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
track_contents
);
resulting_track = std::make_shared<PCMTrack>(std::move(segment));
return std::make_unique<PCMTrack>(std::move(segment));
}
// TODO: find out whether it's possible for a G64 to supply only a partial track. I don't think it is, which would make the
// above correct but supposing I'm wrong, the above would produce some incorrectly clocked tracks
return resulting_track;
// TODO: find out whether it's possible for a G64 to supply only a partial track. I don't think it is, which
// would make the above correct but supposing I'm wrong, the above would produce some incorrectly clocked tracks.
}

View File

@ -31,7 +31,7 @@ public:
// implemented to satisfy @c Disk
HeadPosition get_maximum_head_position() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
using DiskImage::get_is_read_only;
private:

View File

@ -54,7 +54,7 @@ uint16_t HFE::seek_track(Track::Address address) {
return track_length / 2; // Divide by two to give the track length for a single side.
}
std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> HFE::track_at_position(Track::Address address) {
PCMSegment segment;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
@ -96,10 +96,10 @@ std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
}
}
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
void HFE::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void HFE::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
for(auto &track : tracks) {
std::unique_lock lock_guard(file_.get_file_access_mutex());
uint16_t track_length = seek_track(track.first);

View File

@ -33,8 +33,8 @@ public:
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
bool get_is_read_only() final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -98,7 +98,7 @@ int IMD::get_head_count() {
return heads_ + 1;
}
std::shared_ptr<::Storage::Disk::Track> IMD::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> IMD::track_at_position(Track::Address address) {
auto location = track_locations_.find(address);
if(location == track_locations_.end()) {
return nullptr;

View File

@ -31,7 +31,7 @@ public:
// DiskImage interface.
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
FileHolder file_;

View File

@ -186,7 +186,7 @@ int IPF::get_head_count() {
return head_count_;
}
std::shared_ptr<Track> IPF::get_track_at_position([[maybe_unused]] Track::Address address) {
std::unique_ptr<Track> IPF::track_at_position([[maybe_unused]] Track::Address address) {
// Get the track description, if it exists, and check either that the file has contents for the track.
auto pair = tracks_.find(address);
if(pair == tracks_.end()) {
@ -313,7 +313,7 @@ std::shared_ptr<Track> IPF::get_track_at_position([[maybe_unused]] Track::Addres
++block_count;
}
return std::make_shared<Storage::Disk::PCMTrack>(segments);
return std::make_unique<Storage::Disk::PCMTrack>(segments);
}
/// @returns The correct bit length for @c block on a track of @c density.

View File

@ -38,7 +38,7 @@ public:
// implemented to satisfy @c Disk
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -21,7 +21,7 @@ void MFMSectorDump::set_geometry(int sectors_per_track, uint8_t sector_size, uin
first_sector_ = first_sector;
}
std::shared_ptr<Track> MFMSectorDump::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> MFMSectorDump::track_at_position(Track::Address address) {
if(address.head >= get_head_count()) return nullptr;
if(address.position.as_largest() >= get_maximum_head_position().as_largest()) return nullptr;
@ -44,7 +44,7 @@ std::shared_ptr<Track> MFMSectorDump::get_track_at_position(Track::Address addre
density_);
}
void MFMSectorDump::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void MFMSectorDump::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
uint8_t parsed_track[(128 << sector_size_)*sectors_per_track_];
// TODO: it would be more efficient from a file access and locking point of view to parse the sectors

View File

@ -24,8 +24,8 @@ public:
MFMSectorDump(const std::string &file_name);
bool get_is_read_only() final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
protected:
Storage::FileHolder file_;

View File

@ -75,7 +75,7 @@ MSA::MSA(const std::string &file_name) :
throw Error::InvalidFormat;
}
std::shared_ptr<::Storage::Disk::Track> MSA::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> MSA::track_at_position(Track::Address address) {
if(address.head >= sides_) return nullptr;
const auto position = address.position.as_int();

View File

@ -26,7 +26,7 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
bool get_is_read_only() final { return false; }
private:

View File

@ -171,7 +171,7 @@ bool MacintoshIMG::get_is_read_only() {
return file_.get_is_known_read_only();
}
std::shared_ptr<::Storage::Disk::Track> MacintoshIMG::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> MacintoshIMG::track_at_position(Track::Address address) {
/*
The format_ byte has the following meanings:
@ -246,13 +246,13 @@ std::shared_ptr<::Storage::Disk::Track> MacintoshIMG::get_track_at_position(::St
// TODO: it seems some tracks are skewed respective to others; investigate further.
// segment.rotate_right(3000); // Just a test, yo.
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
return nullptr;
}
void MacintoshIMG::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void MacintoshIMG::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
for(const auto &pair: tracks) {
// Determine a data rate for the track.

View File

@ -47,8 +47,8 @@ public:
int get_head_count() final;
bool get_is_read_only() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
private:
Storage::FileHolder file_;

View File

@ -54,7 +54,14 @@ long NIB::file_offset(Track::Address address) {
return long(address.position.as_int()) * track_length;
}
std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Disk::Track::Address address) {
Track::Address NIB::canonical_address(Track::Address address) {
return Track::Address(
address.head,
HeadPosition(address.position.as_int())
);
}
std::unique_ptr<Track> NIB::track_at_position(Track::Address address) {
static constexpr size_t MinimumSyncByteCount = 4;
// NIBs contain data for a fixed quantity of integer-position tracks underneath a single head only.
@ -71,9 +78,6 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
std::vector<uint8_t> track_data;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
if(cached_offset_ == offset && cached_track_) {
return cached_track_;
}
file_.seek(offset, SEEK_SET);
track_data = file_.read(track_length);
}
@ -133,12 +137,10 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
}
std::lock_guard lock_guard(file_.get_file_access_mutex());
cached_offset_ = offset;
cached_track_ = std::make_shared<PCMTrack>(segment);
return cached_track_;
return std::make_unique<PCMTrack>(segment);
}
void NIB::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void NIB::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
// Convert to a map from address to a vector of data that contains the NIB representation
@ -186,5 +188,4 @@ void NIB::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tra
file_.seek(file_offset(track.first), SEEK_SET);
file_.write(track.second);
}
cached_track_ = nullptr; // Conservative, but safe.
}

View File

@ -27,20 +27,15 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
Track::Address canonical_address(Track::Address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
bool get_is_read_only() final;
private:
FileHolder file_;
long get_file_offset_for_position(Track::Address address);
long file_offset(Track::Address address);
// Cache for the last-generated track, given that head steps on an Apple II
// occur in quarter-track increments, so there'll routinely be four gets in
// a row for the same data.
long cached_offset_ = 0;
std::shared_ptr<Storage::Disk::PCMTrack> cached_track_;
};
}

View File

@ -50,7 +50,7 @@ long OricMFMDSK::get_file_offset_for_position(Track::Address address) {
return long(seek_offset) * 6400 + 256;
}
std::shared_ptr<Track> OricMFMDSK::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> OricMFMDSK::track_at_position(Track::Address address) {
PCMSegment segment;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
@ -112,10 +112,10 @@ std::shared_ptr<Track> OricMFMDSK::get_track_at_position(Track::Address address)
}
}
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
void OricMFMDSK::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void OricMFMDSK::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
for(const auto &track : tracks) {
PCMSegment segment = Storage::Disk::track_serialisation(*track.second, Storage::Encodings::MFM::MFMBitLength);
Storage::Encodings::MFM::Shifter shifter;

View File

@ -32,8 +32,8 @@ public:
int get_head_count() final;
bool get_is_read_only() final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -182,7 +182,7 @@ public:
(void)first_sync_;
}
std::shared_ptr<PCMTrack> get_track() {
std::unique_ptr<PCMTrack> get_track() {
// If no contents are supplied, return an unformatted track.
if(sectors_.empty() && track_data_.empty()) {
return nullptr;
@ -192,11 +192,11 @@ public:
// changes and fuzzy bits in sectors only.
if(sectors_.empty()) {
PCMSegment segment;
std::unique_ptr<Storage::Encodings::MFM::Encoder> encoder = Storage::Encodings::MFM::GetMFMEncoder(segment.data);
auto encoder = Storage::Encodings::MFM::GetMFMEncoder(segment.data);
for(auto c: track_data_) {
encoder->add_byte(c);
}
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
// Otherwise, seek to encode the sectors, using the track data to
@ -377,7 +377,7 @@ public:
track_size += 16;
}
return std::make_shared<PCMTrack>(segments);
return std::make_unique<PCMTrack>(segments);
}
private:
@ -448,7 +448,7 @@ int STX::get_head_count() {
return head_count_;
}
std::shared_ptr<::Storage::Disk::Track> STX::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> STX::track_at_position(Track::Address address) {
// These images have two sides, at most.
if(address.head > 1) return nullptr;

View File

@ -30,7 +30,7 @@ public:
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
FileHolder file_;

View File

@ -18,7 +18,7 @@
using namespace Storage::Disk;
std::shared_ptr<Track> Storage::Disk::track_for_sectors(
std::unique_ptr<Track> Storage::Disk::track_for_sectors(
const uint8_t *const source,
int number_of_sectors,
uint8_t track,

View File

@ -17,7 +17,22 @@
namespace Storage::Disk {
std::shared_ptr<Track> track_for_sectors(const uint8_t *source, int number_of_sectors, uint8_t track, uint8_t side, uint8_t first_sector, uint8_t size, Storage::Encodings::MFM::Density density);
void decode_sectors(const Track &track, uint8_t *destination, uint8_t first_sector, uint8_t last_sector, uint8_t sector_size, Storage::Encodings::MFM::Density density);
std::unique_ptr<Track> track_for_sectors(
const uint8_t *source,
int number_of_sectors,
uint8_t track,
uint8_t side,
uint8_t first_sector,
uint8_t size,
Storage::Encodings::MFM::Density density
);
void decode_sectors(
const Track &track,
uint8_t *destination,
uint8_t first_sector,
uint8_t last_sector,
uint8_t sector_size,
Storage::Encodings::MFM::Density density
);
}

View File

@ -147,7 +147,7 @@ bool WOZ::tracks_differ(Track::Address lhs, Track::Address rhs) {
return offset1 != offset2;
}
std::shared_ptr<Track> WOZ::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> WOZ::track_at_position(Track::Address address) {
const long offset = file_offset(address);
if(offset == NoSuchTrack) {
return nullptr;
@ -183,10 +183,10 @@ std::shared_ptr<Track> WOZ::get_track_at_position(Track::Address address) {
}
}
return std::make_shared<PCMTrack>(PCMSegment(number_of_bits, track_contents));
return std::make_unique<PCMTrack>(PCMSegment(number_of_bits, track_contents));
}
void WOZ::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void WOZ::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
if(type_ == Type::WOZ2) return;
for(const auto &pair: tracks) {

View File

@ -26,8 +26,8 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
bool get_is_read_only() final;
bool tracks_differ(Track::Address, Track::Address) final;

View File

@ -179,7 +179,7 @@ public:
}
};
template<class T> std::shared_ptr<Storage::Disk::Track>
template<class T> std::unique_ptr<Storage::Disk::Track>
GTrackWithSectors(
const std::vector<const Sector *> &sectors,
std::size_t post_index_address_mark_bytes, uint8_t post_index_address_mark_value,
@ -300,7 +300,7 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
// Allow the amount of data written to be up to 10% more than the expected size. Which is generous.
if(segment.data.size() > max_size) segment.data.resize(max_size);
return std::make_shared<Storage::Disk::PCMTrack>(std::move(segment));
return std::make_unique<Storage::Disk::PCMTrack>(std::move(segment));
}
Encoder::Encoder(std::vector<bool> &target, std::vector<bool> *fuzzy_target) :
@ -339,7 +339,7 @@ void Encoder::add_crc(bool incorrectly) {
namespace {
template <Density density>
std::shared_ptr<Storage::Disk::Track> TTrackWithSectors(
std::unique_ptr<Storage::Disk::Track> TTrackWithSectors(
const std::vector<const Sector *> &sectors,
std::optional<std::size_t> sector_gap_length,
std::optional<uint8_t> sector_gap_filler_byte
@ -361,7 +361,7 @@ std::shared_ptr<Storage::Disk::Track> TTrackWithSectors(
}
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
Density density,
const std::vector<Sector> &sectors,
std::optional<std::size_t> sector_gap_length,
@ -375,7 +375,7 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
);
}
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
Density density,
const std::vector<const Sector *> &sectors,
std::optional<std::size_t> sector_gap_length,

View File

@ -27,13 +27,13 @@ namespace Storage::Encodings::MFM {
@param sector_gap_length If specified, sets the distance in whole bytes between each ID and its data.
@param sector_gap_filler_byte If specified, sets the value (unencoded) that is used to populate the gap between each ID and its data.
*/
std::shared_ptr<Storage::Disk::Track> TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> TrackWithSectors(
Density density,
const std::vector<Sector> &sectors,
std::optional<std::size_t> sector_gap_length = std::nullopt,
std::optional<uint8_t> sector_gap_filler_byte = std::nullopt);
std::shared_ptr<Storage::Disk::Track> TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> TrackWithSectors(
Density density,
const std::vector<const Sector *> &sectors,
std::optional<std::size_t> sector_gap_length = std::nullopt,