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