xref: /minix3/external/bsd/dhcp/dist/omapip/array.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: array.c,v 1.1.1.2 2014/07/12 11:57:58 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* listener.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Subroutines that support the omapi extensible array type. */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004-2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 2001-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek  *
10*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek  *
14*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek  *
22*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek  *   950 Charter Street
24*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
26*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
27*83ee113eSDavid van Moolenbroek  *
28*83ee113eSDavid van Moolenbroek  */
29*83ee113eSDavid van Moolenbroek 
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: array.c,v 1.1.1.2 2014/07/12 11:57:58 spz Exp $");
32*83ee113eSDavid van Moolenbroek 
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek 
35*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
36*83ee113eSDavid van Moolenbroek 
37*83ee113eSDavid van Moolenbroek /* Allocate a new extensible array. */
38*83ee113eSDavid van Moolenbroek 
omapi_array_allocate(omapi_array_t ** array,omapi_array_ref_t ref,omapi_array_deref_t deref,const char * file,int line)39*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_allocate (omapi_array_t **array,
40*83ee113eSDavid van Moolenbroek 				   omapi_array_ref_t ref,
41*83ee113eSDavid van Moolenbroek 				   omapi_array_deref_t deref,
42*83ee113eSDavid van Moolenbroek 				   const char *file, int line)
43*83ee113eSDavid van Moolenbroek {
44*83ee113eSDavid van Moolenbroek 	omapi_array_t *aptr;
45*83ee113eSDavid van Moolenbroek 
46*83ee113eSDavid van Moolenbroek 	if (!array || *array)
47*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
48*83ee113eSDavid van Moolenbroek 	aptr = dmalloc (sizeof (omapi_array_t),file, line);
49*83ee113eSDavid van Moolenbroek 	if (!aptr)
50*83ee113eSDavid van Moolenbroek 		return ISC_R_NOMEMORY;
51*83ee113eSDavid van Moolenbroek 	*array = aptr;
52*83ee113eSDavid van Moolenbroek 	aptr -> ref = ref;
53*83ee113eSDavid van Moolenbroek 	aptr -> deref = deref;
54*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
55*83ee113eSDavid van Moolenbroek }
56*83ee113eSDavid van Moolenbroek 
omapi_array_free(omapi_array_t ** array,const char * file,int line)57*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_free (omapi_array_t **array,
58*83ee113eSDavid van Moolenbroek 			       const char *file, int line)
59*83ee113eSDavid van Moolenbroek {
60*83ee113eSDavid van Moolenbroek 	omapi_array_t *aptr;
61*83ee113eSDavid van Moolenbroek 	int i;
62*83ee113eSDavid van Moolenbroek 
63*83ee113eSDavid van Moolenbroek 	if (!array || !*array)
64*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
65*83ee113eSDavid van Moolenbroek 	aptr = *array;
66*83ee113eSDavid van Moolenbroek 	for (i = 0; i < aptr -> count; i++)
67*83ee113eSDavid van Moolenbroek 		if (aptr -> data [i] && aptr -> deref)
68*83ee113eSDavid van Moolenbroek 			(*aptr -> deref) (&aptr -> data [i], file, line);
69*83ee113eSDavid van Moolenbroek 	dfree (aptr -> data, MDL);
70*83ee113eSDavid van Moolenbroek 	dfree (aptr, MDL);
71*83ee113eSDavid van Moolenbroek 	*array = (omapi_array_t *)0;
72*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
73*83ee113eSDavid van Moolenbroek }
74*83ee113eSDavid van Moolenbroek 
75*83ee113eSDavid van Moolenbroek /* Extend the size of the array by one entry (we may allocate more than that)
76*83ee113eSDavid van Moolenbroek    and store the specified value in the new array element. */
77*83ee113eSDavid van Moolenbroek 
omapi_array_extend(omapi_array_t * array,char * ptr,int * index,const char * file,int line)78*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_extend (omapi_array_t *array, char *ptr,
79*83ee113eSDavid van Moolenbroek 				 int *index, const char *file, int line)
80*83ee113eSDavid van Moolenbroek {
81*83ee113eSDavid van Moolenbroek 	isc_result_t status;
82*83ee113eSDavid van Moolenbroek 	int new = array -> count;
83*83ee113eSDavid van Moolenbroek 	status = omapi_array_set (array, ptr, new, file, line);
84*83ee113eSDavid van Moolenbroek 	if (index && status == ISC_R_SUCCESS)
85*83ee113eSDavid van Moolenbroek 		*index = new;
86*83ee113eSDavid van Moolenbroek 	return status;
87*83ee113eSDavid van Moolenbroek }
88*83ee113eSDavid van Moolenbroek 
89*83ee113eSDavid van Moolenbroek /* Set a value in the specified array, extending it if necessary. */
90*83ee113eSDavid van Moolenbroek 
omapi_array_set(omapi_array_t * array,void * ptr,int index,const char * file,int line)91*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_set (omapi_array_t *array, void *ptr, int index,
92*83ee113eSDavid van Moolenbroek 			      const char *file, int line)
93*83ee113eSDavid van Moolenbroek {
94*83ee113eSDavid van Moolenbroek 	char **newbuf;
95*83ee113eSDavid van Moolenbroek 	int delta;
96*83ee113eSDavid van Moolenbroek 	isc_result_t status;
97*83ee113eSDavid van Moolenbroek 
98*83ee113eSDavid van Moolenbroek 	if (!array)
99*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
100*83ee113eSDavid van Moolenbroek 	if (!ptr)
101*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
102*83ee113eSDavid van Moolenbroek 	if (index < 0)
103*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
104*83ee113eSDavid van Moolenbroek 
105*83ee113eSDavid van Moolenbroek 	/* If the proposed index is larger than the current available
106*83ee113eSDavid van Moolenbroek 	   space in the array, make more space in the array. */
107*83ee113eSDavid van Moolenbroek 	if (array -> max <= index) {
108*83ee113eSDavid van Moolenbroek 		delta = index - array -> max + 10;
109*83ee113eSDavid van Moolenbroek 		newbuf = dmalloc ((array -> max + delta) * sizeof (char *),
110*83ee113eSDavid van Moolenbroek 				  file, line);
111*83ee113eSDavid van Moolenbroek 		if (!newbuf)
112*83ee113eSDavid van Moolenbroek 			return ISC_R_NOMEMORY;
113*83ee113eSDavid van Moolenbroek 		/* Zero the new elements. */
114*83ee113eSDavid van Moolenbroek 		memset (&newbuf [array -> max], 0, (sizeof (char *)) * delta);
115*83ee113eSDavid van Moolenbroek 		array -> max += delta;
116*83ee113eSDavid van Moolenbroek 		/* Copy the old array data into the new buffer. */
117*83ee113eSDavid van Moolenbroek 		if (array -> data) {
118*83ee113eSDavid van Moolenbroek 		    memcpy (newbuf,
119*83ee113eSDavid van Moolenbroek 			    array -> data, array -> count * sizeof (char *));
120*83ee113eSDavid van Moolenbroek 		    dfree (array -> data, file, line);
121*83ee113eSDavid van Moolenbroek 		}
122*83ee113eSDavid van Moolenbroek 		array -> data = newbuf;
123*83ee113eSDavid van Moolenbroek 	} else {
124*83ee113eSDavid van Moolenbroek 		/* If there's already data there, and this is an array
125*83ee113eSDavid van Moolenbroek 		   of references, dereference what's there. */
126*83ee113eSDavid van Moolenbroek 		if (array -> data [index]) {
127*83ee113eSDavid van Moolenbroek 			status = ((*array -> deref) (&array -> data [index],
128*83ee113eSDavid van Moolenbroek 						     file, line));
129*83ee113eSDavid van Moolenbroek 
130*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
131*83ee113eSDavid van Moolenbroek 				return status;
132*83ee113eSDavid van Moolenbroek 		}
133*83ee113eSDavid van Moolenbroek 	}
134*83ee113eSDavid van Moolenbroek 
135*83ee113eSDavid van Moolenbroek 	/* Store the pointer using the referencer function.  We have
136*83ee113eSDavid van Moolenbroek 	   either just memset this to zero or dereferenced what was
137*83ee113eSDavid van Moolenbroek 	   there previously, so there is no need to do anything if the
138*83ee113eSDavid van Moolenbroek 	   pointer we have been asked to store is null. */
139*83ee113eSDavid van Moolenbroek 	if (ptr) {
140*83ee113eSDavid van Moolenbroek 		status = (*array -> ref) (&array -> data [index], ptr,
141*83ee113eSDavid van Moolenbroek 					  file, line);
142*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS)
143*83ee113eSDavid van Moolenbroek 			return status;
144*83ee113eSDavid van Moolenbroek 	}
145*83ee113eSDavid van Moolenbroek 	if (index >= array -> count)
146*83ee113eSDavid van Moolenbroek 		array -> count = index + 1;
147*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
148*83ee113eSDavid van Moolenbroek }
149*83ee113eSDavid van Moolenbroek 
omapi_array_lookup(char ** ptr,omapi_array_t * array,int index,const char * file,int line)150*83ee113eSDavid van Moolenbroek isc_result_t omapi_array_lookup (char **ptr, omapi_array_t *array, int index,
151*83ee113eSDavid van Moolenbroek 				 const char *file, int line)
152*83ee113eSDavid van Moolenbroek {
153*83ee113eSDavid van Moolenbroek 	if (!array || !ptr || *ptr || index < 0 || index >= array -> count)
154*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
155*83ee113eSDavid van Moolenbroek 	if (array -> data [index])
156*83ee113eSDavid van Moolenbroek 		return (*array -> ref) (ptr,
157*83ee113eSDavid van Moolenbroek 					array -> data [index], file, line);
158*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
159*83ee113eSDavid van Moolenbroek }
160*83ee113eSDavid van Moolenbroek 
161