| e8555c89 Andy McCall |
1 |
#ifndef DIRASDSK_HH |
| 2 |
#define DIRASDSK_HH |
| 3 |
|
| 4 |
#include "DiskImageUtils.hh" |
| 5 |
#include "EmuTime.hh" |
| 6 |
#include "FileOperations.hh" |
| 7 |
#include "SectorBasedDisk.hh" |
| 8 |
|
| 9 |
#include "hash_map.hh" |
| 10 |
|
| 11 |
#include <utility> |
| 12 |
|
| 13 |
namespace openmsx { |
| 14 |
|
| 15 |
class DiskChanger; |
| 16 |
class CliComm; |
| 17 |
|
| 18 |
class DirAsDSK final : public SectorBasedDisk |
| 19 |
{ |
| 20 |
public: |
| 21 |
enum class SyncMode : uint8_t { READONLY, FULL }; |
| 22 |
enum class BootSectorType : uint8_t { DOS1, DOS2 }; |
| 23 |
|
| 24 |
public: |
| 25 |
DirAsDSK(DiskChanger& diskChanger, CliComm& cliComm, |
| 26 |
const Filename& hostDir, SyncMode syncMode, |
| 27 |
BootSectorType bootSectorType); |
| 28 |
|
| 29 |
|
| 30 |
void readSectorImpl (size_t sector, SectorBuffer& buf) override; |
| 31 |
void writeSectorImpl(size_t sector, const SectorBuffer& buf) override; |
| 32 |
[[nodiscard]] bool isWriteProtectedImpl() const override; |
| 33 |
[[nodiscard]] bool hasChanged() const override; |
| 34 |
void checkCaches() override; |
| 35 |
|
| 36 |
private: |
| 37 |
struct DirIndex { |
| 38 |
DirIndex() = default; |
| 39 |
DirIndex(unsigned sector_, unsigned idx_) |
| 40 |
: sector(sector_), idx(idx_) {} |
| 41 |
[[nodiscard]] constexpr bool operator==(const DirIndex&) const = default; |
| 42 |
|
| 43 |
unsigned sector; |
| 44 |
unsigned idx; |
| 45 |
}; |
| 46 |
struct HashDirIndex { |
| 47 |
auto operator()(const DirIndex& d) const { |
| 48 |
std::hash<unsigned> subHasher; |
| 49 |
return 31 * subHasher(d.sector) |
| 50 |
+ subHasher(d.idx); |
| 51 |
} |
| 52 |
}; |
| 53 |
struct MapDir { |
| 54 |
std::string hostName; |
| 55 |
|
| 56 |
|
| 57 |
time_t mtime; |
| 58 |
|
| 59 |
size_t filesize; |
| 60 |
|
| 61 |
|
| 62 |
}; |
| 63 |
|
| 64 |
[[nodiscard]] std::span<SectorBuffer> fat(); |
| 65 |
[[nodiscard]] std::span<SectorBuffer> fat2(); |
| 66 |
[[nodiscard]] MSXDirEntry& msxDir(DirIndex dirIndex); |
| 67 |
void writeFATSector (unsigned sector, const SectorBuffer& buf); |
| 68 |
void writeDIRSector (unsigned sector, DirIndex dirDirIndex, |
| 69 |
const SectorBuffer& buf); |
| 70 |
void writeDataSector(unsigned sector, const SectorBuffer& buf); |
| 71 |
void writeDIREntry(DirIndex dirIndex, DirIndex dirDirIndex, |
| 72 |
const MSXDirEntry& newEntry); |
| 73 |
void syncWithHost(); |
| 74 |
void checkDeletedHostFiles(); |
| 75 |
void deleteMSXFile(DirIndex dirIndex); |
| 76 |
void deleteMSXFilesInDir(unsigned msxDirSector); |
| 77 |
void freeFATChain(unsigned cluster); |
| 78 |
void addNewHostFiles(const std::string& hostSubDir, unsigned msxDirSector); |
| 79 |
void addNewDirectory(const std::string& hostSubDir, const std::string& hostName, |
| 80 |
unsigned msxDirSector, const FileOperations::Stat& fst); |
| 81 |
void addNewHostFile(const std::string& hostSubDir, const std::string& hostName, |
| 82 |
unsigned msxDirSector, const FileOperations::Stat& fst); |
| 83 |
[[nodiscard]] DirIndex fillMSXDirEntry( |
| 84 |
const std::string& hostSubDir, const std::string& hostName, |
| 85 |
unsigned msxDirSector); |
| 86 |
[[nodiscard]] DirIndex getFreeDirEntry(unsigned msxDirSector); |
| 87 |
[[nodiscard]] DirIndex findHostFileInDSK(std::string_view hostName) const; |
| 88 |
[[nodiscard]] bool checkFileUsedInDSK(std::string_view hostName) const; |
| 89 |
[[nodiscard]] unsigned nextMsxDirSector(unsigned sector); |
| 90 |
[[nodiscard]] bool checkMSXFileExists(std::span<const char, 11> msxfilename, |
| 91 |
unsigned msxDirSector); |
| 92 |
void checkModifiedHostFiles(); |
| 93 |
void setMSXTimeStamp(DirIndex dirIndex, const FileOperations::Stat& fst); |
| 94 |
void importHostFile(DirIndex dirIndex, const FileOperations::Stat& fst); |
| 95 |
void exportToHost(DirIndex dirIndex, DirIndex dirDirIndex); |
| 96 |
void exportToHostDir (DirIndex dirIndex, const std::string& hostName); |
| 97 |
void exportToHostFile(DirIndex dirIndex, const std::string& hostName); |
| 98 |
[[nodiscard]] unsigned findNextFreeCluster(unsigned cluster); |
| 99 |
[[nodiscard]] unsigned findFirstFreeCluster(); |
| 100 |
[[nodiscard]] unsigned getFreeCluster(); |
| 101 |
[[nodiscard]] unsigned readFAT(unsigned cluster); |
| 102 |
void writeFAT12(unsigned cluster, unsigned val); |
| 103 |
void exportFileFromFATChange(unsigned cluster, std::span<SectorBuffer> oldFAT); |
| 104 |
std::pair<unsigned, unsigned> getChainStart(unsigned cluster); |
| 105 |
[[nodiscard]] std::optional<DirIndex> isDirSector(unsigned sector); |
| 106 |
|
| 107 |
struct DirEntryForClusterResult { |
| 108 |
DirIndex dirIndex; |
| 109 |
DirIndex dirDirIndex; |
| 110 |
}; |
| 111 |
[[nodiscard]] std::optional<DirEntryForClusterResult> getDirEntryForCluster(unsigned cluster); |
| 112 |
|
| 113 |
void unmapHostFiles(unsigned msxDirSector); |
| 114 |
template<typename FUNC> bool scanMsxDirs( |
| 115 |
FUNC&& func, unsigned msxDirSector); |
| 116 |
friend struct NullScanner; |
| 117 |
friend struct DirScanner; |
| 118 |
friend struct IsDirSector; |
| 119 |
friend struct DirEntryForCluster; |
| 120 |
friend struct UnmapHostFiles; |
| 121 |
|
| 122 |
|
| 123 |
[[nodiscard]] unsigned readFATHelper(std::span<const SectorBuffer> fat, unsigned cluster) const; |
| 124 |
void writeFATHelper(std::span<SectorBuffer> fat, unsigned cluster, unsigned val) const; |
| 125 |
[[nodiscard]] unsigned clusterToSector(unsigned cluster) const; |
| 126 |
[[nodiscard]] std::pair<unsigned, unsigned> sectorToClusterOffset(unsigned sector) const; |
| 127 |
[[nodiscard]] unsigned sectorToCluster(unsigned sector) const; |
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
struct DiskFormat { |
| 132 |
uint8_t mediaDescriptor; |
| 133 |
unsigned sectorsPerCluster; |
| 134 |
unsigned sectorsPerDir; |
| 135 |
}; |
| 136 |
[[nodiscard]] static DiskFormat getDiskFormat(unsigned numTracks, bool doubleSided); |
| 137 |
|
| 138 |
private: |
| 139 |
DiskChanger& diskChanger; |
| 140 |
CliComm& cliComm; |
| 141 |
const std::string hostDir; |
| 142 |
const SyncMode syncMode; |
| 143 |
|
| 144 |
EmuTime lastAccess = EmuTime::zero(); |
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
using MapDirs = hash_map<DirIndex, MapDir, HashDirIndex>; |
| 150 |
MapDirs mapDirs; |
| 151 |
|
| 152 |
|
| 153 |
const DiskFormat diskFormat; |
| 154 |
const unsigned sectorsPerCluster; |
| 155 |
const unsigned sectorsPerDir; |
| 156 |
|
| 157 |
const unsigned nofSectors; |
| 158 |
const unsigned nofSectorsPerFat; |
| 159 |
|
| 160 |
const unsigned firstSector2ndFAT; |
| 161 |
const unsigned firstDirSector; |
| 162 |
const unsigned firstDataSector; |
| 163 |
const unsigned maxCluster; |
| 164 |
|
| 165 |
|
| 166 |
std::vector<SectorBuffer> sectors; |
| 167 |
}; |
| 168 |
|
| 169 |
} |
| 170 |
|
| 171 |
#endif |