openMSX
DiskFactory.cc
Go to the documentation of this file.
1 #include "DiskFactory.hh"
2 #include "Reactor.hh"
3 #include "File.hh"
4 #include "FileContext.hh"
5 #include "DSKDiskImage.hh"
6 #include "XSADiskImage.hh"
7 #include "DMKDiskImage.hh"
8 #include "RamDSKDiskImage.hh"
9 #include "DirAsDSK.hh"
10 #include "DiskPartition.hh"
11 #include "MSXException.hh"
12 #include <memory>
13 #include <stdexcept>
14 
15 using std::string;
16 
17 namespace openmsx {
18 
20  : reactor(reactor_)
21  , syncDirAsDSKSetting(
22  reactor.getCommandController(), "DirAsDSKmode",
23  "type of syncronisation between host directory and dir-as-dsk diskimage",
24  DirAsDSK::SYNC_FULL, EnumSetting<DirAsDSK::SyncMode>::Map{
25  {"read_only", DirAsDSK::SYNC_READONLY},
26  {"full", DirAsDSK::SYNC_FULL}})
27  , bootSectorSetting(
28  reactor.getCommandController(), "bootsector",
29  "boot sector type for dir-as-dsk",
31  {"DOS1", DirAsDSK::BOOTSECTOR_DOS1},
32  {"DOS2", DirAsDSK::BOOTSECTOR_DOS2}})
33 {
34 }
35 
36 std::unique_ptr<Disk> DiskFactory::createDisk(
37  const string& diskImage, DiskChanger& diskChanger)
38 {
39  if (diskImage == "ramdsk") {
40  return std::make_unique<RamDSKDiskImage>();
41  }
42 
43  Filename filename(diskImage, userFileContext());
44  try {
45  // First try DirAsDSK
46  return std::make_unique<DirAsDSK>(
47  diskChanger,
48  reactor.getCliComm(),
49  filename,
50  syncDirAsDSKSetting.getEnum(),
51  bootSectorSetting.getEnum());
52  } catch (MSXException&) {
53  // DirAsDSK didn't work, no problem
54  }
55  try {
56  auto file = std::make_shared<File>(filename, File::PRE_CACHE);
57  try {
58  // first try XSA
59  return std::make_unique<XSADiskImage>(filename, *file);
60  } catch (MSXException&) {
61  // XSA didn't work, still no problem
62  }
63  try {
64  // next try dmk
65  file->seek(0);
66  return std::make_unique<DMKDiskImage>(filename, file);
67  } catch (MSXException& /*e*/) {
68  // DMK didn't work, still no problem
69  }
70  // next try normal DSK
71  return std::make_unique<DSKDiskImage>(filename, std::move(file));
72 
73  } catch (MSXException& e) {
74  // File could not be opened or (very rare) something is wrong
75  // with the DSK image. Try to interpret the filename as
76  // <filename>:<partition-number>
77  // Try this last because the ':' character could be
78  // part of the filename itself. So only try this if
79  // the name could not be interpreted as a valid
80  // filename.
81  auto pos = diskImage.find_last_of(':');
82  if (pos == string::npos) {
83  // does not contain ':', throw previous exception
84  throw;
85  }
86  std::shared_ptr<SectorAccessibleDisk> wholeDisk;
87  try {
88  Filename filename2(diskImage.substr(0, pos));
89  wholeDisk = std::make_shared<DSKDiskImage>(filename2);
90  } catch (MSXException&) {
91  // If this fails we still prefer to show the
92  // previous error message, because it's most
93  // likely more descriptive.
94  throw e;
95  }
96  unsigned num;
97  try {
98  num = fast_stou(string_view(diskImage).substr(pos + 1));
99  } catch (std::invalid_argument&) {
100  // not a valid partion number, throw previous exception
101  throw e;
102  }
103  SectorAccessibleDisk& disk = *wholeDisk;
104  return std::make_unique<DiskPartition>(disk, num, std::move(wholeDisk));
105  }
106 }
107 
108 } // namespace openmsx
Contains the main loop of openMSX.
Definition: Reactor.hh:64
CommandController & getCommandController()
Definition: Reactor.cc:295
FileContext userFileContext(string_view savePath)
Definition: FileContext.cc:161
This class represents a filename.
Definition: Filename.hh:17
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
This class implements a (close approximation) of the std::string_view class.
Definition: string_view.hh:15
DiskFactory(Reactor &reactor)
Definition: DiskFactory.cc:19
CliComm & getCliComm()
Definition: Reactor.cc:285
string_view substr(string_view utf8, string_view::size_type first=0, string_view::size_type len=string_view::npos)
std::unique_ptr< Disk > createDisk(const std::string &diskImage, DiskChanger &diskChanger)
Definition: DiskFactory.cc:36
unsigned fast_stou(string_view s)
Definition: string_view.cc:145