]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/index.c
Imported to git.
[icculus/xz.git] / src / liblzma / common / index.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       index.c
4 /// \brief      Handling of Index in Metadata
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "common.h"
21
22
23 /**
24  * \brief       Duplicates an Index list
25  *
26  * \return      A copy of the Index list, or NULL if memory allocation
27  *              failed or the original Index was empty.
28  */
29 extern LZMA_API lzma_index *
30 lzma_index_dup(const lzma_index *old_current, lzma_allocator *allocator)
31 {
32         lzma_index *new_head = NULL;
33         lzma_index *new_current = NULL;
34
35         while (old_current != NULL) {
36                 lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);
37                 if (i == NULL) {
38                         lzma_index_free(new_head, allocator);
39                         return NULL;
40                 }
41
42                 i->total_size = old_current->total_size;
43                 i->uncompressed_size = old_current->uncompressed_size;
44                 i->next = NULL;
45
46                 if (new_head == NULL)
47                         new_head = i;
48                 else
49                         new_current->next = i;
50
51                 new_current = i;
52                 old_current = old_current->next;
53         }
54
55         return new_head;
56 }
57
58
59 /**
60  * \brief       Frees an Index list
61  *
62  * All Index Recors in the list are freed. This function is convenient when
63  * getting rid of lzma_metadata structures containing an Index.
64  */
65 extern LZMA_API void
66 lzma_index_free(lzma_index *i, lzma_allocator *allocator)
67 {
68         while (i != NULL) {
69                 lzma_index *tmp = i->next;
70                 lzma_free(i, allocator);
71                 i = tmp;
72         }
73
74         return;
75 }
76
77
78 /**
79  * \brief       Calculates properties of an Index list
80  *
81  *
82  */
83 extern LZMA_API lzma_ret
84 lzma_index_count(const lzma_index *i, size_t *count,
85                 lzma_vli *lzma_restrict total_size,
86                 lzma_vli *lzma_restrict uncompressed_size)
87 {
88         *count = 0;
89         *total_size = 0;
90         *uncompressed_size = 0;
91
92         while (i != NULL) {
93                 if (i->total_size == LZMA_VLI_VALUE_UNKNOWN) {
94                         *total_size = LZMA_VLI_VALUE_UNKNOWN;
95                 } else if (i->total_size > LZMA_VLI_VALUE_MAX) {
96                         return LZMA_PROG_ERROR;
97                 } else if (*total_size != LZMA_VLI_VALUE_UNKNOWN) {
98                         *total_size += i->total_size;
99                         if (*total_size > LZMA_VLI_VALUE_MAX)
100                                 return LZMA_PROG_ERROR;
101                 }
102
103                 if (i->uncompressed_size == LZMA_VLI_VALUE_UNKNOWN) {
104                         *uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
105                 } else if (i->uncompressed_size > LZMA_VLI_VALUE_MAX) {
106                         return LZMA_PROG_ERROR;
107                 } else if (*uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
108                         *uncompressed_size += i->uncompressed_size;
109                         if (*uncompressed_size > LZMA_VLI_VALUE_MAX)
110                                 return LZMA_PROG_ERROR;
111                 }
112
113                 ++*count;
114                 i = i->next;
115         }
116
117         // FIXME ?
118         if (*total_size == LZMA_VLI_VALUE_UNKNOWN
119                         || *uncompressed_size == LZMA_VLI_VALUE_UNKNOWN)
120                 return LZMA_HEADER_ERROR;
121
122         return LZMA_OK;
123 }
124
125
126
127 extern LZMA_API lzma_bool
128 lzma_index_is_equal(const lzma_index *a, const lzma_index *b)
129 {
130         while (a != NULL && b != NULL) {
131                 if (a->total_size != b->total_size || a->uncompressed_size
132                                 != b->uncompressed_size)
133                         return false;
134
135                 a = a->next;
136                 b = b->next;
137         }
138
139         return a == b;
140 }