AppleSAWS/src/diskfiles/dos33/diskfile.cxx

215 lines
5.2 KiB
C++

#include "diskfile.h"
#include <QFile>
#include <QDataStream>
#include <QFileInfo>
#include <QDebug>
#include <QDir>
#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<CatalogSector> DiskFile::getCatalogSectors()
{
// qDebug() << "### Start getCatalogSector";
QList<CatalogSector> 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<FileDescriptiveEntry> DiskFile::getAllFDEs()
{
// qDebug() << "### Start getAllFDEs";
QList<FileDescriptiveEntry> retval;
QList<CatalogSector> sectors = getCatalogSectors();
foreach (CatalogSector cs, sectors)
{
QList<FileDescriptiveEntry> 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;
}