From 14301d70831a3bce07284a7a0aff6b4855a7d1b3 Mon Sep 17 00:00:00 2001 From: mlong Date: Mon, 15 Feb 2021 16:30:02 -0600 Subject: [PATCH] Refactoring RawDiskImage out of Dos33DiskImage --- AppleSAWS.pro | 10 +- src/applesoftfile/applesoftfile.cxx | 27 +-- src/applesoftfile/applesoftfile.h | 12 +- src/binaryfile/binaryfile.cxx | 12 +- src/binaryfile/binaryfile.h | 8 +- src/diskfiles/dos33/catalogsector.cxx | 14 +- src/diskfiles/dos33/dos33diskimage.cxx | 199 ++++++++++-------- src/diskfiles/dos33/dos33diskimage.h | 35 +-- src/diskfiles/dos33/dos33disktreeview.cpp | 32 +++ src/diskfiles/dos33/dos33disktreeview.h | 38 ++++ src/diskfiles/dos33/dos33imagemodel.cpp | 19 +- src/diskfiles/dos33/dos33imagemodel.h | 14 ++ src/diskfiles/dos33/filedescriptiveentry.h | 24 +-- src/diskfiles/dos33/genericfile.cxx | 27 +++ src/diskfiles/dos33/genericfile.h | 33 ++- src/diskfiles/dos33/sector.cxx | 14 +- src/diskfiles/dos33/sector.h | 23 +- src/diskfiles/dos33/tracksectorlist.cxx | 10 +- src/diskfiles/dos33/tracksectorlist.h | 8 +- src/diskfiles/dos33/vtoc.cxx | 26 +-- src/diskfiles/dos33/vtoc.h | 7 +- src/diskfiles/rawdiskimage.cpp | 194 +++++++++++++++++ src/diskfiles/rawdiskimage.h | 103 +++++++++ src/diskfiles/{dos33 => }/tspair.cpp | 0 src/diskfiles/{dos33 => }/tspair.h | 16 +- src/intbasic/IntBasicFile.h | 6 +- src/qdarkstyle/style.qss | 20 +- src/relocatablefile/relocatablefile.cxx | 20 +- src/relocatablefile/relocatablefile.h | 9 +- src/textfile/textfile.cxx | 4 - src/textfile/textfile.h | 5 +- src/ui/catalogwidget.cxx | 8 +- src/ui/central/centralappwindow.cpp | 30 ++- src/ui/central/centralappwindow.h | 4 + src/ui/diskexplorer/DiskExplorer.cpp | 9 +- src/ui/diskexplorer/DiskExplorerMapWidget.cpp | 36 ++-- src/ui/diskexplorer/DiskExplorerMapWidget.h | 50 ++++- src/util/chunkbytelist.cpp | 80 +++++++ src/util/chunkbytelist.h | 43 ++++ src/util/util.h | 2 + 40 files changed, 938 insertions(+), 293 deletions(-) create mode 100644 src/diskfiles/dos33/dos33disktreeview.cpp create mode 100644 src/diskfiles/dos33/dos33disktreeview.h create mode 100644 src/diskfiles/rawdiskimage.cpp create mode 100644 src/diskfiles/rawdiskimage.h rename src/diskfiles/{dos33 => }/tspair.cpp (100%) rename src/diskfiles/{dos33 => }/tspair.h (73%) create mode 100644 src/util/chunkbytelist.cpp create mode 100644 src/util/chunkbytelist.h diff --git a/AppleSAWS.pro b/AppleSAWS.pro index 9b14b41..957552a 100644 --- a/AppleSAWS.pro +++ b/AppleSAWS.pro @@ -36,6 +36,8 @@ INCLUDEPATH += src/ui/central DEFINES += WS_VIDEO SOURCES += \ + src/diskfiles/dos33/dos33disktreeview.cpp \ + src/diskfiles/rawdiskimage.cpp \ src/intbasic/IntBasicFile.cxx \ src/main.cpp \ src/diskfiles/dos33/dos33diskimage.cxx \ @@ -45,7 +47,7 @@ SOURCES += \ src/diskfiles/dos33/tracksectorlist.cxx \ src/diskfiles/dos33/filedescriptiveentry.cxx \ src/diskfiles/dos33/genericfile.cxx \ - src/diskfiles/dos33/tspair.cpp \ + src/diskfiles/tspair.cpp \ src/diskfiles/dos33/dos33imagemodel.cpp \ src/diskfiles/dos33/dos33treeitem.cpp \ src/memory/attributedmemory.cpp \ @@ -101,20 +103,23 @@ SOURCES += \ src/applesoftfile/ApplesoftRetokenizer.cpp \ src/internals/JumpLineManager.cpp \ src/ui/widgets/FlowLineTextBrowser.cpp \ + src/util/chunkbytelist.cpp \ src/util/opcodes.cpp HEADERS += \ src/diskfiles/dos33/dos33diskimage.h \ + src/diskfiles/dos33/dos33disktreeview.h \ src/diskfiles/dos33/sector.h \ src/diskfiles/dos33/vtoc.h \ src/diskfiles/dos33/catalogsector.h \ src/diskfiles/dos33/tracksectorlist.h \ src/diskfiles/dos33/filedescriptiveentry.h \ src/diskfiles/dos33/genericfile.h \ - src/diskfiles/dos33/tspair.h \ + src/diskfiles/tspair.h \ src/diskfiles/dos33/dos33imagemodel.h\ src/diskfiles/dos33/dos33treeitem.h\ + src/diskfiles/rawdiskimage.h \ src/intbasic/IntBasicFile.h \ src/memory/attributedmemory.h \ src/memory/memorycell.h \ @@ -134,6 +139,7 @@ HEADERS += \ src/ui/startupdialog.h \ src/ui/viewers/intbasicfileviewer.h \ src/ui/widgets/notesdialog.h \ + src/util/chunkbytelist.h \ src/util/opcodes.h \ src/util/util.h \ src/util/applestring.h \ diff --git a/src/applesoftfile/applesoftfile.cxx b/src/applesoftfile/applesoftfile.cxx index 112f173..ff4557e 100644 --- a/src/applesoftfile/applesoftfile.cxx +++ b/src/applesoftfile/applesoftfile.cxx @@ -11,42 +11,29 @@ ApplesoftFile::ApplesoftFile(QByteArray data) : GenericFile(data) m_retokenizer = Q_NULLPTR; m_data_end = data.length(); - if (!data.isEmpty()) - { - setData(data); - } setAddress(0x801); } -void ApplesoftFile::setData(QByteArray data) +void ApplesoftFile::processData() { if (!m_retokenizer) { m_retokenizer = new ApplesoftRetokenizer(); } - GenericFile::setData(data); + m_length = dataWordAt(0); + setIgnoreOffset(2); - quint8 addlo = m_data.at(0); - quint8 addhi = m_data.at(1); - m_length = makeWord(addlo,addhi); - m_data.remove(0,2); - - m_retokenizer->setData(m_data); + m_retokenizer->setData(data()); m_retokenizer->parse(); m_data_end = m_retokenizer->getEndOfDataOffset(); m_lines = m_retokenizer->getRetokenizedLines(); m_flowTargets = m_retokenizer->getFlowTargets(); + } -QByteArray ApplesoftFile::rawData() { - QByteArray retval; - retval.append(m_length % 255); - retval.append(m_length / 255); - retval.append(m_data); - return retval; -} + QStringList ApplesoftFile::extraDataHexValues() { QStringList retval; @@ -72,7 +59,7 @@ QStringList ApplesoftFile::extraDataHexValues() { QByteArray ApplesoftFile::extraData() { - return m_data.mid(m_data_end); + return data().mid(m_data_end); } diff --git a/src/applesoftfile/applesoftfile.h b/src/applesoftfile/applesoftfile.h index b0b1225..4826dfb 100644 --- a/src/applesoftfile/applesoftfile.h +++ b/src/applesoftfile/applesoftfile.h @@ -14,20 +14,22 @@ class ApplesoftFile : public GenericFile { + friend class Dos33DiskImage; + public: - ApplesoftFile(QByteArray data = QByteArray()); - void setData(QByteArray data); QByteArray extraData(); QStringList extraDataHexValues(); QVector getLines() const { return m_lines; } - quint16 length() const { return m_length; } + int length() const override { return m_length; } - QByteArray rawData(); + +protected: + void processData(); private: - + ApplesoftFile(QByteArray data = QByteArray()); QVector m_lines; int m_data_end; quint16 m_length; diff --git a/src/binaryfile/binaryfile.cxx b/src/binaryfile/binaryfile.cxx index 247e98a..c4b11d3 100644 --- a/src/binaryfile/binaryfile.cxx +++ b/src/binaryfile/binaryfile.cxx @@ -4,8 +4,6 @@ BinaryFile::BinaryFile(QByteArray data) : GenericFile(data) { - m_length = 0; - if (!data.isEmpty()) { setData(data); } @@ -15,17 +13,15 @@ void BinaryFile::setData(QByteArray data) { if (data.length() >= 4) { QByteArray metadata = data.left(4); - m_data = data.mid(4); + GenericFile::setData(data.mid(4)); setAddress(makeWord(metadata[0],metadata[1])); - m_length = makeWord(metadata[2],metadata[3]); - } + setLength(makeWord(metadata[2],metadata[3])); + } } void BinaryFile::dump() { qDebug() << QString("Address: %1 Length: %2") .arg((quint16) address(),4,16,QChar('0')) - .arg(m_length,4,16,QChar('0')).toUpper(); - qDebug() << QString("Data Length Recorded: %1") - .arg(m_data.length(),4,16,QChar('0')).toUpper(); + .arg(length(),4,16,QChar('0')).toUpper(); } diff --git a/src/binaryfile/binaryfile.h b/src/binaryfile/binaryfile.h index ad3d801..56fc330 100644 --- a/src/binaryfile/binaryfile.h +++ b/src/binaryfile/binaryfile.h @@ -5,15 +5,15 @@ class BinaryFile : public GenericFile { -public: - BinaryFile(QByteArray data = QByteArray()); - void setData(QByteArray data) override; + friend class Dos33DiskImage; - virtual quint16 length() const override { return m_length; } +public: void dump(); protected: + BinaryFile(QByteArray data = QByteArray()); + void setData(QByteArray data) override; }; #endif // BINARYFILE_H diff --git a/src/diskfiles/dos33/catalogsector.cxx b/src/diskfiles/dos33/catalogsector.cxx index f6dc9ab..46bf8a8 100644 --- a/src/diskfiles/dos33/catalogsector.cxx +++ b/src/diskfiles/dos33/catalogsector.cxx @@ -7,7 +7,7 @@ CatalogSector::CatalogSector(Sector *data) m_next = TSPair(0,0); - TSPair next(m_data->rawData()[0x01],m_data->rawData()[0x02]); + TSPair next(m_data->at(0x01),m_data->at(0x02)); if (next.isValid() && next.track() == 17) { @@ -48,13 +48,13 @@ void CatalogSector::dumpFDEs() { FileDescriptiveEntry CatalogSector::makeFDE(int offset) { FileDescriptiveEntry fde; - TSPair first(m_data->rawData()[offset + 0x00],m_data->rawData()[offset + 0x01]); + TSPair first(m_data->at(offset + 0x00),m_data->at(offset + 0x01)); fde.setFirstTSListSector(first); - fde.lengthInSectors = makeWord( m_data->rawData()[offset + 0x21], - m_data->rawData()[offset + 0x22]); + fde.lengthInSectors = makeWord(m_data->at(offset + 0x21), + m_data->at(offset + 0x22)); - fde.fileTypeFlags = m_data->rawData()[offset + 0x02]; + fde.fileTypeFlags = m_data->at(offset + 0x02); if (fde.lengthInSectors > 16*35) { @@ -62,7 +62,7 @@ FileDescriptiveEntry CatalogSector::makeFDE(int offset) } for (int idx = 0x03; idx <= 0x20; idx++) { - fde.filename.append(m_data->rawData()[idx+offset]); + fde.filename.append(m_data->at(idx+offset)); } if (fde.firstTSListSector().track() == 0xFF) @@ -71,7 +71,7 @@ FileDescriptiveEntry CatalogSector::makeFDE(int offset) fde.deleted = true; qDebug() << fde.filename; TSPair first = fde.firstTSListSector(); - first.setTrack(m_data->rawData()[offset + 0x20]); + first.setTrack(m_data->at(offset + 0x20)); fde.setFirstTSListSector(first); qDebug() << " New track: " << (quint8) fde.firstTSListSector().track(); qDebug() << " Sector: " << fde.firstTSListSector().sector(); diff --git a/src/diskfiles/dos33/dos33diskimage.cxx b/src/diskfiles/dos33/dos33diskimage.cxx index df3d75d..b2f563a 100644 --- a/src/diskfiles/dos33/dos33diskimage.cxx +++ b/src/diskfiles/dos33/dos33diskimage.cxx @@ -16,80 +16,104 @@ Dos33DiskImage::Dos33DiskImage(QString filename) { + m_disk_image = new RawDiskImage(filename); + if (!filename.isEmpty()) { read(filename); } } +Dos33DiskImage::Dos33DiskImage(RawDiskImage *rawImage) +{ + m_disk_image = rawImage; +} + Dos33DiskImage::~Dos33DiskImage() { - foreach (GenericFile *file, m_files) - { - delete file; - } +// foreach (GenericFile *file, m_files) +// { +// delete file; +// } } bool Dos33DiskImage::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; - } + bool retval = m_disk_image->read(filename); - QFile infile(filename); - QCryptographicHash hash(QCryptographicHash::Md5); - - if (infile.open(QIODevice::ReadOnly)) + if (retval) { - QByteArray contents = infile.readAll(); - int expectedsize = sectorsPerTrack() * tracks() * 256; - if (contents.size() != expectedsize) + for (auto tracknum = 0; tracknum < m_disk_image->numTracks(); tracknum++) { - 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++) + for (auto secnum = 0; secnum < m_disk_image->sectorsPerTrack(); secnum++) { - 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; - } + TSPair tmpts(tracknum,secnum); + Sector newSec; + SectorData * data = m_disk_image->sectorAt(tmpts); + newSec.setData(data); + newSec.setTrackSector(tmpts); + m_contents[tmpts] = newSec; } } - hash.addData(contents); - - m_hash = hash.result(); - // qDebug() << "Hash: " << m_hash; - - return true; } - else - qDebug() << "Could not open file " << filename; - return false; + + 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) { return m_contents[ts]; } + +Sector &Dos33DiskImage::getSector(int track, int sector) { + return getSector(TSPair(track,sector)); } VTOC Dos33DiskImage::getVTOC() @@ -99,8 +123,6 @@ VTOC Dos33DiskImage::getVTOC() QList Dos33DiskImage::getCatalogSectors() { - // qDebug() << "### Start getCatalogSector"; - QList retval; VTOC vtoc = getVTOC(); TSPair ts = vtoc.firstCatalogSector(); @@ -112,7 +134,6 @@ QList Dos33DiskImage::getCatalogSectors() cs = getSector(ts).asCatalogSector(); retval.append(cs); } - // qDebug() << "### End getCatalogSector"; return retval; } @@ -138,30 +159,31 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde) qWarning(" Not returning a file from invalid TSList!"); return nullptr; } - QByteArray data = getDataFromTrackSectorList(tsl); - setFileType(fde.fileType()); - if (fileType() == "A") - { - retval = new ApplesoftFile(data); - } - else if (fileType() == "B") - { - retval = new BinaryFile(data); - } - else if (fileType() == "R") - { - retval = new RelocatableFile(data); - } - else if ((fileType() == "T")) - { - retval = new TextFile(data); - } - else if ((fileType() == "I")) - { - retval = new IntBasicFile(data); - } - else + ChunkByteList data = getDataFromTrackSectorList(tsl); + setFileType(fde.fileTypeIdentifier()); + +// if (fileType() == "A") +// { +// retval = new ApplesoftFile(data); +// } +// else if (fileType() == "B") +// { +// retval = new BinaryFile(data); +// } +// else if (fileType() == "R") +// { +// retval = new RelocatableFile(data); +// } +// else if ((fileType() == "T")) +// { +// retval = new TextFile(data); +// } +// else if ((fileType() == "I")) +// { +// retval = new IntBasicFile(data); +// } +// else { retval = new GenericFile(data); } @@ -173,16 +195,16 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde) } -QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl) +ChunkByteList Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl) { - QByteArray retval; + ChunkByteList retval; foreach(TSPair pair, tsl.getDataTSPairs()) { if (pair.isValid()) { Sector sec = getSector(pair); - retval.append(sec.rawData()); + retval.appendChunk(sec.rawData()); } else { @@ -193,7 +215,7 @@ QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl) auto next = tsl.getNextTSList(); if (next.isValid() && next != TSPair(0,0)) { TrackSectorList nextTsl = getSector(tsl.getNextTSList()).asTrackSectorList(); - retval.append(getDataFromTrackSectorList(nextTsl)); + retval.appendChunkList(getDataFromTrackSectorList(nextTsl)); } return retval; @@ -201,7 +223,6 @@ QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl) QList Dos33DiskImage::getAllFDEs() { - // qDebug() << "### Start getAllFDEs"; QList retval; QList sectors = getCatalogSectors(); @@ -211,7 +232,6 @@ QList Dos33DiskImage::getAllFDEs() QList fdes = cs.getFDEs(); retval.append(fdes); } - // qDebug() << "### End getAllFDEs"; return retval; } @@ -224,3 +244,8 @@ QString Dos33DiskImage::getMetaDataPath() const { return path; } +FileList Dos33DiskImage::fileList() +{ + return { }; +} + diff --git a/src/diskfiles/dos33/dos33diskimage.h b/src/diskfiles/dos33/dos33diskimage.h index 8d8a0e5..e8dd938 100644 --- a/src/diskfiles/dos33/dos33diskimage.h +++ b/src/diskfiles/dos33/dos33diskimage.h @@ -11,22 +11,25 @@ #include "sector.h" #include "vtoc.h" +#include "rawdiskimage.h" +#include "chunkbytelist.h" + + class GenericFile; +using FileList = QList; + class Dos33DiskImage { public: Dos33DiskImage(QString filename = ""); + Dos33DiskImage(RawDiskImage *rawImage); ~Dos33DiskImage(); bool read(QString filename); - Sector &getSector(TSPair ts) { return m_contents[ts]; } - - Sector &getSector(int track, int sector) { - TSPair ts(track,sector); - return getSector(ts); - } + Sector &getSector(TSPair ts); + Sector &getSector(int track, int sector); VTOC getVTOC(); @@ -34,34 +37,36 @@ public: GenericFile *getFile(FileDescriptiveEntry fde); - QByteArray getDataFromTrackSectorList(TrackSectorList tsl); + ChunkByteList getDataFromTrackSectorList(TrackSectorList tsl); QList getAllFDEs(); QByteArray fileHash() const { return m_hash; } - QString getDiskImageName() const { return m_imageName; } - QString getFullDiskImageName() const { return m_fullImageName; } + QString getDiskImageName() const { return m_disk_image->diskImageName(); } + QString getFullDiskImageName() const { return m_disk_image->fullDiskImageName(); } QString getMetaDataPath() const; QString fileType() const { return m_fileType; } void setFileType(QString type) { m_fileType = type; } - quint8 sectorsPerTrack() const { return m_sectors_per_track; } - quint8 tracks() const { return 35; } + int sectorsPerTrack() const { return m_disk_image->sectorsPerTrack(); } + int tracks() const { return m_disk_image->numTracks(); } + + QList fileList(); + + private: + RawDiskImage *m_disk_image; + QMap m_contents; QMap m_files; QByteArray m_hash; - QString m_imageName; - QString m_fullImageName; - QString m_fileType; - quint8 m_sectors_per_track; }; diff --git a/src/diskfiles/dos33/dos33disktreeview.cpp b/src/diskfiles/dos33/dos33disktreeview.cpp new file mode 100644 index 0000000..6e86db4 --- /dev/null +++ b/src/diskfiles/dos33/dos33disktreeview.cpp @@ -0,0 +1,32 @@ +#include "dos33disktreeview.h" + +#include + +Dos33DiskTreeView::Dos33DiskTreeView(QWidget *parent) : QTreeView(parent) +{ + connect(this, &Dos33DiskTreeView::clicked, + this, &Dos33DiskTreeView::handleClick); + connect(this, &Dos33DiskTreeView::pressed, + this, &Dos33DiskTreeView::handlePress); + connect(this, &Dos33DiskTreeView::doubleClicked, + this, &Dos33DiskTreeView::handleDoubleClick); + +} + +void Dos33DiskTreeView::handleClick(const QModelIndex &/*index*/) +{ + +} + +void Dos33DiskTreeView::handleDoubleClick(const QModelIndex &/*index*/) +{ + +} + +void Dos33DiskTreeView::handlePress(const QModelIndex &/*index*/) +{ + if (QGuiApplication::mouseButtons() & Qt::RightButton) + { + + } +} diff --git a/src/diskfiles/dos33/dos33disktreeview.h b/src/diskfiles/dos33/dos33disktreeview.h new file mode 100644 index 0000000..aac1623 --- /dev/null +++ b/src/diskfiles/dos33/dos33disktreeview.h @@ -0,0 +1,38 @@ +#ifndef DOS33DISKTREEVIEW_H +#define DOS33DISKTREEVIEW_H + +#include +#include + +#include "filedescriptiveentry.h" + +class Dos33DiskTreeView : public QTreeView +{ + Q_OBJECT +public: + Dos33DiskTreeView(QWidget *parent = nullptr); + +protected: + + +signals: + void fileClicked(const FileDescriptiveEntry &fde); + void fileRightClicked(const FileDescriptiveEntry &fde); + void fileDoubleClicked(const FileDescriptiveEntry &fde); + void diskClicked(QString name); + void diskRightClicked(QString name); + void sectorClicked(TSPair ts); + 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 diff --git a/src/diskfiles/dos33/dos33imagemodel.cpp b/src/diskfiles/dos33/dos33imagemodel.cpp index ae57ae1..aedb7c5 100644 --- a/src/diskfiles/dos33/dos33imagemodel.cpp +++ b/src/diskfiles/dos33/dos33imagemodel.cpp @@ -43,7 +43,7 @@ bool Dos33ImageModel::addDiskImage(Dos33DiskImage *image, QString name) if (!fde.deleted) { QString fn = AppleString(fde.filename).appleFontPrintable(); - QString type = fde.fileType(); + QString type = fde.fileTypeIdentifier(); QIcon icon; if (type == "A") { icon = m_icon_A; } @@ -53,14 +53,23 @@ bool Dos33ImageModel::addDiskImage(Dos33DiskImage *image, QString name) else if (type == "I") { icon = m_icon_I; } else if (type == "a") { icon = m_icon_a; } else if (type == "b") { icon = m_icon_b; } - else { icon = m_icon_S; } + else if (type == "S") { icon = m_icon_S; } auto item = new Dos33TreeItem(icon,fn); - QVariant data; - data.setValue(fde.firstTSListSector()); - item->setData(data); + QVariant typevar = (int) Dos33ItemType::File; + item->setData(typevar, (int) Dos33TreeRole::ItemType); + + QVariant datavar; + datavar.setValue(fde.firstTSListSector()); + item->setData(datavar, (int) Dos33TreeRole::GetTSPair); + + QVariant fdevar; + fdevar.setValue(fde); + item->setData(fdevar, (int) Dos33TreeRole::GetFDE); + + item->setToolTip(QString("%1 Block(s)").arg(fde.lengthInSectors)); diskImageItem->appendRow(item); } diff --git a/src/diskfiles/dos33/dos33imagemodel.h b/src/diskfiles/dos33/dos33imagemodel.h index c02efb6..3e905f5 100644 --- a/src/diskfiles/dos33/dos33imagemodel.h +++ b/src/diskfiles/dos33/dos33imagemodel.h @@ -9,6 +9,20 @@ #include +enum class Dos33TreeRole { + ItemType = Qt::UserRole, + GetTSPair, + GetFDE, +}; + +enum class Dos33ItemType { + Unknown, + Sector, + File, + DiskImage +}; + + class Dos33ImageModel : public QStandardItemModel { Q_OBJECT diff --git a/src/diskfiles/dos33/filedescriptiveentry.h b/src/diskfiles/dos33/filedescriptiveentry.h index 14cd3c0..362f727 100644 --- a/src/diskfiles/dos33/filedescriptiveentry.h +++ b/src/diskfiles/dos33/filedescriptiveentry.h @@ -21,15 +21,15 @@ struct FileDescriptiveEntry { return f1.filename < filename; } - QString fileType() { - if (fileTypeFlags & (quint8) FileTypeFlag::Integer) { return "I"; } - if (fileTypeFlags & (quint8) FileTypeFlag::Applesoft) { return "A"; } - if (fileTypeFlags & (quint8) FileTypeFlag::Relocatable) { return "R"; } - if (fileTypeFlags & (quint8) FileTypeFlag::Binary) { return "B"; } - if (fileTypeFlags & (quint8) FileTypeFlag::TypeS) { return "S"; } - if (fileTypeFlags & (quint8) FileTypeFlag::TypeA) { return "a"; } - if (fileTypeFlags & (quint8) FileTypeFlag::TypeB) { return "b"; } - return "T"; + QString fileTypeIdentifier() { + if (fileTypeFlags & (quint8) FileTypeFlag::Integer) { return "I"; } + else if (fileTypeFlags & (quint8) FileTypeFlag::Applesoft) { return "A"; } + else if (fileTypeFlags & (quint8) FileTypeFlag::Relocatable) { return "R"; } + else if (fileTypeFlags & (quint8) FileTypeFlag::Binary) { return "B"; } + else if (fileTypeFlags & (quint8) FileTypeFlag::TypeS) { return "S"; } + else if (fileTypeFlags & (quint8) FileTypeFlag::TypeA) { return "a"; } + else if (fileTypeFlags & (quint8) FileTypeFlag::TypeB) { return "b"; } + else return "T"; } bool isLocked() { return (fileTypeFlags & (quint8) FileTypeFlag::IsLockedFlag); } @@ -38,7 +38,7 @@ struct FileDescriptiveEntry { qDebug() << "First TS List Sector: Track: " << QString("%1").arg(firstTSListSector().track(),2,16,QChar('0')).toUpper() << " Sector: " << QString("%1").arg(firstTSListSector().sector(),2,16,QChar('0')).toUpper(); - qDebug() << "File Type and Flags: " << QString::number((quint8) fileTypeFlags) << "(" << fileType() << "," << (isLocked()?"Locked":"Unlocked") << ")"; + qDebug() << "File Type and Flags: " << QString::number((quint8) fileTypeFlags) << "(" << fileTypeIdentifier() << "," << (isLocked()?"Locked":"Unlocked") << ")"; qDebug() << "Filename: " << filename.printable(); qDebug() << "Length in Sectors: " << lengthInSectors; } @@ -46,7 +46,7 @@ struct FileDescriptiveEntry { void catalog() { QString output = QString("%1 %2 %3 %4").arg(QString(isLocked()?"*":" ")) .arg(lengthInSectors,3,10,QChar('0')) - .arg(fileType()) + .arg(fileTypeIdentifier()) .arg(filename.printable().trimmed()); qDebug() << output; } @@ -68,5 +68,5 @@ private: TSPair m_firstTSListSector; }; - +Q_DECLARE_METATYPE(FileDescriptiveEntry); #endif // FILEDESCRIPTIVEENTRY_H diff --git a/src/diskfiles/dos33/genericfile.cxx b/src/diskfiles/dos33/genericfile.cxx index 5c686fa..0681bfd 100644 --- a/src/diskfiles/dos33/genericfile.cxx +++ b/src/diskfiles/dos33/genericfile.cxx @@ -2,20 +2,40 @@ GenericFile::GenericFile(QByteArray data) { + m_data_loaded = false; m_diskfile = 0; if (!data.isEmpty()) { setData(data); + m_data_loaded = true; } m_address = 0x00; m_length = 0x00; + m_ignore_offset = 0; +} + +GenericFile::GenericFile(Dos33DiskImage *image, TSPairList pairs) +{ + m_diskfile = image; + m_ts_pairs = pairs; + m_length = 0x00; + m_address = 0x00; + m_ignore_offset = 0; + m_data_loaded = false; +} + +quint8 GenericFile::dataAt(int offset) const +{ + return m_data[offset ]; } void GenericFile::setData(QByteArray data) { + m_data_loaded = true; m_data = data; m_length = data.size(); } + QString GenericFile::getFileType() const { if (m_file_type == "A" || m_file_type == "B" || m_file_type == "T" || @@ -29,3 +49,10 @@ QString GenericFile::getFileType() const return "?"; } } + + + +quint16 GenericFile::dataWordAt(int offset) const +{ + return makeWord(dataAt(offset),dataAt(offset+1)); +} diff --git a/src/diskfiles/dos33/genericfile.h b/src/diskfiles/dos33/genericfile.h index 8ceb168..2bc3031 100644 --- a/src/diskfiles/dos33/genericfile.h +++ b/src/diskfiles/dos33/genericfile.h @@ -9,23 +9,22 @@ class GenericFile { + friend class Dos33DiskImage; + public: - GenericFile(QByteArray data = QByteArray()); virtual ~GenericFile() { } - virtual void setData(QByteArray data); - virtual QByteArray data() { return m_data; } - - void setFilename(QString filename) { m_filename = filename; } + virtual QByteArray data() { return m_data.mid(m_ignore_offset); } + quint8 dataAt(int offset) const; + quint16 dataWordAt(int offset) const; + + virtual void setFilename(QString filename) { m_filename = filename; } QString filename() const { return m_filename; } virtual void setAddress(quint16 location) { m_address = location; } virtual quint16 address() { return m_address; } - virtual QByteArray rawData() { return m_data; } - - virtual void setLength(quint16 length) { m_length = length; } - virtual quint16 length() const { return m_length; } + virtual int length() const { return m_length; } Dos33DiskImage *diskFile() const { return m_diskfile; } void setDiskFile(Dos33DiskImage *diskfile) { m_diskfile = diskfile; } @@ -33,13 +32,27 @@ public: void setFileType(QString type) { m_file_type = type; } QString getFileType() const; -protected: + QByteArray rawData() const { return m_data; } + void setIgnoreOffset(int offset) { m_ignore_offset = offset; } + int ignoreOffset() const { return m_ignore_offset; } + +protected: + GenericFile(Dos33DiskImage *image, QList pairs); + + GenericFile(QByteArray data = QByteArray()); + virtual void setLength(quint16 length) { m_length = length; } + virtual void setData(QByteArray data); + +private: + int m_ignore_offset; QByteArray m_data; QString m_filename; quint16 m_address; qint16 m_length; Dos33DiskImage * m_diskfile; + bool m_data_loaded; + TSPairList m_ts_pairs; QString m_file_type; diff --git a/src/diskfiles/dos33/sector.cxx b/src/diskfiles/dos33/sector.cxx index 808c7c7..dda00b8 100644 --- a/src/diskfiles/dos33/sector.cxx +++ b/src/diskfiles/dos33/sector.cxx @@ -3,19 +3,13 @@ #include #include -QByteRef Sector::operator[](uint offset) { +quint8 Sector::operator[](uint offset) const { if (offset > 255) { offset = 255; } - return m_data[offset]; + return m_raw_data->at(offset); } -bool Sector::setData(QByteArray data) { - if (data.length() != 256) return false; - - m_data = data; - return true; -} void Sector::dump() { qDebug() << "Dumping Track " << track() << "Sector " << sector() << " ..."; @@ -27,7 +21,7 @@ void Sector::dump() { for (int idx = 0; idx < 16; idx++) { int offset = (jdx*16) + idx; - quint8 val = m_data[offset]; + quint8 val = m_raw_data->at(offset); line += QString("%1 ").arg(uint16ToHex(val)); if (idx == 7) line += " "; } @@ -36,7 +30,7 @@ void Sector::dump() { for (int idx = 0; idx < 16; idx++) { int offset = (jdx*16) + idx; - quint8 val = m_data[offset]; + quint8 val = m_raw_data->at(offset); if (val > 127) { val -= 128; } QChar ch(val); line += QString("%1").arg(ch.isPrint()?ch:'.'); diff --git a/src/diskfiles/dos33/sector.h b/src/diskfiles/dos33/sector.h index 014133f..bb8c7eb 100644 --- a/src/diskfiles/dos33/sector.h +++ b/src/diskfiles/dos33/sector.h @@ -3,6 +3,8 @@ #include +#include "rawdiskimage.h" + #include "vtoc.h" #include "catalogsector.h" #include "tracksectorlist.h" @@ -11,12 +13,18 @@ class Sector { public: - Sector() { - m_data.resize(256); + Sector(SectorData *data = nullptr) { + // m_data.resize(256); + setData(data); m_track = 255; m_sector = 255; } + void setData(SectorData *data) + { + m_raw_data = data; + } + VTOC promoteToVTOC() { return VTOC(this); } @@ -45,18 +53,19 @@ public: void setTrack(int track) { m_track = track; } void setSector(int sector) { m_sector = sector; } - QByteRef operator[](uint offset); - - bool setData(QByteArray data); + quint8 operator[](uint offset) const; + quint8 at(int offset) { return m_raw_data->at(offset); } void dump(); - QByteArray rawData() { return m_data; } + SectorData *rawData() { return m_raw_data; } private: - QByteArray m_data; + // QByteArray m_data; int m_track; int m_sector; + + SectorData *m_raw_data; }; #endif // SECTOR_H diff --git a/src/diskfiles/dos33/tracksectorlist.cxx b/src/diskfiles/dos33/tracksectorlist.cxx index 014ef3f..82e446f 100644 --- a/src/diskfiles/dos33/tracksectorlist.cxx +++ b/src/diskfiles/dos33/tracksectorlist.cxx @@ -6,15 +6,15 @@ TrackSectorList::TrackSectorList(Sector *data) { m_data = data; - m_next_tslist.setTrack(m_data->rawData()[0x01]); - m_next_tslist.setSector(m_data->rawData()[0x02]); + m_next_tslist.setTrack(m_data->at(0x01)); + m_next_tslist.setSector(m_data->at(0x02)); - m_sector_offset.setTrack(m_data->rawData()[0x05]); - m_sector_offset.setSector(m_data->rawData()[0x06]); + m_sector_offset.setTrack(m_data->at(0x05)); + m_sector_offset.setSector(m_data->at(0x06)); for (int idx = 0x0C; idx < 0xff; idx+=2) { - TSPair ts(m_data->rawData()[idx],m_data->rawData()[idx+1]); + TSPair ts(m_data->at(idx),m_data->at(idx+1)); if (ts == TSPair(0,0) && ts.isValid()) { break; } else { diff --git a/src/diskfiles/dos33/tracksectorlist.h b/src/diskfiles/dos33/tracksectorlist.h index ea0f4f2..72868ac 100644 --- a/src/diskfiles/dos33/tracksectorlist.h +++ b/src/diskfiles/dos33/tracksectorlist.h @@ -5,6 +5,8 @@ class Sector; +using TSPairList = QList; + class TrackSectorList { public: @@ -16,14 +18,14 @@ public: TSPair getSectorOffset() const { return m_sector_offset; } bool isSectorOffsetValid() const; - QList getDataTSPairs() const { return m_ts_pairs_for_data; } - QList getValidTSPairs() const; + TSPairList getDataTSPairs() const { return m_ts_pairs_for_data; } + TSPairList getValidTSPairs() const; private: TSPair m_next_tslist; TSPair m_sector_offset; - QList m_ts_pairs_for_data; + TSPairList m_ts_pairs_for_data; Sector *m_data; }; diff --git a/src/diskfiles/dos33/vtoc.cxx b/src/diskfiles/dos33/vtoc.cxx index 83fd95f..e71e227 100644 --- a/src/diskfiles/dos33/vtoc.cxx +++ b/src/diskfiles/dos33/vtoc.cxx @@ -13,40 +13,40 @@ VTOC::VTOC(Sector *data) TSPair VTOC::firstCatalogSector() { // return TSPair(0x11,0x0f); // Force to look at the normal location - return TSPair(m_data->rawData()[0x01], m_data->rawData()[0x02]); + return TSPair(m_data->at(0x01), m_data->at(0x02)); } quint8 VTOC::dosVersion() { - return m_data->rawData()[0x03]; + return m_data->at(0x03); } quint8 VTOC::volumeNumber() { - return m_data->rawData()[0x06]; + return m_data->at(0x06); } quint8 VTOC::maxTSPairs() { - return m_data->rawData()[0x27]; + return m_data->at(0x27); } quint8 VTOC::lastTrackAllocated() { - return m_data->rawData()[0x30]; + return m_data->at(0x30); } qint8 VTOC::directionOfAllocation() { - return m_data->rawData()[0x31]; + return m_data->at(0x31); } quint8 VTOC::tracksPerDisk() { - return m_data->rawData()[0x34]; + return m_data->at(0x34); } quint8 VTOC::sectorsPerDisk() { - return m_data->rawData()[0x35]; + return m_data->at(0x35); } qint16 VTOC::bytesPerSector() { - return makeWord(m_data->rawData()[0x36], - m_data->rawData()[0x37]); + return makeWord(m_data->at(0x36), + m_data->at(0x37)); } bool VTOC::isSectorInUse(TSPair ts) const { @@ -55,8 +55,8 @@ bool VTOC::isSectorInUse(TSPair ts) const { quint8 baseaddr = (track * 4) + 0x38; //quint16 word = (((quint16) m_data->rawData()[baseaddr]) *256) + (quint8) m_data->rawData()[baseaddr+1]; - quint16 word = makeWord(m_data->rawData()[baseaddr+1], - m_data->rawData()[baseaddr]); + quint16 word = makeWord(m_data->at(baseaddr+1), + m_data->at(baseaddr)); quint16 bitpos = (quint16) 0x01 << (quint16) sec; return !(word & bitpos); @@ -119,7 +119,7 @@ void VTOC::dump() qDebug() << " Number sectors per disk: " << QString::number(sectorsPerDisk()); qDebug() << " Number bytes/sector: " << QString::number(bytesPerSector()); qDebug() << " Track Usage (.=free, 0-F=used):"; - for (quint8 track = 0; track < m_data->rawData()[0x34];track++) + for (quint8 track = 0; track < m_data->at(0x34);track++) { qDebug() << " " << QString("Track %1:").arg((int) track,2,10,QChar('0')) << buildUseString(track); } diff --git a/src/diskfiles/dos33/vtoc.h b/src/diskfiles/dos33/vtoc.h index c91fbbe..d9e48fe 100644 --- a/src/diskfiles/dos33/vtoc.h +++ b/src/diskfiles/dos33/vtoc.h @@ -14,17 +14,18 @@ class VTOC public: VTOC(Sector *data); - void dump(); + void dump(); TSPair firstCatalogSector(); quint8 dosVersion(); quint8 volumeNumber(); quint8 maxTSPairs(); quint8 lastTrackAllocated(); - qint8 directionOfAllocation(); + qint8 directionOfAllocation(); quint8 tracksPerDisk(); quint8 sectorsPerDisk(); qint16 bytesPerSector(); - bool isSectorInUse(TSPair ts) const; + + bool isSectorInUse(TSPair ts) const; QList sectorsInUse() const; QList sectorsNotInUse() const; diff --git a/src/diskfiles/rawdiskimage.cpp b/src/diskfiles/rawdiskimage.cpp new file mode 100644 index 0000000..d480772 --- /dev/null +++ b/src/diskfiles/rawdiskimage.cpp @@ -0,0 +1,194 @@ +#include "rawdiskimage.h" + +#include +#include +#include +#include + +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; +} diff --git a/src/diskfiles/rawdiskimage.h b/src/diskfiles/rawdiskimage.h new file mode 100644 index 0000000..302cd97 --- /dev/null +++ b/src/diskfiles/rawdiskimage.h @@ -0,0 +1,103 @@ +#ifndef RAWDISKIMAGE_H +#define RAWDISKIMAGE_H + +#include "tspair.h" + +#include +#include +#include + +using SectorOrderMap = QByteArray; + +using SectorData = QByteArray; +//PRODOS using BlockData = QByteArray; +//PRODOS using BlockPair = QPair; +using TrackData = QList; +using TrackList = QList; + +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 diff --git a/src/diskfiles/dos33/tspair.cpp b/src/diskfiles/tspair.cpp similarity index 100% rename from src/diskfiles/dos33/tspair.cpp rename to src/diskfiles/tspair.cpp diff --git a/src/diskfiles/dos33/tspair.h b/src/diskfiles/tspair.h similarity index 73% rename from src/diskfiles/dos33/tspair.h rename to src/diskfiles/tspair.h index c8df5f8..b84a830 100644 --- a/src/diskfiles/dos33/tspair.h +++ b/src/diskfiles/tspair.h @@ -8,10 +8,10 @@ class TSPair { public: TSPair() { m_track = m_sector = 0; } - TSPair(quint8 trackval, quint8 secval) { m_track=trackval; m_sector = secval; } - TSPair(QPair pair) { m_track = pair.first; m_sector = pair.second;} + TSPair(int trackval, int secval) { m_track=trackval; m_sector = secval; } + TSPair(QPair pair) { m_track = pair.first; m_sector = pair.second;} - void setTrack(quint8 tracknum) + void setTrack(int tracknum) { if (tracknum > 34 && tracknum != 0xff) { qWarning("Setting a track with value %d (> 34 and not 256).",tracknum); @@ -34,8 +34,8 @@ public: return retval; } - quint8 track() const { return m_track; } - quint8 sector() const { return m_sector; } + int track() const { return m_track; } + int sector() const { return m_sector; } bool operator==(const TSPair &other) const { if (other.track() == track() && other.sector() == sector()) return true; @@ -57,14 +57,14 @@ public: } } - QPair toQPair() { return QPair(track(),sector()); } + QPair toQPair() { return QPair(track(),sector()); } void dump() const { qDebug() << "TSPair: track: " << track() << " sector: " << sector(); } private: - quint8 m_track; - quint8 m_sector; + int m_track; + int m_sector; }; Q_DECLARE_METATYPE(TSPair); diff --git a/src/intbasic/IntBasicFile.h b/src/intbasic/IntBasicFile.h index 48aa319..b8e4c92 100644 --- a/src/intbasic/IntBasicFile.h +++ b/src/intbasic/IntBasicFile.h @@ -6,11 +6,13 @@ class IntBasicFile : public GenericFile { -public: - IntBasicFile(QByteArray data = QByteArray()); + friend class Dos33DiskImage; +public: QByteArray detokenize(); + private: + IntBasicFile(QByteArray data = QByteArray()); quint16 get16(quint8 v1, quint8 v2); QByteArray dumpBufferAsIntBasicFile(QByteArray origdata); }; diff --git a/src/qdarkstyle/style.qss b/src/qdarkstyle/style.qss index 7b85e60..da84ee8 100644 --- a/src/qdarkstyle/style.qss +++ b/src/qdarkstyle/style.qss @@ -1,12 +1,4 @@ -/* --------------------------------------------------------------------------- - Created by the qtsass compiler v0.1.1 - - The definitions are in the "qdarkstyle.qss._styles.scss" module - - WARNING! All changes made in this file will be lost! - ---------------------------------------------------------------------------- */ /* QDarkStyleSheet ----------------------------------------------------------- This is the main style sheet, the palette has nine colors. @@ -1010,7 +1002,7 @@ QPushButton { padding: 3px; outline: none; /* Issue #194 - Special case of QPushButton inside dialogs, for better UI */ - min-width: 80px; + min-width: 80px; } QPushButton:disabled { @@ -2187,3 +2179,13 @@ background-color: #32414B; color: #aaa; } + +DEButton { + background-color: #505F69; + border: 1px solid #32414B; + color: #F0F0F0; + border-radius: 4px; + padding: 2px; + outline: none; + min-width: 10px; +} diff --git a/src/relocatablefile/relocatablefile.cxx b/src/relocatablefile/relocatablefile.cxx index cff6587..03c49e3 100644 --- a/src/relocatablefile/relocatablefile.cxx +++ b/src/relocatablefile/relocatablefile.cxx @@ -10,18 +10,18 @@ RelocatableFile::RelocatableFile(QByteArray data) : GenericFile(data) } } -void RelocatableFile::setData(QByteArray data) +void RelocatableFile::setData(QByteArray /*data*/) { // qDebug() << "setData()"; - if (data.length() >= 6) { - m_starting_ram_address = makeWord(m_data[0],m_data[1]); - m_ram_image_length = makeWord(m_data[2],m_data[3]); - m_code_image_length = makeWord(m_data[4],m_data[5]); + if (length() >= 6) { + m_starting_ram_address = dataWordAt(0); + m_ram_image_length = dataWordAt(2); + m_code_image_length = dataWordAt(4); int offset = 0; for (int idx = 6; idx < m_code_image_length+6; idx++) { - quint8 val = m_data[idx]; + quint8 val = dataAt(idx); m_binary_code_image.append(val); } @@ -33,14 +33,12 @@ void RelocatableFile::setData(QByteArray data) // << uint8ToHex(m_data[offset+2]) // << uint8ToHex(m_data[offset+3]); - RelocatableDictItem rdi = RelocatableDictItem(m_data[offset],m_data[offset+1], - m_data[offset+2],m_data[offset+3]); + RelocatableDictItem rdi = RelocatableDictItem( + dataAt(offset),dataAt(offset+1), + dataAt(offset+2),dataAt(offset+3)); m_relocatable_dict.append(rdi); if (rdi.isEndOfRLD()) { break; } } - - - } } diff --git a/src/relocatablefile/relocatablefile.h b/src/relocatablefile/relocatablefile.h index 9a31762..f2455b7 100644 --- a/src/relocatablefile/relocatablefile.h +++ b/src/relocatablefile/relocatablefile.h @@ -77,12 +77,10 @@ private: class RelocatableFile : public GenericFile { + friend class Dos33DiskImage; + public: - RelocatableFile(QByteArray data = QByteArray()); - void setData(QByteArray data); - - virtual quint16 length() { return m_data.length(); } void dump(); @@ -95,6 +93,9 @@ public: QStringList decodeRelocatableDict(); protected: + RelocatableFile(QByteArray data = QByteArray()); + void setData(QByteArray data); + quint16 m_starting_ram_address; quint16 m_ram_image_length; quint16 m_code_image_length; diff --git a/src/textfile/textfile.cxx b/src/textfile/textfile.cxx index 7fb65ff..993b304 100644 --- a/src/textfile/textfile.cxx +++ b/src/textfile/textfile.cxx @@ -8,10 +8,6 @@ TextFile::TextFile(QByteArray data) : GenericFile(data) } } -void TextFile::setData(QByteArray data) -{ - m_data = data; -} void TextFile::dump() { diff --git a/src/textfile/textfile.h b/src/textfile/textfile.h index 5de2518..1e25f69 100644 --- a/src/textfile/textfile.h +++ b/src/textfile/textfile.h @@ -5,13 +5,14 @@ class TextFile : public GenericFile { + friend class Dos33DiskImage; + public: - TextFile(QByteArray data = QByteArray()); - void setData(QByteArray data); void dump(); protected: + TextFile(QByteArray data = QByteArray()); }; #endif // TEXTFILE_H diff --git a/src/ui/catalogwidget.cxx b/src/ui/catalogwidget.cxx index 3e99c8d..3c4f09c 100644 --- a/src/ui/catalogwidget.cxx +++ b/src/ui/catalogwidget.cxx @@ -42,7 +42,7 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) { QString retval; retval += AppleString(fde.filename).printable().trimmed() + (fde.deleted?"(Deleted)":"") + "\n"; - retval += QString("Type: %1\n").arg(fde.fileType()); + retval += QString("Type: %1\n").arg(fde.fileTypeIdentifier()); retval += QString("Sectors: %1 (%2 bytes)\n") .arg(fde.lengthInSectors) .arg(fde.lengthInSectors*256); @@ -54,12 +54,12 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) { .arg(address); if (dynamic_cast(file)) { BinaryFile *binfile = dynamic_cast(file); - quint16 length = binfile->length(); + auto length = binfile->length(); retval += QString("Length: $%1 (%2)\n").arg((quint16) (length),4,16,QChar('0')) .arg(length); } else if (dynamic_cast(file)) { ApplesoftFile *asfile = dynamic_cast(file); - quint16 length = asfile->length(); + auto length = asfile->length(); retval += QString("Length: $%1 (%2)\n").arg((quint16) (length),4,16,QChar('0')) .arg(length); quint16 uabytes = asfile->extraData().length(); @@ -87,7 +87,7 @@ void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, Dos33DiskImage int idx = 0; foreach(FileDescriptiveEntry fde, m_disk->getAllFDEs()) { // qDebug() << " Processing FDE# " << idx; - QString filetype = fde.fileType(); + QString filetype = fde.fileTypeIdentifier(); QString filename = AppleString(fde.filename).printable().trimmed(); quint16 size = fde.lengthInSectors; bool locked = fde.isLocked(); diff --git a/src/ui/central/centralappwindow.cpp b/src/ui/central/centralappwindow.cpp index b6a0ea2..c9cc8c7 100644 --- a/src/ui/central/centralappwindow.cpp +++ b/src/ui/central/centralappwindow.cpp @@ -3,8 +3,9 @@ #include "dos33diskimage.h" #include "dos33imagemodel.h" - +#include "dos33disktreeview.h" #include "sequencetoolbox.h" +#include "DiskExplorerMapWidget.h" #include #include @@ -15,6 +16,9 @@ #include #include #include +#include +#include + #include @@ -36,8 +40,8 @@ CentralAppWindow::CentralAppWindow(QWidget *parent) : QMainWindow(parent) initToolBars(); initDockWidgets(); initStatusBar(); + initCentralWidget(); - setCentralWidget(new SequenceViewer()); } void CentralAppWindow::createActions() @@ -74,14 +78,13 @@ void CentralAppWindow::initToolBars() void CentralAppWindow::initDockWidgets() { QDockWidget *container = new QDockWidget(this); - // container->setLayout(new QGridLayout()); container->setMinimumWidth(200); container->setFeatures(QDockWidget::DockWidgetMovable); m_project_area = new QWidget(container); m_project_area->setMinimumSize(300,200); - m_directory_area = new QTreeView(container); + m_directory_area = new Dos33DiskTreeView(container); m_directory_area->setFont(QFont("Pr Number 3", 12)); m_directory_area->setMinimumSize(300,200); @@ -114,7 +117,7 @@ void CentralAppWindow::initDockWidgets() QDockWidget *stb = new QDockWidget(this); stb->setMinimumWidth(200); stb->setFeatures(QDockWidget::DockWidgetMovable); - stb->setLayout(new QGridLayout()); + // stb->setLayout(new QGridLayout()); m_toolbox = new SequenceToolBox(this); @@ -124,3 +127,20 @@ void CentralAppWindow::initDockWidgets() } + +void CentralAppWindow::initCentralWidget() +{ + m_central_stack = new QStackedWidget(this); + QScrollArea *sa = new QScrollArea(m_central_stack); + sa->setWidgetResizable(true); + m_central_stack->addWidget(sa); + + setCentralWidget(m_central_stack); + + Dos33DiskImage *img = new Dos33DiskImage("c:/develop/git/AppleSAWS/disk-images/ApplesoftToolkit.dsk"); + auto dew = new DiskExplorerMapWidget(img->tracks(),img->sectorsPerTrack()); + dew->setDisk(img); + sa->setWidget(dew); + // m_central_stack->addWidget(dew); +//new SequenceViewer() +} diff --git a/src/ui/central/centralappwindow.h b/src/ui/central/centralappwindow.h index 0a63808..6ebb7ee 100644 --- a/src/ui/central/centralappwindow.h +++ b/src/ui/central/centralappwindow.h @@ -8,6 +8,7 @@ class QTreeView; class QAction; class QStatusBar; class SequenceToolBox; +class QStackedWidget; class CentralAppWindow : public QMainWindow { @@ -22,6 +23,7 @@ private: void initStatusBar(); void initToolBars(); void initDockWidgets(); + void initCentralWidget(); private: QAction *m_quitAction; @@ -32,6 +34,8 @@ private: QStatusBar *m_status_bar; SequenceToolBox *m_toolbox; + + QStackedWidget *m_central_stack; }; #endif // CENTRALAPPWINDOW_H diff --git a/src/ui/diskexplorer/DiskExplorer.cpp b/src/ui/diskexplorer/DiskExplorer.cpp index c5b3009..4aa65d9 100644 --- a/src/ui/diskexplorer/DiskExplorer.cpp +++ b/src/ui/diskexplorer/DiskExplorer.cpp @@ -36,7 +36,7 @@ DiskExplorer::~DiskExplorer() void DiskExplorer::initUi() { QMenuBar *menuBar = new QMenuBar(this); - setMenuBar(menuBar); + setMenuBar(menuBar); QMenu *menu = new QMenu(tr("&File"),this); menuBar->addMenu(menu); @@ -100,7 +100,7 @@ void DiskExplorer::initUi() // if (!m_notesDialog) m_notesDialog = new NotesDialog(this); // connect(action_Notes, &QAction::triggered, m_notesDialog, &NotesDialog::show); - QWidget *widget = new QWidget(0); + QWidget *widget = new QWidget(nullptr); m_gridLayout = new QGridLayout(); m_gridLayout->setVerticalSpacing(4); m_gridLayout->setHorizontalSpacing(4); @@ -125,7 +125,12 @@ void DiskExplorer::initUi() m_key = m_demw->makeKeyWidget(); m_gridLayout->addWidget(m_key,1,1); m_gridLayout->addWidget(m_frame,1,2); + this->setCentralWidget(widget); +// auto lo = new QGridLayout(); +// this->setLayout(lo); +// lo->addWidget(widget); + connect(m_cw, &CatalogWidget::openWithDefaultViewer, this, &DiskExplorer::handleDiskItemSelectedDefaultOpen); diff --git a/src/ui/diskexplorer/DiskExplorerMapWidget.cpp b/src/ui/diskexplorer/DiskExplorerMapWidget.cpp index b2b5451..bcd669e 100644 --- a/src/ui/diskexplorer/DiskExplorerMapWidget.cpp +++ b/src/ui/diskexplorer/DiskExplorerMapWidget.cpp @@ -25,8 +25,9 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid setWindowTitle("Disk Explorer"); QGridLayout *gridlayout = new QGridLayout(this); - gridlayout->setSizeConstraint(QLayout::SetFixedSize); - gridlayout->setHorizontalSpacing(2); + // gridlayout->setSizeConstraint(QLayout::SetFixedSize); + gridlayout->setSizeConstraint(QLayout::SetMinimumSize); + gridlayout->setHorizontalSpacing(1); gridlayout->setVerticalSpacing(1); initColors(); @@ -37,7 +38,7 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid gridlayout->addWidget(tracklabel,0,0,1,m_numtracks+1,Qt::AlignHCenter); for (int track= 0; track < numtracks; track++) { - QLabel *label = new QLabel(QString("%1").arg(track)); + QLabel *label = new QLabel(QString("%1").arg(track,2,10,QChar('0'))); label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); gridlayout->addWidget(label,1,track+1); } @@ -64,13 +65,16 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid gridlayout->addWidget(tb,sec+2,track+1); } } + gridlayout->addWidget(new QLabel("Stretchy Row"),18,0,1,5); + gridlayout->setRowStretch(18,900); + makeStatusWidget(); } void DiskExplorerMapWidget::makeStatusWidget() { - QWidget *statusWidget = new QWidget(this); + QWidget *statusWidget = new QWidget; QHBoxLayout *hbl = new QHBoxLayout(); statusWidget->setLayout(hbl); @@ -125,8 +129,8 @@ 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()); + QByteArray *data = sec.rawData(); + emit showSectorData(*data,track,sector,QVariant()); m_trackSectorLabel->setText( QString("Track: %1 Sector: %2 (%3)") .arg(track) @@ -215,7 +219,7 @@ QLabel *DiskExplorerMapWidget::makeKeyLabel(QWidget *parent, QString name, QColo QGroupBox *DiskExplorerMapWidget::makeKeyWidget() { int idx = 0; - QGroupBox *groupbox= new QGroupBox(this); + QGroupBox *groupbox= new QGroupBox(); groupbox->setTitle("Key"); QGridLayout *layout = new QGridLayout(); layout->setVerticalSpacing(0); @@ -354,15 +358,15 @@ void DiskExplorerMapWidget::mapDiskToButtons() m_sectorDescriptions.insert(DETSPair(tr,se),description); QColor color; - if (fde.fileType() == "I") color = m_intBasicFileColor; - else if (fde.fileType() == "A") color = m_applesoftFileColor; - else if (fde.fileType() == "R") color = m_reloFileColor; - else if (fde.fileType() == "B") color = m_binaryFileColor; - else if (fde.fileType() == "S") color = m_typeSFileColor; - else if (fde.fileType() == "T") color = m_textFileColor; - else if (fde.fileType() == "a") color = m_typeAFileColor; - else if (fde.fileType() == "b") color = m_typeBFileColor; - else qDebug() << "Unknown file type: " << fde.fileType(); + if (fde.fileTypeIdentifier() == "I") color = m_intBasicFileColor; + else if (fde.fileTypeIdentifier() == "A") color = m_applesoftFileColor; + else if (fde.fileTypeIdentifier() == "R") color = m_reloFileColor; + else if (fde.fileTypeIdentifier() == "B") color = m_binaryFileColor; + else if (fde.fileTypeIdentifier() == "S") color = m_typeSFileColor; + else if (fde.fileTypeIdentifier() == "T") color = m_textFileColor; + else if (fde.fileTypeIdentifier() == "a") color = m_typeAFileColor; + else if (fde.fileTypeIdentifier() == "b") color = m_typeBFileColor; + else qDebug() << "Unknown file type: " << fde.fileTypeIdentifier(); buttonAt(tr,se)->setBgColor(color); setButtonText(tr,se,QString("%1").arg(idx)); qDebug() << "Button" << idx << "=" << tr << "," << se << " " << fde.filename.printable(); diff --git a/src/ui/diskexplorer/DiskExplorerMapWidget.h b/src/ui/diskexplorer/DiskExplorerMapWidget.h index 93a2eec..0b2aa50 100644 --- a/src/ui/diskexplorer/DiskExplorerMapWidget.h +++ b/src/ui/diskexplorer/DiskExplorerMapWidget.h @@ -8,29 +8,37 @@ #include #include #include +#include #include "dos33diskimage.h" -class DEButton : public QPushButton +class DEButton : public QToolButton { Q_OBJECT + public: - DEButton(QWidget *parent,int track = -1, int sec = -1) : QPushButton(parent) + + DEButton(QWidget *parent,int track = -1, int sec = -1) : QToolButton(parent) { setTrack(track); setSector(sec); connect(this, &DEButton::clicked, this, &DEButton::handleClick); m_isHighlighted = false; } + void setTrack(int track) { m_track = track; } void setSector(int sector) { m_sector = sector; } int track() const { return m_track; } int sector() const { return m_sector; } - void clearBgColor() { m_backgroundColor = ""; setText(""); setStyleSheet(makeStyleSheet());} + void clearBgColor() { + m_backgroundColor = ""; + setText(""); + setStyleSheet(makeStyleSheet()); + } void setBgColor(QColor color) { m_fgColor = determineFgColor(color).name(); @@ -40,9 +48,18 @@ public: } bool highlighted() const { return m_isHighlighted; } - void setHighlighted(bool highlighted) { m_isHighlighted = highlighted;setStyleSheet(makeStyleSheet()); } - void reset() { setHighlighted(false); setChecked(false); makeStyleSheet(); qDebug() << "Reset";} + void setHighlighted(bool highlighted) { + m_isHighlighted = highlighted; + setStyleSheet(makeStyleSheet()); + } + + void reset() { + setHighlighted(false); + setChecked(false); + makeStyleSheet(); + qDebug() << "Reset"; + } void resetToDefault() { clearBgColor(); reset(); } @@ -59,28 +76,41 @@ signals: void checked(int track, int sec,bool ); private slots: - void handleClick(bool isChecked) { emit checked(m_track,m_sector,isChecked); } + void handleClick(bool isChecked) { + emit checked(m_track,m_sector,isChecked); + } - QSize minimumSizeHint() const Q_DECL_OVERRIDE { return QSize(24,24); } + QSize minimumSizeHint() const Q_DECL_OVERRIDE { return QSize(12,12); } QSize sizeHint() const Q_DECL_OVERRIDE { return QSize(24,24); } bool hasHeightForWidth() const Q_DECL_OVERRIDE { return true; } int heightForWidth(int width) const Q_DECL_OVERRIDE { return width; } private: + QString makeStyleSheet() const { - return QString(" QPushButton { font: 10px; border-width: 1px; color: %1; background-color: %2} " - " QPushButton:checked { font: bold italic 11px; } " - ) .arg(m_fgColor) + return QString("DEButton { " + " font: 10px; " + " border-width: 1px; " + " color: %1; " + " background-color: %2 " + "} " + " " + "DEButton:checked { " + " font: bold italic 11px; " + "}" + ).arg(m_fgColor) .arg(m_backgroundColor); } int m_track; int m_sector; + bool m_isHighlighted; QString m_fgColor; QString m_backgroundColor; QString m_hlColor; + }; diff --git a/src/util/chunkbytelist.cpp b/src/util/chunkbytelist.cpp new file mode 100644 index 0000000..50516eb --- /dev/null +++ b/src/util/chunkbytelist.cpp @@ -0,0 +1,80 @@ +#include "chunkbytelist.h" + +ChunkByteList::ChunkByteList() { } + +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; +} + +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 +{ + 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; +} + +char ChunkByteList::operator[](int i) const +{ + return at(i); +} + + diff --git a/src/util/chunkbytelist.h b/src/util/chunkbytelist.h new file mode 100644 index 0000000..d1c71a3 --- /dev/null +++ b/src/util/chunkbytelist.h @@ -0,0 +1,43 @@ +#ifndef CHUNKBYTELIST_H +#define CHUNKBYTELIST_H + +#include +#include + +class ChunkByteList +{ +public: + ChunkByteList(); + + ChunkByteList &appendChunk(QByteArray *chunk); + ChunkByteList &appendChunkList(ChunkByteList other); + + int count() const; + int size() const; + int length() const; + + 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; + } + + operator QByteArray() { return asQByteArray(); } + +private: + QList m_chunk_list; +}; + + +#endif // CHUNKBYTELIST_H diff --git a/src/util/util.h b/src/util/util.h index 680ac1c..c8f5795 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -39,6 +39,8 @@ enum class TextSet { }; + + inline QString uint8ToHex(quint8 val) { QString retval = QString("%1").arg(val,2,16,QChar('0')).toUpper(); return retval;