1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Now using tmi index files (if present) when loading tar files

This commit is contained in:
Martin Tůma 2017-06-25 12:24:05 +02:00
parent 3ced367fab
commit c2004ded31
2 changed files with 63 additions and 25 deletions

View File

@ -1,5 +1,6 @@
#include <cctype> #include <cctype>
#include <QFile> #include <QFile>
#include <QFileInfo>
#include "tar.h" #include "tar.h"
@ -29,7 +30,7 @@ struct Header
/* 500 */ /* 500 */
}; };
static quint64 number(const char* data, size_t size) static quint64 number(const char* data, size_t size, int base = 8)
{ {
const char *sp; const char *sp;
quint64 val = 0; quint64 val = 0;
@ -38,18 +39,13 @@ static quint64 number(const char* data, size_t size)
if (isdigit(*sp)) if (isdigit(*sp))
break; break;
for (; sp < data + size && isdigit(*sp); sp++) for (; sp < data + size && isdigit(*sp); sp++)
val = val * 8 + *sp - '0'; val = val * base + *sp - '0';
return val; return val;
} }
bool Tar::load(const QString &path) bool Tar::load(const QString &path)
{ {
char buffer[BLOCKSIZE];
struct Header *hdr = (struct Header*)&buffer;
quint64 size;
qint64 ret;
if (_file.isOpen()) if (_file.isOpen())
_file.close(); _file.close();
_index.clear(); _index.clear();
@ -58,14 +54,29 @@ bool Tar::load(const QString &path)
if (!_file.open(QIODevice::ReadOnly)) if (!_file.open(QIODevice::ReadOnly))
return false; return false;
QFileInfo fi(path);
QString tmiPath = fi.path() + "/" + fi.completeBaseName() + ".tmi";
if (loadTmi(tmiPath))
return true;
else
return loadTar();
}
bool Tar::loadTar()
{
char buffer[BLOCKSIZE];
struct Header *hdr = (struct Header*)&buffer;
quint64 size;
qint64 ret;
while ((ret = _file.read(buffer, BLOCKSIZE)) > 0) { while ((ret = _file.read(buffer, BLOCKSIZE)) > 0) {
if (ret < BLOCKSIZE) { if (ret < BLOCKSIZE) {
_file.close(); _file.close();
return false; return false;
} }
size = number(hdr->size, sizeof(hdr->size)); size = number(hdr->size, sizeof(hdr->size));
if (size) _index.insert(hdr->name, _file.pos() / BLOCKSIZE - 1);
_index.insert(hdr->name, Info(size, _file.pos()));
if (!_file.seek(_file.pos() + BLOCKCOUNT(size) * BLOCKSIZE)) { if (!_file.seek(_file.pos() + BLOCKCOUNT(size) * BLOCKSIZE)) {
_file.close(); _file.close();
return false; return false;
@ -75,15 +86,51 @@ bool Tar::load(const QString &path)
return true; return true;
} }
bool Tar::loadTmi(const QString &path)
{
quint64 block;
int ln = 1;
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
return false;
while (!file.atEnd()) {
QByteArray line = file.readLine();
int pos = line.indexOf(':');
if (line.size() < 10 || pos < 7 || !line.startsWith("block")) {
qWarning("%s:%d: syntax error\n", qPrintable(path), ln);
_index.clear();
return false;
}
block = number(line.constData() + 6, line.size() - 6, 10);
QString file(line.mid(pos + 1).trimmed());
_index.insert(file, block);
ln++;
}
file.close();
return true;
}
QByteArray Tar::file(const QString &name) QByteArray Tar::file(const QString &name)
{ {
QMap<QString, Tar::Info>::const_iterator it = _index.find(name); char buffer[BLOCKSIZE];
struct Header *hdr = (struct Header*)&buffer;
quint64 size;
QMap<QString, quint64>::const_iterator it = _index.find(name);
if (it == _index.end()) if (it == _index.end())
return QByteArray(); return QByteArray();
Q_ASSERT(_file.isOpen()); Q_ASSERT(_file.isOpen());
if (_file.seek(it.value().offset())) if (_file.seek(it.value() * BLOCKSIZE)) {
return _file.read(it.value().size()); if (_file.read(buffer, BLOCKSIZE) < BLOCKSIZE)
else return QByteArray();
size = number(hdr->size, sizeof(hdr->size));
return _file.read(size);
} else
return QByteArray(); return QByteArray();
} }

View File

@ -17,20 +17,11 @@ public:
bool isOpen() const {return _file.isOpen();} bool isOpen() const {return _file.isOpen();}
private: private:
class Info bool loadTar();
{ bool loadTmi(const QString &path);
public:
Info(quint64 size, quint64 offset) : _size(size), _offset(offset) {}
quint64 size() const {return _size;}
quint64 offset() const {return _offset;}
private:
quint64 _size;
quint64 _offset;
};
QFile _file; QFile _file;
QMap<QString, Info> _index; QMap<QString, quint64> _index;
}; };
#endif // TAR_H #endif // TAR_H