Cleanup the iterator internals

This commit is contained in:
Jef Driesen 2017-03-08 15:04:17 +01:00
parent f992d201ad
commit 296fad2d9d
3 changed files with 74 additions and 31 deletions

View File

@ -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)
{

View File

@ -22,6 +22,7 @@
#ifndef DC_ITERATOR_PRIVATE_H
#define DC_ITERATOR_PRIVATE_H
#include <libdivecomputer/context.h>
#include <libdivecomputer/iterator.h>
#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 */

View File

@ -21,16 +21,51 @@
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
#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;
}