omapip/array.c

Go to the documentation of this file.
00001 /* listener.c
00002 
00003    Subroutines that support the omapi extensible array type. */
00004 
00005 /*
00006  * Copyright (c) 2004-2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 2001-2003 by Internet Software Consortium
00008  *
00009  * Permission to use, copy, modify, and distribute this software for any
00010  * purpose with or without fee is hereby granted, provided that the above
00011  * copyright notice and this permission notice appear in all copies.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00014  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00015  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00016  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00017  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00018  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00019  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00020  *
00021  *   Internet Systems Consortium, Inc.
00022  *   950 Charter Street
00023  *   Redwood City, CA 94063
00024  *   <info@isc.org>
00025  *   https://www.isc.org/
00026  *
00027  */
00028 
00029 #include "dhcpd.h"
00030 
00031 #include <omapip/omapip_p.h>
00032 
00033 /* Allocate a new extensible array. */
00034 
00035 isc_result_t omapi_array_allocate (omapi_array_t **array,
00036                                    omapi_array_ref_t ref,
00037                                    omapi_array_deref_t deref,
00038                                    const char *file, int line)
00039 {
00040         omapi_array_t *aptr;
00041 
00042         if (!array || *array)
00043                 return DHCP_R_INVALIDARG;
00044         aptr = dmalloc (sizeof (omapi_array_t),file, line);
00045         if (!aptr)
00046                 return ISC_R_NOMEMORY;
00047         *array = aptr;
00048         aptr -> ref = ref;
00049         aptr -> deref = deref;
00050         return ISC_R_SUCCESS;
00051 }
00052 
00053 isc_result_t omapi_array_free (omapi_array_t **array,
00054                                const char *file, int line)
00055 {
00056         omapi_array_t *aptr;
00057         int i;
00058 
00059         if (!array || !*array)
00060                 return DHCP_R_INVALIDARG;
00061         aptr = *array;
00062         for (i = 0; i < aptr -> count; i++)
00063                 if (aptr -> data [i] && aptr -> deref)
00064                         (*aptr -> deref) (&aptr -> data [i], file, line);
00065         dfree (aptr -> data, MDL);
00066         dfree (aptr, MDL);
00067         *array = (omapi_array_t *)0;
00068         return ISC_R_SUCCESS;
00069 }
00070 
00071 /* Extend the size of the array by one entry (we may allocate more than that)
00072    and store the specified value in the new array element. */
00073 
00074 isc_result_t omapi_array_extend (omapi_array_t *array, char *ptr,
00075                                  int *index, const char *file, int line)
00076 {
00077         isc_result_t status;
00078         int new = array -> count;
00079         status = omapi_array_set (array, ptr, new, file, line);
00080         if (index && status == ISC_R_SUCCESS)
00081                 *index = new;
00082         return status;
00083 }
00084 
00085 /* Set a value in the specified array, extending it if necessary. */
00086 
00087 isc_result_t omapi_array_set (omapi_array_t *array, void *ptr, int index,
00088                               const char *file, int line)
00089 {
00090         char **newbuf;
00091         int delta;
00092         isc_result_t status;
00093 
00094         if (!array)
00095                 return DHCP_R_INVALIDARG;
00096         if (!ptr)
00097                 return DHCP_R_INVALIDARG;
00098         if (index < 0)
00099                 return DHCP_R_INVALIDARG;
00100 
00101         /* If the proposed index is larger than the current available
00102            space in the array, make more space in the array. */
00103         if (array -> max <= index) {
00104                 delta = index - array -> max + 10;
00105                 newbuf = dmalloc ((array -> max + delta) * sizeof (char *),
00106                                   file, line);
00107                 if (!newbuf)
00108                         return ISC_R_NOMEMORY;
00109                 /* Zero the new elements. */
00110                 memset (&newbuf [array -> max], 0, (sizeof (char *)) * delta);
00111                 array -> max += delta;
00112                 /* Copy the old array data into the new buffer. */
00113                 if (array -> data) {
00114                     memcpy (newbuf,
00115                             array -> data, array -> count * sizeof (char *));
00116                     dfree (array -> data, file, line);
00117                 }
00118                 array -> data = newbuf;
00119         } else {
00120                 /* If there's already data there, and this is an array
00121                    of references, dereference what's there. */
00122                 if (array -> data [index]) {
00123                         status = ((*array -> deref) (&array -> data [index],
00124                                                      file, line));
00125                 
00126                         if (status != ISC_R_SUCCESS)
00127                                 return status;
00128                 }
00129         }
00130 
00131         /* Store the pointer using the referencer function.  We have
00132            either just memset this to zero or dereferenced what was
00133            there previously, so there is no need to do anything if the
00134            pointer we have been asked to store is null. */
00135         if (ptr) {
00136                 status = (*array -> ref) (&array -> data [index], ptr,
00137                                           file, line);
00138                 if (status != ISC_R_SUCCESS)
00139                         return status;
00140         }
00141         if (index >= array -> count)
00142                 array -> count = index + 1;
00143         return ISC_R_SUCCESS;
00144 }
00145 
00146 isc_result_t omapi_array_lookup (char **ptr, omapi_array_t *array, int index,
00147                                  const char *file, int line)
00148 {
00149         if (!array || !ptr || *ptr || index < 0 || index >= array -> count)
00150                 return DHCP_R_INVALIDARG;
00151         if (array -> data [index])
00152                 return (*array -> ref) (ptr,
00153                                         array -> data [index], file, line);
00154         return ISC_R_NOTFOUND;
00155 }
00156 

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1