xarray.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:7k
源码类别:

多媒体

开发平台:

MultiPlatform

  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 VideoLAN
  7.  *
  8.  * $Id: xarray.c 7397 2004-04-20 17:27:30Z sam $
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  25.  ************************************************************************/
  26. #include <stdlib.h>
  27. #include <string.h> /* memmove(1) */
  28. #include "xarray.h"
  29. #define XARRAY_ASSERT_NOT_NULL(xarray) 
  30.     { 
  31.         if (xarray == NULL) return XARRAY_ENULLPOINTER; 
  32.     }
  33. #define XARRAY_BOUNDS_CHECK(xarray, index) 
  34.     { 
  35.         if (index < 0) 
  36.             return XARRAY_ENEGATIVEINDEX; 
  37.         else if (xarray->last_valid_element != -1 && 
  38.                  (int) index > xarray->last_valid_element) 
  39.             return XARRAY_EINDEXTOOLARGE; 
  40.     }
  41. #define XARRAY_GROW_ARRAY(xarray) 
  42.     { 
  43.         xarray->array = (void *) realloc (xarray->array, xarray->size * 2); 
  44.         if (xarray->array == NULL) return XARRAY_ENOMEM; 
  45.     }
  46. XSTATIC XArray * xarray_New (unsigned int initial_size_hint)
  47. {
  48.     XArray *new_xarray = NULL;
  49.     void *inner_array;
  50.     unsigned int initial_size;
  51.     new_xarray = (XArray *) malloc (sizeof(XArray));
  52.     if (new_xarray == NULL) return NULL;
  53.     if (initial_size_hint <= 0)
  54.         initial_size = XARRAY_DEFAULT_SIZE;
  55.     else
  56.         initial_size = initial_size_hint;
  57.     inner_array = calloc (initial_size, sizeof(void *));
  58.     new_xarray->last_valid_element = -1;
  59.     new_xarray->size = initial_size;
  60.     new_xarray->last_error = 0;
  61.     if (inner_array == NULL)
  62.     {
  63.         free (new_xarray);
  64.         return NULL;
  65.     }
  66.     new_xarray->array = inner_array;
  67.     /* Make a dummy reference to other functions, so that we don't get
  68.      * warnings about unused functions from the compiler.  Ahem :) */
  69.     while (0)
  70.     {
  71.         void *dummy_reference;
  72.         dummy_reference = xarray_AddObject;
  73.         dummy_reference = xarray_InsertObject;
  74.         dummy_reference = xarray_RemoveLastObject;
  75.         dummy_reference = xarray_RemoveObject;
  76.         dummy_reference = xarray_RemoveObjects;
  77.         dummy_reference = xarray_RemoveObjectsAfter;
  78.         dummy_reference = xarray_ReplaceObject;
  79.         dummy_reference = xarray_ObjectAtIndex;
  80.         dummy_reference = xarray_Count;
  81.     }
  82.     
  83.     return new_xarray;
  84. }
  85. XSTATIC int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
  86.         void **out_object)
  87. {
  88.     XARRAY_ASSERT_NOT_NULL (xarray);
  89.     XARRAY_BOUNDS_CHECK (xarray, index);
  90.     *out_object = xarray->array[index];
  91.     return XARRAY_SUCCESS;
  92. }
  93. XSTATIC int xarray_AddObject (XArray *xarray, void *object)
  94. {
  95.     XARRAY_ASSERT_NOT_NULL (xarray);
  96.     ++xarray->last_valid_element;
  97.     if (xarray->last_valid_element >= (int) xarray->size)
  98.     {
  99.         XARRAY_GROW_ARRAY (xarray);
  100.     }
  101.     xarray->array[xarray->last_valid_element] = object;
  102.     return XARRAY_SUCCESS;
  103. }
  104. XSTATIC int xarray_InsertObject (XArray *xarray, void *object,
  105.         unsigned int at_index)
  106. {
  107.     XARRAY_ASSERT_NOT_NULL (xarray);
  108.     ++xarray->last_valid_element;
  109.     XARRAY_BOUNDS_CHECK (xarray, at_index);
  110.     if (xarray->last_valid_element >= (int) xarray->size)
  111.     {
  112.         XARRAY_GROW_ARRAY (xarray);
  113.     }
  114.     /* Shift everything from a[i] onward one pointer forward */
  115.     if ((int) at_index < xarray->last_valid_element)
  116.     {
  117.         (void) memmove (&xarray->array[at_index + 1],
  118.                         &xarray->array[at_index],
  119.                         (xarray->last_valid_element - at_index) *
  120.                             sizeof(void *));
  121.     }
  122.     xarray->array[at_index] = object;
  123.     return XARRAY_SUCCESS;
  124. }
  125. XSTATIC int xarray_RemoveLastObject (XArray *xarray)
  126. {
  127.     XARRAY_ASSERT_NOT_NULL (xarray);
  128.     if (xarray->last_valid_element == -1)
  129.         return XARRAY_EEMPTYARRAY;
  130.     xarray->array[xarray->last_valid_element] = NULL;
  131.     --xarray->last_valid_element;
  132.     return XARRAY_SUCCESS;
  133. }
  134. XSTATIC int xarray_RemoveObject (XArray *xarray, unsigned int at_index)
  135. {
  136.     XARRAY_ASSERT_NOT_NULL (xarray);
  137.     XARRAY_BOUNDS_CHECK (xarray, at_index);
  138.     /* Shift everything from a[i] onward one pointer backward */
  139.     if ((int) at_index < xarray->last_valid_element)
  140.     {
  141.         (void) memmove (&xarray->array[at_index],
  142.                         &xarray->array[at_index + 1],
  143.                         (xarray->last_valid_element - at_index) *
  144.                             sizeof(void *));
  145.     }
  146.     xarray->array[xarray->last_valid_element] = NULL;
  147.     --xarray->last_valid_element;
  148.     return XARRAY_SUCCESS;    
  149. }
  150. XSTATIC int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
  151.         int count)
  152. {
  153.     int i;
  154.     XARRAY_ASSERT_NOT_NULL (xarray);
  155.     XARRAY_BOUNDS_CHECK (xarray, at_index);
  156.     if (count == 0) return XARRAY_SUCCESS;
  157.     if ((int) at_index + (count - 1) > xarray->last_valid_element)
  158.         return XARRAY_ECOUNTOUTOFBOUNDS;
  159.     for (i = 0; i < count; i++)
  160.     {
  161.         int e = xarray_RemoveObject (xarray, at_index);
  162.         if (e != XARRAY_SUCCESS) return e;
  163.     }
  164.     return XARRAY_SUCCESS;
  165. }
  166. XSTATIC int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index)
  167. {
  168.     XARRAY_ASSERT_NOT_NULL (xarray);
  169.     XARRAY_BOUNDS_CHECK (xarray, index);
  170.     index++;
  171.     while ((int) index <= xarray->last_valid_element)
  172.     {
  173.         int e = xarray_RemoveObject (xarray, index);
  174.         if (e != XARRAY_SUCCESS) return e;
  175.     }
  176.     return XARRAY_SUCCESS;
  177. }
  178. XSTATIC int xarray_ReplaceObject (XArray *xarray, unsigned int index,
  179.         void *new_object)
  180. {
  181.     XARRAY_ASSERT_NOT_NULL (xarray);
  182.     XARRAY_BOUNDS_CHECK (xarray, index);
  183.     xarray->array[index] = new_object;
  184.     return XARRAY_SUCCESS;
  185. }
  186. XSTATIC int xarray_Count (XArray *xarray, unsigned int *out_count)
  187. {
  188.     XARRAY_ASSERT_NOT_NULL (xarray);
  189.     *out_count = xarray->last_valid_element + 1;
  190.     return XARRAY_SUCCESS;
  191. }
  192. #undef XARRAY_ASSERT_NOT_NULL
  193. #undef XARRAY_BOUNDS_CHECK
  194. #undef XARRAY_GROW_ARRAY