Skip to content

Commit d4c9db7

Browse files
committed
Move disk image reading to be behind an ImgFile class
Allows different implementations for different platforms (the JS build relies on browser APIs to stream disk images over the network). Setting aside the JS build, this also reduces some code duplication.
1 parent 04956c1 commit d4c9db7

File tree

12 files changed

+186
-114
lines changed

12 files changed

+186
-114
lines changed

devices/common/ata/atahd.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2424
#include <devices/common/ata/atahd.h>
2525

2626
#include <cstring>
27-
#include <sys/stat.h>
2827
#include <fstream>
2928
#include <string>
3029
#include <loguru.hpp>
@@ -35,16 +34,11 @@ AtaHardDisk::AtaHardDisk() : AtaBaseDevice("ATA-HD", DEVICE_TYPE_ATA) {
3534
}
3635

3736
void AtaHardDisk::insert_image(std::string filename) {
38-
this->hdd_img.open(filename, std::fstream::out | std::fstream::in | std::fstream::binary);
39-
40-
struct stat stat_buf;
41-
int rc = stat(filename.c_str(), &stat_buf);
42-
if (!rc) {
43-
this->img_size = stat_buf.st_size;
44-
} else {
45-
ABORT_F("AtaHardDisk: could not determine file size using stat()");
37+
if (!this->hdd_img.open(filename)) {
38+
ABORT_F("AtaHardDisk: could not open image file");
4639
}
47-
this->hdd_img.seekg(0, std::ios_base::beg);
40+
41+
this->img_size = this->hdd_img.size();
4842
}
4943

5044
int AtaHardDisk::perform_command()
@@ -56,7 +50,6 @@ int AtaHardDisk::perform_command()
5650
case NOP:
5751
break;
5852
case RECALIBRATE:
59-
hdd_img.seekg(0, std::ios::beg);
6053
this->r_error = 0;
6154
this->r_cylinder_lo = 0;
6255
this->r_cylinder_hi = 0;
@@ -68,8 +61,7 @@ int AtaHardDisk::perform_command()
6861
uint32_t sector = (r_sect_num << 16);
6962
sector |= ((this->r_cylinder_lo) << 8) + (this->r_cylinder_hi);
7063
uint64_t offset = sector * ATA_HD_SEC_SIZE;
71-
hdd_img.seekg(offset, std::ios::beg);
72-
hdd_img.read(buffer, sec_count * ATA_HD_SEC_SIZE);
64+
hdd_img.read(buffer, offset, sec_count * ATA_HD_SEC_SIZE);
7365
this->r_status &= ~DRQ;
7466
}
7567
break;
@@ -80,8 +72,7 @@ int AtaHardDisk::perform_command()
8072
uint32_t sector = (r_sect_num << 16);
8173
sector |= ((this->r_cylinder_lo) << 8) + (this->r_cylinder_hi);
8274
uint64_t offset = sector * ATA_HD_SEC_SIZE;
83-
hdd_img.seekg(offset, std::ios::beg);
84-
hdd_img.write(buffer, sec_count * ATA_HD_SEC_SIZE);
75+
hdd_img.write(buffer, offset, sec_count * ATA_HD_SEC_SIZE);
8576
this->r_status &= ~DRQ;
8677
}
8778
break;

devices/common/ata/atahd.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2525
#define ATA_HARD_DISK_H
2626

2727
#include <devices/common/ata/atabasedevice.h>
28+
#include <utils/imgfile.h>
29+
2830
#include <string>
29-
#include <fstream>
3031

3132
#define ATA_HD_SEC_SIZE 512
3233

@@ -40,7 +41,7 @@ class AtaHardDisk : public AtaBaseDevice
4041
int perform_command() override;
4142

4243
private:
43-
std::fstream hdd_img;
44+
ImgFile hdd_img;
4445
uint64_t img_size;
4546
char * buffer = new char[1 <<17];
4647

devices/common/scsi/scsicdrom.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
3030

3131
#include <cinttypes>
3232
#include <cstring>
33-
#include <sys/stat.h>
3433

3534
using namespace std;
3635

@@ -50,25 +49,20 @@ ScsiCdrom::ScsiCdrom(int my_id) : ScsiDevice(my_id)
5049

5150
void ScsiCdrom::insert_image(std::string filename)
5251
{
53-
this->cdr_img.open(filename, ios::out | ios::in | ios::binary);
52+
if (!this->cdr_img.open(filename)) {
53+
ABORT_F("SCSI-CDROM: could not open image file");
54+
}
5455

55-
struct stat stat_buf;
56-
int rc = stat(filename.c_str(), &stat_buf);
57-
if (!rc) {
58-
this->img_size = stat_buf.st_size;
59-
this->total_frames = (this->img_size + this->sector_size - 1) / this->sector_size;
56+
this->img_size = this->cdr_img.size();
57+
this->total_frames = (this->img_size + this->sector_size - 1) / this->sector_size;
6058

61-
// create single track descriptor
62-
this->tracks[0] = {.trk_num = 1, .adr_ctrl = 0x14, .start_lba = 0};
63-
this->num_tracks = 1;
59+
// create single track descriptor
60+
this->tracks[0] = {.trk_num = 1, .adr_ctrl = 0x14, .start_lba = 0};
61+
this->num_tracks = 1;
6462

65-
// create Lead-out descriptor containing all data
66-
this->tracks[1] = {.trk_num = LEAD_OUT_TRK_NUM, .adr_ctrl = 0x14,
67-
.start_lba = static_cast<uint32_t>(this->total_frames)};
68-
} else {
69-
ABORT_F("SCSI-CDROM: could not determine file size using stat()");
70-
}
71-
this->cdr_img.seekg(0, std::ios_base::beg);
63+
// create Lead-out descriptor containing all data
64+
this->tracks[1] = {.trk_num = LEAD_OUT_TRK_NUM, .adr_ctrl = 0x14,
65+
.start_lba = static_cast<uint32_t>(this->total_frames)};
7266
}
7367

