2 Bacula® - The Network Backup Solution
4 Copyright (C) 2004-2014 Free Software Foundation Europe e.V.
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.
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.
14 Bacula® is a registered trademark of Kern Sibbald.
17 * Written by Kern Sibbald MMIV
22 /* ========================================================================
24 * Doubly linked list -- dlist
26 * See the end of the file for the dlistString class which
27 * facilitates storing strings in a dlist.
29 * Kern Sibbald, MMIV and MMVII
35 /* In case you want to specifically specify the offset to the link */
36 #define OFFSET(item, link) (int)((char *)(link) - (char *)(item))
38 * There is a lot of extra casting here to work around the fact
39 * that some compilers (Sun and Visual C++) do not accept
40 * (void *) as an lvalue on the left side of an equal.
42 * Loop var through each member of list
45 #define foreach_dlist(var, list) \
46 for((var)=NULL; ((var)=(typeof(var))(list)->next(var)); )
48 #define foreach_dlist(var, list) \
49 for((var)=NULL; (*((void **)&(var))=(void*)((list)->next(var))); )
57 class dlist : public SMARTALLOC {
63 dlist(void *item, dlink *link);
65 ~dlist() { destroy(); }
66 void init(void *item, dlink *link);
68 void prepend(void *item);
69 void append(void *item);
70 void set_prev(void *item, void *prev);
71 void set_next(void *item, void *next);
72 void *get_prev(void *item);
73 void *get_next(void *item);
74 dlink *get_link(void *item);
75 void insert_before(void *item, void *where);
76 void insert_after(void *item, void *where);
77 void *binary_insert(void *item, int compare(void *item1, void *item2));
78 void *binary_search(void *item, int compare(void *item1, void *item2));
79 void binary_insert_multiple(void *item, int compare(void *item1, void *item2));
80 void remove(void *item);
83 void *next(void *item);
84 void *prev(void *item);
92 * This allows us to do explicit initialization,
93 * allowing us to mix C++ classes inside malloc'ed
94 * C structures. Define before called in constructor.
96 inline void dlist::init(void *item, dlink *link)
99 loffset = (int)((char *)link - (char *)item);
100 if (loffset < 0 || loffset > 5000) {
101 Emsg0(M_ABORT, 0, "Improper dlist initialization.\n");
106 inline void dlist::init()
115 * Constructor called with the address of a
116 * member of the list (not the list head), and
117 * the address of the link within that member.
118 * If the link is at the beginning of the list member,
119 * then there is no need to specify the link address
120 * since the offset is zero.
122 inline dlist::dlist(void *item, dlink *link)
127 /* Constructor with link at head of item */
128 inline dlist::dlist(void) : head(0), tail(0), loffset(0), num_items(0)
132 inline void dlist::set_prev(void *item, void *prev)
134 ((dlink *)(((char *)item)+loffset))->prev = prev;
137 inline void dlist::set_next(void *item, void *next)
139 ((dlink *)(((char *)item)+loffset))->next = next;
142 inline void *dlist::get_prev(void *item)
144 return ((dlink *)(((char *)item)+loffset))->prev;
147 inline void *dlist::get_next(void *item)
149 return ((dlink *)(((char *)item)+loffset))->next;
153 inline dlink *dlist::get_link(void *item)
155 return (dlink *)(((char *)item)+loffset);
160 inline bool dlist::empty() const
165 inline int dlist::size() const
172 inline void * dlist::first() const
177 inline void * dlist::last() const
183 * C string helper routines for dlist
184 * The string (char *) is kept in the node
186 * Kern Sibbald, February 2007
192 char *c_str() { return m_str; };
197 /* !!! Don't put anything after this as this space is used
198 * to hold the string in inline
202 extern dlistString *new_dlistString(const char *str, int len);
203 extern dlistString *new_dlistString(const char *str);