예제 #1
0
파일: eina_inarray.c 프로젝트: jigpu/efl
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;
}
예제 #2
0
파일: eina_inarray.c 프로젝트: jigpu/efl
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);
}
예제 #3
0
파일: eina_inarray.c 프로젝트: jigpu/efl
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;
}
예제 #4
0
파일: eina_inarray.c 프로젝트: jigpu/efl
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);
}
예제 #5
0
파일: eina_inarray.c 프로젝트: jigpu/efl
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);
     }
}
예제 #6
0
파일: eina_inarray.c 프로젝트: jigpu/efl
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);
}
예제 #7
0
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);
}
예제 #8
0
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;
}
예제 #9
0
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);
}
예제 #10
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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;
}
예제 #16
0
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;
}
예제 #17
0
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;
}
예제 #18
0
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;
}
예제 #19
0
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;
}
예제 #20
0
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;
}
예제 #21
0
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;
}
예제 #23
0
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;
}
예제 #24
0
EAPI unsigned int
eina_inarray_count(const Eina_Inarray *array)
{
   EINA_MAGIC_CHECK_INARRAY(array, 0);
   return array->len;
}