openMSX
SectorAccessibleDisk.cc
Go to the documentation of this file.
2 #include "EmptyDiskPatch.hh"
3 #include "IPSPatch.hh"
4 #include "DiskExceptions.hh"
5 #include "sha1.hh"
6 #include "xrange.hh"
7 #include <memory>
8 
9 namespace openmsx {
10 
11 #ifndef _MSC_VER
12 // This line is required according to the c++ standard, but because of a vc++
13 // extension, we get a link error in vc++ when we add this line. See also:
14 // http://blogs.msdn.com/b/xiangfan/archive/2010/03/03/vc-s-evil-extension-implicit-definition-of-static-constant-member.aspx
16 #endif
17 
19  : patch(std::make_unique<EmptyDiskPatch>(*this))
20 {
21 }
22 
24 
26 {
27  if (!isDummyDisk() && // in that case we want DriveEmptyException
28  (sector > 1) && // allow reading sector 0 and 1 without calling
29  // getNbSectors() because this potentially calls
30  // detectGeometry() and that would cause an
31  // infinite loop
32  (getNbSectors() <= sector)) {
33  throw NoSuchSectorException("No such sector");
34  }
35  try {
36  // in the end this calls readSectorImpl()
37  patch->copyBlock(sector * sizeof(buf), buf.raw, sizeof(buf));
38  } catch (MSXException& e) {
39  throw DiskIOErrorException("Disk I/O error: ", e.getMessage());
40  }
41 }
42 
43 void SectorAccessibleDisk::writeSector(size_t sector, const SectorBuffer& buf)
44 {
45  if (isWriteProtected()) {
47  }
48  if (!isDummyDisk() && (getNbSectors() <= sector)) {
49  throw NoSuchSectorException("No such sector");
50  }
51  try {
52  writeSectorImpl(sector, buf);
53  } catch (MSXException& e) {
54  throw DiskIOErrorException("Disk I/O error: ", e.getMessage());
55  }
56  flushCaches();
57 }
58 
60 {
61  return getNbSectorsImpl();
62 }
63 
65 {
66  patch = std::make_unique<IPSPatch>(std::move(patchFile), std::move(patch));
67 }
68 
69 std::vector<Filename> SectorAccessibleDisk::getPatches() const
70 {
71  return patch->getFilenames();
72 }
73 
75 {
76  return !patch->isEmptyPatch();
77 }
78 
80 {
81  checkCaches();
82  if (sha1cache.empty()) {
83  sha1cache = getSha1SumImpl(filePool);
84  }
85  return sha1cache;
86 }
87 
89 {
90  try {
91  setPeekMode(true);
92  SHA1 sha1;
93  for (auto i : xrange(getNbSectors())) {
94  SectorBuffer buf;
95  readSector(i, buf);
96  sha1.update(buf.raw, sizeof(buf));
97  }
98  setPeekMode(false);
99  return sha1.digest();
100  } catch (MSXException&) {
101  setPeekMode(false);
102  throw;
103  }
104 }
105 
107  SectorBuffer* buffers, size_t startSector, size_t nbSectors)
108 {
109  try {
110  for (auto i : xrange(nbSectors)) {
111  readSector(startSector + i, buffers[i]);
112  }
113  return 0;
114  } catch (MSXException&) {
115  return -1;
116  }
117 }
118 
120  const SectorBuffer* buffers, size_t startSector, size_t nbSectors)
121 {
122  try {
123  for (auto i : xrange(nbSectors)) {
124  writeSector(startSector + i, buffers[i]);
125  }
126  return 0;
127  } catch (MSXException&) {
128  return -1;
129  }
130 }
131 
133 {
134  return forcedWriteProtect || isWriteProtectedImpl();
135 }
136 
138 {
139  // can't be undone
140  forcedWriteProtect = true;
141 }
142 
144 {
145  return false;
146 }
147 
149 {
150  // nothing
151 }
152 
154 {
155  sha1cache.clear();
156 }
157 
158 } // namespace openmsx
void readSector(size_t sector, SectorBuffer &buf)
void applyPatch(Filename patchFile)
void update(const uint8_t *data, size_t len)
Incrementally calculate the hash value.
Definition: utils/sha1.cc:318
int readSectors(SectorBuffer *buffers, size_t startSector, size_t nbSectors)
const std::string & getMessage() const &
Definition: MSXException.hh:23
auto xrange(T e)
Definition: xrange.hh:170
Sha1Sum getSha1Sum(FilePool &filepool)
Calculate SHA1 of the content of this disk.
STL namespace.
bool empty() const
Definition: utils/sha1.cc:244
This class represents the result of a sha1 calculation (a 160-bit value).
Definition: sha1.hh:19
Sha1Sum digest()
Get the final hash.
Definition: utils/sha1.cc:355
This class represents a filename.
Definition: Filename.hh:17
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
Helper class to perform a sha1 calculation.
Definition: sha1.hh:78
virtual Sha1Sum getSha1SumImpl(FilePool &filepool)
std::vector< Filename > getPatches() const
int writeSectors(const SectorBuffer *buffers, size_t startSector, size_t nbSectors)
void writeSector(size_t sector, const SectorBuffer &buf)