#include #include #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 */ /* 500 */ }; 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) { struct Header hdr; quint64 size; _file.setFileName(path); if (!_file.open(QIODevice::ReadOnly)) return false; while (_file.read((char*)&hdr, BLOCKSIZE)) { size = number(hdr.size, sizeof(hdr.size)); if (size) _index.insert(hdr.name, Info(size, _file.pos())); _file.seek(_file.pos() + BLOCKCOUNT(size) * BLOCKSIZE); } return true; } QByteArray Tar::file(const QString &name) { QMap::const_iterator it = _index.find(name); if (it == _index.end()) return QByteArray(); if (_file.seek(it.value().offset())) return _file.read(it.value().size()); else return QByteArray(); }