Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

array.c

Go to the documentation of this file.
00001 /*! \file array.c
00002     This file implements basic array manipulation tools.
00003  */
00004 
00005 
00006 #include "array.h"
00007 #include "sort.h"
00008 
00009 /*! \brief Initialize an array handler.
00010     \param array Pointer to the array handler to initialize.
00011     \param first_element pointer to the first element of the array.
00012     \param size Size of the array (that is: the maximum number of elements in the array).
00013     \param copy_data User defined function used to copy data from/to the array.
00014                      Upon successful completion the function returns 0, otherwise it returns 1.
00015                      See the description of <i>struct s_array</i> for a complete description.
00016                      <FONT COLOR="#FF0000"><B>WARNING:</B></FONT> The function copy_data <B>MUST</B> take care off memory 
00017                      allocation/desallocation (if required).
00018     \param remove_data User defined function used to remove an element from the array.
00019                        Upon successful completion the function returns 0, otherwise it returns 1.
00020                        See the description of <i>struct s_array</i> for a complete description.
00021                        <i>remove_data</i> can be a NULL pointer if no special operation is required to remove an element.
00022     \param compare User defined function used to compare two elements of the array.
00023                    The function must return:
00024                    <UL>
00025                      <li>-1 if <i>d1 < d2</i>
00026                      <li>0  if <i>d1 = d2</i>
00027                      <li>+1 if <i>d1 > d2</i>
00028                      <li>-2 if an error occured.
00029                    </UL>
00030                    See the description of <i>struct s_array</i> for a complete description.
00031     \param index User defined function that returns a pointer to the element which index is <i>idx</i>.
00032                  See the description of <i>struct s_array</i> for a complete description.
00033     \param init_data User defined function used to initialize data. You can specify a NULL pointer if initialization is not required.
00034                      See the description of <i>struct s_array</i> for a complete description.
00035     \return Upon successful completion the function returns 0, otherwise it returns -1.
00036  */
00037 
00038 int array_init (
00039                   Array *array,
00040                   void  *first_element,
00041                   int   size,
00042                   int   (*copy_data)(void *src, void *dest),
00043                   int   (*remove_data)(void *target),
00044                   int   (*compare)(void *d1, void *d2),
00045                   void* (*index)(void *start, int idx),
00046                   int   (*init_data)(void *data)
00047                )
00048 {
00049   array->first_element      = first_element;
00050   array->array_size         = size;
00051   array->number_of_elements = 0;
00052   array->copy_data          = copy_data;
00053   array->remove_data        = remove_data;
00054   array->compare            = compare;
00055   array->index              = index;
00056   array->init_data          = init_data;
00057   array->element_to_remove  = 0;
00058   array->to_remove          = (int*)malloc(array->array_size * sizeof(int));
00059 
00060   if (array->to_remove == NULL) { return -1; }
00061 
00062   return 0;
00063 }
00064 
00065 /*! \example test_array.c
00066     This program shows how to use the array API
00067  */
00068 
00069 /*! \brief Free all memory allocated for the array structure.
00070     \warning This function <B>DOES NOT</B> free memory allocated for the user's data (this is the responsability of the user).
00071  */
00072 
00073 void array_free (Array *array) { free(array->to_remove); return; }
00074 
00075 /*! \example test_array.c
00076     This program shows how to use the array API
00077  */
00078 
00079 /*! \brief Schedule an element of the array for removing.
00080     \param array Pointer to an array data structure.
00081     \param idx Index of the element to remove.
00082     \return Upon successful completion the function returns 0, otherwise it returns -1.
00083  */
00084 
00085 int array_schedule_for_rem (Array *array, int idx)
00086 {
00087   int i;
00088 
00089   /* ------------------------------------------------- */
00090   /* First make sure that this index is not already    */
00091   /* scheduled.                                        */
00092   /* ------------------------------------------------- */
00093 
00094   for (i=0; i<array->element_to_remove; i++)
00095   { if (array->to_remove[i] == idx) { return 0; } }
00096 
00097   /* ------------------------------------------------- */
00098   /* Then, make sure that we can add an element to     */
00099   /* the list of elements to remove.                   */
00100   /* ------------------------------------------------- */
00101 
00102   if (array->element_to_remove >= array->array_size) { return -1; }
00103 
00104   /* ------------------------------------------------- */
00105   /* Add the index to the list of index to remove      */
00106   /* ------------------------------------------------- */
00107 
00108   array->to_remove[array->element_to_remove] = idx;
00109 
00110   /* ------------------------------------------------- */
00111   /* Increment the number of index to remove and exit  */
00112   /* ------------------------------------------------- */
00113 
00114   array->element_to_remove += 1;
00115 
00116   return 0;
00117 }
00118 
00119 /*! \example test_array.c
00120     This program shows how to use the array API
00121  */
00122 
00123 
00124 /* ------------------------------------------------------------ */
00125 /* Compare two integers -- Not part of public API               */
00126 /* ------------------------------------------------------------ */
00127 
00128 static int compare_int(const void *int1, const void *int2)
00129 {
00130   if (*(const int *)int1 > *(const int *)int2) { return 1; }
00131   if (*(const int *)int1 < *(const int *)int2) { return -1; }
00132   return 0;
00133 }
00134 
00135 /*! \brief Remove a list of previouly scheduled element.
00136     \param array Pointer to an array data structure.
00137     \return Upon successful completion the function returns 0, otherwise it returns -1.
00138  */
00139 
00140 int array_rem_all (Array *array)
00141 {
00142   int i;
00143 
00144   /* ------------------------------------------------- */
00145   /* Is there something to remove ?                    */
00146   /* ------------------------------------------------- */
00147 
00148   if (array->element_to_remove == 0) { return 0; }
00149 
00150   /* ------------------------------------------------- */
00151   /* Sort the idexes of the elements to remove         */
00152   /* ------------------------------------------------- */
00153 
00154   issort((void*)array->to_remove, array->element_to_remove, sizeof(int), compare_int);
00155 
00156   /* ------------------------------------------------- */
00157   /* Modify indexes, so we take care of the left shift */
00158   /* ------------------------------------------------- */
00159 
00160   for (i=0; i<array->element_to_remove; i++) { array->to_remove[i] -= i; }
00161 
00162   /* ------------------------------------------------- */
00163   /* Now remove the elements                           */
00164   /* ------------------------------------------------- */
00165   
00166   for (i=0; i<array->element_to_remove; i++)
00167   { if (array_rem(array, array->to_remove[i]) == -1) { return -1; } }
00168 
00169   /* ------------------------------------------------- */
00170   /* Reset the number of element to remove             */
00171   /* ------------------------------------------------- */
00172 
00173   array->element_to_remove = 0;
00174 
00175   return 0;
00176 }
00177 
00178 /*! \brief Initialize all elements of an array.
00179     \param array Pointer to an array data structure.
00180     \return Upon successful completion the function returns 0, otherwise it returns -1.
00181     \warning Depending on what you put in the function <i>init_data()</i>, you may call this function one or more times.
00182  */
00183 
00184 int array_init_element (Array *array)
00185 {
00186   void *location;
00187   int  i;
00188 
00189   for (i=0; i<array->array_size; i++)
00190   {
00191     location = array->index(array->first_element, i);
00192     if (array->init_data(location) == 1) { return -1; }
00193   }
00194 
00195   return 0;
00196 }
00197 
00198 /*! \example test_array.c
00199     This program shows how to use the array API
00200  */
00201 
00202 /*! \brief Add an element to the array (the element id added after the last element).
00203     \param array Pointer to the array handler to initialize.
00204     \param element Pointer to the element to add to the array.
00205     \return Upon successful completion the function returns 0, otherwise it returns -1.
00206  */
00207 
00208 int array_add (
00209                 Array *array,
00210                 void  *element
00211               )
00212 {
00213   void *location;
00214 
00215   /* ------------------------------------------------- */
00216   /* First, make sure that we can add an element       */
00217   /* ------------------------------------------------- */
00218 
00219   if (array->number_of_elements >= array->array_size) { return -1; }
00220 
00221   /* ------------------------------------------------- */
00222   /* Get a pointer to the first available location     */
00223   /* (That is, the end of the array)                   */
00224   /* Indexes start at 0. The index of the Nth element  */
00225   /* is N-1.                                           */
00226   /* ------------------------------------------------- */
00227 
00228   location = array->index(array->first_element, array->number_of_elements);
00229 
00230   /* ------------------------------------------------- */
00231   /* Copy the element to the available location        */
00232   /* ------------------------------------------------- */
00233 
00234   if (array->copy_data (element, location) == 1) { return -1; }
00235   
00236   /* ------------------------------------------------- */
00237   /* Increment the number of elements and exit         */ 
00238   /* ------------------------------------------------- */
00239 
00240   array->number_of_elements += 1;
00241 
00242   return 0;
00243 
00244 }
00245 
00246 /*! \example test_array.c
00247     This program shows how to use the array API
00248  */
00249 
00250 /*! \brief Remove an element from an array. The elements next to the one removed are shifted to the left (so there is no gaps, and the
00251            elements' order does not change).
00252     \param array Pointer to the array handler to initialize.
00253     \param idx Index of the element to remove.
00254     \return Upon successful completion the function returns 0, otherwise it returns -1.
00255  */
00256 
00257 int array_rem (
00258                 Array *array,
00259                 int   idx
00260               )
00261 {
00262   void *location, *src, *dst;
00263   int  i;
00264 
00265   /* ------------------------------------------------- */
00266   /* First, make sure that 'idx' is not out of the     */
00267   /* array. Indexes start at 0. The index of the Nth   */
00268   /* element is N-1                                    */
00269   /* ------------------------------------------------- */
00270 
00271   if (idx > array->number_of_elements-1) { return -1; }
00272 
00273   /* ------------------------------------------------- */
00274   /* Get a pointer to the location pointed by 'idx'    */
00275   /* ------------------------------------------------- */
00276 
00277   location = array->index(array->first_element, idx);
00278 
00279   /* ------------------------------------------------- */
00280   /* Remove the element and shift the next elements    */
00281   /* ------------------------------------------------- */
00282 
00283   if (array->remove_data != NULL)
00284   { if (array->remove_data(location) == 1) { return -1; } }
00285 
00286   /* ------------------------------------------------- */
00287   /* Now, the difficult part: shift all the elements   */
00288   /* ------------------------------------------------- */
00289 
00290   for (i=idx; i<array->number_of_elements-1; i++)
00291   {
00292     dst = array->index(array->first_element, i);
00293     src = array->index(array->first_element, i+1);
00294 
00295     if (array->copy_data (src, dst) == 1) { return -1; }
00296   }
00297 
00298   /* ------------------------------------------------- */
00299   /* Remove the last element. Keep in mind that the    */
00300   /* function 'copy_data' doest not remove the source  */
00301   /* ------------------------------------------------- */
00302 
00303   if (array->remove_data != NULL)
00304   {
00305     location = array->index(array->first_element, array->number_of_elements-1);
00306     if (array->remove_data(location) == 1) { return -1; }
00307   }
00308 
00309   /* ------------------------------------------------- */
00310   /* Decrement the number of element in the array and  */
00311   /* exit                                              */
00312   /* ------------------------------------------------- */
00313 
00314   array->number_of_elements -= 1;
00315 
00316   return 0;
00317 }
00318 
00319 /*! \example test_array.c
00320     This program shows how to use the array API
00321  */
00322 
00323 /*! \brief Insert an element in an array.
00324     \param array Pointer to an array data structure.
00325     \param idx Index in the array where to insert the new elememt.
00326     \param data Pointer to a user defined data (that represents the content of the new element).
00327     \return Upon successful completion the function returns 0, otherwise it returns -1.
00328  */
00329 
00330 int array_insert (
00331                    Array *array,
00332                    int   idx,
00333                    void  *data
00334                  )
00335 {
00336 
00337   void *src, *dst, *location;
00338   int  i;
00339 
00340   /* ------------------------------------------------- */
00341   /* First, make sure that we can add an element       */
00342   /* ------------------------------------------------- */
00343 
00344   if (array->number_of_elements >= array->array_size) { return -1; }
00345 
00346   /* ------------------------------------------------- */
00347   /* The make shure that 'idx' is a valid position     */
00348   /* Note: the index of the last element is            */
00349   /*       (array->number_of_elements - 1)             */
00350   /* ------------------------------------------------- */
00351 
00352   if (idx >= array->number_of_elements) { return -1; } 
00353 
00354   /* ------------------------------------------------- */
00355   /* Shift all elements which index is greater that    */
00356   /* 'idx' to the right.                               */
00357   /* ------------------------------------------------- */
00358 
00359   for (i=array->number_of_elements; i>idx; i--)
00360   {
00361     src = array->index(array->first_element, i-1);
00362     dst = array->index(array->first_element, i);
00363 
00364     if (array->copy_data (src, dst) == 1) { return -1; }
00365   }
00366 
00367   /* ------------------------------------------------- */
00368   /* Now copy 'data' at index 'idx'.                   */
00369   /* ------------------------------------------------- */
00370 
00371   location = array->index(array->first_element, idx);
00372   if (array->copy_data (data, location) == 1) { return -1; }
00373 
00374   /* ------------------------------------------------- */
00375   /* Increment the number of elements and exit         */
00376   /* ------------------------------------------------- */
00377 
00378   array->number_of_elements += 1;
00379 
00380   return 0;
00381 }
00382 
00383 /*! \example test_array.c
00384     This program shows how to use the array API
00385  */
00386 
00387 /*! \brief Find an given element in the array.
00388     \param array Pointer to the array data structure.
00389     \param data Pointer to the user defined element to find.
00390     \return If the element is found, then the function returns the index of the element. Otherwise the function
00391             returns -1.
00392  */
00393 
00394 int array_find (
00395                    Array *array,
00396                    void  *data
00397                )
00398 {
00399   int  idx;
00400   void *location;
00401 
00402   for (idx=0; idx<array->number_of_elements; idx++)
00403   {
00404     location = array->index(array->first_element, idx);
00405     if (array->compare(location, data) == 0) { return idx; }
00406   }
00407 
00408   return -1;
00409 }
00410 
00411 /*! \example test_array.c
00412     This program shows how to use the array API
00413  */
00414 
00415 

Generated on Thu Apr 3 16:23:42 2003 for Common_C_libraries by doxygen1.3-rc1