You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ph...@apache.org on 2017/10/20 17:18:14 UTC

[03/51] [partial] nifi-minifi-cpp git commit: MINIFICPP-72: Add Tar and Zip Support for MergeContent

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write.c
new file mode 100644
index 0000000..0634a22
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write.c
@@ -0,0 +1,734 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:00Z kientzle $");
+
+/*
+ * This file contains the "essential" portions of the write API, that
+ * is, stuff that will essentially always be used by any client that
+ * actually needs to write an archive.  Optional pieces have been, as
+ * far as possible, separated out into separate files to reduce
+ * needlessly bloating statically-linked clients.
+ */
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+static struct archive_vtable *archive_write_vtable(void);
+
+static int	_archive_filter_code(struct archive *, int);
+static const char *_archive_filter_name(struct archive *, int);
+static int64_t	_archive_filter_bytes(struct archive *, int);
+static int  _archive_write_filter_count(struct archive *);
+static int	_archive_write_close(struct archive *);
+static int	_archive_write_free(struct archive *);
+static int	_archive_write_header(struct archive *, struct archive_entry *);
+static int	_archive_write_finish_entry(struct archive *);
+static ssize_t	_archive_write_data(struct archive *, const void *, size_t);
+
+struct archive_none {
+	size_t buffer_size;
+	size_t avail;
+	char *buffer;
+	char *next;
+};
+
+static struct archive_vtable *
+archive_write_vtable(void)
+{
+	static struct archive_vtable av;
+	static int inited = 0;
+
+	if (!inited) {
+		av.archive_close = _archive_write_close;
+		av.archive_filter_bytes = _archive_filter_bytes;
+		av.archive_filter_code = _archive_filter_code;
+		av.archive_filter_name = _archive_filter_name;
+		av.archive_filter_count = _archive_write_filter_count;
+		av.archive_free = _archive_write_free;
+		av.archive_write_header = _archive_write_header;
+		av.archive_write_finish_entry = _archive_write_finish_entry;
+		av.archive_write_data = _archive_write_data;
+		inited = 1;
+	}
+	return (&av);
+}
+
+/*
+ * Allocate, initialize and return an archive object.
+ */
+struct archive *
+archive_write_new(void)
+{
+	struct archive_write *a;
+	unsigned char *nulls;
+
+	a = (struct archive_write *)calloc(1, sizeof(*a));
+	if (a == NULL)
+		return (NULL);
+	a->archive.magic = ARCHIVE_WRITE_MAGIC;
+	a->archive.state = ARCHIVE_STATE_NEW;
+	a->archive.vtable = archive_write_vtable();
+	/*
+	 * The value 10240 here matches the traditional tar default,
+	 * but is otherwise arbitrary.
+	 * TODO: Set the default block size from the format selected.
+	 */
+	a->bytes_per_block = 10240;
+	a->bytes_in_last_block = -1;	/* Default */
+
+	/* Initialize a block of nulls for padding purposes. */
+	a->null_length = 1024;
+	nulls = (unsigned char *)calloc(1, a->null_length);
+	if (nulls == NULL) {
+		free(a);
+		return (NULL);
+	}
+	a->nulls = nulls;
+	return (&a->archive);
+}
+
+/*
+ * Set the block size.  Returns 0 if successful.
+ */
+int
+archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
+	a->bytes_per_block = bytes_per_block;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Get the current block size.  -1 if it has never been set.
+ */
+int
+archive_write_get_bytes_per_block(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
+	return (a->bytes_per_block);
+}
+
+/*
+ * Set the size for the last block.
+ * Returns 0 if successful.
+ */
+int
+archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
+	a->bytes_in_last_block = bytes;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Return the value set above.  -1 indicates it has not been set.
+ */
+int
+archive_write_get_bytes_in_last_block(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
+	return (a->bytes_in_last_block);
+}
+
+/*
+ * dev/ino of a file to be rejected.  Used to prevent adding
+ * an archive to itself recursively.
+ */
+int
+archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
+	a->skip_file_set = 1;
+	a->skip_file_dev = d;
+	a->skip_file_ino = i;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Allocate and return the next filter structure.
+ */
+struct archive_write_filter *
+__archive_write_allocate_filter(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f;
+
+	f = calloc(1, sizeof(*f));
+	f->archive = _a;
+	if (a->filter_first == NULL)
+		a->filter_first = f;
+	else
+		a->filter_last->next_filter = f;
+	a->filter_last = f;
+	return f;
+}
+
+/*
+ * Write data to a particular filter.
+ */
+int
+__archive_write_filter(struct archive_write_filter *f,
+    const void *buff, size_t length)
+{
+	int r;
+	if (length == 0)
+		return(ARCHIVE_OK);
+	if (f->write == NULL)
+		/* If unset, a fatal error has already occurred, so this filter
+		 * didn't open. We cannot write anything. */
+		return(ARCHIVE_FATAL);
+	r = (f->write)(f, buff, length);
+	f->bytes_written += length;
+	return (r);
+}
+
+/*
+ * Open a filter.
+ */
+int
+__archive_write_open_filter(struct archive_write_filter *f)
+{
+	if (f->open == NULL)
+		return (ARCHIVE_OK);
+	return (f->open)(f);
+}
+
+/*
+ * Close a filter.
+ */
+int
+__archive_write_close_filter(struct archive_write_filter *f)
+{
+	if (f->close != NULL)
+		return (f->close)(f);
+	if (f->next_filter != NULL)
+		return (__archive_write_close_filter(f->next_filter));
+	return (ARCHIVE_OK);
+}
+
+int
+__archive_write_output(struct archive_write *a, const void *buff, size_t length)
+{
+	return (__archive_write_filter(a->filter_first, buff, length));
+}
+
+int
+__archive_write_nulls(struct archive_write *a, size_t length)
+{
+	if (length == 0)
+		return (ARCHIVE_OK);
+
+	while (length > 0) {
+		size_t to_write = length < a->null_length ? length : a->null_length;
+		int r = __archive_write_output(a, a->nulls, to_write);
+		if (r < ARCHIVE_OK)
+			return (r);
+		length -= to_write;
+	}
+	return (ARCHIVE_OK);
+}
+
+static int
+archive_write_client_open(struct archive_write_filter *f)
+{
+	struct archive_write *a = (struct archive_write *)f->archive;
+	struct archive_none *state;
+	void *buffer;
+	size_t buffer_size;
+
+	f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
+	f->bytes_in_last_block =
+	    archive_write_get_bytes_in_last_block(f->archive);
+	buffer_size = f->bytes_per_block;
+
+	state = (struct archive_none *)calloc(1, sizeof(*state));
+	buffer = (char *)malloc(buffer_size);
+	if (state == NULL || buffer == NULL) {
+		free(state);
+		free(buffer);
+		archive_set_error(f->archive, ENOMEM,
+		    "Can't allocate data for output buffering");
+		return (ARCHIVE_FATAL);
+	}
+
+	state->buffer_size = buffer_size;
+	state->buffer = buffer;
+	state->next = state->buffer;
+	state->avail = state->buffer_size;
+	f->data = state;
+
+	if (a->client_opener == NULL)
+		return (ARCHIVE_OK);
+	return (a->client_opener(f->archive, a->client_data));
+}
+
+static int
+archive_write_client_write(struct archive_write_filter *f,
+    const void *_buff, size_t length)
+{
+	struct archive_write *a = (struct archive_write *)f->archive;
+        struct archive_none *state = (struct archive_none *)f->data;
+	const char *buff = (const char *)_buff;
+	ssize_t remaining, to_copy;
+	ssize_t bytes_written;
+
+	remaining = length;
+
+	/*
+	 * If there is no buffer for blocking, just pass the data
+	 * straight through to the client write callback.  In
+	 * particular, this supports "no write delay" operation for
+	 * special applications.  Just set the block size to zero.
+	 */
+	if (state->buffer_size == 0) {
+		while (remaining > 0) {
+			bytes_written = (a->client_writer)(&a->archive,
+			    a->client_data, buff, remaining);
+			if (bytes_written <= 0)
+				return (ARCHIVE_FATAL);
+			remaining -= bytes_written;
+			buff += bytes_written;
+		}
+		return (ARCHIVE_OK);
+	}
+
+	/* If the copy buffer isn't empty, try to fill it. */
+	if (state->avail < state->buffer_size) {
+		/* If buffer is not empty... */
+		/* ... copy data into buffer ... */
+		to_copy = ((size_t)remaining > state->avail) ?
+			state->avail : (size_t)remaining;
+		memcpy(state->next, buff, to_copy);
+		state->next += to_copy;
+		state->avail -= to_copy;
+		buff += to_copy;
+		remaining -= to_copy;
+		/* ... if it's full, write it out. */
+		if (state->avail == 0) {
+			char *p = state->buffer;
+			size_t to_write = state->buffer_size;
+			while (to_write > 0) {
+				bytes_written = (a->client_writer)(&a->archive,
+				    a->client_data, p, to_write);
+				if (bytes_written <= 0)
+					return (ARCHIVE_FATAL);
+				if ((size_t)bytes_written > to_write) {
+					archive_set_error(&(a->archive),
+					    -1, "write overrun");
+					return (ARCHIVE_FATAL);
+				}
+				p += bytes_written;
+				to_write -= bytes_written;
+			}
+			state->next = state->buffer;
+			state->avail = state->buffer_size;
+		}
+	}
+
+	while ((size_t)remaining >= state->buffer_size) {
+		/* Write out full blocks directly to client. */
+		bytes_written = (a->client_writer)(&a->archive,
+		    a->client_data, buff, state->buffer_size);
+		if (bytes_written <= 0)
+			return (ARCHIVE_FATAL);
+		buff += bytes_written;
+		remaining -= bytes_written;
+	}
+
+	if (remaining > 0) {
+		/* Copy last bit into copy buffer. */
+		memcpy(state->next, buff, remaining);
+		state->next += remaining;
+		state->avail -= remaining;
+	}
+	return (ARCHIVE_OK);
+}
+
+static int
+archive_write_client_close(struct archive_write_filter *f)
+{
+	struct archive_write *a = (struct archive_write *)f->archive;
+	struct archive_none *state = (struct archive_none *)f->data;
+	ssize_t block_length;
+	ssize_t target_block_length;
+	ssize_t bytes_written;
+	int ret = ARCHIVE_OK;
+
+	/* If there's pending data, pad and write the last block */
+	if (state->next != state->buffer) {
+		block_length = state->buffer_size - state->avail;
+
+		/* Tricky calculation to determine size of last block */
+		if (a->bytes_in_last_block <= 0)
+			/* Default or Zero: pad to full block */
+			target_block_length = a->bytes_per_block;
+		else
+			/* Round to next multiple of bytes_in_last_block. */
+			target_block_length = a->bytes_in_last_block *
+			    ( (block_length + a->bytes_in_last_block - 1) /
+			        a->bytes_in_last_block);
+		if (target_block_length > a->bytes_per_block)
+			target_block_length = a->bytes_per_block;
+		if (block_length < target_block_length) {
+			memset(state->next, 0,
+			    target_block_length - block_length);
+			block_length = target_block_length;
+		}
+		bytes_written = (a->client_writer)(&a->archive,
+		    a->client_data, state->buffer, block_length);
+		ret = bytes_written <= 0 ? ARCHIVE_FATAL : ARCHIVE_OK;
+	}
+	if (a->client_closer)
+		(*a->client_closer)(&a->archive, a->client_data);
+	free(state->buffer);
+	free(state);
+	/* Clear the close handler myself not to be called again. */
+	f->close = NULL;
+	a->client_data = NULL;
+	/* Clear passphrase. */
+	if (a->passphrase != NULL) {
+		memset(a->passphrase, 0, strlen(a->passphrase));
+		free(a->passphrase);
+		a->passphrase = NULL;
+	}
+	return (ret);
+}
+
+/*
+ * Open the archive using the current settings.
+ */
+int
+archive_write_open(struct archive *_a, void *client_data,
+    archive_open_callback *opener, archive_write_callback *writer,
+    archive_close_callback *closer)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *client_filter;
+	int ret, r1;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_open");
+	archive_clear_error(&a->archive);
+
+	a->client_writer = writer;
+	a->client_opener = opener;
+	a->client_closer = closer;
+	a->client_data = client_data;
+
+	client_filter = __archive_write_allocate_filter(_a);
+	client_filter->open = archive_write_client_open;
+	client_filter->write = archive_write_client_write;
+	client_filter->close = archive_write_client_close;
+
+	ret = __archive_write_open_filter(a->filter_first);
+	if (ret < ARCHIVE_WARN) {
+		r1 = __archive_write_close_filter(a->filter_first);
+		return (r1 < ret ? r1 : ret);
+	}
+
+	a->archive.state = ARCHIVE_STATE_HEADER;
+	if (a->format_init)
+		ret = (a->format_init)(a);
+	return (ret);
+}
+
+/*
+ * Close out the archive.
+ */
+static int
+_archive_write_close(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
+	    "archive_write_close");
+	if (a->archive.state == ARCHIVE_STATE_NEW
+	    || a->archive.state == ARCHIVE_STATE_CLOSED)
+		return (ARCHIVE_OK); /* Okay to close() when not open. */
+
+	archive_clear_error(&a->archive);
+
+	/* Finish the last entry if a finish callback is specified */
+	if (a->archive.state == ARCHIVE_STATE_DATA
+	    && a->format_finish_entry != NULL)
+		r = ((a->format_finish_entry)(a));
+
+	/* Finish off the archive. */
+	/* TODO: have format closers invoke compression close. */
+	if (a->format_close != NULL) {
+		r1 = (a->format_close)(a);
+		if (r1 < r)
+			r = r1;
+	}
+
+	/* Finish the compression and close the stream. */
+	r1 = __archive_write_close_filter(a->filter_first);
+	if (r1 < r)
+		r = r1;
+
+	if (a->archive.state != ARCHIVE_STATE_FATAL)
+		a->archive.state = ARCHIVE_STATE_CLOSED;
+	return (r);
+}
+
+static int
+_archive_write_filter_count(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *p = a->filter_first;
+	int count = 0;
+	while(p) {
+		count++;
+		p = p->next_filter;
+	}
+	return count;
+}
+
+void
+__archive_write_filters_free(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	int r = ARCHIVE_OK, r1;
+
+	while (a->filter_first != NULL) {
+		struct archive_write_filter *next
+		    = a->filter_first->next_filter;
+		if (a->filter_first->free != NULL) {
+			r1 = (*a->filter_first->free)(a->filter_first);
+			if (r > r1)
+				r = r1;
+		}
+		free(a->filter_first);
+		a->filter_first = next;
+	}
+	a->filter_last = NULL;
+}
+
+/*
+ * Destroy the archive structure.
+ *
+ * Be careful: user might just call write_new and then write_free.
+ * Don't assume we actually wrote anything or performed any non-trivial
+ * initialization.
+ */
+static int
+_archive_write_free(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	int r = ARCHIVE_OK, r1;
+
+	if (_a == NULL)
+		return (ARCHIVE_OK);
+	/* It is okay to call free() in state FATAL. */
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
+	if (a->archive.state != ARCHIVE_STATE_FATAL)
+		r = archive_write_close(&a->archive);
+
+	/* Release format resources. */
+	if (a->format_free != NULL) {
+		r1 = (a->format_free)(a);
+		if (r1 < r)
+			r = r1;
+	}
+
+	__archive_write_filters_free(_a);
+
+	/* Release various dynamic buffers. */
+	free((void *)(uintptr_t)(const void *)a->nulls);
+	archive_string_free(&a->archive.error_string);
+	if (a->passphrase != NULL) {
+		/* A passphrase should be cleaned. */
+		memset(a->passphrase, 0, strlen(a->passphrase));
+		free(a->passphrase);
+	}
+	a->archive.magic = 0;
+	__archive_clean(&a->archive);
+	free(a);
+	return (r);
+}
+
+/*
+ * Write the appropriate header.
+ */
+static int
+_archive_write_header(struct archive *_a, struct archive_entry *entry)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	int ret, r2;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
+	archive_clear_error(&a->archive);
+
+	if (a->format_write_header == NULL) {
+		archive_set_error(&(a->archive), -1,
+		    "Format must be set before you can write to an archive.");
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+
+	/* In particular, "retry" and "fatal" get returned immediately. */
+	ret = archive_write_finish_entry(&a->archive);
+	if (ret == ARCHIVE_FATAL) {
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN)
+		return (ret);
+
+	if (a->skip_file_set &&
+	    archive_entry_dev_is_set(entry) &&
+	    archive_entry_ino_is_set(entry) &&
+	    archive_entry_dev(entry) == (dev_t)a->skip_file_dev &&
+	    archive_entry_ino64(entry) == a->skip_file_ino) {
+		archive_set_error(&a->archive, 0,
+		    "Can't add archive to itself");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* Format and write header. */
+	r2 = ((a->format_write_header)(a, entry));
+	if (r2 == ARCHIVE_FAILED) {
+		return (ARCHIVE_FAILED);
+	}
+	if (r2 == ARCHIVE_FATAL) {
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	if (r2 < ret)
+		ret = r2;
+
+	a->archive.state = ARCHIVE_STATE_DATA;
+	return (ret);
+}
+
+static int
+_archive_write_finish_entry(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	int ret = ARCHIVE_OK;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_write_finish_entry");
+	if (a->archive.state & ARCHIVE_STATE_DATA
+	    && a->format_finish_entry != NULL)
+		ret = (a->format_finish_entry)(a);
+	a->archive.state = ARCHIVE_STATE_HEADER;
+	return (ret);
+}
+
+/*
+ * Note that the compressor is responsible for blocking.
+ */
+static ssize_t
+_archive_write_data(struct archive *_a, const void *buff, size_t s)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	const size_t max_write = INT_MAX;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_DATA, "archive_write_data");
+	/* In particular, this catches attempts to pass negative values. */
+	if (s > max_write)
+		s = max_write;
+	archive_clear_error(&a->archive);
+	return ((a->format_write_data)(a, buff, s));
+}
+
+static struct archive_write_filter *
+filter_lookup(struct archive *_a, int n)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f = a->filter_first;
+	if (n == -1)
+		return a->filter_last;
+	if (n < 0)
+		return NULL;
+	while (n > 0 && f != NULL) {
+		f = f->next_filter;
+		--n;
+	}
+	return f;
+}
+
+static int
+_archive_filter_code(struct archive *_a, int n)
+{
+	struct archive_write_filter *f = filter_lookup(_a, n);
+	return f == NULL ? -1 : f->code;
+}
+
+static const char *
+_archive_filter_name(struct archive *_a, int n)
+{
+	struct archive_write_filter *f = filter_lookup(_a, n);
+	return f != NULL ? f->name : NULL;
+}
+
+static int64_t
+_archive_filter_bytes(struct archive *_a, int n)
+{
+	struct archive_write_filter *f = filter_lookup(_a, n);
+	return f == NULL ? -1 : f->bytes_written;
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter.c
new file mode 100644
index 0000000..08f518a
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2012 Ondrej Holy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+
+/* A table that maps filter codes to functions. */
+static const
+struct { int code; int (*setter)(struct archive *); } codes[] =
+{
+	{ ARCHIVE_FILTER_NONE,		archive_write_add_filter_none },
+	{ ARCHIVE_FILTER_GZIP,		archive_write_add_filter_gzip },
+	{ ARCHIVE_FILTER_BZIP2,		archive_write_add_filter_bzip2 },
+	{ ARCHIVE_FILTER_COMPRESS,	archive_write_add_filter_compress },
+	{ ARCHIVE_FILTER_GRZIP,		archive_write_add_filter_grzip },
+	{ ARCHIVE_FILTER_LRZIP,		archive_write_add_filter_lrzip },
+	{ ARCHIVE_FILTER_LZ4,		archive_write_add_filter_lz4 },
+	{ ARCHIVE_FILTER_LZIP,		archive_write_add_filter_lzip },
+	{ ARCHIVE_FILTER_LZMA,		archive_write_add_filter_lzma },
+	{ ARCHIVE_FILTER_LZOP,		archive_write_add_filter_lzip },
+	{ ARCHIVE_FILTER_UU,		archive_write_add_filter_uuencode },
+	{ ARCHIVE_FILTER_XZ,		archive_write_add_filter_xz },
+	{ -1,			NULL }
+};
+
+int
+archive_write_add_filter(struct archive *a, int code)
+{
+	int i;
+
+	for (i = 0; codes[i].code != -1; i++) {
+		if (code == codes[i].code)
+			return ((codes[i].setter)(a));
+	}
+
+	archive_set_error(a, EINVAL, "No such filter");
+	return (ARCHIVE_FATAL);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_b64encode.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_b64encode.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_b64encode.c
new file mode 100644
index 0000000..85eb087
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_b64encode.c
@@ -0,0 +1,314 @@
+/*-
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+#define LBYTES	57
+
+struct private_b64encode {
+	int			mode;
+	struct archive_string	name;
+	struct archive_string	encoded_buff;
+	size_t			bs;
+	size_t			hold_len;
+	unsigned char		hold[LBYTES];
+};
+
+static int archive_filter_b64encode_options(struct archive_write_filter *,
+    const char *, const char *);
+static int archive_filter_b64encode_open(struct archive_write_filter *);
+static int archive_filter_b64encode_write(struct archive_write_filter *,
+    const void *, size_t);
+static int archive_filter_b64encode_close(struct archive_write_filter *);
+static int archive_filter_b64encode_free(struct archive_write_filter *);
+static void b64_encode(struct archive_string *, const unsigned char *, size_t);
+static int64_t atol8(const char *, size_t);
+
+static const char base64[] = {
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+	'w', 'x', 'y', 'z', '0', '1', '2', '3',
+	'4', '5', '6', '7', '8', '9', '+', '/'
+};
+
+/*
+ * Add a compress filter to this write handle.
+ */
+int
+archive_write_add_filter_b64encode(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+	struct private_b64encode *state;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_uu");
+
+	state = (struct private_b64encode *)calloc(1, sizeof(*state));
+	if (state == NULL) {
+		archive_set_error(f->archive, ENOMEM,
+		    "Can't allocate data for b64encode filter");
+		return (ARCHIVE_FATAL);
+	}
+	archive_strcpy(&state->name, "-");
+	state->mode = 0644;
+
+	f->data = state;
+	f->name = "b64encode";
+	f->code = ARCHIVE_FILTER_UU;
+	f->open = archive_filter_b64encode_open;
+	f->options = archive_filter_b64encode_options;
+	f->write = archive_filter_b64encode_write;
+	f->close = archive_filter_b64encode_close;
+	f->free = archive_filter_b64encode_free;
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_filter_b64encode_options(struct archive_write_filter *f, const char *key,
+    const char *value)
+{
+	struct private_b64encode *state = (struct private_b64encode *)f->data;
+
+	if (strcmp(key, "mode") == 0) {
+		if (value == NULL) {
+			archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+			    "mode option requires octal digits");
+			return (ARCHIVE_FAILED);
+		}
+		state->mode = (int)atol8(value, strlen(value)) & 0777;
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "name") == 0) {
+		if (value == NULL) {
+			archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+			    "name option requires a string");
+			return (ARCHIVE_FAILED);
+		}
+		archive_strcpy(&state->name, value);
+		return (ARCHIVE_OK);
+	}
+
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_filter_b64encode_open(struct archive_write_filter *f)
+{
+	struct private_b64encode *state = (struct private_b64encode *)f->data;
+	size_t bs = 65536, bpb;
+	int ret;
+
+	ret = __archive_write_open_filter(f->next_filter);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
+		/* Buffer size should be a multiple number of the of bytes
+		 * per block for performance. */
+		bpb = archive_write_get_bytes_per_block(f->archive);
+		if (bpb > bs)
+			bs = bpb;
+		else if (bpb != 0)
+			bs -= bs % bpb;
+	}
+
+	state->bs = bs;
+	if (archive_string_ensure(&state->encoded_buff, bs + 512) == NULL) {
+		archive_set_error(f->archive, ENOMEM,
+		    "Can't allocate data for b64encode buffer");
+		return (ARCHIVE_FATAL);
+	}
+
+	archive_string_sprintf(&state->encoded_buff, "begin-base64 %o %s\n",
+	    state->mode, state->name.s);
+
+	f->data = state;
+	return (0);
+}
+
+static void
+b64_encode(struct archive_string *as, const unsigned char *p, size_t len)
+{
+	int c;
+
+	for (; len >= 3; p += 3, len -= 3) {
+		c = p[0] >> 2;
+		archive_strappend_char(as, base64[c]);
+		c = ((p[0] & 0x03) << 4) | ((p[1] & 0xf0) >> 4);
+		archive_strappend_char(as, base64[c]);
+		c = ((p[1] & 0x0f) << 2) | ((p[2] & 0xc0) >> 6);
+		archive_strappend_char(as, base64[c]);
+		c = p[2] & 0x3f;
+		archive_strappend_char(as, base64[c]);
+	}
+	if (len > 0) {
+		c = p[0] >> 2;
+		archive_strappend_char(as, base64[c]);
+		c = (p[0] & 0x03) << 4;
+		if (len == 1) {
+			archive_strappend_char(as, base64[c]);
+			archive_strappend_char(as, '=');
+			archive_strappend_char(as, '=');
+		} else {
+			c |= (p[1] & 0xf0) >> 4;
+			archive_strappend_char(as, base64[c]);
+			c = (p[1] & 0x0f) << 2;
+			archive_strappend_char(as, base64[c]);
+			archive_strappend_char(as, '=');
+		}
+	}
+	archive_strappend_char(as, '\n');
+}
+
+/*
+ * Write data to the encoded stream.
+ */
+static int
+archive_filter_b64encode_write(struct archive_write_filter *f, const void *buff,
+    size_t length)
+{
+	struct private_b64encode *state = (struct private_b64encode *)f->data;
+	const unsigned char *p = buff;
+	int ret = ARCHIVE_OK;
+
+	if (length == 0)
+		return (ret);
+
+	if (state->hold_len) {
+		while (state->hold_len < LBYTES && length > 0) {
+			state->hold[state->hold_len++] = *p++;
+			length--;
+		}
+		if (state->hold_len < LBYTES)
+			return (ret);
+		b64_encode(&state->encoded_buff, state->hold, LBYTES);
+		state->hold_len = 0;
+	}
+
+	for (; length >= LBYTES; length -= LBYTES, p += LBYTES)
+		b64_encode(&state->encoded_buff, p, LBYTES);
+
+	/* Save remaining bytes. */
+	if (length > 0) {
+		memcpy(state->hold, p, length);
+		state->hold_len = length;
+	}
+	while (archive_strlen(&state->encoded_buff) >= state->bs) {
+		ret = __archive_write_filter(f->next_filter,
+		    state->encoded_buff.s, state->bs);
+		memmove(state->encoded_buff.s,
+		    state->encoded_buff.s + state->bs,
+		    state->encoded_buff.length - state->bs);
+		state->encoded_buff.length -= state->bs;
+	}
+
+	return (ret);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_filter_b64encode_close(struct archive_write_filter *f)
+{
+	struct private_b64encode *state = (struct private_b64encode *)f->data;
+	int ret, ret2;
+
+	/* Flush remaining bytes. */
+	if (state->hold_len != 0)
+		b64_encode(&state->encoded_buff, state->hold, state->hold_len);
+	archive_string_sprintf(&state->encoded_buff, "====\n");
+	/* Write the last block */
+	archive_write_set_bytes_in_last_block(f->archive, 1);
+	ret = __archive_write_filter(f->next_filter,
+	    state->encoded_buff.s, archive_strlen(&state->encoded_buff));
+	ret2 = __archive_write_close_filter(f->next_filter);
+	if (ret > ret2)
+		ret = ret2;
+	return (ret);
+}
+
+static int
+archive_filter_b64encode_free(struct archive_write_filter *f)
+{
+	struct private_b64encode *state = (struct private_b64encode *)f->data;
+
+	archive_string_free(&state->name);
+	archive_string_free(&state->encoded_buff);
+	free(state);
+	return (ARCHIVE_OK);
+}
+
+static int64_t
+atol8(const char *p, size_t char_cnt)
+{
+	int64_t l;
+	int digit;
+        
+	l = 0;
+	while (char_cnt-- > 0) {
+		if (*p >= '0' && *p <= '7')
+			digit = *p - '0';
+		else
+			break;
+		p++;
+		l <<= 3;
+		l |= digit;
+	}
+	return (l);
+}
+

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_by_name.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_by_name.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_by_name.c
new file mode 100644
index 0000000..85a8d47
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_by_name.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+
+/* A table that maps names to functions. */
+static const
+struct { const char *name; int (*setter)(struct archive *); } names[] =
+{
+	{ "b64encode",		archive_write_add_filter_b64encode },
+	{ "bzip2",		archive_write_add_filter_bzip2 },
+	{ "compress",		archive_write_add_filter_compress },
+	{ "grzip",		archive_write_add_filter_grzip },
+	{ "gzip",		archive_write_add_filter_gzip },
+	{ "lrzip",		archive_write_add_filter_lrzip },
+	{ "lz4",		archive_write_add_filter_lz4 },
+	{ "lzip",		archive_write_add_filter_lzip },
+	{ "lzma",		archive_write_add_filter_lzma },
+	{ "lzop",		archive_write_add_filter_lzop },
+	{ "uuencode",		archive_write_add_filter_uuencode },
+	{ "xz",			archive_write_add_filter_xz },
+	{ NULL,			NULL }
+};
+
+int
+archive_write_add_filter_by_name(struct archive *a, const char *name)
+{
+	int i;
+
+	for (i = 0; names[i].name != NULL; i++) {
+		if (strcmp(name, names[i].name) == 0)
+			return ((names[i].setter)(a));
+	}
+
+	archive_set_error(a, EINVAL, "No such filter '%s'", name);
+	a->state = ARCHIVE_STATE_FATAL;
+	return (ARCHIVE_FATAL);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_bzip2.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_bzip2.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_bzip2.c
new file mode 100644
index 0000000..68ed957
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_bzip2.c
@@ -0,0 +1,407 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_bzip2(struct archive *a)
+{
+	__archive_write_filters_free(a);
+	return (archive_write_add_filter_bzip2(a));
+}
+#endif
+
+struct private_data {
+	int		 compression_level;
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+	bz_stream	 stream;
+	int64_t		 total_in;
+	char		*compressed;
+	size_t		 compressed_buffer_size;
+#else
+	struct archive_write_program_data *pdata;
+#endif
+};
+
+static int archive_compressor_bzip2_close(struct archive_write_filter *);
+static int archive_compressor_bzip2_free(struct archive_write_filter *);
+static int archive_compressor_bzip2_open(struct archive_write_filter *);
+static int archive_compressor_bzip2_options(struct archive_write_filter *,
+		    const char *, const char *);
+static int archive_compressor_bzip2_write(struct archive_write_filter *,
+		    const void *, size_t);
+
+/*
+ * Add a bzip2 compression filter to this write handle.
+ */
+int
+archive_write_add_filter_bzip2(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+	struct private_data *data;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_bzip2");
+
+	data = calloc(1, sizeof(*data));
+	if (data == NULL) {
+		archive_set_error(&a->archive, ENOMEM, "Out of memory");
+		return (ARCHIVE_FATAL);
+	}
+	data->compression_level = 9; /* default */
+
+	f->data = data;
+	f->options = &archive_compressor_bzip2_options;
+	f->close = &archive_compressor_bzip2_close;
+	f->free = &archive_compressor_bzip2_free;
+	f->open = &archive_compressor_bzip2_open;
+	f->code = ARCHIVE_FILTER_BZIP2;
+	f->name = "bzip2";
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+	return (ARCHIVE_OK);
+#else
+	data->pdata = __archive_write_program_allocate("bzip2");
+	if (data->pdata == NULL) {
+		free(data);
+		archive_set_error(&a->archive, ENOMEM, "Out of memory");
+		return (ARCHIVE_FATAL);
+	}
+	data->compression_level = 0;
+	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+	    "Using external bzip2 program");
+	return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_bzip2_options(struct archive_write_filter *f,
+    const char *key, const char *value)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	if (strcmp(key, "compression-level") == 0) {
+		if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
+		    value[1] != '\0')
+			return (ARCHIVE_WARN);
+		data->compression_level = value[0] - '0';
+		/* Make '0' be a synonym for '1'. */
+		/* This way, bzip2 compressor supports the same 0..9
+		 * range of levels as gzip. */
+		if (data->compression_level < 1)
+			data->compression_level = 1;
+		return (ARCHIVE_OK);
+	}
+
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+/* Don't compile this if we don't have bzlib. */
+
+/*
+ * Yuck.  bzlib.h is not const-correct, so I need this one bit
+ * of ugly hackery to convert a const * pointer to a non-const pointer.
+ */
+#define	SET_NEXT_IN(st,src)					\
+	(st)->stream.next_in = (char *)(uintptr_t)(const void *)(src)
+static int drive_compressor(struct archive_write_filter *,
+		    struct private_data *, int finishing);
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_bzip2_open(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	int ret;
+
+	ret = __archive_write_open_filter(f->next_filter);
+	if (ret != 0)
+		return (ret);
+
+	if (data->compressed == NULL) {
+		size_t bs = 65536, bpb;
+		if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
+			/* Buffer size should be a multiple number of the of bytes
+			 * per block for performance. */
+			bpb = archive_write_get_bytes_per_block(f->archive);
+			if (bpb > bs)
+				bs = bpb;
+			else if (bpb != 0)
+				bs -= bs % bpb;
+		}
+		data->compressed_buffer_size = bs;
+		data->compressed
+		    = (char *)malloc(data->compressed_buffer_size);
+		if (data->compressed == NULL) {
+			archive_set_error(f->archive, ENOMEM,
+			    "Can't allocate data for compression buffer");
+			return (ARCHIVE_FATAL);
+		}
+	}
+
+	memset(&data->stream, 0, sizeof(data->stream));
+	data->stream.next_out = data->compressed;
+	data->stream.avail_out = data->compressed_buffer_size;
+	f->write = archive_compressor_bzip2_write;
+
+	/* Initialize compression library */
+	ret = BZ2_bzCompressInit(&(data->stream),
+	    data->compression_level, 0, 30);
+	if (ret == BZ_OK) {
+		f->data = data;
+		return (ARCHIVE_OK);
+	}
+
+	/* Library setup failed: clean up. */
+	archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+	    "Internal error initializing compression library");
+
+	/* Override the error message if we know what really went wrong. */
+	switch (ret) {
+	case BZ_PARAM_ERROR:
+		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+		    "Internal error initializing compression library: "
+		    "invalid setup parameter");
+		break;
+	case BZ_MEM_ERROR:
+		archive_set_error(f->archive, ENOMEM,
+		    "Internal error initializing compression library: "
+		    "out of memory");
+		break;
+	case BZ_CONFIG_ERROR:
+		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+		    "Internal error initializing compression library: "
+		    "mis-compiled library");
+		break;
+	}
+
+	return (ARCHIVE_FATAL);
+
+}
+
+/*
+ * Write data to the compressed stream.
+ *
+ * Returns ARCHIVE_OK if all data written, error otherwise.
+ */
+static int
+archive_compressor_bzip2_write(struct archive_write_filter *f,
+    const void *buff, size_t length)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	/* Update statistics */
+	data->total_in += length;
+
+	/* Compress input data to output buffer */
+	SET_NEXT_IN(data, buff);
+	data->stream.avail_in = length;
+	if (drive_compressor(f, data, 0))
+		return (ARCHIVE_FATAL);
+	return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression.
+ */
+static int
+archive_compressor_bzip2_close(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	int ret, r1;
+
+	/* Finish compression cycle. */
+	ret = drive_compressor(f, data, 1);
+	if (ret == ARCHIVE_OK) {
+		/* Write the last block */
+		ret = __archive_write_filter(f->next_filter,
+		    data->compressed,
+		    data->compressed_buffer_size - data->stream.avail_out);
+	}
+
+	switch (BZ2_bzCompressEnd(&(data->stream))) {
+	case BZ_OK:
+		break;
+	default:
+		archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Failed to clean up compressor");
+		ret = ARCHIVE_FATAL;
+	}
+
+	r1 = __archive_write_close_filter(f->next_filter);
+	return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_bzip2_free(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	free(data->compressed);
+	free(data);
+	f->data = NULL;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Utility function to push input data through compressor, writing
+ * full output blocks as necessary.
+ *
+ * Note that this handles both the regular write case (finishing ==
+ * false) and the end-of-archive case (finishing == true).
+ */
+static int
+drive_compressor(struct archive_write_filter *f,
+    struct private_data *data, int finishing)
+{
+	int ret;
+
+	for (;;) {
+		if (data->stream.avail_out == 0) {
+			ret = __archive_write_filter(f->next_filter,
+			    data->compressed,
+			    data->compressed_buffer_size);
+			if (ret != ARCHIVE_OK) {
+				/* TODO: Handle this write failure */
+				return (ARCHIVE_FATAL);
+			}
+			data->stream.next_out = data->compressed;
+			data->stream.avail_out = data->compressed_buffer_size;
+		}
+
+		/* If there's nothing to do, we're done. */
+		if (!finishing && data->stream.avail_in == 0)
+			return (ARCHIVE_OK);
+
+		ret = BZ2_bzCompress(&(data->stream),
+		    finishing ? BZ_FINISH : BZ_RUN);
+
+		switch (ret) {
+		case BZ_RUN_OK:
+			/* In non-finishing case, did compressor
+			 * consume everything? */
+			if (!finishing && data->stream.avail_in == 0)
+				return (ARCHIVE_OK);
+			break;
+		case BZ_FINISH_OK:  /* Finishing: There's more work to do */
+			break;
+		case BZ_STREAM_END: /* Finishing: all done */
+			/* Only occurs in finishing case */
+			return (ARCHIVE_OK);
+		default:
+			/* Any other return value indicates an error */
+			archive_set_error(f->archive,
+			    ARCHIVE_ERRNO_PROGRAMMER,
+			    "Bzip2 compression failed;"
+			    " BZ2_bzCompress() returned %d",
+			    ret);
+			return (ARCHIVE_FATAL);
+		}
+	}
+}
+
+#else /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
+
+static int
+archive_compressor_bzip2_open(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	struct archive_string as;
+	int r;
+
+	archive_string_init(&as);
+	archive_strcpy(&as, "bzip2");
+
+	/* Specify compression level. */
+	if (data->compression_level > 0) {
+		archive_strcat(&as, " -");
+		archive_strappend_char(&as, '0' + data->compression_level);
+	}
+	f->write = archive_compressor_bzip2_write;
+
+	r = __archive_write_program_open(f, data->pdata, as.s);
+	archive_string_free(&as);
+	return (r);
+}
+
+static int
+archive_compressor_bzip2_write(struct archive_write_filter *f, const void *buff,
+    size_t length)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_compressor_bzip2_close(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	return __archive_write_program_close(f, data->pdata);
+}
+
+static int
+archive_compressor_bzip2_free(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	__archive_write_program_free(data->pdata);
+	free(data);
+	return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_compress.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_compress.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_compress.c
new file mode 100644
index 0000000..26fcef4
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_compress.c
@@ -0,0 +1,455 @@
+/*-
+ * Copyright (c) 2008 Joerg Sonnenberger
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1985, 1986, 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Diomidis Spinellis and James A. Woods, derived from original
+ * work by Spencer Thomas and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_compress.c 201111 2009-12-28 03:33:05Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#define	HSIZE		69001	/* 95% occupancy */
+#define	HSHIFT		8	/* 8 - trunc(log2(HSIZE / 65536)) */
+#define	CHECK_GAP 10000		/* Ratio check interval. */
+
+#define	MAXCODE(bits)	((1 << (bits)) - 1)
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define	FIRST	257		/* First free entry. */
+#define	CLEAR	256		/* Table clear output code. */
+
+struct private_data {
+	int64_t in_count, out_count, checkpoint;
+
+	int code_len;			/* Number of bits/code. */
+	int cur_maxcode;		/* Maximum code, given n_bits. */
+	int max_maxcode;		/* Should NEVER generate this code. */
+	int hashtab [HSIZE];
+	unsigned short codetab [HSIZE];
+	int first_free;		/* First unused entry. */
+	int compress_ratio;
+
+	int cur_code, cur_fcode;
+
+	int bit_offset;
+	unsigned char bit_buf;
+
+	unsigned char	*compressed;
+	size_t		 compressed_buffer_size;
+	size_t		 compressed_offset;
+};
+
+static int archive_compressor_compress_open(struct archive_write_filter *);
+static int archive_compressor_compress_write(struct archive_write_filter *,
+		    const void *, size_t);
+static int archive_compressor_compress_close(struct archive_write_filter *);
+static int archive_compressor_compress_free(struct archive_write_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_compress(struct archive *a)
+{
+	__archive_write_filters_free(a);
+	return (archive_write_add_filter_compress(a));
+}
+#endif
+
+/*
+ * Add a compress filter to this write handle.
+ */
+int
+archive_write_add_filter_compress(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_compress");
+	f->open = &archive_compressor_compress_open;
+	f->code = ARCHIVE_FILTER_COMPRESS;
+	f->name = "compress";
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_compress_open(struct archive_write_filter *f)
+{
+	int ret;
+	struct private_data *state;
+	size_t bs = 65536, bpb;
+
+	f->code = ARCHIVE_FILTER_COMPRESS;
+	f->name = "compress";
+
+	ret = __archive_write_open_filter(f->next_filter);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	state = (struct private_data *)calloc(1, sizeof(*state));
+	if (state == NULL) {
+		archive_set_error(f->archive, ENOMEM,
+		    "Can't allocate data for compression");
+		return (ARCHIVE_FATAL);
+	}
+
+	if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
+		/* Buffer size should be a multiple number of the of bytes
+		 * per block for performance. */
+		bpb = archive_write_get_bytes_per_block(f->archive);
+		if (bpb > bs)
+			bs = bpb;
+		else if (bpb != 0)
+			bs -= bs % bpb;
+	}
+	state->compressed_buffer_size = bs;
+	state->compressed = malloc(state->compressed_buffer_size);
+
+	if (state->compressed == NULL) {
+		archive_set_error(f->archive, ENOMEM,
+		    "Can't allocate data for compression buffer");
+		free(state);
+		return (ARCHIVE_FATAL);
+	}
+
+	f->write = archive_compressor_compress_write;
+	f->close = archive_compressor_compress_close;
+	f->free = archive_compressor_compress_free;
+
+	state->max_maxcode = 0x10000;	/* Should NEVER generate this code. */
+	state->in_count = 0;		/* Length of input. */
+	state->bit_buf = 0;
+	state->bit_offset = 0;
+	state->out_count = 3;		/* Includes 3-byte header mojo. */
+	state->compress_ratio = 0;
+	state->checkpoint = CHECK_GAP;
+	state->code_len = 9;
+	state->cur_maxcode = MAXCODE(state->code_len);
+	state->first_free = FIRST;
+
+	memset(state->hashtab, 0xff, sizeof(state->hashtab));
+
+	/* Prime output buffer with a gzip header. */
+	state->compressed[0] = 0x1f; /* Compress */
+	state->compressed[1] = 0x9d;
+	state->compressed[2] = 0x90; /* Block mode, 16bit max */
+	state->compressed_offset = 3;
+
+	f->data = state;
+	return (0);
+}
+
+/*-
+ * Output the given code.
+ * Inputs:
+ * 	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
+ *		that n_bits <= (long)wordsize - 1.
+ * Outputs:
+ * 	Outputs code to the file.
+ * Assumptions:
+ *	Chars are 8 bits long.
+ * Algorithm:
+ * 	Maintain a BITS character long buffer (so that 8 codes will
+ * fit in it exactly).  Use the VAX insv instruction to insert each
+ * code in turn.  When the buffer fills up empty it and start over.
+ */
+
+static const unsigned char rmask[9] =
+	{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
+static int
+output_byte(struct archive_write_filter *f, unsigned char c)
+{
+	struct private_data *state = f->data;
+
+	state->compressed[state->compressed_offset++] = c;
+	++state->out_count;
+
+	if (state->compressed_buffer_size == state->compressed_offset) {
+		int ret = __archive_write_filter(f->next_filter,
+		    state->compressed, state->compressed_buffer_size);
+		if (ret != ARCHIVE_OK)
+			return ARCHIVE_FATAL;
+		state->compressed_offset = 0;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int
+output_code(struct archive_write_filter *f, int ocode)
+{
+	struct private_data *state = f->data;
+	int bits, ret, clear_flg, bit_offset;
+
+	clear_flg = ocode == CLEAR;
+
+	/*
+	 * Since ocode is always >= 8 bits, only need to mask the first
+	 * hunk on the left.
+	 */
+	bit_offset = state->bit_offset % 8;
+	state->bit_buf |= (ocode << bit_offset) & 0xff;
+	output_byte(f, state->bit_buf);
+
+	bits = state->code_len - (8 - bit_offset);
+	ocode >>= 8 - bit_offset;
+	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+	if (bits >= 8) {
+		output_byte(f, ocode & 0xff);
+		ocode >>= 8;
+		bits -= 8;
+	}
+	/* Last bits. */
+	state->bit_offset += state->code_len;
+	state->bit_buf = ocode & rmask[bits];
+	if (state->bit_offset == state->code_len * 8)
+		state->bit_offset = 0;
+
+	/*
+	 * If the next entry is going to be too big for the ocode size,
+	 * then increase it, if possible.
+	 */
+	if (clear_flg || state->first_free > state->cur_maxcode) {
+	       /*
+		* Write the whole buffer, because the input side won't
+		* discover the size increase until after it has read it.
+		*/
+		if (state->bit_offset > 0) {
+			while (state->bit_offset < state->code_len * 8) {
+				ret = output_byte(f, state->bit_buf);
+				if (ret != ARCHIVE_OK)
+					return ret;
+				state->bit_offset += 8;
+				state->bit_buf = 0;
+			}
+		}
+		state->bit_buf = 0;
+		state->bit_offset = 0;
+
+		if (clear_flg) {
+			state->code_len = 9;
+			state->cur_maxcode = MAXCODE(state->code_len);
+		} else {
+			state->code_len++;
+			if (state->code_len == 16)
+				state->cur_maxcode = state->max_maxcode;
+			else
+				state->cur_maxcode = MAXCODE(state->code_len);
+		}
+	}
+
+	return (ARCHIVE_OK);
+}
+
+static int
+output_flush(struct archive_write_filter *f)
+{
+	struct private_data *state = f->data;
+	int ret;
+
+	/* At EOF, write the rest of the buffer. */
+	if (state->bit_offset % 8) {
+		state->code_len = (state->bit_offset % 8 + 7) / 8;
+		ret = output_byte(f, state->bit_buf);
+		if (ret != ARCHIVE_OK)
+			return ret;
+	}
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_compress_write(struct archive_write_filter *f,
+    const void *buff, size_t length)
+{
+	struct private_data *state = (struct private_data *)f->data;
+	int i;
+	int ratio;
+	int c, disp, ret;
+	const unsigned char *bp;
+
+	if (length == 0)
+		return ARCHIVE_OK;
+
+	bp = buff;
+
+	if (state->in_count == 0) {
+		state->cur_code = *bp++;
+		++state->in_count;
+		--length;
+	}
+
+	while (length--) {
+		c = *bp++;
+		state->in_count++;
+		state->cur_fcode = (c << 16) + state->cur_code;
+		i = ((c << HSHIFT) ^ state->cur_code);	/* Xor hashing. */
+
+		if (state->hashtab[i] == state->cur_fcode) {
+			state->cur_code = state->codetab[i];
+			continue;
+		}
+		if (state->hashtab[i] < 0)	/* Empty slot. */
+			goto nomatch;
+		/* Secondary hash (after G. Knott). */
+		if (i == 0)
+			disp = 1;
+		else
+			disp = HSIZE - i;
+ probe:
+		if ((i -= disp) < 0)
+			i += HSIZE;
+
+		if (state->hashtab[i] == state->cur_fcode) {
+			state->cur_code = state->codetab[i];
+			continue;
+		}
+		if (state->hashtab[i] >= 0)
+			goto probe;
+ nomatch:
+		ret = output_code(f, state->cur_code);
+		if (ret != ARCHIVE_OK)
+			return ret;
+		state->cur_code = c;
+		if (state->first_free < state->max_maxcode) {
+			state->codetab[i] = state->first_free++;	/* code -> hashtable */
+			state->hashtab[i] = state->cur_fcode;
+			continue;
+		}
+		if (state->in_count < state->checkpoint)
+			continue;
+
+		state->checkpoint = state->in_count + CHECK_GAP;
+
+		if (state->in_count <= 0x007fffff && state->out_count != 0)
+			ratio = (int)(state->in_count * 256 / state->out_count);
+		else if ((ratio = (int)(state->out_count / 256)) == 0)
+			ratio = 0x7fffffff;
+		else
+			ratio = (int)(state->in_count / ratio);
+
+		if (ratio > state->compress_ratio)
+			state->compress_ratio = ratio;
+		else {
+			state->compress_ratio = 0;
+			memset(state->hashtab, 0xff, sizeof(state->hashtab));
+			state->first_free = FIRST;
+			ret = output_code(f, CLEAR);
+			if (ret != ARCHIVE_OK)
+				return ret;
+		}
+	}
+
+	return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_compress_close(struct archive_write_filter *f)
+{
+	struct private_data *state = (struct private_data *)f->data;
+	int ret, ret2;
+
+	ret = output_code(f, state->cur_code);
+	if (ret != ARCHIVE_OK)
+		goto cleanup;
+	ret = output_flush(f);
+	if (ret != ARCHIVE_OK)
+		goto cleanup;
+
+	/* Write the last block */
+	ret = __archive_write_filter(f->next_filter,
+	    state->compressed, state->compressed_offset);
+cleanup:
+	ret2 = __archive_write_close_filter(f->next_filter);
+	if (ret > ret2)
+		ret = ret2;
+	free(state->compressed);
+	free(state);
+	return (ret);
+}
+
+static int
+archive_compressor_compress_free(struct archive_write_filter *f)
+{
+	(void)f; /* UNUSED */
+	return (ARCHIVE_OK);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_grzip.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_grzip.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_grzip.c
new file mode 100644
index 0000000..371102d
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_grzip.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_write_private.h"
+
+struct write_grzip {
+	struct archive_write_program_data *pdata;
+};
+
+static int archive_write_grzip_open(struct archive_write_filter *);
+static int archive_write_grzip_options(struct archive_write_filter *,
+		    const char *, const char *);
+static int archive_write_grzip_write(struct archive_write_filter *,
+		    const void *, size_t);
+static int archive_write_grzip_close(struct archive_write_filter *);
+static int archive_write_grzip_free(struct archive_write_filter *);
+
+int
+archive_write_add_filter_grzip(struct archive *_a)
+{
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+	struct write_grzip *data;
+
+	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_grzip");
+
+	data = calloc(1, sizeof(*data));
+	if (data == NULL) {
+		archive_set_error(_a, ENOMEM, "Can't allocate memory");
+		return (ARCHIVE_FATAL);
+	}
+	data->pdata = __archive_write_program_allocate("grzip");
+	if (data->pdata == NULL) {
+		free(data);
+		archive_set_error(_a, ENOMEM, "Can't allocate memory");
+		return (ARCHIVE_FATAL);
+	}
+
+	f->name = "grzip";
+	f->code = ARCHIVE_FILTER_GRZIP;
+	f->data = data;
+	f->open = archive_write_grzip_open;
+	f->options = archive_write_grzip_options;
+	f->write = archive_write_grzip_write;
+	f->close = archive_write_grzip_close;
+	f->free = archive_write_grzip_free;
+
+	/* Note: This filter always uses an external program, so we
+	 * return "warn" to inform of the fact. */
+	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+	    "Using external grzip program for grzip compression");
+	return (ARCHIVE_WARN);
+}
+
+static int
+archive_write_grzip_options(struct archive_write_filter *f, const char *key,
+    const char *value)
+{
+	(void)f; /* UNUSED */
+	(void)key; /* UNUSED */
+	(void)value; /* UNUSED */
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
+static int
+archive_write_grzip_open(struct archive_write_filter *f)
+{
+	struct write_grzip *data = (struct write_grzip *)f->data;
+
+	return __archive_write_program_open(f, data->pdata, "grzip");
+}
+
+static int
+archive_write_grzip_write(struct archive_write_filter *f,
+    const void *buff, size_t length)
+{
+	struct write_grzip *data = (struct write_grzip *)f->data;
+
+	return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_write_grzip_close(struct archive_write_filter *f)
+{
+	struct write_grzip *data = (struct write_grzip *)f->data;
+
+	return __archive_write_program_close(f, data->pdata);
+}
+
+static int
+archive_write_grzip_free(struct archive_write_filter *f)
+{
+	struct write_grzip *data = (struct write_grzip *)f->data;
+
+	__archive_write_program_free(data->pdata);
+	free(data);
+	return (ARCHIVE_OK);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_gzip.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_gzip.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_gzip.c
new file mode 100644
index 0000000..04eb06c
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_gzip.c
@@ -0,0 +1,442 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <time.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_gzip(struct archive *a)
+{
+	__archive_write_filters_free(a);
+	return (archive_write_add_filter_gzip(a));
+}
+#endif
+
+/* Don't compile this if we don't have zlib. */
+
+struct private_data {
+	int		 compression_level;
+	int		 timestamp;
+#ifdef HAVE_ZLIB_H
+	z_stream	 stream;
+	int64_t		 total_in;
+	unsigned char	*compressed;
+	size_t		 compressed_buffer_size;
+	unsigned long	 crc;
+#else
+	struct archive_write_program_data *pdata;
+#endif
+};
+
+/*
+ * Yuck.  zlib.h is not const-correct, so I need this one bit
+ * of ugly hackery to convert a const * pointer to a non-const pointer.
+ */
+#define	SET_NEXT_IN(st,src)					\
+	(st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src)
+
+static int archive_compressor_gzip_options(struct archive_write_filter *,
+		    const char *, const char *);
+static int archive_compressor_gzip_open(struct archive_write_filter *);
+static int archive_compressor_gzip_write(struct archive_write_filter *,
+		    const void *, size_t);
+static int archive_compressor_gzip_close(struct archive_write_filter *);
+static int archive_compressor_gzip_free(struct archive_write_filter *);
+#ifdef HAVE_ZLIB_H
+static int drive_compressor(struct archive_write_filter *,
+		    struct private_data *, int finishing);
+#endif
+
+
+/*
+ * Add a gzip compression filter to this write handle.
+ */
+int
+archive_write_add_filter_gzip(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+	struct private_data *data;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_gzip");
+
+	data = calloc(1, sizeof(*data));
+	if (data == NULL) {
+		archive_set_error(&a->archive, ENOMEM, "Out of memory");
+		return (ARCHIVE_FATAL);
+	}
+	f->data = data;
+	f->open = &archive_compressor_gzip_open;
+	f->options = &archive_compressor_gzip_options;
+	f->close = &archive_compressor_gzip_close;
+	f->free = &archive_compressor_gzip_free;
+	f->code = ARCHIVE_FILTER_GZIP;
+	f->name = "gzip";
+#ifdef HAVE_ZLIB_H
+	data->compression_level = Z_DEFAULT_COMPRESSION;
+	return (ARCHIVE_OK);
+#else
+	data->pdata = __archive_write_program_allocate("gzip");
+	if (data->pdata == NULL) {
+		free(data);
+		archive_set_error(&a->archive, ENOMEM, "Out of memory");
+		return (ARCHIVE_FATAL);
+	}
+	data->compression_level = 0;
+	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+	    "Using external gzip program");
+	return (ARCHIVE_WARN);
+#endif
+}
+
+static int
+archive_compressor_gzip_free(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+#ifdef HAVE_ZLIB_H
+	free(data->compressed);
+#else
+	__archive_write_program_free(data->pdata);
+#endif
+	free(data);
+	f->data = NULL;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
+    const char *value)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	if (strcmp(key, "compression-level") == 0) {
+		if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
+		    value[1] != '\0')
+			return (ARCHIVE_WARN);
+		data->compression_level = value[0] - '0';
+		return (ARCHIVE_OK);
+	}
+	if (strcmp(key, "timestamp") == 0) {
+		data->timestamp = (value == NULL)?-1:1;
+		return (ARCHIVE_OK);
+	}
+
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
+#ifdef HAVE_ZLIB_H
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_gzip_open(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	int ret;
+
+	ret = __archive_write_open_filter(f->next_filter);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	if (data->compressed == NULL) {
+		size_t bs = 65536, bpb;
+		if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
+			/* Buffer size should be a multiple number of
+			 * the of bytes per block for performance. */
+			bpb = archive_write_get_bytes_per_block(f->archive);
+			if (bpb > bs)
+				bs = bpb;
+			else if (bpb != 0)
+				bs -= bs % bpb;
+		}
+		data->compressed_buffer_size = bs;
+		data->compressed
+		    = (unsigned char *)malloc(data->compressed_buffer_size);
+		if (data->compressed == NULL) {
+			archive_set_error(f->archive, ENOMEM,
+			    "Can't allocate data for compression buffer");
+			return (ARCHIVE_FATAL);
+		}
+	}
+
+	data->crc = crc32(0L, NULL, 0);
+	data->stream.next_out = data->compressed;
+	data->stream.avail_out = (uInt)data->compressed_buffer_size;
+
+	/* Prime output buffer with a gzip header. */
+	data->compressed[0] = 0x1f; /* GZip signature bytes */
+	data->compressed[1] = 0x8b;
+	data->compressed[2] = 0x08; /* "Deflate" compression */
+	data->compressed[3] = 0; /* No options */
+	if (data->timestamp >= 0) {
+		time_t t = time(NULL);
+		data->compressed[4] = (uint8_t)(t)&0xff;  /* Timestamp */
+		data->compressed[5] = (uint8_t)(t>>8)&0xff;
+		data->compressed[6] = (uint8_t)(t>>16)&0xff;
+		data->compressed[7] = (uint8_t)(t>>24)&0xff;
+	} else
+		memset(&data->compressed[4], 0, 4);
+	data->compressed[8] = 0; /* No deflate options */
+	data->compressed[9] = 3; /* OS=Unix */
+	data->stream.next_out += 10;
+	data->stream.avail_out -= 10;
+
+	f->write = archive_compressor_gzip_write;
+
+	/* Initialize compression library. */
+	ret = deflateInit2(&(data->stream),
+	    data->compression_level,
+	    Z_DEFLATED,
+	    -15 /* < 0 to suppress zlib header */,
+	    8,
+	    Z_DEFAULT_STRATEGY);
+
+	if (ret == Z_OK) {
+		f->data = data;
+		return (ARCHIVE_OK);
+	}
+
+	/* Library setup failed: clean up. */
+	archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error "
+	    "initializing compression library");
+
+	/* Override the error message if we know what really went wrong. */
+	switch (ret) {
+	case Z_STREAM_ERROR:
+		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+		    "Internal error initializing "
+		    "compression library: invalid setup parameter");
+		break;
+	case Z_MEM_ERROR:
+		archive_set_error(f->archive, ENOMEM,
+		    "Internal error initializing compression library");
+		break;
+	case Z_VERSION_ERROR:
+		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+		    "Internal error initializing "
+		    "compression library: invalid library version");
+		break;
+	}
+
+	return (ARCHIVE_FATAL);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
+    size_t length)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	int ret;
+
+	/* Update statistics */
+	data->crc = crc32(data->crc, (const Bytef *)buff, (uInt)length);
+	data->total_in += length;
+
+	/* Compress input data to output buffer */
+	SET_NEXT_IN(data, buff);
+	data->stream.avail_in = (uInt)length;
+	if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
+		return (ret);
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_gzip_close(struct archive_write_filter *f)
+{
+	unsigned char trailer[8];
+	struct private_data *data = (struct private_data *)f->data;
+	int ret, r1;
+
+	/* Finish compression cycle */
+	ret = drive_compressor(f, data, 1);
+	if (ret == ARCHIVE_OK) {
+		/* Write the last compressed data. */
+		ret = __archive_write_filter(f->next_filter,
+		    data->compressed,
+		    data->compressed_buffer_size - data->stream.avail_out);
+	}
+	if (ret == ARCHIVE_OK) {
+		/* Build and write out 8-byte trailer. */
+		trailer[0] = (uint8_t)(data->crc)&0xff;
+		trailer[1] = (uint8_t)(data->crc >> 8)&0xff;
+		trailer[2] = (uint8_t)(data->crc >> 16)&0xff;
+		trailer[3] = (uint8_t)(data->crc >> 24)&0xff;
+		trailer[4] = (uint8_t)(data->total_in)&0xff;
+		trailer[5] = (uint8_t)(data->total_in >> 8)&0xff;
+		trailer[6] = (uint8_t)(data->total_in >> 16)&0xff;
+		trailer[7] = (uint8_t)(data->total_in >> 24)&0xff;
+		ret = __archive_write_filter(f->next_filter, trailer, 8);
+	}
+
+	switch (deflateEnd(&(data->stream))) {
+	case Z_OK:
+		break;
+	default:
+		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+		    "Failed to clean up compressor");
+		ret = ARCHIVE_FATAL;
+	}
+	r1 = __archive_write_close_filter(f->next_filter);
+	return (r1 < ret ? r1 : ret);
+}
+
+/*
+ * Utility function to push input data through compressor,
+ * writing full output blocks as necessary.
+ *
+ * Note that this handles both the regular write case (finishing ==
+ * false) and the end-of-archive case (finishing == true).
+ */
+static int
+drive_compressor(struct archive_write_filter *f,
+    struct private_data *data, int finishing)
+{
+	int ret;
+
+	for (;;) {
+		if (data->stream.avail_out == 0) {
+			ret = __archive_write_filter(f->next_filter,
+			    data->compressed,
+			    data->compressed_buffer_size);
+			if (ret != ARCHIVE_OK)
+				return (ARCHIVE_FATAL);
+			data->stream.next_out = data->compressed;
+			data->stream.avail_out =
+			    (uInt)data->compressed_buffer_size;
+		}
+
+		/* If there's nothing to do, we're done. */
+		if (!finishing && data->stream.avail_in == 0)
+			return (ARCHIVE_OK);
+
+		ret = deflate(&(data->stream),
+		    finishing ? Z_FINISH : Z_NO_FLUSH );
+
+		switch (ret) {
+		case Z_OK:
+			/* In non-finishing case, check if compressor
+			 * consumed everything */
+			if (!finishing && data->stream.avail_in == 0)
+				return (ARCHIVE_OK);
+			/* In finishing case, this return always means
+			 * there's more work */
+			break;
+		case Z_STREAM_END:
+			/* This return can only occur in finishing case. */
+			return (ARCHIVE_OK);
+		default:
+			/* Any other return value indicates an error. */
+			archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+			    "GZip compression failed:"
+			    " deflate() call returned status %d",
+			    ret);
+			return (ARCHIVE_FATAL);
+		}
+	}
+}
+
+#else /* HAVE_ZLIB_H */
+
+static int
+archive_compressor_gzip_open(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	struct archive_string as;
+	int r;
+
+	archive_string_init(&as);
+	archive_strcpy(&as, "gzip");
+
+	/* Specify compression level. */
+	if (data->compression_level > 0) {
+		archive_strcat(&as, " -");
+		archive_strappend_char(&as, '0' + data->compression_level);
+	}
+	if (data->timestamp < 0)
+		/* Do not save timestamp. */
+		archive_strcat(&as, " -n");
+	else if (data->timestamp > 0)
+		/* Save timestamp. */
+		archive_strcat(&as, " -N");
+
+	f->write = archive_compressor_gzip_write;
+	r = __archive_write_program_open(f, data->pdata, as.s);
+	archive_string_free(&as);
+	return (r);
+}
+
+static int
+archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
+    size_t length)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_compressor_gzip_close(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	return __archive_write_program_close(f, data->pdata);
+}
+
+#endif /* HAVE_ZLIB_H */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_lrzip.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_lrzip.c b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_lrzip.c
new file mode 100644
index 0000000..e215f89
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write_add_filter_lrzip.c
@@ -0,0 +1,197 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+struct write_lrzip {
+	struct archive_write_program_data *pdata;
+	int	compression_level;
+	enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression;
+};
+
+static int archive_write_lrzip_open(struct archive_write_filter *);
+static int archive_write_lrzip_options(struct archive_write_filter *,
+		    const char *, const char *);
+static int archive_write_lrzip_write(struct archive_write_filter *,
+		    const void *, size_t);
+static int archive_write_lrzip_close(struct archive_write_filter *);
+static int archive_write_lrzip_free(struct archive_write_filter *);
+
+int
+archive_write_add_filter_lrzip(struct archive *_a)
+{
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+	struct write_lrzip *data;
+
+	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_lrzip");
+
+	data = calloc(1, sizeof(*data));
+	if (data == NULL) {
+		archive_set_error(_a, ENOMEM, "Can't allocate memory");
+		return (ARCHIVE_FATAL);
+	}
+	data->pdata = __archive_write_program_allocate("lrzip");
+	if (data->pdata == NULL) {
+		free(data);
+		archive_set_error(_a, ENOMEM, "Can't allocate memory");
+		return (ARCHIVE_FATAL);
+	}
+
+	f->name = "lrzip";
+	f->code = ARCHIVE_FILTER_LRZIP;
+	f->data = data;
+	f->open = archive_write_lrzip_open;
+	f->options = archive_write_lrzip_options;
+	f->write = archive_write_lrzip_write;
+	f->close = archive_write_lrzip_close;
+	f->free = archive_write_lrzip_free;
+
+	/* Note: This filter always uses an external program, so we
+	 * return "warn" to inform of the fact. */
+	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+	    "Using external lrzip program for lrzip compression");
+	return (ARCHIVE_WARN);
+}
+
+static int
+archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
+    const char *value)
+{
+	struct write_lrzip *data = (struct write_lrzip *)f->data;
+
+	if (strcmp(key, "compression") == 0) {
+		if (value == NULL)
+			return (ARCHIVE_WARN);
+		else if (strcmp(value, "bzip2") == 0)
+			data->compression = bzip2;
+		else if (strcmp(value, "gzip") == 0)
+			data->compression = gzip;
+		else if (strcmp(value, "lzo") == 0)
+			data->compression = lzo;
+		else if (strcmp(value, "none") == 0)
+			data->compression = none;
+		else if (strcmp(value, "zpaq") == 0)
+			data->compression = zpaq;
+		else
+			return (ARCHIVE_WARN);
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "compression-level") == 0) {
+		if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
+		    value[1] != '\0')
+			return (ARCHIVE_WARN);
+		data->compression_level = value[0] - '0';
+		return (ARCHIVE_OK);
+	}
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
+static int
+archive_write_lrzip_open(struct archive_write_filter *f)
+{
+	struct write_lrzip *data = (struct write_lrzip *)f->data;
+	struct archive_string as;
+	int r;
+
+	archive_string_init(&as);
+	archive_strcpy(&as, "lrzip -q");
+
+	/* Specify compression type. */
+	switch (data->compression) {
+	case lzma:/* default compression */
+		break;
+	case bzip2:
+		archive_strcat(&as, " -b");
+		break;
+	case gzip:
+		archive_strcat(&as, " -g");
+		break;
+	case lzo:
+		archive_strcat(&as, " -l");
+		break;
+	case none:
+		archive_strcat(&as, " -n");
+		break;
+	case zpaq:
+		archive_strcat(&as, " -z");
+		break;
+	}
+
+	/* Specify compression level. */
+	if (data->compression_level > 0) {
+		archive_strcat(&as, " -L ");
+		archive_strappend_char(&as, '0' + data->compression_level);
+	}
+
+	r = __archive_write_program_open(f, data->pdata, as.s);
+	archive_string_free(&as);
+	return (r);
+}
+
+static int
+archive_write_lrzip_write(struct archive_write_filter *f,
+    const void *buff, size_t length)
+{
+	struct write_lrzip *data = (struct write_lrzip *)f->data;
+
+	return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_write_lrzip_close(struct archive_write_filter *f)
+{
+	struct write_lrzip *data = (struct write_lrzip *)f->data;
+
+	return __archive_write_program_close(f, data->pdata);
+}
+
+static int
+archive_write_lrzip_free(struct archive_write_filter *f)
+{
+	struct write_lrzip *data = (struct write_lrzip *)f->data;
+
+	__archive_write_program_free(data->pdata);
+	free(data);
+	return (ARCHIVE_OK);
+}