2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2004-2014 Free Software Foundation Europe e.V.
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.
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.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Written by Kern Sibbald MMIV
26 /* ========================================================================
28 * Doubly linked list -- dlist
30 * See the end of the file for the dlistString class which
31 * facilitates storing strings in a dlist.
33 * Kern Sibbald, MMIV and MMVII
39 /* In case you want to specifically specify the offset to the link */
40 #define OFFSET(item, link) (int)((char *)(link) - (char *)(item))
42 * There is a lot of extra casting here to work around the fact
43 * that some compilers (Sun and Visual C++) do not accept
44 * (void *) as an lvalue on the left side of an equal.
46 * Loop var through each member of list
49 #define foreach_dlist(var, list) \
50 for((var)=NULL; ((var)=(typeof(var))(list)->next(var)); )
52 #define foreach_dlist(var, list) \
53 for((var)=NULL; (*((void **)&(var))=(void*)((list)->next(var))); )
61 class dlist : public SMARTALLOC {
67 dlist(void *item, dlink *link);
69 ~dlist() { destroy(); }
70 void init(void *item, dlink *link);
72 void prepend(void *item);
73 void append(void *item);
74 void set_prev(void *item, void *prev);
75 void set_next(void *item, void *next);
76 void *get_prev(void *item);
77 void *get_next(void *item);
78 dlink *get_link(void *item);
79 void insert_before(void *item, void *where);
80 void insert_after(void *item, void *where);
81 void *binary_insert(void *item, int compare(void *item1, void *item2));
82 void *binary_search(void *item, int compare(void *item1, void *item2));
83 void binary_insert_multiple(void *item, int compare(void *item1, void *item2));
84 void remove(void *item);
87 void *next(void *item);
88 void *prev(void *item);
96 * This allows us to do explicit initialization,
97 * allowing us to mix C++ classes inside malloc'ed
98 * C structures. Define before called in constructor.
100 inline void dlist::init(void *item, dlink *link)
103 loffset = (int)((char *)link - (char *)item);
104 if (loffset < 0 || loffset > 5000) {
105 Emsg0(M_ABORT, 0, "Improper dlist initialization.\n");
110 inline void dlist::init()
119 * Constructor called with the address of a
120 * member of the list (not the list head), and
121 * the address of the link within that member.
122 * If the link is at the beginning of the list member,
123 * then there is no need to specify the link address
124 * since the offset is zero.
126 inline dlist::dlist(void *item, dlink *link)
131 /* Constructor with link at head of item */
132 inline dlist::dlist(void) : head(0), tail(0), loffset(0), num_items(0)
136 inline void dlist::set_prev(void *item, void *prev)
138 ((dlink *)(((char *)item)+loffset))->prev = prev;
141 inline void dlist::set_next(void *item, void *next)
143 ((dlink *)(((char *)item)+loffset))->next = next;
146 inline void *dlist::get_prev(void *item)
148 return ((dlink *)(((char *)item)+loffset))->prev;
151 inline void *dlist::get_next(void *item)
153 return ((dlink *)(((char *)item)+loffset))->next;
157 inline dlink *dlist::get_link(void *item)
159 return (dlink *)(((char *)item)+loffset);
164 inline bool dlist::empty() const
169 inline int dlist::size() const
176 inline void * dlist::first() const
181 inline void * dlist::last() const
187 * C string helper routines for dlist
188 * The string (char *) is kept in the node
190 * Kern Sibbald, February 2007
196 char *c_str() { return m_str; };
197 dlink get_link() { return m_link; }; /* eliminate clang compiler warning */
202 /* !!! Don't put anything after this as this space is used
203 * to hold the string in inline
207 extern dlistString *new_dlistString(const char *str, int len);
208 extern dlistString *new_dlistString(const char *str);