EAPI Eina_Accessor * eina_inarray_accessor_new(const Eina_Inarray *array) { Eina_Accessor_Inarray *ac; EINA_MAGIC_CHECK_INARRAY(array, NULL); eina_error_set(0); ac = calloc(1, sizeof(Eina_Accessor_Inarray)); if (!ac) { eina_error_set(EINA_ERROR_OUT_OF_MEMORY); return NULL; } EINA_MAGIC_SET(ac, EINA_MAGIC_INARRAY_ACCESSOR); EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); ac->array = array; ac->accessor.version = EINA_ACCESSOR_VERSION; ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(_eina_inarray_accessor_get_at); ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER (_eina_inarray_accessor_get_container); ac->accessor.free = FUNC_ACCESSOR_FREE(_eina_inarray_accessor_free); return &ac->accessor; }
EAPI void * eina_inarray_nth(const Eina_Inarray *array, unsigned int position) { EINA_MAGIC_CHECK_INARRAY(array, NULL); EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, NULL); return _eina_inarray_get(array, position); }
EAPI Eina_Iterator * eina_inarray_iterator_reversed_new(const Eina_Inarray *array) { Eina_Iterator_Inarray *it; EINA_MAGIC_CHECK_INARRAY(array, NULL); eina_error_set(0); it = calloc(1, sizeof(Eina_Iterator_Inarray)); if (!it) { eina_error_set(EINA_ERROR_OUT_OF_MEMORY); return NULL; } EINA_MAGIC_SET(it, EINA_MAGIC_INARRAY_ITERATOR); EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); it->array = array; it->pos = array->len; it->iterator.version = EINA_ITERATOR_VERSION; it->iterator.next = FUNC_ITERATOR_NEXT(_eina_inarray_iterator_prev); it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER (_eina_inarray_iterator_get_container); it->iterator.free = FUNC_ITERATOR_FREE(_eina_inarray_iterator_free); return &it->iterator; }
EAPI void eina_inarray_sort(Eina_Inarray *array, Eina_Compare_Cb compare) { EINA_MAGIC_CHECK_INARRAY(array); EINA_SAFETY_ON_NULL_RETURN(compare); qsort(array->members, array->len, array->member_size, compare); }
EAPI void eina_inarray_reverse(Eina_Inarray *array) { size_t sz; unsigned char *fwd, *rev, *fwd_end; void *tmp; EINA_MAGIC_CHECK_INARRAY(array); if (array->len < 2) return; sz = array->member_size; tmp = alloca(sz); EINA_SAFETY_ON_NULL_RETURN(tmp); fwd = array->members; fwd_end = fwd + (array->len / 2) * sz; rev = fwd + (array->len - 1) * sz; for (; fwd < fwd_end; fwd += sz, rev -= sz) { memcpy(tmp, fwd, sz); memcpy(fwd, rev, sz); memcpy(rev, tmp, sz); } }
EAPI int eina_inarray_insert(Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) { const unsigned char *itr, *itr_end; unsigned int sz; EINA_MAGIC_CHECK_INARRAY(array, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); sz = array->member_size; itr = array->members; itr_end = itr + array->len * sz; for (; itr < itr_end; itr += sz) { unsigned int offset, position; int cmp = compare(itr, data); if (cmp <= 0) continue; offset = itr - (unsigned char *)array->members; position = offset / sz; if (!eina_inarray_insert_at(array, position, data)) return -1; return position; } return eina_inarray_push(array, data); }
EAPI int eina_inarray_search(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) { EINA_MAGIC_CHECK_INARRAY(array, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); return _eina_inarray_search(array, data, compare); }
EAPI void eina_inarray_flush(Eina_Inarray *array) { EINA_MAGIC_CHECK_INARRAY(array); free(array->members); array->len = 0; array->max = 0; array->members = NULL; }
EAPI void * eina_inarray_pop(Eina_Inarray *array) { EINA_MAGIC_CHECK_INARRAY(array, NULL); EINA_SAFETY_ON_TRUE_RETURN_VAL(array->len == 0, NULL); if (!_eina_inarray_resize(array, array->len - 1)) return NULL; array->len--; return _eina_inarray_get(array, array->len + 1); }
EAPI void eina_inarray_free(Eina_Inarray *array) { if (!array) return; EINA_MAGIC_CHECK_INARRAY(array); free(array->members); free(array); }
EAPI Eina_Bool eina_inarray_resize(Eina_Inarray *array, unsigned int new_size) { Eina_Bool r; EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); r = _eina_inarray_resize(array, new_size); if(!r) return EINA_FALSE; array->len = new_size; return EINA_TRUE; }
EAPI Eina_Bool eina_inarray_replace_at(Eina_Inarray *array, unsigned int position, const void *data) { unsigned char *p; EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); p = _eina_inarray_get(array, position); memcpy(p, data, array->member_size); return EINA_TRUE; }
EAPI int eina_inarray_search_sorted(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) { unsigned int pos; int cmp; EINA_MAGIC_CHECK_INARRAY(array, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); pos = _eina_inarray_search_sorted_near(array, data, compare, &cmp); if (cmp == 0) return pos; return -1; }
EAPI void * eina_inarray_grow(Eina_Inarray *array, unsigned int size) { void *p; EINA_MAGIC_CHECK_INARRAY(array, NULL); if (!size) return NULL; if (!_eina_inarray_resize(array, array->len + size)) return NULL; p = _eina_inarray_get(array, array->len); array->len += size; return p; }
EAPI Eina_Bool eina_inarray_remove_at(Eina_Inarray *array, unsigned int position) { EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); if (position + 1 < array->len) { unsigned int sz = array->member_size; unsigned char *p = _eina_inarray_get(array, position); memmove(p, p + sz, (array->len - position - 1) * sz); } _eina_inarray_resize(array, array->len - 1); array->len--; return EINA_TRUE; }
EAPI int eina_inarray_push(Eina_Inarray *array, const void *data) { void *p; EINA_MAGIC_CHECK_INARRAY(array, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); if (!_eina_inarray_resize(array, array->len + 1)) return -1; p = _eina_inarray_get(array, array->len); memcpy(p, data, array->member_size); array->len++; return array->len - 1; }
EAPI Eina_Bool eina_inarray_foreach(const Eina_Inarray *array, Eina_Each_Cb function, const void *user_data) { unsigned char *itr, *itr_end; unsigned int sz; Eina_Bool ret = EINA_TRUE; EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(function, EINA_FALSE); sz = array->member_size; itr = array->members; itr_end = itr + array->len * sz; for (; (itr < itr_end) && (ret); itr += sz) ret = function(array, itr, (void *)user_data); return ret; }
EAPI Eina_Bool eina_inarray_remove_at(Eina_Inarray *array, unsigned int position) { EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); if (position + 1 < array->len) { unsigned int sz = array->member_size; unsigned char *p = _eina_inarray_get(array, position); memmove(p, p + sz, (array->len - position - 1) * sz); } /* should never fail as we reduce the buffer, but just let make compiler happy */ if (!_eina_inarray_resize(array, array->len - 1)) return EINA_FALSE; array->len--; return EINA_TRUE; }
EAPI Eina_Bool eina_inarray_insert_at(Eina_Inarray *array, unsigned int position, const void *data) { unsigned int sz; unsigned char *p; EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); EINA_SAFETY_ON_TRUE_RETURN_VAL(position > array->len, EINA_FALSE); if (!_eina_inarray_resize(array, array->len + 1)) return EINA_FALSE; p = _eina_inarray_get(array, position); sz = array->member_size; if (array->len > position) memmove(p + sz, p, (array->len - position) * sz); memcpy(p, data, sz); array->len++; return EINA_TRUE; }
EAPI void * eina_inarray_alloc_at(Eina_Inarray *array, unsigned int position, unsigned int member_count) { unsigned int sz; unsigned char *p; EINA_MAGIC_CHECK_INARRAY(array, NULL); EINA_SAFETY_ON_TRUE_RETURN_VAL(position > array->len, NULL); EINA_SAFETY_ON_TRUE_RETURN_VAL(member_count == 0, NULL); if (!_eina_inarray_resize(array, array->len + member_count)) return NULL; p = _eina_inarray_get(array, position); sz = array->member_size; if (array->len > position) memmove(p + member_count * sz, p, (array->len - position) * sz); array->len += member_count; return p; }
EAPI int eina_inarray_foreach_remove(Eina_Inarray *array, Eina_Each_Cb match, const void *user_data) { unsigned int i = 0, count = 0; EINA_MAGIC_CHECK_INARRAY(array, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(match, -1); while (i < array->len) { void *p = _eina_inarray_get(array, i); if (match(array, p, (void *)user_data) == EINA_FALSE) { i++; continue; } eina_inarray_remove_at(array, i); count++; } return count; }
EAPI Eina_Iterator * eina_inarray_iterator_new(const Eina_Inarray *array) { Eina_Iterator_Inarray *it; EINA_MAGIC_CHECK_INARRAY(array, NULL); it = calloc(1, sizeof(Eina_Iterator_Inarray)); if (!it) return NULL; EINA_MAGIC_SET(it, EINA_MAGIC_INARRAY_ITERATOR); EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); it->array = array; it->iterator.version = EINA_ITERATOR_VERSION; it->iterator.next = FUNC_ITERATOR_NEXT(_eina_inarray_iterator_next); it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER (_eina_inarray_iterator_get_container); it->iterator.free = FUNC_ITERATOR_FREE(_eina_inarray_iterator_free); return &it->iterator; }
EAPI int eina_inarray_remove(Eina_Inarray *array, const void *data) { const unsigned char *itr, *itr_end; unsigned int position, sz; EINA_MAGIC_CHECK_INARRAY(array, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); sz = array->member_size; if ((data >= array->members) && (data < _eina_inarray_get(array, array->len))) { unsigned int offset = ((unsigned char *)data - (unsigned char *)array->members); position = offset / sz; goto found; } itr = array->members; itr_end = itr + array->len * sz; for (; itr < itr_end; itr += sz) { if (memcmp(data, itr, sz) == 0) { unsigned int offset = itr - (unsigned char *)array->members; position = offset / sz; goto found; } } return -1; found: if (!eina_inarray_remove_at(array, position)) return -1; return position; }
EAPI unsigned int eina_inarray_count(const Eina_Inarray *array) { EINA_MAGIC_CHECK_INARRAY(array, 0); return array->len; }