summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils/iterator.h
blob: b4ff85bfbb4ccda2fa4a922c83bfd64c41f33f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/**
 * @file iterator.h
 * 
 * @brief Interface iterator_t.
 * 
 */

/*
 * Copyright (C) 2005-2006 Martin Willi
 * Copyright (C) 2005 Jan Hutter
 * Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#ifndef ITERATOR_H_
#define ITERATOR_H_

#include <library.h>

typedef enum hook_result_t hook_result_t;

/**
 * @brief Return value of an iterator hook.
 *
 * Returning HOOK_AGAIN is useful to "inject" additional elements in an
 * iteration, HOOK_NEXT is the normal iterator behavior, and HOOK_SKIP may
 * be used to filter elements out.
 *
 * @ingroup utils
 */
enum hook_result_t {

	/**
	 * A value was placed in out, hook is called again with the same "in"
	 */
	HOOK_AGAIN,
	
	/**
	 * A value was placed in out, hook is called again with next "in" (if any)
	 */
	HOOK_NEXT,
	
	/**
	 * No value in out, call again with next "in" (if any)
	 */
	HOOK_SKIP,
};

/**
 * @brief Iterator hook function prototype.
 *
 * @param param		user supplied parameter
 * @param in		the value the hook receives from the iterator
 * @param out		the value supplied as a result to the iterator
 * @return			a hook_result_t
 *
 * @ingroup utils
 */
typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);


typedef struct iterator_t iterator_t;

/**
 * @brief Iterator interface, allows iteration over collections.
 *
 * iterator_t defines an interface for iterating over collections.
 * It allows searching, deleting, updating and inserting.
 *
 * @b Constructors:
 * - via linked_list_t.create_iterator, or
 * - any other class which supports the iterator_t interface
 *
 * @see linked_list_t
 *
 * @ingroup utils 
 */
struct iterator_t {

	/**
	 * @brief Return number of list items.
	 * 
	 * @param this 			calling object
	 * @return				number of list items
	 */
	int (*get_count) (iterator_t *this);
	
	/**
	 * @brief Iterate over all items.
	 * 
	 * The easy way to iterate over items.
	 * 
	 * @param this 			calling object
	 * @param[out] value 	item
	 * @return
	 * 						- TRUE, if there was an element available,
	 * 						- FALSE otherwise
	 */
	bool (*iterate) (iterator_t *this, void** value);
	
	/**
	 * @brief Hook a function into the iterator.
	 *
	 * Sometimes it is useful to hook in an iterator. The hook function is
	 * called before any successful return of iterate(). It takes the
	 * iterator value, may manipulate it (or the references object), and returns
	 * the value that the iterate() function returns. Depending on the hook
	 * return value, the hook is called again, called with next, or skipped.
	 * A value of NULL deactivates the iterator hook.
	 * If an iterator is hooked, only the iterate() method is valid,
	 * all other methods behave undefined.
	 * 
	 * @param this 			calling object
	 * @param hook			iterator hook which manipulates the iterated value
	 * @param param			user supplied parameter to pass back to the hook
	 */
	void (*set_iterator_hook) (iterator_t *this, iterator_hook_t *hook,
							   void *param);
	
	/**
	 * @brief Inserts a new item before the given iterator position.
	 * 
	 * The iterator position is not changed after inserting
	 * 
	 * @param this 			calling iterator
	 * @param[in] item 		value to insert in list
	 */
	void (*insert_before) (iterator_t *this, void *item);

	/**
	 * @brief Inserts a new item after the given iterator position.
	 * 
	 * The iterator position is not changed after inserting.
	 * 
	 * @param this 			calling iterator
	 * @param[in] item 		value to insert in list
	 */
	void (*insert_after) (iterator_t *this, void *item);
	
	/**
	 * @brief Replace the current item at current iterator position.
	 * 
	 * The iterator position is not changed after replacing.
	 * 
	 * @param this 			calling iterator
	 * @param[out] old_item	old value will be written here(can be NULL)
	 * @param[in] new_item  new value
	 * 
	 * @return 
	 * 						- SUCCESS
	 * 						- FAILED if iterator is on an invalid position
	 */
	status_t (*replace) (iterator_t *this, void **old_item, void *new_item);

	/**
	 * @brief Removes an element from list at the given iterator position.
	 * 
	 * The iterator is set the the following position:
	 * - to the item before, if available
	 * - it gets reseted, otherwise
	 * 
	 * @param this		 	calling object
	 * @return 
	 * 						- SUCCESS
	 * 						- FAILED if iterator is on an invalid position
	 */
	status_t (*remove) (iterator_t *this);
	
	/**
	 * @brief Resets the iterator position.
	 * 
	 * After reset, the iterator_t objects doesn't point to an element.
	 * A call to iterator_t.has_next is necessary to do any other operations
	 * with the resetted iterator.
	 * 
	 * @param this 			calling object
	 */
	void (*reset) (iterator_t *this);

	/**
	 * @brief Destroys an iterator.
	 * 
	 * @param this 			iterator to destroy
	 * 
	 */
	void (*destroy) (iterator_t *this);
};

#endif /*ITERATOR_H_*/