aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/common/index.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2007-12-09 00:42:33 +0200
committerLasse Collin <lasse.collin@tukaani.org>2007-12-09 00:42:33 +0200
commit5d018dc03549c1ee4958364712fb0c94e1bf2741 (patch)
tree1b211911fb33fddb3f04b77f99e81df23623ffc4 /src/liblzma/common/index.c
downloadxz-5d018dc03549c1ee4958364712fb0c94e1bf2741.tar.xz
Imported to git.
Diffstat (limited to 'src/liblzma/common/index.c')
-rw-r--r--src/liblzma/common/index.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/liblzma/common/index.c b/src/liblzma/common/index.c
new file mode 100644
index 00000000..6816b37a
--- /dev/null
+++ b/src/liblzma/common/index.c
@@ -0,0 +1,140 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index.c
+/// \brief Handling of Index in Metadata
+//
+// Copyright (C) 2007 Lasse Collin
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+/**
+ * \brief Duplicates an Index list
+ *
+ * \return A copy of the Index list, or NULL if memory allocation
+ * failed or the original Index was empty.
+ */
+extern LZMA_API lzma_index *
+lzma_index_dup(const lzma_index *old_current, lzma_allocator *allocator)
+{
+ lzma_index *new_head = NULL;
+ lzma_index *new_current = NULL;
+
+ while (old_current != NULL) {
+ lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);
+ if (i == NULL) {
+ lzma_index_free(new_head, allocator);
+ return NULL;
+ }
+
+ i->total_size = old_current->total_size;
+ i->uncompressed_size = old_current->uncompressed_size;
+ i->next = NULL;
+
+ if (new_head == NULL)
+ new_head = i;
+ else
+ new_current->next = i;
+
+ new_current = i;
+ old_current = old_current->next;
+ }
+
+ return new_head;
+}
+
+
+/**
+ * \brief Frees an Index list
+ *
+ * All Index Recors in the list are freed. This function is convenient when
+ * getting rid of lzma_metadata structures containing an Index.
+ */
+extern LZMA_API void
+lzma_index_free(lzma_index *i, lzma_allocator *allocator)
+{
+ while (i != NULL) {
+ lzma_index *tmp = i->next;
+ lzma_free(i, allocator);
+ i = tmp;
+ }
+
+ return;
+}
+
+
+/**
+ * \brief Calculates properties of an Index list
+ *
+ *
+ */
+extern LZMA_API lzma_ret
+lzma_index_count(const lzma_index *i, size_t *count,
+ lzma_vli *lzma_restrict total_size,
+ lzma_vli *lzma_restrict uncompressed_size)
+{
+ *count = 0;
+ *total_size = 0;
+ *uncompressed_size = 0;
+
+ while (i != NULL) {
+ if (i->total_size == LZMA_VLI_VALUE_UNKNOWN) {
+ *total_size = LZMA_VLI_VALUE_UNKNOWN;
+ } else if (i->total_size > LZMA_VLI_VALUE_MAX) {
+ return LZMA_PROG_ERROR;
+ } else if (*total_size != LZMA_VLI_VALUE_UNKNOWN) {
+ *total_size += i->total_size;
+ if (*total_size > LZMA_VLI_VALUE_MAX)
+ return LZMA_PROG_ERROR;
+ }
+
+ if (i->uncompressed_size == LZMA_VLI_VALUE_UNKNOWN) {
+ *uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
+ } else if (i->uncompressed_size > LZMA_VLI_VALUE_MAX) {
+ return LZMA_PROG_ERROR;
+ } else if (*uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
+ *uncompressed_size += i->uncompressed_size;
+ if (*uncompressed_size > LZMA_VLI_VALUE_MAX)
+ return LZMA_PROG_ERROR;
+ }
+
+ ++*count;
+ i = i->next;
+ }
+
+ // FIXME ?
+ if (*total_size == LZMA_VLI_VALUE_UNKNOWN
+ || *uncompressed_size == LZMA_VLI_VALUE_UNKNOWN)
+ return LZMA_HEADER_ERROR;
+
+ return LZMA_OK;
+}
+
+
+
+extern LZMA_API lzma_bool
+lzma_index_is_equal(const lzma_index *a, const lzma_index *b)
+{
+ while (a != NULL && b != NULL) {
+ if (a->total_size != b->total_size || a->uncompressed_size
+ != b->uncompressed_size)
+ return false;
+
+ a = a->next;
+ b = b->next;
+ }
+
+ return a == b;
+}