2 * Copyright (c) 2018 JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
37 static int tr_list_destructor(void *object)
39 TR_LIST *list = talloc_get_type_abort(object, TR_LIST);
41 g_ptr_array_unref(*list);
45 /* Note that the TR_LIST type is a pointer-to-pointer to
46 * a GPtrArray. This is done so that we can hook a talloc destructor
47 * to the list to ensure that the GLib reference count is handled correctly
48 * when used with talloc. */
49 TR_LIST *tr_list_new(TALLOC_CTX *mem_ctx)
51 TR_LIST *list = talloc(mem_ctx, TR_LIST);
53 *list = g_ptr_array_new();
58 talloc_set_destructor((void *)list, tr_list_destructor);
63 void tr_list_free(TR_LIST *list)
69 * Add an item to the list
71 * If steal != 0, performs a talloc_steal() to put the new item in the
72 * list's context. If steal == 0, does not do this - in that case, you'll
73 * need to be sure that the memory is cleaned up through some other means.
74 * (This allows the list to represent non-talloc'ed items.)
76 * @param list list to add an item to
77 * @param item pointer to the item to add
78 * @param steal if non-zero, the item will be added to the list's context with talloc_steal()
79 * @return pointer to the added item or null if there was an error
81 void *tr_list_add(TR_LIST *list, void *item, int steal)
83 guint old_len = (*list)->len;
84 g_ptr_array_add((*list), item);
86 if ((*list)->len == old_len)
87 return NULL; /* failed to add */
90 talloc_steal(list, item);
96 * Call func(item, cookie) on each item in the list.
98 * @param list list to iterate over
99 * @param func function, takes two void pointer arguments, first is the item, second the cookie
102 void tr_list_foreach(TR_LIST *list, TR_LIST_FOREACH_FUNC *func, void *cookie)
104 g_ptr_array_foreach((*list), func, cookie);
107 TR_LIST_ITER *tr_list_iter_new(TALLOC_CTX *mem_ctx)
109 TR_LIST_ITER *iter = talloc(mem_ctx, TR_LIST_ITER);
115 void tr_list_iter_free(TR_LIST_ITER *iter)
120 void *tr_list_iter_first(TR_LIST_ITER *iter, TR_LIST *list)
122 if (!iter || !list || (!(*list)))
127 return tr_list_iter_next(iter);
130 void *tr_list_iter_next(TR_LIST_ITER *iter)
135 if (iter->index < (*(iter->list))->len)
136 return g_ptr_array_index(*(iter->list), iter->index++);