openMSX
DirAsDSK.hh
Go to the documentation of this file.
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
13namespace openmsx {
14
15class DiskChanger;
16class CliComm;
17
18class DirAsDSK final : public SectorBasedDisk
19{
20public:
21 enum class SyncMode { READONLY, FULL };
22 enum class BootSectorType { DOS1, DOS2 };
23
24public:
25 DirAsDSK(DiskChanger& diskChanger, CliComm& cliComm,
26 const Filename& hostDir, SyncMode syncMode,
27 BootSectorType bootSectorType);
28
29 // SectorBasedDisk
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
36private:
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; // path relative to 'hostDir'
55 // The following two are used to detect changes in the host
56 // file compared to the last host->virtual-disk sync.
57 time_t mtime; // Modification time of host file at the time of
58 // the last sync.
59 size_t filesize; // Host file size, normally the same as msx
60 // filesize, except when the host file was
61 // truncated.
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 // internal helper functions
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
129private:
130 DiskChanger& diskChanger; // used to query time / report disk change
131 CliComm& cliComm; // TODO don't use CliComm to report errors/warnings
132 const std::string hostDir;
133 const SyncMode syncMode;
134
135 EmuTime lastAccess = EmuTime::zero(); // last time there was a sector read/write
136
137 // For each directory entry that has a mapped host file/directory we
138 // store the name, last modification time and size of the corresponding
139 // host file/dir.
141 MapDirs mapDirs;
142
143 // format parameters which depend on single/double sided
144 // varying root parameters
145 const unsigned nofSectors;
146 const unsigned nofSectorsPerFat;
147 // parameters that depend on these and thus also vary
148 const unsigned firstSector2ndFAT;
149 const unsigned firstDirSector;
150 const unsigned firstDataSector;
151 const unsigned maxCluster; // First cluster number that can NOT be used anymore.
152
153 // Storage for the whole virtual disk.
154 std::vector<SectorBuffer> sectors;
155};
156
157} // namespace openmsx
158
159#endif
void writeSectorImpl(size_t sector, const SectorBuffer &buf) override
Definition DirAsDSK.cc:899
bool isWriteProtectedImpl() const override
Definition DirAsDSK.cc:334
void checkCaches() override
Definition DirAsDSK.cc:349
void readSectorImpl(size_t sector, SectorBuffer &buf) override
Definition DirAsDSK.cc:368
bool hasChanged() const override
Has the content of this disk changed, by some other means than the MSX writing to the disk.
Definition DirAsDSK.cc:339
This class represents a filename.
Definition Filename.hh:20
Abstract class for disk images that only represent the logical sector information (so not the raw tra...
This file implemented 3 utility functions:
Definition Autofire.cc:11