#include "diskfile.h" #include #include #include #include #include #include "tracksectorlist.h" #include "applesoftfile.h" #include "binaryfile.h" #include "IntBasicFile.h" #include "relocatablefile.h" #include "textfile.h" DiskFile::DiskFile(QString filename) { if (!filename.isEmpty()) { read(filename); } } DiskFile::~DiskFile() { foreach (GenericFile *file, m_files) { delete file; } } bool DiskFile::read(QString filename) { m_fullImageName = filename; m_imageName = QFileInfo(filename).fileName(); if (m_imageName.toUpper().contains(".D13")) { m_sectors_per_track = 13; } else { m_sectors_per_track = 16; } QFile infile(filename); QCryptographicHash hash(QCryptographicHash::Md5); if (infile.open(QIODevice::ReadOnly)) { QByteArray contents = infile.readAll(); QDataStream qds(contents); for (int track = 0; track < 35; track++) { for (int sector = 0; sector < m_sectors_per_track; sector++) { char buffer[256]; if (qds.readRawData(buffer,256) == 256) { // qDebug() << "Track " << track << " Sector " << sector; Sector sec; sec.setTrackSector(track,sector); sec.setData(QByteArray(buffer,256)); m_contents[track][sector] = sec; } else { qDebug() << "Invalid sector read!"; return false; } } } hash.addData(contents); m_hash = hash.result(); // qDebug() << "Hash: " << m_hash; return true; } else qDebug() << "Could not open file " << filename; return false; } VTOC DiskFile::getVTOC() { return getSector(17,0).promoteToVTOC(); } QList DiskFile::getCatalogSectors() { // qDebug() << "### Start getCatalogSector"; QList retval; VTOC vtoc = getVTOC(); TSPair ts = vtoc.firstCatalogSector(); CatalogSector cs = getSector(ts).promoteToCatalogSector(); retval.append(cs); while (cs.nextCatalogSector() != TSPair(0,0)) { ts = cs.nextCatalogSector(); cs = getSector(ts).promoteToCatalogSector(); retval.append(cs); } // qDebug() << "### End getCatalogSector"; return retval; } GenericFile *DiskFile::getFile(FileDescriptiveEntry fde) { GenericFile *retval = 0; if (m_files.contains(fde)) { retval = m_files[fde]; } else { if (!fde.firstTSListSector().isValid()) { qWarning(" Not returning a file from invalid TSList!"); return nullptr; } TrackSectorList tsl = getSector(fde.firstTSListSector()).promoteToTrackSectorList(); if (!fde.firstTSListSector().isValid()) { qWarning(" Not returning a file from invalid TSList!"); return nullptr; } QByteArray data = getDataFromTrackSectorList(tsl); if (fde.fileType() == "A") { retval = new ApplesoftFile(data); } else if (fde.fileType() == "B") { retval = new BinaryFile(data); } else if (fde.fileType() == "R") { retval = new RelocatableFile(data); } else if ((fde.fileType() == "T")) { retval = new TextFile(data); } else if ((fde.fileType() == "I")) { retval = new IntBasicFile(data); } else { retval = new GenericFile(data); } m_files[fde] = retval; } if (retval) { retval->setDiskFile(this); } return retval; } QByteArray DiskFile::getDataFromTrackSectorList(TrackSectorList tsl) { QByteArray retval; foreach(TSPair pair, tsl.getDataTSPairs()) { if (pair.isValid()) { Sector sec = getSector(pair); retval.append(sec.rawData()); } else { qWarning("Not adding data from invalid TSList"); } } auto next = tsl.getNextTSList(); if (next.isValid() && next != TSPair(0,0)) { TrackSectorList nextTsl = getSector(tsl.getNextTSList()).promoteToTrackSectorList(); retval.append(getDataFromTrackSectorList(nextTsl)); } return retval; } QList DiskFile::getAllFDEs() { // qDebug() << "### Start getAllFDEs"; QList retval; QList sectors = getCatalogSectors(); foreach (CatalogSector cs, sectors) { QList fdes = cs.getFDEs(); retval.append(fdes); } // qDebug() << "### End getAllFDEs"; return retval; } QString DiskFile::getMetaDataPath() const { QString path = QString("%1.metadata/").arg(getFullDiskImageName()); QDir dir(path); dir.mkpath("."); return path; }