summaryrefslogtreecommitdiff
path: root/src/libstrongswan/collections/enumerator.h
blob: 99f8847e4c298f576aa2525c75207a8941eccdaf (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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
 * Copyright (C) 2013-2017 Tobias Brunner
 * Copyright (C) 2007 Martin Willi
 * HSR 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.
 */

/**
 * @defgroup enumerator enumerator
 * @{ @ingroup collections
 */

#ifndef ENUMERATOR_H_
#define ENUMERATOR_H_

typedef struct enumerator_t enumerator_t;

#include <utils/utils.h>

/**
 * Enumerator interface, allows enumeration over collections.
 */
struct enumerator_t {

	/**
	 * Enumerate collection.
	 *
	 * The enumerate() method takes a variable number of pointer arguments
	 * where the enumerated values get written to.
	 *
	 * @note Just assigning the generic enumerator_enumerate_default() function
	 * that calls the enumerator's venumerate() method is usually enough.
	 *
	 * @param ...	variable list of enumerated items, implementation dependent
	 * @return		TRUE if pointers returned
	 */
	bool (*enumerate)(enumerator_t *this, ...);

	/**
	 * Enumerate collection.
	 *
	 * The venumerate() method takes a variable argument list containing
	 * pointers where the enumerated values get written to.
	 *
	 * To simplify the implementation the VA_ARGS_VGET() macro may be used.
	 *
	 * @param args	variable list of enumerated items, implementation dependent
	 * @return		TRUE if pointers returned
	 */
	bool (*venumerate)(enumerator_t *this, va_list args);

	/**
	 * Destroy an enumerator_t instance.
	 */
	void (*destroy)(enumerator_t *this);
};

/**
 * Generic implementation of enumerator_t::enumerate() that simply calls
 * the enumerator's venumerate() method.
 *
 * @param enumerator	the enumerator
 * @param ...			arguments passed to enumerate()
 */
bool enumerator_enumerate_default(enumerator_t *enumerator, ...);

/**
 * Create an enumerator which enumerates over nothing
 *
 * @return			an enumerator over no values
 */
enumerator_t* enumerator_create_empty();

/**
 * Create an enumerator which enumerates over a single item
 *
 * @param item		item to enumerate
 * @param cleanup	cleanup function called on destroy with the item
 * @return			an enumerator over a single value
 */
enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item));

/**
 * Create an enumerator over files/subdirectories in a directory.
 *
 * This enumerator_t.enumerate() function returns a (to the directory) relative
 * filename (as a char*), an absolute filename (as a char*) and a file status
 * (to a struct stat), which all may be NULL. "." and ".." entries are
 * skipped.
 *
 * Example:
 *
 * @code
	char *rel, *abs;
	struct stat st;
	enumerator_t *e;

	e = enumerator_create_directory("/tmp");
	if (e)
	{
		while (e->enumerate(e, &rel, &abs, &st))
		{
			if (S_ISDIR(st.st_mode) && *rel != '.')
			{
				printf("%s\n", abs);
			}
		}
		e->destroy(e);
	}
   @endcode
 *
 * @param path		path of the directory
 * @return 			the directory enumerator, NULL on failure
 */
enumerator_t* enumerator_create_directory(const char *path);

/**
 * Create an enumerator over files/directories matching a file pattern.
 *
 * This enumerator_t.enumerate() function returns the filename (as a char*),
 * and a file status (to a struct stat), which both may be NULL.
 *
 * Example:
 *
 * @code
	char *file;
	struct stat st;
	enumerator_t *e;

	e = enumerator_create_glob("/etc/ipsec.*.conf");
	if (e)
	{
		while (e->enumerate(e, &file, &st))
		{
			if (S_ISREG(st.st_mode))
			{
				printf("%s\n", file);
			}
		}
		e->destroy(e);
	}
   @endcode
 *
 * @param pattern	file pattern to match
 * @return 			the enumerator, NULL if not supported
 */
enumerator_t* enumerator_create_glob(const char *pattern);

/**
 * Create an enumerator over tokens of a string.
 *
 * Tokens are separated by one of the characters in sep and trimmed by the
 * characters in trim.
 *
 * @param string	string to parse
 * @param sep		separator characters
 * @param trim		characters to trim from tokens
 * @return			enumerator over char* tokens
 */
enumerator_t* enumerator_create_token(const char *string, const char *sep,
									  const char *trim);

/**
 * Creates an enumerator which enumerates over enumerated enumerators :-).
 *
 * The outer enumerator is expected to return objects that, when passed to
 * inner_contructor, will create a new enumerator that will be enumerated until
 * completion (to this enumerator will the pointer arguments that are passed to
 * this enumerator be forwarded) at which point a new element from the outer
 * enumerator is requested to create a new inner enumerator.
 *
 * @param outer					outer enumerator
 * @param inner_constructor		constructor to create inner enumerator
 * @param data					data to pass to each inner_constructor call
 * @param destructor			destructor function to clean up data after use
 * @return						the nested enumerator
 */
enumerator_t *enumerator_create_nested(enumerator_t *outer,
					enumerator_t *(*inner_constructor)(void *outer, void *data),
					void *data, void (*destructor)(void *data));

/**
 * Creates an enumerator which filters/maps output of another enumerator.
 *
 * The filter function receives the user supplied "data" followed by the
 * original enumerator, followed by the arguments passed to the outer
 * enumerator.  It returns TRUE to deliver the values assigned to these
 * arguments to the caller of enumerate() and FALSE to end the enumeration.
 * Filtering items is simple as the filter function may just skip enumerated
 * items from the original enumerator.
 *
 * @param orig					original enumerator to wrap, gets destroyed
 * @param filter				filter function
 * @param data					user data to supply to filter
 * @param destructor			destructor function to clean up data after use
 * @return						the filtered enumerator
 */
enumerator_t *enumerator_create_filter(enumerator_t *orig,
				bool (*filter)(void *data, enumerator_t *orig, va_list args),
				void *data, void (*destructor)(void *data));

/**
 * Create an enumerator wrapper which does a cleanup on destroy.
 *
 * @param wrapped				wrapped enumerator
 * @param cleanup				cleanup function called on destroy
 * @param data					user data to supply to cleanup
 * @return						the enumerator with cleanup
 */
enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
					void (*cleanup)(void *data), void *data);

#endif /** ENUMERATOR_H_ @}*/