From 424d46d3365e5d53fd4e91eed1b19aeb2fe77d0c Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Tue, 7 Feb 2017 22:49:13 +1000 Subject: [PATCH] + group.[ch] --- src/group.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/group.h | 35 +++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 src/group.c create mode 100644 src/group.h diff --git a/src/group.c b/src/group.c new file mode 100644 index 0000000..721bd99 --- /dev/null +++ b/src/group.c @@ -0,0 +1,96 @@ +/* + * 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. + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "group.h" + +#define FREE(x) free((x)), (x) = NULL; + +static const int grow_step = 10; + +static bool +group_grow(group_t *group, int size) { + int *p = NULL; + + assert(group != NULL); + + if (size <= 0) + return false; + if (size <= group->caps) + return false; + + if ((p = realloc(group->ids, size * sizeof(int))) == NULL) + return false; + + group->ids = p, + group->caps = size; + + return true; +} + +group_t * +group_create(int num, int size) { + group_t *tmp = NULL; + + if ((tmp = calloc(1, sizeof(group_t))) == NULL) + return NULL; + tmp->num = num; + + if (size == 0) + return tmp; + + if (!group_grow(tmp, size)) + FREE(tmp); + + return tmp; +} + +bool +group_append(group_t *group, int id) { + assert(group != NULL); + + for (int i = 0; i < group->size; i++) { + if (group->ids[i] == id) + return true; + } + + if (group->size >= group->caps) { + int newcaps = group->caps ? group->caps * 2 : grow_step; + if (!group_grow(group, newcaps)) + return false; + } + + group->ids[group->size] = id, + group->size++; + + return true; +} + +void +group_free(group_t *group) { + assert(group != NULL); + + FREE(group->ids); + group->size = 0, + group->caps = 0; +} diff --git a/src/group.h b/src/group.h new file mode 100644 index 0000000..fdd0450 --- /dev/null +++ b/src/group.h @@ -0,0 +1,35 @@ +#ifndef GROUP_H_ +#define GROUP_H_ 1 + +/** group of similar images */ +typedef struct group_t { + struct group_t *next; /**< pointer to next group in list */ + int num; /**< group number */ + int size; /**< images count in this group */ + int caps; /**< allocated slots for images */ + int *ids; /**< images ids */ +} group_t; + +/** + * @brief Creates new image group + * @param num Group number + * @param size Initial preallocated slots + * @returns Pointer to new group of NULL on error + */ +group_t * group_create(int num, int size); + +/** + * @brief Append new image id to given group + * @param group Pointer to group struct + * @param id Image id to add (dublicates will be ignored) + * @returns true on success, false on error + */ +bool group_append(group_t *group, int id); + +/** + * @brief Remove all group members and free allocated memory + * @param group Pointer to group struct + */ +void group_free(group_t *group); + +#endif /* GROUP_H_ */