/* * Copyright 2009-2011 John Lindgren * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "mowgli.h" struct mowgli_index_ { void **data; int count, size; int (*compare)(const void *a, const void *b, void *data); void *compare_data; }; static mowgli_heap_t *index_heap = NULL; void mowgli_index_init(void) { index_heap = mowgli_heap_create(sizeof(mowgli_index_t), 32, BH_NOW); } mowgli_index_t * mowgli_index_create(void) { mowgli_index_t *index = mowgli_heap_alloc(index_heap); index->data = NULL; index->count = 0; index->size = 0; index->compare = NULL; index->compare_data = NULL; return index; } void mowgli_index_destroy(mowgli_index_t *index) { mowgli_free(index->data); mowgli_heap_free(index_heap, index); } int mowgli_index_count(mowgli_index_t *index) { return index->count; } void mowgli_index_allocate(mowgli_index_t *index, int size) { size_t oldsize; void *new_ptr; if (size <= index->size) return; if (!index->size) index->size = 64; oldsize = index->size; while (size > index->size) { index->size <<= 1; } new_ptr = mowgli_alloc_array(sizeof(void *), index->size); if (index->data != NULL) { memcpy(new_ptr, index->data, oldsize); mowgli_free(index->data); } index->data = new_ptr; } void mowgli_index_set(mowgli_index_t *index, int at, void *value) { index->data[at] = value; } void * mowgli_index_get(mowgli_index_t *index, int at) { return index->data[at]; } static void make_room(mowgli_index_t *index, int at, int count) { mowgli_index_allocate(index, index->count + count); if (at < index->count) memmove(index->data + at + count, index->data + at, sizeof(void *) * (index->count - at)); index->count += count; } void mowgli_index_insert(mowgli_index_t *index, int at, void *value) { make_room(index, at, 1); index->data[at] = value; } void mowgli_index_append(mowgli_index_t *index, void *value) { mowgli_index_insert(index, index->count, value); } void mowgli_index_copy_set(mowgli_index_t *source, int from, mowgli_index_t *target, int to, int count) { memcpy(target->data + to, source->data + from, sizeof(void *) * count); } void mowgli_index_copy_insert(mowgli_index_t *source, int from, mowgli_index_t *target, int to, int count) { make_room(target, to, count); memcpy(target->data + to, source->data + from, sizeof(void *) * count); } void mowgli_index_copy_append(mowgli_index_t *source, int from, mowgli_index_t *target, int count) { mowgli_index_copy_insert(source, from, target, target->count, count); } void mowgli_index_merge_insert(mowgli_index_t *first, int at, mowgli_index_t *second) { mowgli_index_copy_insert(second, 0, first, at, second->count); } void mowgli_index_merge_append(mowgli_index_t *first, mowgli_index_t *second) { mowgli_index_copy_insert(second, 0, first, first->count, second->count); } void mowgli_index_move(mowgli_index_t *index, int from, int to, int count) { memmove(index->data + to, index->data + from, sizeof(void *) * count); } void mowgli_index_delete(mowgli_index_t *index, int at, int count) { index->count -= count; memmove(index->data + at, index->data + at + count, sizeof(void *) * (index->count - at)); } void mowgli_index_sort(mowgli_index_t *index, int (*compare)(const void *, const void *)) { qsort(index->data, index->count, sizeof(void *), compare); } #ifdef NOTYET static int mowgli_index_compare_with_data(const void *a, const void *b, void *_index) { mowgli_index_t *index = _index; return index->compare(*(const void **) a, *(const void **) b, index->compare_data); } void mowgli_index_sort_with_data(mowgli_index_t *index, int(*compare) (const void *a, const void *b, void *data), void *data) { index->compare = compare; index->compare_data = data; g_qsort_with_data(index->data, index->count, sizeof(void *), mowgli_index_compare_with_data, index); index->compare = NULL; index->compare_data = NULL; } #endif