Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 LunarG, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24.  * DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  
  29. #include <stdlib.h>
  30. #include <string.h>
  31.  
  32. #include "egllog.h"
  33. #include "eglarray.h"
  34.  
  35.  
  36. /**
  37.  * Grow the size of the array.
  38.  */
  39. static EGLBoolean
  40. _eglGrowArray(_EGLArray *array)
  41. {
  42.    EGLint new_size;
  43.    void **elems;
  44.  
  45.    new_size = array->MaxSize;
  46.    while (new_size <= array->Size)
  47.       new_size *= 2;
  48.  
  49.    elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));
  50.    if (!elems) {
  51.       _eglLog(_EGL_DEBUG, "failed to grow %s array to %d",
  52.             array->Name, new_size);
  53.       return EGL_FALSE;
  54.    }
  55.  
  56.    array->Elements = elems;
  57.    array->MaxSize = new_size;
  58.  
  59.    return EGL_TRUE;
  60. }
  61.  
  62.  
  63. /**
  64.  * Create an array.
  65.  */
  66. _EGLArray *
  67. _eglCreateArray(const char *name, EGLint init_size)
  68. {
  69.    _EGLArray *array;
  70.  
  71.    array = calloc(1, sizeof(*array));
  72.    if (array) {
  73.       array->Name = name;
  74.       array->MaxSize = (init_size > 0) ? init_size : 1;
  75.       if (!_eglGrowArray(array)) {
  76.          free(array);
  77.          array = NULL;
  78.       }
  79.    }
  80.  
  81.    return array;
  82. }
  83.  
  84.  
  85. /**
  86.  * Destroy an array, optionally free the data.
  87.  */
  88. void
  89. _eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))
  90. {
  91.    if (free_cb) {
  92.       EGLint i;
  93.       for (i = 0; i < array->Size; i++)
  94.          free_cb(array->Elements[i]);
  95.    }
  96.    free(array->Elements);
  97.    free(array);
  98. }
  99.  
  100.  
  101. /**
  102.  * Append a element to an array.
  103.  */
  104. void
  105. _eglAppendArray(_EGLArray *array, void *elem)
  106. {
  107.    if (array->Size >= array->MaxSize && !_eglGrowArray(array))
  108.       return;
  109.  
  110.    array->Elements[array->Size++] = elem;
  111. }
  112.  
  113.  
  114. /**
  115.  * Erase an element from an array.
  116.  */
  117. void
  118. _eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *))
  119. {
  120.    if (free_cb)
  121.       free_cb(array->Elements[i]);
  122.    if (i < array->Size - 1) {
  123.       memmove(&array->Elements[i], &array->Elements[i + 1],
  124.             (array->Size - i - 1) * sizeof(array->Elements[0]));
  125.    }
  126.    array->Size--;
  127. }
  128.  
  129.  
  130. /**
  131.  * Find in an array for the given element.
  132.  */
  133. void *
  134. _eglFindArray(_EGLArray *array, void *elem)
  135. {
  136.    EGLint i;
  137.  
  138.    if (!array)
  139.       return NULL;
  140.  
  141.    for (i = 0; i < array->Size; i++)
  142.       if (array->Elements[i] == elem)
  143.          return elem;
  144.    return NULL;
  145. }
  146.  
  147.  
  148. /**
  149.  * Filter an array and return the number of filtered elements.
  150.  */
  151. EGLint
  152. _eglFilterArray(_EGLArray *array, void **data, EGLint size,
  153.                 _EGLArrayForEach filter, void *filter_data)
  154. {
  155.    EGLint count = 0, i;
  156.  
  157.    if (!array)
  158.       return 0;
  159.  
  160.    if (filter) {
  161.       for (i = 0; i < array->Size; i++) {
  162.          if (filter(array->Elements[i], filter_data)) {
  163.             if (data && count < size)
  164.                data[count] = array->Elements[i];
  165.             count++;
  166.          }
  167.          if (data && count >= size)
  168.             break;
  169.       }
  170.    }
  171.    else {
  172.       if (data) {
  173.          count = (size < array->Size) ? size : array->Size;
  174.          memcpy(data, array->Elements, count * sizeof(array->Elements[0]));
  175.       }
  176.       else {
  177.          count = array->Size;
  178.       }
  179.    }
  180.  
  181.    return count;
  182. }
  183.  
  184.  
  185. /**
  186.  * Flatten an array by converting array elements into another form and store
  187.  * them in a buffer.
  188.  */
  189. EGLint
  190. _eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
  191.                  _EGLArrayForEach flatten)
  192. {
  193.    EGLint i, count;
  194.  
  195.    if (!array)
  196.       return 0;
  197.  
  198.    count = array->Size;
  199.    if (buffer) {
  200.       /* do not exceed buffer size */
  201.       if (count > size)
  202.          count = size;
  203.       for (i = 0; i < count; i++)
  204.          flatten(array->Elements[i],
  205.                (void *) ((char *) buffer + elem_size * i));
  206.    }
  207.  
  208.    return count;
  209. }
  210.