openMSX
SectorAccessibleDisk.cc
Go to the documentation of this file.
2#include "DiskImageUtils.hh"
3#include "EmptyDiskPatch.hh"
4#include "IPSPatch.hh"
5#include "DiskExceptions.hh"
6#include "sha1.hh"
7#include "xrange.hh"
8#include <memory>
9
10namespace openmsx {
11
13 : patch(std::make_unique<EmptyDiskPatch>(*this))
14{
15}
16
18
20{
21 readSectors(&buf, sector, 1);
22}
23
25 SectorBuffer* buffers, size_t startSector, size_t nbSectors)
26{
27 auto last = startSector + nbSectors - 1;
28 if (!isDummyDisk() && // in that case we want DriveEmptyException
29 (last > 1) && // allow reading sector 0 and 1 without calling
30 // getNbSectors() because this potentially calls
31 // detectGeometry() and that would cause an
32 // infinite loop
33 (getNbSectors() <= last)) {
34 throw NoSuchSectorException("No such sector");
35 }
36 try {
37 // in the end this calls readSectorsImpl()
38 patch->copyBlock(startSector * sizeof(SectorBuffer),
39 buffers[0].raw,
40 nbSectors * sizeof(SectorBuffer));
41 } catch (MSXException& e) {
42 throw DiskIOErrorException("Disk I/O error: ", e.getMessage());
43 }
44}
45
47 SectorBuffer* buffers, size_t startSector, size_t nbSectors)
48{
49 // Default implementation reads one sector at a time. But subclasses can
50 // override this method if they can do it more efficiently.
51 for (auto i : xrange(nbSectors)) {
52 readSectorImpl(startSector + i, buffers[i]);
53 }
54}
55
56void SectorAccessibleDisk::readSectorImpl(size_t /*sector*/, SectorBuffer& /*buf*/)
57{
58 // subclass should override exactly one of
59 // readSectorImpl() or readSectorsImpl()
60 assert(false);
61}
62
63void SectorAccessibleDisk::writeSector(size_t sector, const SectorBuffer& buf)
64{
65 if (isWriteProtected()) {
67 }
68 if (!isDummyDisk() && (getNbSectors() <= sector)) {
69 throw NoSuchSectorException("No such sector");
70 }
71 try {
72 writeSectorImpl(sector, buf);
73 } catch (MSXException& e) {
74 throw DiskIOErrorException("Disk I/O error: ", e.getMessage());
75 }
77}
78
80 const SectorBuffer* buffers, size_t startSector, size_t nbSectors)
81{
82 // Simply write one-at-a-time. There's no possibility (nor any need) yet
83 // to allow to optimize this
84 for (auto i : xrange(nbSectors)) {
85 writeSector(startSector + i, buffers[i]);
86 }
87}
88
89
91{
92 return getNbSectorsImpl();
93}
94
96{
97 patch = std::make_unique<IPSPatch>(std::move(patchFile), std::move(patch));
98}
99
100std::vector<Filename> SectorAccessibleDisk::getPatches() const
101{
102 return patch->getFilenames();
103}
104
106{
107 return !patch->isEmptyPatch();
108}
109
111{
112 checkCaches();
113 if (sha1cache.empty()) {
114 sha1cache = getSha1SumImpl(filePool);
115 }
116 return sha1cache;
117}
118
120{
121 try {
122 setPeekMode(true);
123 SHA1 sha1;
124
125 constexpr size_t MAX_CHUNK = 32;
126 SectorBuffer buf[MAX_CHUNK];
127 size_t total = getNbSectors();
128 size_t sector = 0;
129 while (sector < total) {
130 auto chunk = std::min(MAX_CHUNK, total - sector);
131 readSectors(buf, sector, chunk);
132 sha1.update({buf[0].raw, chunk * sizeof(SectorBuffer)});
133 sector += chunk;
134 }
135
136 setPeekMode(false);
137 return sha1.digest();
138 } catch (MSXException&) {
139 setPeekMode(false);
140 throw;
141 }
142}
143
145{
146 return forcedWriteProtect || isWriteProtectedImpl();
147}
148
150{
151 // can't be undone
152 forcedWriteProtect = true;
153}
154
156{
157 return false;
158}
159
161{
162 // nothing
163}
164
166{
167 sha1cache.clear();
168}
169
170} // namespace openmsx
This class represents a filename.
Definition: Filename.hh:18
Helper class to perform a sha1 calculation.
Definition: sha1.hh:79
Sha1Sum digest()
Get the final hash.
Definition: utils/sha1.cc:357
void update(std::span< const uint8_t > data)
Incrementally calculate the hash value.
Definition: utils/sha1.cc:314
void readSector(size_t sector, SectorBuffer &buf)
void readSectors(SectorBuffer *buffers, size_t startSector, size_t nbSectors)
Sha1Sum getSha1Sum(FilePool &filepool)
Calculate SHA1 of the content of this disk.
virtual void readSectorsImpl(SectorBuffer *buffers, size_t startSector, size_t nbSectors)
virtual Sha1Sum getSha1SumImpl(FilePool &filepool)
void writeSectors(const SectorBuffer *buffers, size_t startSector, size_t nbSectors)
std::vector< Filename > getPatches() const
void applyPatch(Filename patchFile)
void writeSector(size_t sector, const SectorBuffer &buf)
virtual void readSectorImpl(size_t sector, SectorBuffer &buf)
This class represents the result of a sha1 calculation (a 160-bit value).
Definition: sha1.hh:22
bool empty() const
Definition: utils/sha1.cc:241
constexpr double e
Definition: Math.hh:18
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:265
This file implemented 3 utility functions:
Definition: Autofire.cc:9
STL namespace.
constexpr auto xrange(T e)
Definition: xrange.hh:133