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.hh"
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(make_unique<EmptyDiskPatch>(*this))
20  , forcedWriteProtect(false)
21  , peekMode(false)
22 {
23 }
24 
26 
28 {
29  if (!isDummyDisk() && // in that case we want DriveEmptyException
30  (sector > 1) && // allow reading sector 0 and 1 without calling
31  // getNbSectors() because this potentially calls
32  // detectGeometry() and that would cause an
33  // infinite loop
34  (getNbSectors() <= sector)) {
35  throw NoSuchSectorException("No such sector");
36  }
37  try {
38  // in the end this calls readSectorImpl()
39  patch->copyBlock(sector * sizeof(buf), buf.raw, sizeof(buf));
40  } catch (MSXException& e) {
41  throw DiskIOErrorException("Disk I/O error: ", e.getMessage());
42  }
43 }
44 
45 void SectorAccessibleDisk::writeSector(size_t sector, const SectorBuffer& buf)
46 {
47  if (isWriteProtected()) {
49  }
50  if (!isDummyDisk() && (getNbSectors() <= sector)) {
51  throw NoSuchSectorException("No such sector");
52  }
53  try {
54  writeSectorImpl(sector, buf);
55  } catch (MSXException& e) {
56  throw DiskIOErrorException("Disk I/O error: ", e.getMessage());
57  }
58  flushCaches();
59 }
60 
62 {
63  return getNbSectorsImpl();
64 }
65 
67 {
68  patch = make_unique<IPSPatch>(std::move(patchFile), std::move(patch));
69 }
70 
71 std::vector<Filename> SectorAccessibleDisk::getPatches() const
72 {
73  return patch->getFilenames();
74 }
75 
77 {
78  return !patch->isEmptyPatch();
79 }
80 
82 {
83  checkCaches();
84  if (sha1cache.empty()) {
85  sha1cache = getSha1SumImpl(filePool);
86  }
87  return sha1cache;
88 }
89 
91 {
92  try {
93  setPeekMode(true);
94  SHA1 sha1;
95  for (auto i : xrange(getNbSectors())) {
96  SectorBuffer buf;
97  readSector(i, buf);
98  sha1.update(buf.raw, sizeof(buf));
99  }
100  setPeekMode(false);
101  return sha1.digest();
102  } catch (MSXException&) {
103  setPeekMode(false);
104  throw;
105  }
106 }
107 
109  SectorBuffer* buffers, size_t startSector, size_t nbSectors)
110 {
111  try {
112  for (auto i : xrange(nbSectors)) {
113  readSector(startSector + i, buffers[i]);
114  }
115  return 0;
116  } catch (MSXException&) {
117  return -1;
118  }
119 }
120 
122  const SectorBuffer* buffers, size_t startSector, size_t nbSectors)
123 {
124  try {
125  for (auto i : xrange(nbSectors)) {
126  writeSector(startSector + i, buffers[i]);
127  }
128  return 0;
129  } catch (MSXException&) {
130  return -1;
131  }
132 }
133 
135 {
136  return forcedWriteProtect || isWriteProtectedImpl();
137 }
138 
140 {
141  // can't be undone
142  forcedWriteProtect = true;
143 }
144 
146 {
147  return false;
148 }
149 
151 {
152  // nothing
153 }
154 
156 {
157  sha1cache.clear();
158 }
159 
160 } // 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:320
int readSectors(SectorBuffer *buffers, size_t startSector, size_t nbSectors)
Sha1Sum getSha1Sum(FilePool &filepool)
Calculate SHA1 of the content of this disk.
const std::string & getMessage() const
Definition: MSXException.hh:23
bool empty() const
Definition: utils/sha1.cc:243
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:357
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)
std::unique_ptr< T > make_unique()
Definition: memory.hh:27
XRange< T > xrange(T e)
Definition: xrange.hh:98
void writeSector(size_t sector, const SectorBuffer &buf)