New work with diskimglib now stable

This commit is contained in:
mlong 2021-03-12 12:04:58 -06:00
parent b093bf432a
commit 9e2320e051
42 changed files with 705 additions and 808 deletions

2
ads

@ -1 +1 @@
Subproject commit 13853573ea51f9f0e682f7d005ca4443398512ae
Subproject commit 6f8995cbd1b2999ba6ded903731eb4dd2a0af333

@ -1 +1 @@
Subproject commit 7c637c4e6d2e0f7e0a60676bbda1bcd4618e1234
Subproject commit 169a13206f4ff02a13cf22d3f3c2a5821a432686

View File

@ -45,7 +45,7 @@ void ApplesoftFile::processData()
}
m_length = dataWordAt(0);
QByteArray tmp = rawData().asQByteArray().mid(2);
QByteArray tmp = rawData().mid(2);
m_retokenizer->setData(tmp);
m_retokenizer->parse();

View File

@ -28,7 +28,7 @@ BinaryFile::BinaryFile(Dos33DiskImage *image, FileDescriptiveEntry &fde)
void BinaryFile::setupData()
{
QByteArray data = rawData().asQByteArray();
QByteArray data = rawData();
if (data.length() >= 4) {
QByteArray metadata = data.left(4);

View File

@ -18,7 +18,9 @@
#include "asdiskdata.h"
ASDiskData::ASDiskData()
#include <QDebug>
ASDiskData::ASDiskData(QObject *parent) : QObject(parent)
{
}
@ -28,39 +30,63 @@ ASDiskData::~ASDiskData()
}
void ASDiskData::setUseSectors(int numSectors, int numTracks)
void ASDiskData::setUseSectors(int numTracks, int numSectors)
{
m_numsectors = numSectors;
m_numtracks = numTracks;
m_dataformat = DataFormat::Sectors;
m_chunk_data.resize(m_numsectors * m_numtracks * 256); // Todo: magic number
}
void ASDiskData::setUseBlocks(int numBlocks)
{
m_numblocks = numBlocks;
m_dataformat = DataFormat::Blocks;
m_chunk_data.resize(m_numblocks * 512);// Todo: magic number
}
void ASDiskData::addSector(int track, int sector, QByteArray sectordata)
{
if (sectordata.length() != 256 || track >= m_numtracks || sector >= m_numsectors
|| track < 0 || sector < 0)
{
qWarning("Invalid data in addSector.");
return;
}
auto offset = tsToOffset(track,sector);
m_chunks[offset] = sectordata;
m_chunk_data.replace(offset*256,256,sectordata);
}
void ASDiskData::addBlock(int number, QByteArray blockdata)
{
m_chunks[number] = blockdata;
if (blockdata.length() != 512 || number >= m_numblocks || number < 0)
{
qWarning("Invalid data in addBlock.");
return;
};
m_chunk_data.replace(number*512,512,blockdata);
}
ASDiskData::SectorData &ASDiskData::getSector(int track, int sector)
QByteArray ASDiskData::getSector(int track, int sector) const
{
auto offset = tsToOffset(track,sector);
return m_chunks[offset];
if (offset >= m_chunk_data.size() / 256)
{
qWarning("Sector %d,%d out of bounds! Returning null data!",track,sector);
return QByteArray();
}
return m_chunk_data.mid(offset*256,256);
}
ASDiskData::BlockData &ASDiskData::getBlock(int blocknum)
QByteArray ASDiskData::getBlock(int blocknum) const
{
return m_chunks[blocknum];
if (blocknum >= m_chunk_data.size() / 256)
{
qWarning("Block %d out of bounds! Returning null data!",blocknum);
return QByteArray();
}
return m_chunk_data.mid(blocknum*512,512);
}
int ASDiskData::numTracks() const
@ -119,8 +145,8 @@ QDataStream &ASDiskData::read(QDataStream &dataStream)
dataStream >> m_fsname;
m_metadata.clear();
dataStream >> m_metadata;
m_chunks.clear();
dataStream >> m_chunks;
m_chunk_data.clear();
dataStream >> m_chunk_data;
m_original_file_contents.clear();
dataStream >> m_original_file_contents;
}
@ -147,7 +173,7 @@ QDataStream &ASDiskData::write(QDataStream &dataStream) const
dataStream << m_fstype;
dataStream << m_fsname;
dataStream << m_metadata;
dataStream << m_chunks;
dataStream << m_chunk_data;
dataStream << m_original_file_contents;
return dataStream;
@ -159,9 +185,11 @@ void ASDiskData::setFSInfo(QString name, int fstypeval)
m_fstype = fstypeval;
}
int ASDiskData::tsToOffset(int track, int sector)
int ASDiskData::tsToOffset(int track, int sector) const
{
return (track * m_numsectors) + sector;
int val = (track * m_numsectors) + sector;
//qDebug() << "TsToOffset: " << track << "," << sector << " = " << val;
return val;
}
QDataStream &operator<<(QDataStream &out, const ASDiskData &outObject)

View File

@ -20,32 +20,33 @@
#define ASDISKDATA_H
#include <QString>
#include <QMap>
#include <QVector>
#include <QVariant>
#include <QDataStream>
class ASDiskData
class ASDiskData : public QObject
{
Q_OBJECT
using AttributeMap = QMap<QString, QVariant>;
using ChunkData = QByteArray;
using DataMap = QMap<int,ChunkData>;
public:
using SectorData = QByteArray;
using BlockData = QByteArray;
// using SectorData = QByteArray;
// using BlockData = QByteArray;
enum class DataFormat { Sectors, Blocks };
ASDiskData();
ASDiskData(QObject *parent = nullptr);
virtual ~ASDiskData();
QStringList attributeList() const { return m_metadata.keys(); }
QVariant getAttribute(QString key) const;
bool setAttribute(QString key, QVariant value);
void setUseSectors(int numSectors = 16, int numTracks = 35);
void setUseSectors(int numTracks = 35, int numSectors = 16);
void setUseBlocks(int numBlocks);
void setDataFormat(DataFormat format) { m_dataformat = format; }
bool useSectors() const { return m_dataformat == DataFormat::Sectors; }
bool useBlocks() const { return m_dataformat == DataFormat::Blocks; }
@ -54,8 +55,8 @@ public:
void addSector(int track, int sector, QByteArray sectordata);
void addBlock(int number, QByteArray blockdata);
SectorData &getSector(int track, int sector);
BlockData &getBlock(int blocknum);
QByteArray getSector(int track, int sector) const;
QByteArray getBlock(int blocknum) const;
int numTracks() const;
int numSectorsPerTrack() const;
@ -84,7 +85,7 @@ public:
QDataStream &write(QDataStream &dataStream) const;
protected:
int tsToOffset(int track, int sector);
int tsToOffset(int track, int sector) const;
protected:
QString m_filename { "[unknown]" };
@ -102,9 +103,11 @@ protected:
AttributeMap m_metadata;
DataMap m_chunks;
QByteArray m_chunk_data;
QByteArray m_original_file_contents;
QByteArray m_nulldata;
};
QDataStream &operator<<(QDataStream &out, const ASDiskData &outData);

View File

