2019-05-16 20:23:37 +02:00
|
|
|
#include <QFile>
|
2019-05-10 18:56:19 +02:00
|
|
|
#include "img.h"
|
|
|
|
#include "subfile.h"
|
|
|
|
|
|
|
|
SubFile::Type SubFile::type(const char str[3])
|
|
|
|
{
|
|
|
|
if (!memcmp(str, "TRE", 3))
|
|
|
|
return TRE;
|
|
|
|
else if (!memcmp(str, "RGN", 3))
|
|
|
|
return RGN;
|
|
|
|
else if (!memcmp(str, "LBL", 3))
|
|
|
|
return LBL;
|
|
|
|
else if (!memcmp(str, "TYP", 3))
|
|
|
|
return TYP;
|
|
|
|
else if (!memcmp(str, "GMP", 3))
|
|
|
|
return GMP;
|
|
|
|
else if (!memcmp(str, "NET", 3))
|
|
|
|
return NET;
|
|
|
|
else
|
|
|
|
return Unknown;
|
|
|
|
}
|
|
|
|
|
2019-05-16 20:23:37 +02:00
|
|
|
SubFile::SubFile(QFile *file) : _img(0), _file(file), _size(0)
|
|
|
|
{
|
|
|
|
if (!_file->open(QIODevice::ReadOnly))
|
|
|
|
qWarning("Error opening %s: %s", qPrintable(_file->fileName()),
|
|
|
|
qPrintable(_file->errorString()));
|
|
|
|
}
|
|
|
|
|
2019-05-10 18:56:19 +02:00
|
|
|
bool SubFile::isValid() const
|
|
|
|
{
|
2019-05-16 20:23:37 +02:00
|
|
|
return _file
|
|
|
|
? _file->isOpen()
|
|
|
|
: ((quint32)_img->blockSize() * (quint32)_blocks.size() - _size
|
|
|
|
< (quint32)_img->blockSize());
|
2019-05-10 18:56:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SubFile::seek(Handle &handle, quint32 pos) const
|
|
|
|
{
|
2019-05-16 20:23:37 +02:00
|
|
|
Q_ASSERT(_img || _file);
|
2019-05-10 18:56:19 +02:00
|
|
|
|
2019-05-16 20:23:37 +02:00
|
|
|
if (_file)
|
|
|
|
return _file->seek(pos);
|
|
|
|
else {
|
|
|
|
quint32 blockSize = _img->blockSize();
|
|
|
|
int blockNum = pos / blockSize;
|
|
|
|
|
|
|
|
if (handle.blockNum != blockNum) {
|
|
|
|
if (blockNum >= _blocks.size())
|
|
|
|
return false;
|
|
|
|
if (!_img->readBlock(_blocks.at(blockNum), handle.data))
|
|
|
|
return false;
|
|
|
|
handle.blockNum = blockNum;
|
|
|
|
}
|
2019-05-10 18:56:19 +02:00
|
|
|
|
2019-05-16 20:23:37 +02:00
|
|
|
handle.blockPos = pos % blockSize;
|
|
|
|
handle.pos = pos;
|
2019-05-10 18:56:19 +02:00
|
|
|
|
2019-05-16 20:23:37 +02:00
|
|
|
return true;
|
|
|
|
}
|
2019-05-10 18:56:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SubFile::readByte(Handle &handle, quint8 &val) const
|
|
|
|
{
|
2019-05-16 20:23:37 +02:00
|
|
|
Q_ASSERT(_img || _file);
|
|
|
|
|
|
|
|
if (_file)
|
|
|
|
return _file->getChar((char*)&val);
|
|
|
|
else {
|
|
|
|
val = handle.data.at(handle.blockPos++);
|
|
|
|
handle.pos++;
|
|
|
|
return (handle.blockPos >= _img->blockSize())
|
|
|
|
? seek(handle, handle.pos) : true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
quint32 SubFile::size() const
|
|
|
|
{
|
2019-08-12 22:20:12 +02:00
|
|
|
return _file ? (quint32)_file->size() : _size;
|
2019-05-10 18:56:19 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 20:23:37 +02:00
|
|
|
QString SubFile::fileName() const
|
2019-05-10 18:56:19 +02:00
|
|
|
{
|
2019-08-12 22:20:12 +02:00
|
|
|
return _file ? _file->fileName() : _img->fileName();
|
2019-05-10 18:56:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef QT_NO_DEBUG
|
|
|
|
QDebug operator<<(QDebug dbg, const SubFile &file)
|
|
|
|
{
|
|
|
|
bool continuous = true;
|
|
|
|
for (int i = 1; i < file._blocks.size(); i++) {
|
|
|
|
if (file._blocks.at(i) != file._blocks.at(i-1) + 1) {
|
|
|
|
continuous = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dbg.nospace() << "SubFile(" << file._size << ", " << file._blocks.size()
|
|
|
|
<< ", " << continuous << ")";
|
|
|
|
return dbg.space();
|
|
|
|
}
|
|
|
|
#endif // QT_NO_DEBUG
|