xarray.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:6k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*************************************************************************
  2.  * xarray.c: Mutable (dynamically growable) array
  3.  *************************************************************************
  4.  * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
  5.  *                    Organisation (CSIRO) Australia
  6.  * Copyright (C) 2004 the VideoLAN team
  7.  *
  8.  * $Id: 73eeb635fc8137e62dacde4d2e8464e34a9f4c81 $
  9.  *
  10.  * Authors: Andre Pang <Andre.Pang@csiro.au>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  ************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <stddef.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "xarray.h"
  33. /* local prototypes */
  34. XArray * xarray_New (unsigned int);
  35. #define XARRAY_ASSERT_NOT_NULL(xarray) 
  36.     { 
  37.         if (xarray == NULL) return XARRAY_ENULLPOINTER; 
  38.     }
  39. #define XARRAY_BOUNDS_CHECK(xarray, index) 
  40.     { 
  41.         if (xarray->last_valid_element != -1 && 
  42.                  (int) index > xarray->last_valid_element) 
  43.             return XARRAY_EINDEXTOOLARGE; 
  44.     }
  45. #define XARRAY_GROW_ARRAY(xarray) 
  46.     { 
  47.         xarray->array = (void *) realloc (xarray->array, xarray->size * 2); 
  48.         if (xarray->array == NULL) return XARRAY_ENOMEM; 
  49.     }
  50. XArray * xarray_New (unsigned int initial_size_hint)
  51. {
  52.     XArray *new_xarray = NULL;
  53.     void *inner_array;
  54.     unsigned int initial_size;
  55.     new_xarray = (XArray *) malloc (sizeof(XArray));
  56.     if (new_xarray == NULL) return NULL;
  57.     if (initial_size_hint == 0)
  58.         initial_size = XARRAY_DEFAULT_SIZE;
  59.     else
  60.         initial_size = initial_size_hint;
  61.     inner_array = calloc (initial_size, sizeof(void *));
  62.     new_xarray->last_valid_element = -1;
  63.     new_xarray->size = initial_size;
  64.     new_xarray->last_error = 0;
  65.     if (inner_array == NULL)
  66.     {
  67.         free (new_xarray);
  68.         return NULL;
  69.     }
  70.     new_xarray->array = inner_array;
  71.     return new_xarray;
  72. }
  73. int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
  74.         void **out_object)
  75. {
  76.     XARRAY_ASSERT_NOT_NULL (xarray);
  77.     XARRAY_BOUNDS_CHECK (xarray, index);
  78.     *out_object = xarray->array[index];
  79.     return XARRAY_SUCCESS;
  80. }
  81. int xarray_AddObject (XArray *xarray, void *object)
  82. {
  83.     XARRAY_ASSERT_NOT_NULL (xarray);
  84.     ++xarray->last_valid_element;
  85.     if (xarray->last_valid_element >= (int) xarray->size)
  86.     {
  87.         XARRAY_GROW_ARRAY (xarray);
  88.     }
  89.     xarray->array[xarray->last_valid_element] = object;
  90.     return XARRAY_SUCCESS;
  91. }
  92. int xarray_InsertObject (XArray *xarray, void *object,
  93.         unsigned int at_index)
  94. {
  95.     XARRAY_ASSERT_NOT_NULL (xarray);
  96.     ++xarray->last_valid_element;
  97.     XARRAY_BOUNDS_CHECK (xarray, at_index);
  98.     if (xarray->last_valid_element >= (int) xarray->size)
  99.     {
  100.         XARRAY_GROW_ARRAY (xarray);
  101.     }
  102.     /* Shift everything from a[i] onward one pointer forward */
  103.     if ((int) at_index < xarray->last_valid_element)
  104.     {
  105.         (void) memmove (&xarray->array[at_index + 1],
  106.                         &xarray->array[at_index],
  107.                         (xarray->last_valid_element - at_index) *
  108.                             sizeof(void *));
  109.     }
  110.     xarray->array[at_index] = object;
  111.     return XARRAY_SUCCESS;
  112. }
  113. int xarray_RemoveLastObject (XArray *xarray)
  114. {
  115.     XARRAY_ASSERT_NOT_NULL (xarray);
  116.     if (xarray->last_valid_element == -1)
  117.         return XARRAY_EEMPTYARRAY;
  118.     xarray->array[xarray->last_valid_element] = NULL;
  119.     --xarray->last_valid_element;
  120.     return XARRAY_SUCCESS;
  121. }
  122. int xarray_RemoveObject (XArray *xarray, unsigned int at_index)
  123. {
  124.     XARRAY_ASSERT_NOT_NULL (xarray);
  125.     XARRAY_BOUNDS_CHECK (xarray, at_index);
  126.     /* Shift everything from a[i] onward one pointer backward */
  127.     if ((int) at_index < xarray->last_valid_element)
  128.     {
  129.         (void) memmove (&xarray->array[at_index],
  130.                         &xarray->array[at_index + 1],
  131.                         (xarray->last_valid_element - at_index) *
  132.                             sizeof(void *));
  133.     }
  134.     xarray->array[xarray->last_valid_element] = NULL;
  135.     --xarray->last_valid_element;
  136.     return XARRAY_SUCCESS;
  137. }
  138. int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
  139.         int count)
  140. {
  141.     int i;
  142.     XARRAY_ASSERT_NOT_NULL (xarray);
  143.     XARRAY_BOUNDS_CHECK (xarray, at_index);
  144.     if (count == 0) return XARRAY_SUCCESS;
  145.     if ((int) at_index + (count - 1) > xarray->last_valid_element)
  146.         return XARRAY_ECOUNTOUTOFBOUNDS;
  147.     for (i = 0; i < count; i++)
  148.     {
  149.         int e = xarray_RemoveObject (xarray, at_index);
  150.         if (e != XARRAY_SUCCESS) return e;
  151.     }
  152.     return XARRAY_SUCCESS;
  153. }
  154. int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index)
  155. {
  156.     XARRAY_ASSERT_NOT_NULL (xarray);
  157.     XARRAY_BOUNDS_CHECK (xarray, index);
  158.     index++;
  159.     while ((int) index <= xarray->last_valid_element)
  160.     {
  161.         int e = xarray_RemoveObject (xarray, index);
  162.         if (e != XARRAY_SUCCESS) return e;
  163.     }
  164.     return XARRAY_SUCCESS;
  165. }
  166. int xarray_ReplaceObject (XArray *xarray, unsigned int index,
  167.         void *new_object)
  168. {
  169.     XARRAY_ASSERT_NOT_NULL (xarray);
  170.     XARRAY_BOUNDS_CHECK (xarray, index);
  171.     xarray->array[index] = new_object;
  172.     return XARRAY_SUCCESS;
  173. }
  174. int xarray_Count (XArray *xarray, unsigned int *out_count)
  175. {
  176.     XARRAY_ASSERT_NOT_NULL (xarray);
  177.     *out_count = xarray->last_valid_element + 1;
  178.     return XARRAY_SUCCESS;
  179. }
  180. #undef XARRAY_ASSERT_NOT_NULL
  181. #undef XARRAY_BOUNDS_CHECK
  182. #undef XARRAY_GROW_ARRAY