@ -62,9 +62,11 @@ bool ASDiskImporter::importImage(QString filename, ASDiskData &into)
int numsectors = image.GetNumSectPerTrack();\
into.setNumSectorsPerTrack(numsectors);
if (image.ShowAsBlocks())
{
into.setDataFormat(ASDiskData::DataFormat::Blocks);
into.setUseBlocks(numblocks);
char *buffer = new char[512]; // Todo: Remove magic number
for (int idx = 0; idx < numblocks; idx++)
@ -77,7 +79,7 @@ bool ASDiskImporter::importImage(QString filename, ASDiskData &into)
}
else
{
into.setDataFormat(ASDiskData::DataFormat::Sectors);
into.setUseSectors(numtracks,numsectors);
char *buffer = new char[256]; // Todo: Remove magic number
for (int track = 0; track < numtracks; track++)

View File

@ -19,7 +19,7 @@
#include "catalogsector.h"
#include "sector.h"
CatalogSector::CatalogSector(Sector *data)
CatalogSector::CatalogSector(QSharedPointer<const Sector> data)
{
m_data = data;
@ -42,13 +42,13 @@ CatalogSector::CatalogSector(Sector *data)
{
FileDescriptiveEntry fde = makeFDE(idx*0x23+0x0B);
if (fde.firstTSListSector() != TSPair(0,0)) {
// if (fde.firstTSListSector().isValid())
if (fde.firstTSListSector().isValid())
{
m_fdes.append(fde);
}
// else qDebug() << "Not appending invalid TSPair.";
else qDebug() << "Not appending invalid TSPair.";
}
// else { qWarning("fde.firstTSListSector() is 0,0"); }
// else { qWarning("fde.firstTSListSector() is 0,0"); }
}
}

View File

@ -33,11 +33,10 @@
class Sector;
class CatalogSector
{
public:
CatalogSector(Sector *sector);
CatalogSector(QSharedPointer<const Sector> sector);
FileDescriptiveEntry getFDE(quint8 number) {
if (m_fdes.length() == 0) { return FileDescriptiveEntry(); }
@ -53,7 +52,7 @@ public:
void dumpFDEs();
Sector *getSector() const { return m_data; }
QSharedPointer<const Sector> getSector() const { return m_data; }
FileDescriptiveEntry makeFDE(int offset);
@ -61,7 +60,7 @@ public:
private:
private:
Sector *m_data;
QSharedPointer<const Sector> m_data;
QList<FileDescriptiveEntry> m_fdes;
TSPair m_next;
};

View File

@ -35,120 +35,44 @@
Dos33DiskImage::Dos33DiskImage(QString filename)
{
m_disk_image = new RawDiskImage(filename);
m_disk_image = new ASDiskData();
if (!filename.isEmpty())
{
read(filename);
//TODO: Cross reference & dbl. check sec/track with VTOC
}
auto dummy_data = new SectorData;
dummy_data->resize(256);
m_dummy_sector.setData(dummy_data);
}
Dos33DiskImage::Dos33DiskImage(RawDiskImage *rawImage)
{
m_disk_image = rawImage;
//TODO: Cross reference & dbl. check sec/track with VTOC
}
Dos33DiskImage::~Dos33DiskImage()
{
// foreach (GenericFile *file, m_files)
// {
// delete file;
// }
delete m_disk_image;
}
bool Dos33DiskImage::read(QString filename)
{
bool retval = m_disk_image->read(filename);
ASDiskImporter importer;
bool retval = importer.importImage(filename, *m_disk_image);
if (retval)
{
for (auto tracknum = 0; tracknum < m_disk_image->numTracks(); tracknum++)
{
for (auto secnum = 0; secnum < m_disk_image->sectorsPerTrack(); secnum++)
{
TSPair tmpts(tracknum,secnum);
Sector newSec;
SectorData * data = m_disk_image->sectorAt(tmpts);
newSec.setData(data);
newSec.setTrackSector(tmpts);
m_contents[tmpts] = newSec;
}
}
}
// TODO: Cache sectors!!
return retval;
// m_fullImageName = filename;
// m_imageName = QFileInfo(filename).fileName();
// QFile infile(filename);
// QCryptographicHash hash(QCryptographicHash::Md5);
// if (infile.open(QIODevice::ReadOnly))
// {
// QByteArray contents = infile.readAll();
// int expectedsize = sectorsPerTrack() * tracks() * 256;
// if (contents.size() != expectedsize)
// {
// if (contents.size() == 35*16*256) { m_sectors_per_track = 16; }
// else if (contents.size() == 35*13*256) { m_sectors_per_track = 13; }
// else qWarning() << QString("Size mismatch in file! Expected %1, got %2")
// .arg(expectedsize)
// .arg(contents.size());
// }
// 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)
// {
// TSPair tmpts(track,sector);
// Sector newSec;
// newSec.setTrackSector(tmpts);
// newSec.setData(QByteArray(buffer,256));
// m_contents[tmpts] = newSec;
// }
// 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;
}
Sector &Dos33DiskImage::getSector(TSPair ts) {
if (m_contents.contains(ts))
return m_contents[ts];
else
return m_dummy_sector;
pSector Dos33DiskImage::getSector(TSPair ts) const {
return getSector(ts.track(),ts.sector());
}
Sector &Dos33DiskImage::getSector(int track, int sector) {
return getSector(TSPair(track,sector));
pSector Dos33DiskImage::getSector(int track, int sector) const {
auto sectorData
= m_disk_image->getSector(track,sector);
qDebug() << "Dos33DiskImage::getSector("<<track<<","<<sector<<"); [SIZE = " << sectorData.size() << "]";
auto val = QSharedPointer<Sector>(new Sector(sectorData, track, sector));
val->dump();
return val;
}
VTOC Dos33DiskImage::getVTOC()
VTOC Dos33DiskImage::getVTOC() const
{
return getSector(17,0).promoteToVTOC();
return getSector(17,0)->promoteToVTOC();
}
QList<CatalogSector> Dos33DiskImage::getCatalogSectors()
@ -156,12 +80,15 @@ QList<CatalogSector> Dos33DiskImage::getCatalogSectors()
QList<CatalogSector> retval;
VTOC vtoc = getVTOC();
TSPair ts = vtoc.firstCatalogSector();
qDebug() << "First TSPair for catalogsectors is " << ts.track() << "," << ts.sector();
CatalogSector cs = getSector(ts).asCatalogSector();
CatalogSector cs = getSector(ts)->asCatalogSector();
retval.append(cs);
while (cs.nextCatalogSector() != TSPair(0,0)) {
ts = cs.nextCatalogSector();
cs = getSector(ts).asCatalogSector();
qDebug() << "Next TSPair for catalogsectors is " << ts.track() << "," << ts.sector();
cs = getSector(ts)->asCatalogSector();
retval.append(cs);
}
@ -183,7 +110,7 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde)
return nullptr;
}
TrackSectorList tsl = getSector(fde.firstTSListSector()).asTrackSectorList();
TrackSectorList tsl = getSector(fde.firstTSListSector())->asTrackSectorList();
if (!fde.firstTSListSector().isValid())
{
qWarning(" Not returning a file from invalid TSList!");
@ -224,17 +151,17 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde)
}
ChunkByteList Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
{
ChunkByteList retval;
QByteArray retval;
foreach(TSPair pair, tsl.getDataTSPairs())
{
if (pair.isValid())
{
Sector sec = getSector(pair);
retval.appendChunk(sec.rawData());
pSector sec = getSector(pair);
retval.append(sec->rawData());
}
else
{
@ -244,22 +171,22 @@ ChunkByteList Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
auto next = tsl.getNextTSList();
if (next.isValid() && next != TSPair(0,0)) {
TrackSectorList nextTsl = getSector(tsl.getNextTSList()).asTrackSectorList();
retval.appendChunkList(getDataFromTrackSectorList(nextTsl));
TrackSectorList nextTsl = getSector(tsl.getNextTSList())->asTrackSectorList();
retval.append(getDataFromTrackSectorList(nextTsl));
}
return retval;
}
ChunkByteList Dos33DiskImage::getDataFromTSPairList(TSPairList list)
QByteArray Dos33DiskImage::getDataFromTSPairList(TSPairList list)
{
ChunkByteList retval;
QByteArray retval;
foreach(TSPair pair, list)
{
if (pair.isValid())
{
Sector sec = getSector(pair);
retval.appendChunk(sec.rawData());
pSector sec = getSector(pair);
retval.append(sec->rawData());
}
else
{

View File

@ -32,9 +32,11 @@
#include "vtoc.h"
#include "tracksectorlist.h"
#include "rawdiskimage.h"
#include "chunkbytelist.h"
#include "asdiskimporter.h"
#include "asdiskdata.h"
class GenericFile;
@ -44,48 +46,43 @@ class Dos33DiskImage
{
public:
Dos33DiskImage(QString filename = "");
Dos33DiskImage(RawDiskImage *rawImage);
~Dos33DiskImage();
bool read(QString filename);
Sector &getSector(TSPair ts);
Sector &getSector(int track, int sector);
pSector getSector(TSPair ts) const;
pSector getSector(int track, int sector) const;
VTOC getVTOC();
VTOC getVTOC() const;
QList<CatalogSector> getCatalogSectors();
GenericFile *getFile(FileDescriptiveEntry fde);
ChunkByteList getDataFromTrackSectorList(TrackSectorList tsl);
ChunkByteList getDataFromTSPairList(TSPairList list);
QByteArray getDataFromTrackSectorList(TrackSectorList tsl);
QByteArray getDataFromTSPairList(TSPairList list);
QList<FileDescriptiveEntry> getAllFDEs();
QByteArray fileHash() const { return m_hash; }
QString getDiskImageName() const { return m_disk_image->diskImageName(); }
QString getFullDiskImageName() const { return m_disk_image->fullDiskImageName(); }
QString getDiskImageName() const { return m_disk_image->filename(); }
QString getFullDiskImageName() const { return m_disk_image->/*fullDiskImageName*/filename(); }
QString getMetaDataPath() const;
RawDiskImage *rawImage() const { return m_disk_image; }
ASDiskData *rawImage() const { return m_disk_image; }
int sectorsPerTrack() const { return m_disk_image->sectorsPerTrack(); }
int sectorsPerTrack() const { return m_disk_image->numSectorsPerTrack(); }
int tracks() const { return m_disk_image->numTracks(); }
QList<GenericFile *> fileList();
private:
RawDiskImage *m_disk_image;
ASDiskData *m_disk_image;
QMap<TSPair, Sector> m_contents;
QMap<FileDescriptiveEntry, GenericFile *> m_files;
QByteArray m_hash;
Sector m_dummy_sector; // Returned for non-existant sectors on disk
};
#endif // DOS33DISKIMAGE_H

View File

@ -34,7 +34,6 @@ public:
protected:
signals:
void fileClicked(const FileDescriptiveEntry &fde);
void fileRightClicked(const FileDescriptiveEntry &fde);
@ -45,14 +44,11 @@ signals:
void sectorRightClicked(TSPair ts);
void sectorDoubleClicked(TSPair ts);
private slots:
void handleClick(const QModelIndex &index);
void handleDoubleClick(const QModelIndex &index);
void handlePress(const QModelIndex &index);
};
#endif // DOS33DISKTREEVIEW_H

View File

@ -19,8 +19,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include "dos33treeitem.h"
#include "dos33diskimage.h"
@ -42,7 +40,6 @@ enum class Dos33ItemType {
DiskImage
};
class Dos33ImageModel : public QStandardItemModel
{
Q_OBJECT
@ -57,8 +54,6 @@ public:
Dos33DiskImage *getDiskImage(QString name);
Dos33DiskImage *removeDiskImage(QString name);
private:
QIcon m_icon_A;
QIcon m_icon_a;

View File

@ -19,8 +19,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include <QStandardItem>
class Dos33TreeItem : public QStandardItem

View File

@ -51,7 +51,7 @@ QByteArray GenericFile::data()
{
if (m_data_cache.size() == 0)
{
m_data_cache = rawData().asQByteArray();
m_data_cache = rawData();
}
}
else
@ -72,7 +72,7 @@ void GenericFile::resetToDefaultData()
}
ChunkByteList &GenericFile::rawData()
QByteArray GenericFile::rawData()
{
if (!m_data_loaded)
{
@ -87,20 +87,13 @@ void GenericFile::updateFromFDE(FileDescriptiveEntry &fde)
setLength(fde.lengthInSectors * m_diskfile->rawImage()->sectorSize());
}
SectorData *GenericFile::peekFirstSector() const
QByteArray GenericFile::peekFirstSector() const
{
SectorData *retval = nullptr;
auto tsl = m_diskfile->getSector(m_fde.firstTSListSector())->asTrackSectorList();
TSPairList pairs = tsl.getValidTSPairs();
return m_diskfile->getSector(pairs.first())->rawData();
if (m_diskfile)
{
auto tsl = m_diskfile->getSector(m_fde.firstTSListSector()).asTrackSectorList();
TSPairList pairs = tsl.getValidTSPairs();
if (pairs.size())
{
retval = m_diskfile->getSector(pairs.first()).rawData();
}
}
return retval;
}
void GenericFile::initDataFromImage()
@ -109,7 +102,7 @@ void GenericFile::initDataFromImage()
{
if (m_diskfile)
{
auto tsl = m_diskfile->getSector(m_fde.firstTSListSector()).asTrackSectorList();
auto tsl = m_diskfile->getSector(m_fde.firstTSListSector())->asTrackSectorList();
TSPairList pairs = tsl.getValidTSPairs();
m_data_loaded = true;
m_data = m_diskfile->getDataFromTSPairList(pairs);

View File

@ -55,7 +55,7 @@ public:
virtual quint8 rawDataAt(int offset) ;
virtual quint16 rawDataWordAt(int offset);
virtual ChunkByteList &rawData();
virtual QByteArray rawData();
[[deprecated("Only used for legacy purposes")]]
@ -93,7 +93,7 @@ public:
void initDataFromImage();
protected:
SectorData *peekFirstSector() const;
QByteArray peekFirstSector() const;
private:
Dos33DiskImage * m_diskfile;
@ -106,7 +106,7 @@ private:
bool m_locked;
QString m_filename;
ChunkByteList m_data;
QByteArray m_data;
bool m_data_loaded;

View File

@ -21,18 +21,19 @@
#include <QString>
#include <QDebug>
quint8 Sector::operator[](uint offset) const {
if (offset > 255) {
offset = 255;
}
if ((int) offset >= m_raw_data->size()) return 0;
//quint8 Sector::operator[](uint offset) const {
// if (offset > 255) {
// offset = 255;
// }
// if ((int) offset >= m_raw_data.size()) return 0;
return m_raw_data->at(offset);
}
// return m_raw_data.at(offset);
//}
void Sector::dump() {
void Sector::dump() const {
qDebug() << "Dumping Track " << track() << "Sector " << sector() << " ...";
qDebug() << " RawData size: " << m_raw_data.size();
for (int jdx = 0; jdx < 16; jdx++)
{
QString line;
@ -41,8 +42,8 @@ void Sector::dump() {
for (int idx = 0; idx < 16; idx++)
{
int offset = (jdx*16) + idx;
quint8 val = m_raw_data->at(offset);
line += QString("%1 ").arg(uint16ToHex(val));
quint8 val = m_raw_data.at(offset);
line += QString("%1 ").arg(uint8ToHex(val));
if (idx == 7) line += " ";
}
line = line.toUpper();
@ -50,7 +51,7 @@ void Sector::dump() {
for (int idx = 0; idx < 16; idx++)
{
int offset = (jdx*16) + idx;
quint8 val = m_raw_data->at(offset);
quint8 val = m_raw_data.at(offset);
if (val > 127) { val -= 128; }
QChar ch(val);
line += QString("%1").arg(ch.isPrint()?ch:'.');

View File

@ -1,14 +1,3 @@
#ifndef SECTOR_H
#define SECTOR_H
#include <QByteArray>
#include "rawdiskimage.h"
#include "vtoc.h"
#include "catalogsector.h"
#include "tracksectorlist.h"
/*****************************************************************************
* AppleSAWS - The Apple Software Analysis WorkShop *
* Copyright (C) 2015-2021 Mark D. Long *
@ -27,68 +16,78 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#ifndef SECTOR_H
#define SECTOR_H
#include <QByteArray>
#include <QSharedPointer>
//#include "rawdiskimage.h"
class Sector
#include "vtoc.h"
#include "catalogsector.h"
#include "tracksectorlist.h"
#include "asdiskdata.h"
class Sector;
using pSector = QSharedPointer<Sector>;
class Sector : public QEnableSharedFromThis<Sector>
{
public:
Sector(SectorData *data = nullptr) {
setData(data);
m_track = 255;
m_sector = 255;
}
void setData(SectorData *data)
Sector(QByteArray &data, int track, int sector )
{
m_raw_data = data;
qDebug() << "Sector ctor: Datasize: " << data.size() << " t/s: " << track << "," << sector;
m_track = track;
m_sector = sector;
m_raw_data = data;
m_raw_data.append(12);
m_raw_data.chop(1);
if (m_raw_data.size() != 256)
{
qWarning() << "Setting sector with invalid sized data! [Size = " << data.size() << "]";
}
}
VTOC promoteToVTOC() {
return VTOC(this);
~Sector() { qDebug() << "Sector dtor for " << m_track << "," << m_sector; }
VTOC promoteToVTOC() const {
return VTOC(sharedFromThis());
}
CatalogSector asCatalogSector() {
return CatalogSector(this);
CatalogSector asCatalogSector() const {
return CatalogSector(sharedFromThis());
}
TrackSectorList asTrackSectorList() {
return TrackSectorList(this);
TrackSectorList asTrackSectorList() const {
return TrackSectorList(sharedFromThis());
}
int sector() { return m_sector; }
int track() { return m_track; }
int sector() const { return m_sector; }
int track() const { return m_track; }
void setTrackSector(int track, int sector) {
setTrack(track);
setSector(sector);
quint8 at(int offset) const {
if (offset >= m_raw_data.size()) {
qWarning() << "sector::at() offset = " << offset
<< ". m_raw_data.size() == " << m_raw_data.size();
}
return m_raw_data.at(offset);
}
void setTrackSector(TSPair ts)
{
setTrackSector(ts.track(),ts.sector());
}
void dump() const;
void setTrack(int track) { m_track = track; }
void setSector(int sector) { m_sector = sector; }
quint8 operator[](uint offset) const;
quint8 at(int offset) {
if (offset >= m_raw_data->size()) return 0;
return m_raw_data->at(offset);
}
void dump();
SectorData *rawData() { return m_raw_data; }
QByteArray rawData() { return m_raw_data; }
private:
// QByteArray m_data;
int m_track;
int m_sector;
SectorData *m_raw_data;
QByteArray m_raw_data;
};
#endif // SECTOR_H

View File

@ -20,7 +20,7 @@
#include "sector.h"
TrackSectorList::TrackSectorList(Sector *data)
TrackSectorList::TrackSectorList(QSharedPointer<const Sector> data)
{
m_data = data;

View File

@ -23,6 +23,8 @@
#include "tspair.h"
#include <QSharedPointer>
class Sector;
using TSPairList = QList<TSPair>;
@ -30,7 +32,7 @@ using TSPairList = QList<TSPair>;
class TrackSectorList
{
public:
TrackSectorList(Sector *data);
TrackSectorList(QSharedPointer<const Sector> data);
TSPair getNextTSList() const { return m_next_tslist; }
bool isNextTSListValid() const;
@ -47,7 +49,7 @@ private:
TSPair m_sector_offset;
TSPairList m_ts_pairs_for_data;
Sector *m_data;
QSharedPointer<const Sector> m_data;
};
#endif // TRACKSECTORLIST_H

View File

@ -24,35 +24,54 @@
#include "sector.h"
#include "util.h"
VTOC::VTOC(Sector *data)
VTOC::VTOC(QSharedPointer<const Sector> data)
{
m_data = data;
m_first_catalog_sector = TSPair(m_data->at(0x01), m_data->at(0x02));
m_dos_version = m_data->at(0x03);
m_volnum = m_data->at(0x06);
m_max_ts_pairs = m_data->at(0x27);
m_last_track_alloc = m_data->at(0x30);
m_dir_of_alloc= m_data->at(0x31);
m_tracks_per_disk = m_data->at(0x34);
m_sec_per_track = m_data->at(0x35);
m_byte_per_sec = makeWord(m_data->at(0x36),
m_data->at(0x37));
}
TSPair VTOC::firstCatalogSector() {
TSPair VTOC::firstCatalogSector() const {
// return TSPair(0x11,0x0f); // Force to look at the normal location
return TSPair(m_data->at(0x01), m_data->at(0x02));
// return TSPair(m_data->at(0x01), m_data->at(0x02));
return m_first_catalog_sector;
}
quint8 VTOC::dosVersion() {
return m_data->at(0x03);
return m_dos_version;
//return m_data->at(0x03);
}
quint8 VTOC::volumeNumber() {
return m_data->at(0x06);
return m_volnum;
//return m_data->at(0x06);
}
quint8 VTOC::maxTSPairs() {
return m_data->at(0x27);
//return m_data->at(0x27);
return m_max_ts_pairs;
}
quint8 VTOC::lastTrackAllocated() {
return m_data->at(0x30);
return m_last_track_alloc;
//return m_data->at(0x30);
}
qint8 VTOC::directionOfAllocation() {
return m_data->at(0x31);
return m_dir_of_alloc;
//return m_data->at(0x31);
}
quint8 VTOC::tracksPerDisk() {
@ -60,12 +79,14 @@ quint8 VTOC::tracksPerDisk() {
}
quint8 VTOC::sectorsPerTrack() {
return m_data->at(0x35);
return m_sec_per_track;
//return m_data->at(0x35);
}
qint16 VTOC::bytesPerSector() {
return makeWord(m_data->at(0x36),
m_data->at(0x37));
return m_byte_per_sec;
// return makeWord(m_data->at(0x36),
// m_data->at(0x37));
}
bool VTOC::isSectorInUse(TSPair ts) const {

View File

@ -26,15 +26,18 @@
#include "tspair.h"
class Sector;
class QString;
class VTOC
{
public:
VTOC(Sector *data);
VTOC(QSharedPointer<const Sector> data);
void dump();
TSPair firstCatalogSector();
TSPair firstCatalogSector() const;
quint8 dosVersion();
quint8 volumeNumber();
quint8 maxTSPairs();
@ -53,7 +56,18 @@ public:
private:
QString buildUseString(quint8 track);
Sector *m_data;
QSharedPointer<const Sector> m_data;
TSPair m_first_catalog_sector;
quint8 m_dos_version;
quint8 m_volnum;
quint8 m_max_ts_pairs;
quint8 m_last_track_alloc;
qint8 m_dir_of_alloc;
quint8 m_tracks_per_disk;
quint8 m_sec_per_track;
quint16 m_byte_per_sec;
};
#endif // VTOC_H

View File

@ -1,214 +0,0 @@
/*****************************************************************************
* AppleSAWS - The Apple Software Analysis WorkShop *
* Copyright (C) 2015-2021 Mark D. Long *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include "rawdiskimage.h"
#include <QFileInfo>
#include <QFile>
#include <QCryptographicHash>
#include <QDataStream>
RawDiskImage::RawDiskImage(QString name)
{
setCustomOrderMap0(dosOrderMap());
setCustomOrderMap1(prodosOrderMap());
// Set everything up assuming a 140k DOS image as a default for now
m_track_count = 35;
m_sector_size = 256;
m_sectors_per_track = 16;
m_sector_order = SectorOrder::Dos33;
m_empty_image = true;
if (!name.isEmpty())
{
read(name);
}
}
RawDiskImage::~RawDiskImage()
{
foreach (auto track, m_tracks)
{
while (track.count())
{
auto sectorblock = track.takeFirst();
delete sectorblock;
}
}
}
bool RawDiskImage::read(QString filename)
{
if (!isEmpty()) return false; // Don't reread a disk!
m_full_filename = filename;
m_filename = QFileInfo(filename).fileName();
if (m_filename.toUpper().contains(".D13"))
{
setSectorsPerTrack(13);
}
else
{
setSectorsPerTrack(16);
}
QFile infile(filename);
QCryptographicHash hash(QCryptographicHash::Md5);
if (infile.open(QIODevice::ReadOnly))
{
QByteArray contents = infile.readAll();
int expectedsize = sectorsPerTrack() * numTracks() * 256;
if (contents.size() != expectedsize)
{
if (contents.size() == 35*16*256) { m_sectors_per_track = 16; }
else if (contents.size() == 35*13*256) { m_sectors_per_track = 13; }
else qWarning() << QString("Size mismatch in file! Expected %1, got %2")
.arg(expectedsize)
.arg(contents.size());
}
QDataStream qds(contents);
for (int track = 0; track < numTracks(); track++)
{
TrackData td;
for (int sector = 0; sector < m_sectors_per_track; sector++)
{
char buffer[256];
if (qds.readRawData(buffer,sectorSize()) == sectorSize())
{
TSPair tmpts(track,sector);
SectorData *newSec = new SectorData();
*newSec = QByteArray(buffer,sectorSize());
td.append(newSec);
}
else
{
qDebug() << "Invalid sector read!";
return false;
}
}
m_tracks.append(td);
}
hash.addData(contents);
m_hash = hash.result();
return true;
}
else
{
qDebug() << "Could not open file " << filename;
return false;
}
}
bool RawDiskImage::isEmpty() const { return m_empty_image; }
HashValue RawDiskImage::hash() const { return m_hash; }
QString RawDiskImage::diskImageName() const { return m_filename; }
QString RawDiskImage::fullDiskImageName() const { return m_full_filename; }
void RawDiskImage::setNumTracks(int count) { m_track_count = count; }
int RawDiskImage::numTracks() const { return m_track_count; }
bool RawDiskImage::hasSectors() const {return true; }
int RawDiskImage::sectorSize() const { return m_sector_size; }
void RawDiskImage::setSectorSize(int size) { m_sector_size = size; }
void RawDiskImage::setSectorsPerTrack(int spt) { m_sectors_per_track = spt; }
int RawDiskImage::sectorsPerTrack() const { return m_sectors_per_track; }
void RawDiskImage::setSectorOrder(SectorOrder order) { m_sector_order = order; }
SectorOrder RawDiskImage::sectorOrder() const { return m_sector_order; }
bool RawDiskImage::reorderSectorsTo(SectorOrder)
{
//TODO: Handle Reordering
return false;
}
SectorData *RawDiskImage::sectorAt(int track, int sector)
{
if (track >= numTracks() || sector >= sectorsPerTrack())
{
return nullptr;
}
return m_tracks[track][sector];
}
SectorData *RawDiskImage::sectorAt(TSPair ts)
{
return sectorAt(ts.track(),ts.sector());
}
SectorOrderMap RawDiskImage::dosOrderMap() const {
return QByteArrayLiteral("\x0\xD\xB\x9\x7\x5\x3\x1\xE\xC\xA\x8\x6\x4\x2\xF");
}
SectorOrderMap RawDiskImage::prodosOrderMap() const {
return QByteArrayLiteral("\x0\x8\x1\x9\x2\xA\x3\xB\x4\xC\x5\xD\x6\xE\x7\xF");
}
SectorOrderMap RawDiskImage::pascalOrderMap() const {
return QByteArrayLiteral("\x0\x2\x4\x6\x8\xA\xC\xE\x1\x3\x5\x7x9xBxDxF");
}
SectorOrderMap RawDiskImage::cpmOrderMap() const {
return QByteArrayLiteral("\x0\x3\x6\x9\xC\xF\x2\x5\x8\xB\xE\x1\x4\x7\xA\xD");
}
SectorOrderMap RawDiskImage::customOrderMap0() const { return m_custom_order_map_0; }
SectorOrderMap RawDiskImage::customOrderMap1() const { return m_custom_order_map_0; }
bool RawDiskImage::setCustomOrderMap0(SectorOrderMap map)
{
if (map.count() < m_sectors_per_track)
{
return false;
}
m_custom_order_map_0 = map.left(m_sectors_per_track);
return true;
}
bool RawDiskImage::setCustomOrderMap1(SectorOrderMap map)
{
if (map.count() < m_sectors_per_track)
{
return false;
}
m_custom_order_map_1 = map.left(m_sectors_per_track);
return true;
}

View File

@ -1,123 +0,0 @@
#ifndef RAWDISKIMAGE_H
#define RAWDISKIMAGE_H
/*****************************************************************************
* AppleSAWS - The Apple Software Analysis WorkShop *
* Copyright (C) 2015-2021 Mark D. Long *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include "tspair.h"
#include <QString>
#include <QByteArray>
#include <QVector>
using SectorOrderMap = QByteArray;
using SectorData = QByteArray;
//PRODOS using BlockData = QByteArray;
//PRODOS using BlockPair = QPair<TSPair, TSPair>;
using TrackData = QList<SectorData*>;
using TrackList = QList<TrackData>;
using HashValue = QByteArray;
enum class SectorOrder
{
Unknown = 0,
Dos33 = 0,
ProDos,
Pascal,
CPM,
Custom1,
Custom2
};
class RawDiskImage
{
public:
RawDiskImage(QString filename = QString());
~RawDiskImage();
bool read(QString filename);
bool isEmpty() const;
HashValue hash() const;
QString diskImageName() const;
QString fullDiskImageName() const;
void setNumTracks(int count);
int numTracks() const;
bool hasSectors() const;
int sectorSize() const;
void setSectorSize(int size);
void setSectorsPerTrack(int spt);
int sectorsPerTrack() const;
//PRODOS bool hasBlocks();
//PRODOS int blockSize();
//PRODOS int blocksPerTrack();
void setSectorOrder(SectorOrder order);
SectorOrder sectorOrder() const;
bool reorderSectorsTo(SectorOrder newOrder);
SectorData *sectorAt(int track, int sector);
SectorData *sectorAt(TSPair ts);
inline SectorOrderMap dosOrderMap() const;;
inline SectorOrderMap prodosOrderMap() const;
inline SectorOrderMap pascalOrderMap() const;
inline SectorOrderMap cpmOrderMap() const;
SectorOrderMap customOrderMap0() const;
SectorOrderMap customOrderMap1() const;
bool setCustomOrderMap0(SectorOrderMap map);
bool setCustomOrderMap1(SectorOrderMap map);
private:
//PRODOS BlockPair mapBlockToTS(int blocknum);
private:
TrackList m_tracks;
bool m_empty_image;
int m_sector_size;
int m_sectors_per_track;
int m_track_count;
QString m_full_filename;
QString m_filename;
SectorOrder m_sector_order;
SectorOrderMap m_custom_order_map_0;
SectorOrderMap m_custom_order_map_1;
HashValue m_hash;
};
#endif // RAWDISKIMAGE_H

View File

@ -31,6 +31,7 @@ public:
TSPair(int trackval, int secval) { m_track=trackval; m_sector = secval; }
TSPair(QPair<int,int> pair) { m_track = pair.first; m_sector = pair.second;}
void setTrack(int tracknum)
{
if (tracknum > 34 && tracknum != 0xff) {

View File

@ -34,7 +34,7 @@ QByteArray IntBasicFile::detokenize()
// uint = unsigned int
// quint8 = unsigned char
// ==========================================================================
return dumpBufferAsIntBasicFile(rawData().asQByteArray());
return dumpBufferAsIntBasicFile(rawData());
}
@ -152,9 +152,10 @@ QByteArray IntBasicFile::dumpBufferAsIntBasicFile(QByteArray origdata)
QByteArray retval;
QVector<quint8> data;
QList<quint8> data;
QByteArray data0 = origdata;
if (origdata.size() == 0) return retval;
foreach (quint8 value, origdata)
{

View File

@ -29,8 +29,23 @@
#include "applesoftfile.h"
#include "startupdialog.h"
//#include <QByteArray>
//#include "sector.h"
int main(int argc, char** argv)
{
// QByteArray ba(256,0xff);
// Sector s(ba,1,2);
// s.dump();
// Sector t(s);
// t.dump();
//qDebug () << "S at 1: " << s.at(1);
//qDebug () << "T at 1: " << s.at(1);
//qDebug () << "S at 2: " << s.at(2);
//qDebug () << "T at 2: " << s.at(2);
// return 0;
QApplication a(argc, argv);
QCoreApplication::setOrganizationName("LydianScaleSoftware");

View File

@ -31,16 +31,17 @@ INCLUDEPATH += ./memory
INCLUDEPATH += ./memory/roles
INCLUDEPATH += ./sequence
INCLUDEPATH += ./ui/central
INCLUDEPATH += ./diskfiles/diskstore
INCLUDEPATH += ../ads/src/
INCLUDEPATH += ../cpress/ciderpress/diskimg/
DEFINES += WS_VIDEO
SOURCES += \
./diskfiles/dos33/dos33disktreeview.cpp \
./diskfiles/rawdiskimage.cpp \
./intbasic/IntBasicFile.cxx \
./main.cpp \
./diskfiles/dos33/dos33diskimage.cxx \
@ -132,7 +133,6 @@ HEADERS += \
./diskfiles/tspair.h \
./diskfiles/dos33/dos33imagemodel.h\
./diskfiles/dos33/dos33treeitem.h\
./diskfiles/rawdiskimage.h \
./intbasic/IntBasicFile.h \
./memory/attributedmemory.h \
./memory/memorycell.h \
@ -205,7 +205,8 @@ HEADERS += \
diskfiles/cpressfile.h \
diskfiles/diskstore/asdiskdata.h \
diskfiles/diskstore/asdiskimporter.h \
diskfiles/diskstore/asdiskstore.h
diskfiles/diskstore/asdiskstore.h \
util/referencelist.h
FORMS += \
./sequence/sequenceviewer.ui \

View File

@ -230,7 +230,7 @@ void DiskExplorer::handleShowSectorData(QByteArray /*data*/, int track, int sect
}
}
auto sec = m_disk->getSector(track,sector);
m_vws->setSector(&sec, viewer);
m_vws->setSector(sec, viewer);
}
void DiskExplorer::showLoadDialog(bool parentToThis)

View File

@ -170,10 +170,10 @@ void DiskExplorerMapWidget::handleButtonCheck(int track, int sector, bool checke
if (checked)
{
Sector sec = m_disk->getSector(track,sector);
QByteArray *data = sec.rawData();
emit showSectorData(*data,track,sector,QVariant((int) m_roles[TSPair(track,sector)]));
emit showSector(&sec,track,sector,m_roles[TSPair(track,sector)]);
pSector sec = m_disk->getSector(track,sector);
const QByteArray data = sec->rawData();
emit showSectorData(data,track,sector,QVariant((int) m_roles[TSPair(track,sector)]));
emit showSector(sec,track,sector,m_roles[TSPair(track,sector)]);
m_trackSectorLabel->setText(
QString("Track: %1 Sector: %2 (%3)")
@ -338,6 +338,8 @@ void DiskExplorerMapWidget::defineRoles(TSPair vtoc)
m_numbers.clear();
m_roles.clear();
qDebug() << "in defineRoles with vtoc at : " << vtoc.track() << "," << vtoc.sector();
int buttonNumber = 0;
for (auto track = 0; track < m_numtracks; track++)
@ -380,14 +382,19 @@ void DiskExplorerMapWidget::defineRoles(TSPair vtoc)
void DiskExplorerMapWidget::mapCatalogSectors(int &buttonNumber)
{
int catSectorCount = 0;
foreach (CatalogSector cs, m_disk->getCatalogSectors())
foreach (auto cs, m_disk->getCatalogSectors())
{
TSPair ts(cs.sectorLocation());
qDebug() << "Processing buttons for catalog sectors";
TSPair ts = cs.sectorLocation();
qDebug() << "Sector location: " << ts.track() << "," << ts.sector();
if (setButtonRole(ts,DiskSectorRole::CatalogSector))
{
QString desc = QString("Catalog Sector #%1").arg(++catSectorCount);
qDebug() << "Desc: " << desc;
setDescription(ts,desc);
setButtonNumber(ts,buttonNumber++);
// qDebug() << "Setting button number " << buttonNumber-1
// << " at " << ts.track() << "," << ts.sector();
int fdeNum = 0;
foreach (FileDescriptiveEntry fde, cs.getFDEs())
@ -444,7 +451,7 @@ void DiskExplorerMapWidget::mapTSListSector(TSPair location,
return;
}
Sector *s = &(m_disk->getSector(location));
pSector s = m_disk->getSector(location);
TrackSectorList tsl(s);
if (setButtonRole(location,DiskSectorRole::TSList))
@ -608,7 +615,7 @@ void DiskExplorerMapWidget::mapButtonsFromRoles()
void DiskExplorerMapWidget::checkForUsedButUnknown(TSPair vtoc)
{
auto vtocsector = m_disk->getSector(vtoc).promoteToVTOC();
auto vtocsector = m_disk->getSector(vtoc)->promoteToVTOC();
for (auto track = 0; track < m_numtracks; track++)
{

View File

@ -180,7 +180,7 @@ public:
signals:
void showSectorData(QByteArray data, int track, int sector, QVariant metadata);
void showSector(Sector *sec, int track, int sector, DiskSectorRole role);
void showSector(pSector sec, int track, int sector, DiskSectorRole role);
public slots:
void handleButtonCheck(int track, int sector, bool checked);

View File

@ -48,7 +48,7 @@ CatalogSectorView::~CatalogSectorView()
delete ui;
}
void CatalogSectorView::setSector(Sector *sec)
void CatalogSectorView::setSector(QSharedPointer<Sector>sec)
{
m_sector = sec;

View File

@ -37,12 +37,12 @@ public:
explicit CatalogSectorView(QWidget *parent = nullptr);
~CatalogSectorView();
void setSector(Sector *sec);
void setSector(QSharedPointer<Sector> sec);
private:
Ui::CatalogSectorView *ui;
Sector *m_sector;
QSharedPointer<Sector> m_sector;
};
#endif // CATALOGSECTORVIEW_H

View File

@ -24,7 +24,7 @@ TSListView::TSListView(QWidget *parent) : QTextBrowser(parent)
}
void TSListView::setSector(Sector *sec)
void TSListView::setSector(pSector sec)
{
m_sector = sec;
if (sec)

View File

@ -31,12 +31,12 @@ class TSListView : public QTextBrowser
public:
explicit TSListView(QWidget *parent = nullptr);
void setSector(Sector *sec);
void setSector(QSharedPointer<Sector> sec);
signals:
private:
Sector *m_sector;
QSharedPointer<Sector> m_sector;
};

View File

@ -29,11 +29,11 @@ ViewWidgetStack::ViewWidgetStack(QWidget *parent) : QTabWidget(parent)
setSector(nullptr);
}
void ViewWidgetStack::setSector(Sector *sec, PreferredViewer viewer)
void ViewWidgetStack::setSector(QSharedPointer<Sector> sec, PreferredViewer viewer)
{
if (sec)
{
m_hdv->setRawData(*(sec->rawData()));
m_hdv->setRawData(sec->rawData());
}
else
{
@ -79,7 +79,7 @@ void ViewWidgetStack::makeWidgets()
setCurrentWidget(m_hdv);
}
void ViewWidgetStack::handleShowSectorData(Sector *data, int /*track*/,
void ViewWidgetStack::handleShowSectorData(pSector data, int /*track*/,
int /*sector*/, DiskSectorRole role)
{
ViewWidgetStack::PreferredViewer viewer =

View File

@ -47,9 +47,9 @@ public:
explicit ViewWidgetStack(QWidget *parent = nullptr);
public slots:
void setSector(Sector *sec, PreferredViewer viewer = PreferredViewer::DontCare);
void setSector(QSharedPointer<Sector> sec, PreferredViewer viewer = PreferredViewer::DontCare);
void handleShowSectorData(Sector *data, int track, int sector, DiskSectorRole role);
void handleShowSectorData(QSharedPointer<Sector> data, int track, int sector, DiskSectorRole role);

View File

@ -31,7 +31,7 @@ VTOCView::~VTOCView()
{
delete ui;
}
void VTOCView::setSector(Sector *sec)
void VTOCView::setSector(QSharedPointer<const Sector> sec)
{
m_sector = sec;

View File

@ -37,12 +37,12 @@ public:
explicit VTOCView(QWidget *parent = nullptr);
~VTOCView();
void setSector(Sector *sec);
void setSector(QSharedPointer<const Sector> sec);
private:
Ui::VTOCView *ui;
Sector *m_sector;
QSharedPointer<const Sector> m_sector;
};

View File

@ -1,88 +0,0 @@
/*****************************************************************************
* AppleSAWS - The Apple Software Analysis WorkShop *
* Copyright (C) 2015-2021 Mark D. Long *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include "chunkbytelist.h"
ChunkByteList::ChunkByteList()
{
m_preamble_size = 0;
}
ChunkByteList &ChunkByteList::appendChunk(QByteArray *chunk)
{
if (chunk)
{
m_chunk_list.append(chunk);
}
return *this;
}
ChunkByteList &ChunkByteList::appendChunkList(ChunkByteList other)
{
if (&other != this)
{
for (auto count = 0; count < other.numChunks(); count++)
{
m_chunk_list.append(other.getChunk(count));
}
}
return *this;
}
int ChunkByteList::count() const
{
int size = 0;
foreach (auto chunk, m_chunk_list)
{
size += chunk->size();
}
return size - preambleLength();
}
int ChunkByteList::size() const
{
return count();
}
int ChunkByteList::length() const
{
return count();
}
bool ChunkByteList::isEmpty() const
{
if (m_chunk_list.size() == 0) return true;
foreach (auto chunk, m_chunk_list)
{
if (!chunk->isEmpty()) return false;
}
return false;
}
char ChunkByteList::at(int i) const
{
return preambleData(i + preambleLength());
}
char ChunkByteList::operator[](int i) const
{
return at(i);
}

View File

@ -1,87 +0,0 @@
#ifndef CHUNKBYTELIST_H
#define CHUNKBYTELIST_H
/*****************************************************************************
* AppleSAWS - The Apple Software Analysis WorkShop *
* Copyright (C) 2015-2021 Mark D. Long *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
*****************************************************************************/
#include <QByteArray>
#include <QList>
#include <QSharedPointer>
class ChunkByteList
{
public:
ChunkByteList();
ChunkByteList &appendChunk(QByteArray *chunk);
ChunkByteList &appendChunkList(ChunkByteList other);
void setPreambleLength(int bytes) { m_preamble_size = bytes; };
int preambleLength() const { return m_preamble_size; };
int count() const;
int size() const;
int length() const;
char preambleData(int i) const
{
int offset = 0;
foreach (auto chunk, m_chunk_list)
{
int upperbound = offset + chunk->size();
if (i < upperbound)
{
return chunk->at(i-offset);
}
else
{
offset += chunk->size();
}
}
return 0;
}
int actualSize() const { return count() + preambleLength(); }
bool isEmpty() const;
char at(int i) const;
char operator[](int i) const;
int numChunks() const { return m_chunk_list.size(); }
QByteArray *getChunk(int chunk) const { return m_chunk_list[chunk]; }
QByteArray asQByteArray() const {
QByteArray retval;
foreach (auto chunk, m_chunk_list)
{
retval.append(*chunk);
}
return retval;
}
explicit operator QByteArray() { return asQByteArray(); }
private:
QList<QByteArray *> m_chunk_list;
int m_preamble_size;
};
#endif // CHUNKBYTELIST_H

409
src/util/referencelist.h Normal file
View File

@ -0,0 +1,409 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* ReferenceList.h *
* *
* Copyright 2014 Tory Gaurnier <tory.gaurnier@linuxmail.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; version 3. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef REFERENCELIST_HPP
#define REFERENCELIST_HPP
#include <QDataStream>
#include <QDebug>
#include <QList>
/**
* class ReferenceList
*
* Uses QList under the hood to store pointers, on the surface recieves and returns nothing but the
* references.
*
* NOTE: Any method that calls it's QList<T*> counterpart with parameter T, T must not be const, if
* it is then QList<T*> would have to be QList<const T *const> instead.
*/
template<class T>
class ReferenceList : public QList<T*> {
public:
// Forward declare iterators
class const_iterator;
class iterator;
// Set iterators as friends
friend class const_iterator;
friend class iterator;
ReferenceList() {}
ReferenceList(const QList<T*> &other) : QList<T*>(other) { }
ReferenceList(const ReferenceList<T> &other) : QList<T*>(other) { }
ReferenceList(ReferenceList<T> &&other) : QList<T*>(std::move(other)) { }
~ReferenceList() {}
void append(T &value) {
QList<T*>::append(&value);
}
void append(const ReferenceList<T> other) {
QList<T*>::append(other);
}
const T & at(int i) const {
return *QList<T*>::at(i);
}
T & back() {
return *QList<T*>::back();
}
const T & back() const {
return *QList<T*>::back();
}
iterator begin() {
return iterator(iterator(QList<T*>::begin()));
}
const_iterator begin() const {
return const_iterator(QList<T*>::begin());
}
const_iterator cbegin() const {
return const_iterator(QList<T*>::cbegin());
}
const_iterator cend() const {
return const_iterator(QList<T*>::cend());
}
void clear() {
QList<T*>::clear();
}
const_iterator constBegin() const {
return const_iterator(QList<T*>::constBegin());
}
const_iterator constEnd() const {
return const_iterator(QList<T*>::constEnd());
}
bool contains(T &value) const {
return QList<T*>::contains(&value);
}
int count(T &value) const {
return QList<T*>::count(&value);
}
int count() const {
return QList<T*>::count();
}
bool empty() const {
return QList<T*>::empty();
}
iterator end() {
return iterator(QList<T*>::end());
}
const_iterator end() const {
return const_iterator(QList<T*>::end());
}
bool endsWith(T &value) const {
return QList<T*>::endsWith(&value);
}
iterator erase(iterator pos) {
return iterator(QList<T*>::erase(pos));
}
iterator erase(iterator begin, iterator end) {
return iterator(QList<T*>::erase(begin, end));
}
T & first() {
return *QList<T*>::first();
}
const T & first() const {
return *QList<T*>::first();
}
/**
* Inherited "from" methods are unsupported.
*/
static ReferenceList<T> fromSet(const QSet<T> & set) = delete;
static ReferenceList<T> fromStdList(const std::list<T> & list) = delete;
static ReferenceList<T> fromVector(const QVector<T> & vector) = delete;
T & front() {
return *QList<T*>::front();
}
const T & front() const {
return *QList<T*>::front();
}
int indexOf(T &value, int from = 0) const {
return QList<T*>::indexOf(&value, from);
}
void insert(int i, T &value) {
QList<T*>::insert(i, &value);
}
iterator insert(iterator before, T &value) {
return iterator(QList<T*>::insert(before, &value));
}
bool isEmpty() const {
return QList<T*>::isEmpty();
}
T & last() {
return *QList<T*>::last();
}
const T & last() const {
return *QList<T*>::last();
}
int lastIndexOf(T &value, int from = -1) const {
return QList<T*>::lastIndexOf(&value, from);
}
int length() const {
return QList<T*>::length();
}
ReferenceList<T> mid(int pos, int length = -1) const {
return ReferenceList<T>(QList<T*>::mid(pos, length));
}
void move(int from, int to) {
QList<T*>::move(from, to);
}
void pop_back() {
QList<T*>::pop_back();
}
void pop_front() {
QList<T*>::pop_front();
}
void prepend(T &value) {
QList<T*>::prepend(&value);
}
void push_back(T &value) {
QList<T*>::push_back(&value);
}
void push_front(T &value) {
QList<T*>::push_front(&value);
}
int removeAll(T &value) {
return QList<T*>::removeAll(&value);
}
void removeAt(int i) {
QList<T*>::removeAt(i);
}
void removeFirst() {
QList<T*>::removeFirst();
}
void removeLast() {
QList<T*>::removeLast();
}
bool removeOne(T &value) {
return QList<T*>::removeOne(&value);
}
void replace(int i, T &value) {
QList<T*>::replace(i, &value);
}
void reserve(int alloc) {
QList<T*>::reserve(alloc);
}
int size() const {
return QList<T*>::size();
}
bool startsWith(T &value) const {
return QList<T*>::startsWith(&value);
}
void swap(ReferenceList<T> &other) {
QList<T*>::swap(other);
}
void swap(int i, int j) {
QList<T*>::swap(i, j);
}
T & takeAt(int i) {
return *QList<T*>::takeAt(i);
}
T & takeFirst() {
return *QList<T*>::takeFirst();
}
T & takeLast() {
return *QList<T*>::takeLast();
}
/**
* Inherited "to" methods are not supported.
*/
QSet<T> toSet() const = delete;
std::list<T> toStdList() const = delete;
QVector<T> toVector() const = delete;
T & value(int i) const {
return *QList<T*>::value(i);
}
T & value(int i, T &default_value) const {
return *QList<T*>::value(i, &default_value);
}
bool operator!=(const ReferenceList<T> &other) const {
return QList<T*>::operator!=(other);
}
ReferenceList<T> operator+(const ReferenceList<T> &other) const {
return ReferenceList<T>(QList<T*>::operator+(other));
}
ReferenceList<T> & operator+=(const ReferenceList<T> &other) {
QList<T*>::operator+=(other);
return *this;
}
ReferenceList<T> & operator+=(T &value) {
QList<T*>::operator+=(&value);
return *this;
}
ReferenceList<T> & operator<<(const ReferenceList<T> &other) {
QList<T*>::operator<<(other);
return *this;
}
ReferenceList<T> & operator<<(T &value) {
QList<T*>::operator<<(&value);
return *this;
}
ReferenceList<T> & operator=(ReferenceList<T> &other) {
QList<T*>::operator=(other);
return *this;
}
ReferenceList & operator=(ReferenceList<T> &&other) {
QList<T*>::operator=(std::move(other));
return *this;
}
bool operator==(const ReferenceList<T> &other) const {
return QList<T*>::operator==(other);
}
T & operator[](int i) {
return *QList<T*>::operator[](i);
}
const T & operator[](int i) const {
return *QList<T*>::operator[](i);
}
class iterator : public QList<T*>::iterator {
public:
iterator() { }
iterator(const typename QList<T*>::iterator &other)
: QList<T*>::iterator(other) { }
iterator(const iterator &other) : QList<T*>::iterator(other) { }
T & operator*() const { return *QList<T*>::iterator::operator*(); }
T * operator->() const { return *QList<T*>::iterator::operator->(); }
T & operator[](int j) const { return *QList<T*>::iterator::operator[](j); }
};
class const_iterator : public QList<T*>::const_iterator {
public:
const_iterator() { }
const_iterator(const typename QList<T*>::const_iterator &other)
: QList<T*>::const_iterator(other) { }
const_iterator(const const_iterator &other)
: QList<T*>::const_iterator(other) { }
const_iterator(const iterator &other)
: QList<T*>::const_iterator(other) { }
T & operator*() const { return *QList<T*>::const_iterator::operator*(); }
T * operator->() const { return *QList<T*>::const_iterator::operator->(); }
T & operator[](int j) const { return *QList<T*>::const_iterator::operator[](j); }
};
};
/**
* Implement QDebug << operator so that it will print out values rather than pointer addresses (do
* to it implicitly converting to QList<T*>).
*/
template <class T>
QDebug operator<<(QDebug debug, const ReferenceList<T> &list) {
debug.nospace() << '(';
for(typename QList<T>::size_type i = 0; i < list.count(); ++i) {
if(i) debug << ", ";
debug << list.at(i);
}
debug << ')';
return debug.space();
}
/**
* QDataStream << ReferenceList<T> should have same output as the QDataStream << QList<T>.
*/
template<class T>
QDataStream & operator<<(QDataStream &out, const ReferenceList<T>& list) {
out << quint32(list.size());
for(int i = 0; i < list.size(); ++i) out << list.at(i);
return out;
}
/**
* Make sure QDataStream >> is not callable, there is no scenario where it would be useful with a
* ReferenceList.
*/
template<class T>
QDataStream & operator>>(QDataStream &out, const ReferenceList<T>& list) = delete;
#endif