vector.h

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  Contains the API for a generic vector.  Note that vector functions
00004  *  are not thread-safe.
00005  *
00006  *  @author Jeremy A. Mowery jmowery@tresys.com
00007  *  @author Jason Tang jtang@tresys.com
00008  *
00009  *  Copyright (C) 2006-2007 Tresys Technology, LLC
00010  *
00011  *  This library is free software; you can redistribute it and/or
00012  *  modify it under the terms of the GNU Lesser General Public
00013  *  License as published by the Free Software Foundation; either
00014  *  version 2.1 of the License, or (at your option) any later version.
00015  *
00016  *  This library is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  Lesser General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU Lesser General Public
00022  *  License along with this library; if not, write to the Free Software
00023  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00024  */
00025 
00026 #ifndef APOL_VECTOR_H
00027 #define APOL_VECTOR_H
00028 
00029 #ifdef  __cplusplus
00030 extern "C"
00031 {
00032 #endif
00033 
00034 #include <stdlib.h>
00035 #include <qpol/iterator.h>
00036 
00037         typedef struct apol_vector apol_vector_t;
00038 
00039         typedef int (apol_vector_comp_func) (const void *a, const void *b, void *data);
00040         typedef void (apol_vector_free_func) (void *elem);
00041         typedef void *(apol_vector_dup_func) (const void *elem, void *data);
00042 
00043 /**
00044  *  Allocate and initialize an empty vector with default
00045  *  capacity.
00046  *
00047  *  @param fr Function to call when destroying the vector.  Each
00048  *  element of the vector will be passed into this function; it should
00049  *  free the memory used by that element.  If this parameter is NULL,
00050  *  the elements will not be freed.
00051  *
00052  *  @return A pointer to a newly created vector on success and NULL on
00053  *  failure.  If the call fails, errno will be set.  The caller is
00054  *  responsible for calling apol_vector_destroy() to free memory used.
00055  */
00056         extern apol_vector_t *apol_vector_create(apol_vector_free_func * fr);
00057 
00058 /**
00059  *  Allocate and initialize an empty vector with starting capacity of
00060  *  cap.
00061  *
00062  *  @param cap The starting capacity to allocate for the internal
00063  *  array.
00064  *  @param fr Function to call when destroying the vector.  Each
00065  *  element of the vector will be passed into this function; it should
00066  *  free the memory used by that element.  If this parameter is NULL,
00067  *  the elements will not be freed.
00068  *
00069  *  @return A pointer to a newly created vector on success and NULL on
00070  *  failure.  If the call fails, errno will be set.  The caller is
00071  *  responsible for calling apol_vector_destroy() to free memory used.
00072  */
00073         extern apol_vector_t *apol_vector_create_with_capacity(size_t cap, apol_vector_free_func * fr);
00074 
00075 /**
00076  *  Allocate and return a vector that has been initialized with the
00077  *  contents of a qpol iterator.  <b>This function merely makes a
00078  *  shallow copy of the iterator's contents</b>; any memory ownership
00079  *  restrictions imposed by the iterator apply to this vector as well.
00080  *  Also note that this function begins copying from the iterator's
00081  *  current position, leaving the iterator at its end position
00082  *  afterwards.
00083  *
00084  *  @param iter qpol iterator from which to obtain vector's contents.
00085  *  @param fr Function to call when destroying the vector.  Each
00086  *  element of the vector will be passed into this function; it should
00087  *  free the memory used by that element.  If this parameter is NULL,
00088  *  the elements will not be freed.
00089  *
00090  *  @return A pointer to a newly created vector on success and NULL on
00091  *  failure.  If the call fails, errno will be set.  The caller is
00092  *  responsible for calling apol_vector_destroy() to free memory used.
00093  */
00094         extern apol_vector_t *apol_vector_create_from_iter(qpol_iterator_t * iter, apol_vector_free_func * fr);
00095 
00096 /**
00097  *  Allocate and return a vector that has been initialized with the
00098  *  contents of another vector.
00099  *
00100  *  @param v Vector from which to copy.
00101  *  @param dup If NULL, then make a shallow copy of the original
00102  *  vector's contents.  Otherwise this function will be called upon
00103  *  for each element from the original vector; the return value will
00104  *  be the value stored in the new vector.
00105  *  @param data Arbitrary data to pass as dup's second parameter.
00106  *  @param fr Function to call when destroying the new vector.  Each
00107  *  element of the vector will be passed into this function; it should
00108  *  free the memory used by that element.  If this parameter is NULL,
00109  *  the elements will not be freed.
00110  *
00111  *  @return A pointer to a newly created vector on success and NULL on
00112  *  failure.  If the call fails, errno will be set.  The caller is
00113  *  responsible for calling apol_vector_destroy() to free memory used.
00114  */
00115         extern apol_vector_t *apol_vector_create_from_vector(const apol_vector_t * v, apol_vector_dup_func * dup, void *data,
00116                                                              apol_vector_free_func * fr);
00117 
00118 /**
00119  *  Allocate and return a vector that has been initialized with the
00120  *  contents common to two other vectors.  <b>This function merely
00121  *  makes a shallow copy of the vectors' contents</b>; any memory
00122  *  ownership restrictions imposed by the original vectors apply to
00123  *  this new vector as well.  Note that if a source vector contains
00124  *  duplicate elements the returned vector may (or may not) have
00125  *  duplicates as well.  If the caller does not want duplicate entries
00126  *  then apol_vector_sort_uniquify() should be called afterwards.
00127  *
00128  *  @param v1 First vector from which to compute the intersection.
00129  *  @param v2 Other vector to compute intersection.
00130  *  @param cmp A comparison call back for the type of element stored
00131  *  in the vector.  The expected return value from this function is
00132  *  less than, equal to, or greater than 0 if the first argument is
00133  *  less than, equal to, or greater than the second respectively.  If
00134  *  this is NULL then do pointer address comparison.
00135  *  @param data Arbitrary data to pass as the comparison function's
00136  *  third paramater.
00137  *
00138  *  @return A pointer to a newly created vector on success and NULL on
00139  *  failure.  If the call fails, errno will be set.  The caller is
00140  *  responsible for calling apol_vector_destroy() to free memory used.
00141  */
00142         extern apol_vector_t *apol_vector_create_from_intersection(const apol_vector_t * v1,
00143                                                                    const apol_vector_t * v2, apol_vector_comp_func * cmp,
00144                                                                    void *data);
00145 
00146 /**
00147  *  Free a vector and any memory used by it.  This will recursively
00148  *  invoke the free function that was stored within the vector when it
00149  *  was created.
00150  *
00151  *  @param v Pointer to the vector to free.  The pointer will be set
00152  *  to NULL afterwards.  If already NULL then this function does
00153  *  nothing.
00154  */
00155         extern void apol_vector_destroy(apol_vector_t ** v);
00156 
00157 /**
00158  *  Get the number of elements in the vector.
00159  *
00160  *  @param v The vector from which to get the number of elements.
00161  *  Must be non-NULL.
00162  *
00163  *  @return The number of elements in the vector; if v is NULL,
00164  *  returns 0.
00165  */
00166         extern size_t apol_vector_get_size(const apol_vector_t * v);
00167 
00168 /**
00169  *  Get the current capacity of the vector.
00170  *
00171  *  @param v The vector from which to get the current capacity.  Must
00172  *  be non-NULL.
00173  *
00174  *  @return The capacity of the vector; this value will be greater or
00175  *  equal to the number of elements in the vector.  If v is NULL,
00176  *  returns 0.
00177  */
00178         extern size_t apol_vector_get_capacity(const apol_vector_t * v);
00179 
00180 /**
00181  *  Get the element at the requested index.
00182  *
00183  *  @param v The vector from which to get the element.
00184  *  @param idx The index of the desired element.
00185  *
00186  *  @return A pointer to the element requested.  If v is NULL or idx is
00187  *  out of range, returns NULL and sets errno.
00188  */
00189         extern void *apol_vector_get_element(const apol_vector_t * v, size_t idx);
00190 
00191 /**
00192  *  Find an element within a vector, returning its index within the vector.
00193  *
00194  *  @param v The vector from which to get the element.
00195  *  @param elem The element to find.
00196  *  @param cmp A comparison call back for the type of element stored
00197  *  in the vector.  The first parameter will be an existing element
00198  *  from the vector; next will be elem and then data.  The expected
00199  *  return value from this function is less than, equal to, or greater
00200  *  than 0 if the first argument is less than, equal to, or greater
00201  *  than the second respectively.  For use in this function the return
00202  *  value is only checked for 0 or non-zero return.  If this is NULL
00203  *  then do pointer address comparison.
00204  *  @param data Arbitrary data to pass as the comparison function's
00205  *  third paramater.
00206  *  @param i Index into vector where element was found.  This value is
00207  *  undefined if the element was not found.
00208  *
00209  *  @return 0 if element was found, or < 0 if not found.
00210  */
00211         extern int apol_vector_get_index(const apol_vector_t * v, const void *elem, apol_vector_comp_func * cmp, void *data,
00212                                          size_t * i);
00213 
00214 /**
00215  *  Add an element to the end of a vector.
00216  *
00217  *  @param v The vector to which to add the element.
00218  *  @param elem The element to add.  Once added the element will be
00219  *  the last element in the vector.
00220  *
00221  *  @return 0 on success and < 0 on failure.  If the call fails, errno
00222  *  will be set and v will be unchanged.
00223  */
00224         extern int apol_vector_append(apol_vector_t * v, void *elem);
00225 
00226 /**
00227  *  Add an element to the end of a vector unless that element is equal
00228  *  to an existing element.
00229  *
00230  *  @param v The vector to which to add the element.
00231  *  @param elem The element to add; must be non-NULL.
00232  *  @param cmp A comparison call back for the type of element stored
00233  *  in the vector.  The expected return value from this function is
00234  *  less than, equal to, or greater than 0 if the first argument is
00235  *  less than, equal to, or greater than the second respectively.  For
00236  *  use in this function the return value is only checked for 0 or
00237  *  non-zero return.  If this is NULL then do pointer address
00238  *  comparison.
00239  *  @param data Arbitrary data to pass as the comparison function's
00240  *  third paramater.
00241  *
00242  *  @return 0 on success, < 0 on failure, and > 0 if the element
00243  *  already exists in the vector.  If the call fails or the element
00244  *  already exists errno will be set.
00245  */
00246         extern int apol_vector_append_unique(apol_vector_t * v, void *elem, apol_vector_comp_func * cmp, void *data);
00247 
00248 /**
00249  *  Concatenate two vectors.  Appends all elements of src to dest.
00250  *  <b>NOTE: No type checking is done for elements in the two
00251  *  vectors.</b>  Elements are not deep copies.
00252  *  @param dest Vector to which to append elements.
00253  *  @param src Vector containing elements to append.
00254  *  @return 0 on success and < 0 on failure; if the call fails,
00255  *  errno will be set and dest's contents will be reverted.
00256  */
00257         extern int apol_vector_cat(apol_vector_t * dest, const apol_vector_t * src);
00258 
00259 /**
00260  *  Remove an element from a vector, and renumber all subsequent
00261  *  elements.  <b>This does not free memory that was used by the
00262  *  removed element</b>; the caller is responsible for doing that.
00263  *
00264  *  @param v Vector containing element.
00265  *  @param idx Index to the element to remove.
00266  *  @return 0 on success and < 0 on failure; if the call fails,
00267  *  errno will be set and v's contents will be reverted.
00268  */
00269         extern int apol_vector_remove(apol_vector_t * v, const size_t idx);
00270 
00271 /**
00272  *  Compare two vectors, determining if one is different than the
00273  *  other.  This uses a callback to compare elements across the
00274  *  vectors.
00275  *
00276  *  @param a First vector to compare.
00277  *  @param b Second vector to compare.
00278  *  @param cmp A comparison call back for the type of element stored
00279  *  in the vector.  The expected return value from this function is
00280  *  less than, equal to, or greater than 0 if the first argument is
00281  *  less than, equal to, or greater than the second respectively.  If
00282  *  this is NULL then do pointer address comparison.
00283  *  @param data Arbitrary data to pass as the comparison function's
00284  *  third paramater.
00285  *  @param i Reference to where to store the index of the first
00286  *  detected difference.  The value is undefined if vectors are
00287  *  equivalent (return value of 0).  Note that the index may be
00288  *  greater than a vector's size if the vectors are of unequal
00289  *  lengths.
00290  *
00291  *  @return < 0 if vector A is less than B, > 0 if A is greater than
00292  *  B, or 0 if equivalent.
00293  */
00294         extern int apol_vector_compare(const apol_vector_t * a, const apol_vector_t * b, apol_vector_comp_func * cmp, void *data,
00295                                        size_t * i);
00296 
00297 /**
00298  *  Sort the vector's elements within place, using an unstable sorting
00299  *  algorithm.
00300  *
00301  *  @param v The vector to sort.
00302  *  @param cmp A comparison call back for the type of element stored
00303  *  in the vector.  The expected return value from this function is
00304  *  less than, equal to, or greater than 0 if the first argument is
00305  *  less than, equal to, or greater than the second respectively.  If
00306  *  this is NULL then treat the vector's contents as unsigned integers
00307  *  and sort in increasing order.
00308  *  @param data Arbitrary data to pass as the comparison function's
00309  *  third paramater.
00310  */
00311         extern void apol_vector_sort(apol_vector_t * v, apol_vector_comp_func * cmp, void *data);
00312 
00313 /**
00314  *  Sort the vector's elements within place (see apol_vector_sort()),
00315  *  and then compact vector by removing duplicate entries.  The
00316  *  vector's free function will be used to free the memory used by
00317  *  non-unique elements.
00318  *
00319  *  @param v The vector to sort.
00320  *  @param cmp A comparison call back for the type of element stored
00321  *  in the vector.  The expected return value from this function is
00322  *  less than, equal to, or greater than 0 if the first argument is
00323  *  less than, equal to, or greater than the second respectively.  If
00324  *  this is NULL then treat the vector's contents as unsigned integers
00325  *  and sort in increasing order.
00326  *  @param data Arbitrary data to pass as the comparison function's
00327  *  third paramater.
00328  */
00329         extern void apol_vector_sort_uniquify(apol_vector_t * v, apol_vector_comp_func * cmp, void *data);
00330 
00331 #ifdef  __cplusplus
00332 }
00333 #endif
00334 
00335 #endif                                 /* APOL_VECTOR_H */