]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/alist.c
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / lib / alist.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2003-2014 Free Software Foundation Europe e.V.
6
7    The original author of Bacula is Kern Sibbald, with contributions
8    from many others, a complete list can be found in the file AUTHORS.
9
10    You may use this file and others of this release according to the
11    license defined in the LICENSE file, which includes the Affero General
12    Public License, v3.0 ("AGPLv3") and some additional permissions and
13    terms pursuant to its AGPLv3 Section 7.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21  *  Bacula array list routines
22  *
23  *    alist is a simple malloc'ed array of pointers.  For the moment,
24  *      it simply malloc's a bigger array controlled by num_grow.
25  *      Default is to realloc the pointer array for each new member.
26  *
27  *   Kern Sibbald, June MMIII
28  *
29  */
30
31 #include "bacula.h"
32
33 /*
34  * Private grow list function. Used to insure that
35  *   at least one more "slot" is available.
36  */
37 void alist::grow_list()
38 {
39    if (items == NULL) {
40       if (num_grow == 0) {
41          num_grow = 1;                /* default if not initialized */
42       }
43       items = (void **)malloc(num_grow * sizeof(void *));
44       max_items = num_grow;
45    } else if (num_items == max_items) {
46       max_items += num_grow;
47       items = (void **)realloc(items, max_items * sizeof(void *));
48    }
49 }
50
51 void *alist::first()
52 {
53    cur_item = 1;
54    if (num_items == 0) {
55       return NULL;
56    } else {
57       return items[0];
58    }
59 }
60
61 void *alist::last()
62 {
63    if (num_items == 0) {
64       return NULL;
65    } else {
66       cur_item = num_items;
67       return items[num_items-1];
68    }
69 }
70
71 void *alist::next()
72 {
73    if (cur_item >= num_items) {
74       return NULL;
75    } else {
76       return items[cur_item++];
77    }
78 }
79
80 void *alist::prev()
81 {
82    if (cur_item <= 1) {
83       return NULL;
84    } else {
85       return items[--cur_item];
86    }
87 }
88
89 /*
90  * prepend an item to the list -- i.e. add to beginning
91  */
92 void alist::prepend(void *item) {
93    grow_list();
94    if (num_items == 0) {
95       items[num_items++] = item;
96       return;
97    }
98    for (int i=num_items; i > 0; i--) {
99       items[i] = items[i-1];
100    }
101    items[0] = item;
102    num_items++;
103 }
104
105
106 /*
107  * Append an item to the list
108  */
109 void alist::append(void *item) {
110    grow_list();
111    items[num_items++] = item;
112 }
113
114 /* Remove an item from the list */
115 void * alist::remove(int index)
116 {
117    void *item;
118    if (index < 0 || index >= num_items) {
119       return NULL;
120    }
121    item = items[index];
122    num_items--;
123    for (int i=index; i < num_items; i++) {
124       items[i] = items[i+1];
125    }
126    return item;
127 }
128
129
130 /* Get the index item -- we should probably allow real indexing here */
131 void * alist::get(int index)
132 {
133    if (index < 0 || index >= num_items) {
134       return NULL;
135    }
136    return items[index];
137 }
138
139 /* Destroy the list and its contents */
140 void alist::destroy()
141 {
142    if (items) {
143       if (own_items) {
144          for (int i=0; i<num_items; i++) {
145             free(items[i]);
146             items[i] = NULL;
147          }
148       }
149       free(items);
150       items = NULL;
151    }
152 }
153
154 #ifdef TEST_PROGRAM
155
156
157 struct FILESET {
158    alist mylist;
159 };
160
161 int main()
162 {
163    FILESET *fileset;
164    char buf[30];
165    alist *mlist;
166
167    fileset = (FILESET *)malloc(sizeof(FILESET));
168    memset(fileset, 0, sizeof(FILESET));
169    fileset->mylist.init();
170
171    printf("Manual allocation/destruction of list:\n");
172
173    for (int i=0; i<20; i++) {
174       sprintf(buf, "This is item %d", i);
175       fileset->mylist.append(bstrdup(buf));
176    }
177    for (int i=0; i< fileset->mylist.size(); i++) {
178       printf("Item %d = %s\n", i, (char *)fileset->mylist[i]);
179    }
180    fileset->mylist.destroy();
181    free(fileset);
182
183    printf("Allocation/destruction using new delete\n");
184    mlist = new alist(10);
185
186    for (int i=0; i<20; i++) {
187       sprintf(buf, "This is item %d", i);
188       mlist->append(bstrdup(buf));
189    }
190    for (int i=0; i< mlist->size(); i++) {
191       printf("Item %d = %s\n", i, (char *)mlist->get(i));
192    }
193
194    delete mlist;
195
196
197    sm_dump(false);       /* test program */
198
199 }
200 #endif