7468
void ScsiCdrom::process_command()
@@ -155,8 +149,7 @@ void ScsiCdrom::read(const uint32_t lba, const uint16_t transfer_len, const uint
155149
transfer_size *= this->sector_size;
156150
uint64_t device_offset = lba * this->sector_size;
157151

158-
this->cdr_img.seekg(device_offset, this->cdr_img.beg);
159-
this->cdr_img.read(this->data_buf, transfer_size);
152+
this->cdr_img.read(this->data_buf, device_offset, transfer_size);
160153

161154
this->bytes_out = transfer_size;
162155
this->msg_buf[0] = ScsiMessage::COMMAND_COMPLETE;

devices/common/scsi/scsicdrom.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2525
#define SCSI_CDROM_H
2626

2727
#include <devices/common/scsi/scsi.h>
28+
#include <utils/imgfile.h>
2829

2930
#include <cinttypes>
30-
#include <fstream>
3131
#include <memory>
3232
#include <string>
3333

@@ -74,7 +74,7 @@ class ScsiCdrom : public ScsiDevice {
7474
AddrMsf lba_to_msf(const int lba);
7575

7676
private:
77-
std::fstream cdr_img;
77+
ImgFile cdr_img;
7878
uint64_t img_size;
7979
int total_frames;
8080
int num_tracks;

devices/common/scsi/scsihd.cpp

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
3030

3131
#include <fstream>
3232
#include <cstring>
33-
#include <sys/stat.h>
3433

3534
#define HDD_SECTOR_SIZE 512
3635

@@ -43,17 +42,12 @@ ScsiHardDisk::ScsiHardDisk(int my_id) : ScsiDevice(my_id) {
4342
void ScsiHardDisk::insert_image(std::string filename) {
4443
//We don't want to store everything in memory, but
4544
//we want to keep the hard disk available.
46-
this->hdd_img.open(filename, ios::out | ios::in | ios::binary);
47-
48-
struct stat stat_buf;
49-
int rc = stat(filename.c_str(), &stat_buf);
50-
if (!rc) {
51-
this->img_size = stat_buf.st_size;
52-
this->total_blocks = (this->img_size + HDD_SECTOR_SIZE - 1) / HDD_SECTOR_SIZE;
53-
} else {
54-
ABORT_F("ScsiHardDisk: could not determine file size using stat()");
45+
if (!this->hdd_img.open(filename)) {
46+
ABORT_F("ScsiHardDisk: could not open image file");
5547
}
56-
this->hdd_img.seekg(0, std::ios_base::beg);
48+
49+
this->img_size = this->hdd_img.size();
50+
this->total_blocks = (this->img_size + HDD_SECTOR_SIZE - 1) / HDD_SECTOR_SIZE;
5751
}
5852

5953
void ScsiHardDisk::process_command() {
@@ -267,8 +261,7 @@ void ScsiHardDisk::read(uint32_t lba, uint16_t transfer_len, uint8_t cmd_len) {
267261
transfer_size *= HDD_SECTOR_SIZE;
268262
uint64_t device_offset = lba * HDD_SECTOR_SIZE;
269263

270-
this->hdd_img.seekg(device_offset, this->hdd_img.beg);
271-
this->hdd_img.read(img_buffer, transfer_size);
264+
this->hdd_img.read(img_buffer, device_offset, transfer_size);
272265

273266
this->cur_buf_cnt = transfer_size;
274267
this->msg_buf[0] = ScsiMessage::COMMAND_COMPLETE;
@@ -288,20 +281,17 @@ void ScsiHardDisk::write(uint32_t lba, uint16_t transfer_len, uint8_t cmd_len) {
288281

289282
this->incoming_size = transfer_size;
290283

291-
this->hdd_img.seekg(device_offset, this->hdd_img.beg);
292-
293-
this->post_xfer_action = [this]() {
294-
this->hdd_img.write(this->img_buffer, this->incoming_size);
284+
this->post_xfer_action = [this, device_offset]() {
285+
this->hdd_img.write(this->img_buffer, device_offset, this->incoming_size);
295286
};
296287
}
297288

298289
void ScsiHardDisk::seek(uint32_t lba) {
299-
uint64_t device_offset = lba * HDD_SECTOR_SIZE;
300-
this->hdd_img.seekg(device_offset, this->hdd_img.beg);
290+
// No-op
301291
}
302292

303293
void ScsiHardDisk::rewind() {
304-
this->hdd_img.seekg(0, this->hdd_img.beg);
294+
// No-op
305295
}
306296

307297
static const PropMap SCSI_HD_Properties = {

devices/common/scsi/scsihd.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2525
#define SCSI_HD_H
2626

2727
#include <devices/common/scsi/scsi.h>
28+
#include <utils/imgfile.h>
2829

2930
#include <cinttypes>
30-
#include <fstream>
3131
#include <memory>
3232
#include <string>
3333

@@ -60,7 +60,7 @@ class ScsiHardDisk : public ScsiDevice {
6060
void rewind();
6161

6262
private:
63-
std::fstream hdd_img;
63+
ImgFile hdd_img;
6464
uint64_t img_size;
6565
int total_blocks;
6666
uint64_t file_offset = 0;

0 commit comments

Comments
 (0)