diff --git a/src/descriptor.c b/src/descriptor.c index 49df56d..2f5c9e3 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -48,6 +48,8 @@ #define C_ARRAY_SIZE(array) (sizeof (array) / sizeof *(array)) +static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item); + struct dc_descriptor_t { const char *vendor; const char *product; @@ -55,6 +57,17 @@ struct dc_descriptor_t { unsigned int model; }; +typedef struct dc_descriptor_iterator_t { + dc_iterator_t base; + size_t current; +} dc_descriptor_iterator_t; + +static const dc_iterator_vtable_t dc_descriptor_iterator_vtable = { + sizeof(dc_descriptor_iterator_t), + dc_descriptor_iterator_next, + NULL, +}; + /* * The model numbers in the table are the actual model numbers reported by the * device. For devices where there is no model number available (or known), an @@ -331,19 +344,6 @@ static const dc_descriptor_t g_descriptors[] = { {"Cochran", "EMC-20H", DC_FAMILY_COCHRAN_COMMANDER, 5}, }; -typedef struct dc_descriptor_iterator_t { - dc_iterator_t base; - size_t current; -} dc_descriptor_iterator_t; - -static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item); -static dc_status_t dc_descriptor_iterator_free (dc_iterator_t *iterator); - -static const dc_iterator_vtable_t dc_descriptor_iterator_vtable = { - dc_descriptor_iterator_free, - dc_descriptor_iterator_next -}; - dc_status_t dc_descriptor_iterator (dc_iterator_t **out) { @@ -352,11 +352,10 @@ dc_descriptor_iterator (dc_iterator_t **out) if (out == NULL) return DC_STATUS_INVALIDARGS; - iterator = (dc_descriptor_iterator_t *) malloc (sizeof (dc_descriptor_iterator_t)); + iterator = (dc_descriptor_iterator_t *) dc_iterator_allocate (NULL, &dc_descriptor_iterator_vtable); if (iterator == NULL) return DC_STATUS_NOMEMORY; - iterator->base.vtable = &dc_descriptor_iterator_vtable; iterator->current = 0; *out = (dc_iterator_t *) iterator; @@ -364,14 +363,6 @@ dc_descriptor_iterator (dc_iterator_t **out) return DC_STATUS_SUCCESS; } -static dc_status_t -dc_descriptor_iterator_free (dc_iterator_t *iterator) -{ - free (iterator); - - return DC_STATUS_SUCCESS; -} - static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *abstract, void *out) { diff --git a/src/iterator-private.h b/src/iterator-private.h index 105d40f..0cc1bfe 100644 --- a/src/iterator-private.h +++ b/src/iterator-private.h @@ -22,6 +22,7 @@ #ifndef DC_ITERATOR_PRIVATE_H #define DC_ITERATOR_PRIVATE_H +#include #include #ifdef __cplusplus @@ -32,13 +33,24 @@ typedef struct dc_iterator_vtable_t dc_iterator_vtable_t; struct dc_iterator_t { const dc_iterator_vtable_t *vtable; + dc_context_t *context; }; struct dc_iterator_vtable_t { - dc_status_t (*free) (dc_iterator_t *iterator); + size_t size; dc_status_t (*next) (dc_iterator_t *iterator, void *item); + dc_status_t (*free) (dc_iterator_t *iterator); }; +dc_iterator_t * +dc_iterator_allocate (dc_context_t *context, const dc_iterator_vtable_t *vtable); + +void +dc_iterator_deallocate (dc_iterator_t *iterator); + +int +dc_iterator_isinstance (dc_iterator_t *iterator, const dc_iterator_vtable_t *vtable); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/iterator.c b/src/iterator.c index 100f85a..83ad070 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -21,16 +21,51 @@ #include #include +#include +#include "context-private.h" #include "iterator-private.h" +dc_iterator_t * +dc_iterator_allocate (dc_context_t *context, const dc_iterator_vtable_t *vtable) +{ + dc_iterator_t *iterator = NULL; + + assert(vtable != NULL); + assert(vtable->size >= sizeof(dc_iterator_t)); + + // Allocate memory. + iterator = (dc_iterator_t *) malloc (vtable->size); + if (iterator == NULL) { + ERROR (context, "Failed to allocate memory."); + return iterator; + } + + iterator->vtable = vtable; + iterator->context = context; + + return iterator; +} + +void +dc_iterator_deallocate (dc_iterator_t *iterator) +{ + free (iterator); +} + +int +dc_iterator_isinstance (dc_iterator_t *iterator, const dc_iterator_vtable_t *vtable) +{ + if (iterator == NULL) + return 0; + + return iterator->vtable == vtable; +} + dc_status_t dc_iterator_next (dc_iterator_t *iterator, void *item) { - if (iterator == NULL) - return DC_STATUS_UNSUPPORTED; - - if (iterator->vtable->next == NULL) + if (iterator == NULL || iterator->vtable->next == NULL) return DC_STATUS_UNSUPPORTED; if (item == NULL) @@ -42,11 +77,16 @@ dc_iterator_next (dc_iterator_t *iterator, void *item) dc_status_t dc_iterator_free (dc_iterator_t *iterator) { + dc_status_t status = DC_STATUS_SUCCESS; + if (iterator == NULL) return DC_STATUS_SUCCESS; - if (iterator->vtable->free == NULL) - return DC_STATUS_UNSUPPORTED; + if (iterator->vtable->free) { + status = iterator->vtable->free (iterator); + } - return iterator->vtable->free (iterator); + dc_iterator_deallocate (iterator); + + return status; }