Camel.Iterator
From Evolution
Contents |
Camel.Iterator
CamelIterator is a simple interface for iterators. Although it is defined in Camel.Object, it is not used currently except in the disksummary branch, where it is used extensively.
Iterators are designed to be simple to setup and simple to use. The
next function should handle any refcounting or memory
management, so that the calling function has a usable pointer until
next is called again, or the iterator is freed or reset.
A simple vtable is used rather than a full-blown class, so they are
easier to create. There is also limited functionality to avoid
overcomplicating them.
Camel.IteratorVTable
Currently, all virtual methods except free MUST be
intialised.
struct _CamelIteratorVTable {
void (*free)(void *it);
const void *(*next)(void *it, CamelException *ex);
void (*reset)(void *it);
int (*length)(void *it);
};
- free
- Must free any fields allocated. The base object will always be freed by
g_free. - next
- Go to the next item. Return NULL if there are none, or if there is an error, and set the Camel.Exception as appropriate.
- reset
- The next call to
nextwill again return the first item. - length
- Estimate the number of items. This can be used for progress reporting, but it must be aware that the implementation may not be able to calculate it accurately.
Examples
There are also extensive examples in the disksummary-branch code.
Example: a GPtrArray iterator
This example implements a simple iterator which walks a GPtrArray. It doesn't do any memory management on the pointers the GPtrArray implements, although that would be simple to add.
struct _gpiter {
GPtrArray *array;
int index;
}
static void gpi_free(void *it) {
struct _gpiter *iter = it;
g_ptr_array_free(iter->array);
}
static const void *gpi_next(void *it, CamelException *ex) {
struct _gpiter *iter = it;
if (iter->array->len < iter->index)
return iter->array->pdata[iter->index++];
else
return NULL;
}
static void *gpi_reset(void *it) {
struct _gpiter *iter = it;
iter->index = 0;
}
static int gpi_length(void *it) {
struct _gpiter *iter = it;
return iter->array->len;
}
static struct _CamelIteratorVTable gpi_vtable = {
.free = gpi_free,
.next = gpi_next,
.reset = gpi_reset,
.length = gpi_length
}
CamelIterator *gptrarray_iterator_new(GPtrArray *array)
{
struct _gpiter *iter = camel_terator_new(&gpi_vtable, sizeof(*iter));
iter->array = array;
return iter;
}
Note that it also steals the array.
This example is untested.
Notes
The Camel.Index code uses its own cursor/iterators, it could probably be changed to use CamelIterator instead.
