openMSX
DirAsDSK.hh
Go to the documentation of this file.
1 #ifndef DIRASDSK_HH
2 #define DIRASDSK_HH
3 
4 #include "SectorBasedDisk.hh"
5 #include "DiskImageUtils.hh"
6 #include "FileOperations.hh"
7 #include "EmuTime.hh"
8 #include "hash_map.hh"
9 #include <utility>
10 
11 namespace openmsx {
12 
13 class DiskChanger;
14 class CliComm;
15 
16 class DirAsDSK final : public SectorBasedDisk
17 {
18 public:
21 
22 public:
23  DirAsDSK(DiskChanger& diskChanger, CliComm& cliComm,
24  const Filename& hostDir, SyncMode syncMode,
25  BootSectorType bootSectorType);
26 
27  // SectorBasedDisk
28  void readSectorImpl (size_t sector, SectorBuffer& buf) override;
29  void writeSectorImpl(size_t sector, const SectorBuffer& buf) override;
30  [[nodiscard]] bool isWriteProtectedImpl() const override;
31  void checkCaches() override;
32 
33 private:
34  struct DirIndex {
35  DirIndex() = default;
36  DirIndex(unsigned sector_, unsigned idx_)
37  : sector(sector_), idx(idx_) {}
38  friend bool operator==(const DirIndex& x, const DirIndex& y) {
39  return (x.sector == y.sector) &&
40  (x.idx == y.idx);
41  }
42  unsigned sector;
43  unsigned idx;
44  };
45  struct HashDirIndex {
46  auto operator()(const DirIndex& d) const {
47  std::hash<unsigned> subHasher;
48  return 31 * subHasher(d.sector)
49  + subHasher(d.idx);
50  }
51  };
52  struct MapDir {
53  std::string hostName; // path relative to 'hostDir'
54  // The following two are used to detect changes in the host
55  // file compared to the last host->virtual-disk sync.
56  time_t mtime; // Modification time of host file at the time of
57  // the last sync.
58  size_t filesize; // Host file size, normally the same as msx
59  // filesize, except when the host file was
60  // truncated.
61  };
62 
63  [[nodiscard]] SectorBuffer* fat();
64  [[nodiscard]] SectorBuffer* fat2();
65  [[nodiscard]] MSXDirEntry& msxDir(DirIndex dirIndex);
66  void writeFATSector (unsigned sector, const SectorBuffer& buf);
67  void writeDIRSector (unsigned sector, DirIndex dirDirIndex,
68  const SectorBuffer& buf);
69  void writeDataSector(unsigned sector, const SectorBuffer& buf);
70  void writeDIREntry(DirIndex dirIndex, DirIndex dirDirIndex,
71  const MSXDirEntry& newEntry);
72  void syncWithHost();
73  void checkDeletedHostFiles();
74  void deleteMSXFile(DirIndex dirIndex);
75  void deleteMSXFilesInDir(unsigned msxDirSector);
76  void freeFATChain(unsigned cluster);
77  void addNewHostFiles(const std::string& hostSubDir, unsigned msxDirSector);
78  void addNewDirectory(const std::string& hostSubDir, const std::string& hostName,
79  unsigned msxDirSector, FileOperations::Stat& fst);
80  void addNewHostFile(const std::string& hostSubDir, const std::string& hostName,
81  unsigned msxDirSector, FileOperations::Stat& fst);
82  [[nodiscard]] DirIndex fillMSXDirEntry(
83  const std::string& hostSubDir, const std::string& hostName,
84  unsigned msxDirSector);
85  [[nodiscard]] DirIndex getFreeDirEntry(unsigned msxDirSector);
86  [[nodiscard]] DirIndex findHostFileInDSK(std::string_view hostName);
87  [[nodiscard]] bool checkFileUsedInDSK(std::string_view hostName);
88  [[nodiscard]] unsigned nextMsxDirSector(unsigned sector);
89  [[nodiscard]] bool checkMSXFileExists(const std::string& msxfilename,
90  unsigned msxDirSector);
91  void checkModifiedHostFiles();
92  void setMSXTimeStamp(DirIndex dirIndex, FileOperations::Stat& fst);
93  void importHostFile(DirIndex dirIndex, FileOperations::Stat& fst);
94  void exportToHost(DirIndex dirIndex, DirIndex dirDirIndex);
95  void exportToHostDir (DirIndex dirIndex, const std::string& hostName);
96  void exportToHostFile(DirIndex dirIndex, const std::string& hostName);
97  [[nodiscard]] unsigned findNextFreeCluster(unsigned cluster);
98  [[nodiscard]] unsigned findFirstFreeCluster();
99  [[nodiscard]] unsigned getFreeCluster();
100  [[nodiscard]] unsigned readFAT(unsigned cluster);
101  void writeFAT12(unsigned cluster, unsigned val);
102  void exportFileFromFATChange(unsigned cluster, SectorBuffer* oldFAT);
103  std::pair<unsigned, unsigned> getChainStart(unsigned cluster);
104  [[nodiscard]] bool isDirSector(unsigned sector, DirIndex& dirDirIndex);
105  bool getDirEntryForCluster(unsigned cluster,
106  DirIndex& dirIndex, DirIndex& dirDirIndex);
107  [[nodiscard]] DirIndex getDirEntryForCluster(unsigned cluster);
108  void unmapHostFiles(unsigned msxDirSector);
109  template<typename FUNC> bool scanMsxDirs(
110  FUNC func, unsigned msxDirSector);
111  friend struct NullScanner;
112  friend struct DirScanner;
113  friend struct IsDirSector;
114  friend struct DirEntryForCluster;
115  friend struct UnmapHostFiles;
116 
117  // internal helper functions
118  [[nodiscard]] unsigned readFATHelper(const SectorBuffer* fat, unsigned cluster) const;
119  void writeFATHelper(SectorBuffer* fat, unsigned cluster, unsigned val) const;
120  [[nodiscard]] unsigned clusterToSector(unsigned cluster) const;
121  [[nodiscard]] std::pair<unsigned, unsigned> sectorToClusterOffset(unsigned sector) const;
122  [[nodiscard]] unsigned sectorToCluster(unsigned sector) const;
123 
124 private:
125  DiskChanger& diskChanger; // used to query time / report disk change
126  CliComm& cliComm; // TODO don't use CliComm to report errors/warnings
127  const std::string hostDir;
128  const SyncMode syncMode;
129 
130  EmuTime lastAccess; // last time there was a sector read/write
131 
132  // For each directory entry that has a mapped host file/directory we
133  // store the name, last modification time and size of the corresponding
134  // host file/dir.
136  MapDirs mapDirs;
137 
138  // format parameters which depend on single/double sided
139  // varying root parameters
140  const unsigned nofSectors;
141  const unsigned nofSectorsPerFat;
142  // parameters that depend on these and thus also vary
143  const unsigned firstSector2ndFAT;
144  const unsigned firstDirSector;
145  const unsigned firstDataSector;
146  const unsigned maxCluster; // First cluster number that can NOT be used anymore.
147 
148  // Storage for the whole virtual disk.
149  std::vector<SectorBuffer> sectors;
150 };
151 
152 } // namespace openmsx
153 
154 #endif
openmsx::DirAsDSK::BOOTSECTOR_DOS1
@ BOOTSECTOR_DOS1
Definition: DirAsDSK.hh:20
openmsx::SectorBuffer
Definition: DiskImageUtils.hh:90
openmsx::DirEntryForCluster
Definition: DirAsDSK.cc:1098
openmsx::DirAsDSK
Definition: DirAsDSK.hh:17
openmsx::DiskChanger
Definition: DiskChanger.hh:25
openmsx::FileOperations::Stat
struct stat Stat
Definition: FileOperations.hh:235
openmsx::DirAsDSK::SyncMode
SyncMode
Definition: DirAsDSK.hh:19
openmsx::DirAsDSK::BootSectorType
BootSectorType
Definition: DirAsDSK.hh:20
openmsx::DiskChanger
DiskChanger
Definition: DiskChanger.cc:416
openmsx::NullScanner
Definition: DirAsDSK.cc:1049
SectorBasedDisk.hh
openmsx::DirAsDSK::isWriteProtectedImpl
bool isWriteProtectedImpl() const override
Definition: DirAsDSK.cc:326
openmsx::DirAsDSK::checkCaches
void checkCaches() override
Definition: DirAsDSK.cc:331
openmsx::DirAsDSK::writeSectorImpl
void writeSectorImpl(size_t sector, const SectorBuffer &buf) override
Definition: DirAsDSK.cc:882
DiskImageUtils.hh
openmsx::UnmapHostFiles
Definition: DirAsDSK.cc:1133
openmsx::DirAsDSK::DirAsDSK
DirAsDSK(DiskChanger &diskChanger, CliComm &cliComm, const Filename &hostDir, SyncMode syncMode, BootSectorType bootSectorType)
Definition: DirAsDSK.cc:259
hash_map.hh
FileOperations.hh
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1414
openmsx::IsDirSector
Definition: DirAsDSK.cc:1083
EmuTime.hh
openmsx::SectorBasedDisk
Abstract class for disk images that only represent the logical sector information (so not the raw tra...
Definition: SectorBasedDisk.hh:14
operator==
constexpr bool operator==(const uint128 &a, const uint128 &b)
Definition: uint128.hh:238
openmsx::CliComm
Definition: CliComm.hh:11
openmsx::DirAsDSK::BOOTSECTOR_DOS2
@ BOOTSECTOR_DOS2
Definition: DirAsDSK.hh:20
openmsx::DirScanner
Definition: DirAsDSK.cc:1067
openmsx::DirAsDSK::readSectorImpl
void readSectorImpl(size_t sector, SectorBuffer &buf) override
Definition: DirAsDSK.cc:350
openmsx::Filename
This class represents a filename.
Definition: Filename.hh:18
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::DirAsDSK::SYNC_READONLY
@ SYNC_READONLY
Definition: DirAsDSK.hh:19
hash_map< DirIndex, MapDir, HashDirIndex >
openmsx::DirAsDSK::SYNC_FULL
@ SYNC_FULL
Definition: DirAsDSK.hh:19