Skip to content

Commit

Permalink
Tar: fix after rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickvP committed Jan 27, 2020
1 parent f75cfe6 commit 4d01af9
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 188 deletions.
168 changes: 0 additions & 168 deletions src/libutil/compression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,174 +120,6 @@ struct NoneSink : CompressionSink
void write(const unsigned char * data, size_t len) override { nextSink(data, len); }
};

<<<<<<< HEAD
struct GzipDecompressionSink : CompressionSink
{
Sink & nextSink;
z_stream strm;
bool finished = false;
uint8_t outbuf[BUFSIZ];

GzipDecompressionSink(Sink & nextSink) : nextSink(nextSink)
{
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);

// Enable gzip and zlib decoding (+32) with 15 windowBits
int ret = inflateInit2(&strm,15+32);
if (ret != Z_OK)
throw CompressionError("unable to initialise gzip encoder");
}

~GzipDecompressionSink()
{
inflateEnd(&strm);
}

void finish() override
{
CompressionSink::flush();
write(nullptr, 0);
}

void write(const unsigned char * data, size_t len) override
{
assert(len <= std::numeric_limits<decltype(strm.avail_in)>::max());

strm.next_in = (Bytef *) data;
strm.avail_in = len;

while (!finished && (!data || strm.avail_in)) {
checkInterrupt();

int ret = inflate(&strm,Z_SYNC_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
throw CompressionError("error while decompressing gzip file: %d (%d, %d)",
zError(ret), len, strm.avail_in);

finished = ret == Z_STREAM_END;

if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
strm.next_out = (Bytef *) outbuf;
strm.avail_out = sizeof(outbuf);
}
}
}
};

struct XzDecompressionSink : CompressionSink
{
Sink & nextSink;
uint8_t outbuf[BUFSIZ];
lzma_stream strm = LZMA_STREAM_INIT;
bool finished = false;

XzDecompressionSink(Sink & nextSink) : nextSink(nextSink)
{
lzma_ret ret = lzma_stream_decoder(
&strm, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK)
throw CompressionError("unable to initialise lzma decoder");

strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
}

~XzDecompressionSink()
{
lzma_end(&strm);
}

void finish() override
{
CompressionSink::flush();
write(nullptr, 0);
}

void write(const unsigned char * data, size_t len) override
{
strm.next_in = data;
strm.avail_in = len;

while (!finished && (!data || strm.avail_in)) {
checkInterrupt();

lzma_ret ret = lzma_code(&strm, data ? LZMA_RUN : LZMA_FINISH);
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
throw CompressionError("error %d while decompressing xz file", ret);

finished = ret == LZMA_STREAM_END;

if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
}
}
}
};

struct BzipDecompressionSink : ChunkedCompressionSink
{
Sink & nextSink;
bz_stream strm;
bool finished = false;

BzipDecompressionSink(Sink & nextSink) : nextSink(nextSink)
{
memset(&strm, 0, sizeof(strm));
int ret = BZ2_bzDecompressInit(&strm, 0, 0);
if (ret != BZ_OK)
throw CompressionError("unable to initialise bzip2 decoder");

strm.next_out = (char *) outbuf;
strm.avail_out = sizeof(outbuf);
}

~BzipDecompressionSink()
{
BZ2_bzDecompressEnd(&strm);
}

void finish() override
{
flush();
write(nullptr, 0);
}

void writeInternal(const unsigned char * data, size_t len) override
{
assert(len <= std::numeric_limits<decltype(strm.avail_in)>::max());

strm.next_in = (char *) data;
strm.avail_in = len;

while (strm.avail_in) {
checkInterrupt();

int ret = BZ2_bzDecompress(&strm);
if (ret != BZ_OK && ret != BZ_STREAM_END)
throw CompressionError("error while decompressing bzip2 file");

finished = ret == BZ_STREAM_END;

if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
strm.next_out = (char *) outbuf;
strm.avail_out = sizeof(outbuf);
}
}
}
};

=======
>>>>>>> Change decompress() to use libarchive for all except brotli
struct BrotliDecompressionSink : ChunkedCompressionSink
{
Sink & nextSink;
Expand Down
2 changes: 1 addition & 1 deletion src/libutil/serialise.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void Source::drain(Sink& s)
size_t n;
try {
n = read(buf.data(), buf.size());
s(buf.data(), buf.size());
s(buf.data(), n);
} catch (EndOfFile &) {
break;
}
Expand Down
51 changes: 32 additions & 19 deletions src/libutil/tarfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "tarfile.hh"

namespace nix {

static int callback_open(struct archive *, void *self) {
return ARCHIVE_OK;
}
Expand Down Expand Up @@ -36,29 +37,41 @@ void TarArchive::check(int err, const char *reason)
throw Error(reason, archive_error_string(this->archive));
}

TarArchive::TarArchive(Source& source, bool raw) : buffer(4096)
{
this->archive = archive_read_new();
this->source = &source;

if (!raw) {
archive_read_support_filter_all(archive);
archive_read_support_format_all(archive);
} else {
archive_read_support_filter_all(archive);
archive_read_support_format_raw(archive);
archive_read_support_format_empty(archive);
}
check(archive_read_open(archive, (void *)this, callback_open, callback_read, callback_close), "Failed to open archive (%s)");
}

TarArchive::TarArchive(const Path &path) {
this->archive = archive_read_new();
TarArchive::TarArchive(Source& source, bool raw) : buffer(4096)
{
this->archive = archive_read_new();
this->source = &source;

if (!raw) {
archive_read_support_filter_all(archive);
archive_read_support_format_all(archive);
check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s");
} else {
archive_read_support_filter_all(archive);
archive_read_support_format_raw(archive);
archive_read_support_format_empty(archive);
}
check(archive_read_open(archive, (void *)this, callback_open, callback_read, callback_close), "Failed to open archive (%s)");
}


TarArchive::TarArchive(const Path &path)
{
this->archive = archive_read_new();

archive_read_support_filter_all(archive);
archive_read_support_format_all(archive);
check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s");
}

void TarArchive::close()
{
check(archive_read_close(this->archive), "Failed to close archive (%s)");
}

TarArchive::~TarArchive()
{
if (this->archive) archive_read_free(this->archive);
}

static void extract_archive(TarArchive & archive, const Path & destDir)
{
Expand Down

0 comments on commit 4d01af9

Please sign in to comment.