1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 23:03:22 +02:00
GPXSee/src/tar.cpp

90 lines
2.0 KiB
C++
Raw Normal View History

2017-03-21 01:15:29 +01:00
#include <cctype>
#include <QFile>
#include "tar.h"
#define BLOCKSIZE 512
#define BLOCKCOUNT(size) \
((size)/BLOCKSIZE + ((size) % BLOCKSIZE > 0 ? 1 : 0))
struct Header
{
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[155]; /* 345 */
2017-03-26 15:32:55 +02:00
/* 500 */
2017-03-21 01:15:29 +01:00
};
static quint64 number(const char* data, size_t size)
{
const char *sp;
quint64 val = 0;
for (sp = data; sp < data + size; sp++)
if (isdigit(*sp))
break;
for (; sp < data + size && isdigit(*sp); sp++)
val = val * 8 + *sp - '0';
return val;
}
bool Tar::load(const QString &path)
{
2017-03-26 18:08:37 +02:00
char buffer[BLOCKSIZE];
struct Header *hdr = (struct Header*)&buffer;
2017-03-21 01:15:29 +01:00
quint64 size;
2017-03-26 18:08:37 +02:00
qint64 ret;
2017-03-21 01:15:29 +01:00
2017-04-15 13:13:26 +02:00
if (_file.isOpen())
_file.close();
_index.clear();
2017-03-21 01:15:29 +01:00
_file.setFileName(path);
if (!_file.open(QIODevice::ReadOnly))
return false;
2017-03-26 18:08:37 +02:00
while ((ret = _file.read(buffer, BLOCKSIZE)) > 0) {
2017-04-14 22:39:33 +02:00
if (ret < BLOCKSIZE) {
_file.close();
2017-03-26 18:08:37 +02:00
return false;
2017-04-14 22:39:33 +02:00
}
2017-03-26 18:08:37 +02:00
size = number(hdr->size, sizeof(hdr->size));
2017-03-21 01:15:29 +01:00
if (size)
2017-03-26 18:08:37 +02:00
_index.insert(hdr->name, Info(size, _file.pos()));
2017-04-14 22:39:33 +02:00
if (!_file.seek(_file.pos() + BLOCKCOUNT(size) * BLOCKSIZE)) {
_file.close();
2017-03-26 18:08:37 +02:00
return false;
2017-04-14 22:39:33 +02:00
}
2017-03-21 01:15:29 +01:00
}
return true;
}
QByteArray Tar::file(const QString &name)
{
QMap<QString, Tar::Info>::const_iterator it = _index.find(name);
2017-03-26 15:32:55 +02:00
if (it == _index.end())
return QByteArray();
2017-03-21 01:15:29 +01:00
2017-04-14 22:39:33 +02:00
Q_ASSERT(_file.isOpen());
2017-03-21 01:15:29 +01:00
if (_file.seek(it.value().offset()))
return _file.read(it.value().size());
else
return QByteArray();
}