2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many 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 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Written by Kern Sibbald MMIV
25 /* ========================================================================
27 * Doubly linked list -- dlist
29 * See the end of the file for the dlistString class which
30 * facilitates storing strings in a dlist.
32 * Kern Sibbald, MMIV and MMVII
38 /* In case you want to specifically specify the offset to the link */
39 #define OFFSET(item, link) (int)((char *)(link) - (char *)(item))
41 * There is a lot of extra casting here to work around the fact
42 * that some compilers (Sun and Visual C++) do not accept
43 * (void *) as an lvalue on the left side of an equal.
45 * Loop var through each member of list
48 #define foreach_dlist(var, list) \
49 for((var)=NULL; ((var)=(typeof(var))(list)->next(var)); )
51 #define foreach_dlist(var, list) \
52 for((var)=NULL; (*((void **)&(var))=(void*)((list)->next(var))); )
60 class dlist : public SMARTALLOC {
66 dlist(void *item, dlink *link);
68 ~dlist() { destroy(); }
69 void init(void *item, dlink *link);
71 void prepend(void *item);
72 void append(void *item);
73 void set_prev(void *item, void *prev);
74 void set_next(void *item, void *next);
75 void *get_prev(void *item);
76 void *get_next(void *item);
77 dlink *get_link(void *item);
78 void insert_before(void *item, void *where);
79 void insert_after(void *item, void *where);
80 void *binary_insert(void *item, int compare(void *item1, void *item2));
81 void *binary_search(void *item, int compare(void *item1, void *item2));
82 void binary_insert_multiple(void *item, int compare(void *item1, void *item2));
83 void remove(void *item);
86 void *next(void *item);
87 void *prev(void *item);
95 * This allows us to do explicit initialization,
96 * allowing us to mix C++ classes inside malloc'ed
97 * C structures. Define before called in constructor.
99 inline void dlist::init(void *item, dlink *link)
102 loffset = (int)((char *)link - (char *)item);
103 if (loffset < 0 || loffset > 5000) {
104 Emsg0(M_ABORT, 0, "Improper dlist initialization.\n");
109 inline void dlist::init()
118 * Constructor called with the address of a
119 * member of the list (not the list head), and
120 * the address of the link within that member.
121 * If the link is at the beginning of the list member,
122 * then there is no need to specify the link address
123 * since the offset is zero.
125 inline dlist::dlist(void *item, dlink *link)
130 /* Constructor with link at head of item */
131 inline dlist::dlist(void) : head(0), tail(0), loffset(0), num_items(0)
135 inline void dlist::set_prev(void *item, void *prev)
137 ((dlink *)(((char *)item)+loffset))->prev = prev;
140 inline void dlist::set_next(void *item, void *next)
142 ((dlink *)(((char *)item)+loffset))->next = next;
145 inline void *dlist::get_prev(void *item)
147 return ((dlink *)(((char *)item)+loffset))->prev;
150 inline void *dlist::get_next(void *item)
152 return ((dlink *)(((char *)item)+loffset))->next;
156 inline dlink *dlist::get_link(void *item)
158 return (dlink *)(((char *)item)+loffset);
163 inline bool dlist::empty() const
168 inline int dlist::size() const
175 inline void * dlist::first() const
180 inline void * dlist::last() const
186 * C string helper routines for dlist
187 * The string (char *) is kept in the node
189 * Kern Sibbald, February 2007
195 char *c_str() { return m_str; };
196 dlink get_link() { return m_link; }; /* eliminate clang compiler warning */
201 /* !!! Don't put anything after this as this space is used
202 * to hold the string in inline
206 extern dlistString *new_dlistString(const char *str, int len);
207 extern dlistString *new_dlistString(const char *str);