1*1fcced4cSJordan Brown /*
2*1fcced4cSJordan Brown  * CDDL HEADER START
3*1fcced4cSJordan Brown  *
4*1fcced4cSJordan Brown  * The contents of this file are subject to the terms of the
5*1fcced4cSJordan Brown  * Common Development and Distribution License (the "License").
6*1fcced4cSJordan Brown  * You may not use this file except in compliance with the License.
7*1fcced4cSJordan Brown  *
8*1fcced4cSJordan Brown  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1fcced4cSJordan Brown  * or http://www.opensolaris.org/os/licensing.
10*1fcced4cSJordan Brown  * See the License for the specific language governing permissions
11*1fcced4cSJordan Brown  * and limitations under the License.
12*1fcced4cSJordan Brown  *
13*1fcced4cSJordan Brown  * When distributing Covered Code, include this CDDL HEADER in each
14*1fcced4cSJordan Brown  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1fcced4cSJordan Brown  * If applicable, add the following below this CDDL HEADER, with the
16*1fcced4cSJordan Brown  * fields enclosed by brackets "[]" replaced with your own identifying
17*1fcced4cSJordan Brown  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1fcced4cSJordan Brown  *
19*1fcced4cSJordan Brown  * CDDL HEADER END
20*1fcced4cSJordan Brown  */
21*1fcced4cSJordan Brown 
22*1fcced4cSJordan Brown /*
23*1fcced4cSJordan Brown  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*1fcced4cSJordan Brown  * Use is subject to license terms.
25*1fcced4cSJordan Brown  */
26*1fcced4cSJordan Brown 
27*1fcced4cSJordan Brown /*
28*1fcced4cSJordan Brown  * Much like calloc, but with functions to report the size of the
29*1fcced4cSJordan Brown  * allocation given only the pointer.
30*1fcced4cSJordan Brown  */
31*1fcced4cSJordan Brown 
32*1fcced4cSJordan Brown #include <assert.h>
33*1fcced4cSJordan Brown #include <string.h>
34*1fcced4cSJordan Brown #include <malloc.h>
35*1fcced4cSJordan Brown #include "sized_array.h"
36*1fcced4cSJordan Brown 
37*1fcced4cSJordan Brown /*
38*1fcced4cSJordan Brown  * Assumes that int is at least 32 bits and that nothing needs more than
39*1fcced4cSJordan Brown  * 8-byte alignment.
40*1fcced4cSJordan Brown  */
41*1fcced4cSJordan Brown 
42*1fcced4cSJordan Brown /* COOKIE provides some bad-pointer protection. */
43*1fcced4cSJordan Brown #define	COOKIE	"SACOOKIE"
44*1fcced4cSJordan Brown 
45*1fcced4cSJordan Brown struct sized_array {
46*1fcced4cSJordan Brown 	int	n;
47*1fcced4cSJordan Brown 	int	sz;
48*1fcced4cSJordan Brown #if	defined(COOKIE)
49*1fcced4cSJordan Brown 	char	cookie[8];
50*1fcced4cSJordan Brown #endif
51*1fcced4cSJordan Brown };
52*1fcced4cSJordan Brown 
53*1fcced4cSJordan Brown 
54*1fcced4cSJordan Brown void *
sized_array(size_t n,size_t sz)55*1fcced4cSJordan Brown sized_array(size_t n, size_t sz)
56*1fcced4cSJordan Brown {
57*1fcced4cSJordan Brown 	struct sized_array *sa;
58*1fcced4cSJordan Brown 	size_t total;
59*1fcced4cSJordan Brown 
60*1fcced4cSJordan Brown 	total = sizeof (struct sized_array) + n*sz;
61*1fcced4cSJordan Brown 
62*1fcced4cSJordan Brown 	sa = malloc(total);
63*1fcced4cSJordan Brown 
64*1fcced4cSJordan Brown 	if (sa == NULL)
65*1fcced4cSJordan Brown 		return (NULL);
66*1fcced4cSJordan Brown 
67*1fcced4cSJordan Brown 	(void) memset(sa, 0, total);
68*1fcced4cSJordan Brown 
69*1fcced4cSJordan Brown 	sa->n = n;
70*1fcced4cSJordan Brown 	sa->sz = sz;
71*1fcced4cSJordan Brown 
72*1fcced4cSJordan Brown #if	defined(COOKIE)
73*1fcced4cSJordan Brown 	(void) memcpy(sa->cookie, COOKIE, sizeof (sa->cookie));
74*1fcced4cSJordan Brown #endif
75*1fcced4cSJordan Brown 
76*1fcced4cSJordan Brown 	return ((void *)(sa + 1));
77*1fcced4cSJordan Brown }
78*1fcced4cSJordan Brown 
79*1fcced4cSJordan Brown void
sized_array_free(void * p)80*1fcced4cSJordan Brown sized_array_free(void *p)
81*1fcced4cSJordan Brown {
82*1fcced4cSJordan Brown 	struct sized_array *sa;
83*1fcced4cSJordan Brown 
84*1fcced4cSJordan Brown 	if (p == NULL)
85*1fcced4cSJordan Brown 		return;
86*1fcced4cSJordan Brown 
87*1fcced4cSJordan Brown 	sa = ((struct sized_array *)p)-1;
88*1fcced4cSJordan Brown 
89*1fcced4cSJordan Brown #if	defined(COOKIE)
90*1fcced4cSJordan Brown 	assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0);
91*1fcced4cSJordan Brown #endif
92*1fcced4cSJordan Brown 
93*1fcced4cSJordan Brown 	free(sa);
94*1fcced4cSJordan Brown }
95*1fcced4cSJordan Brown 
96*1fcced4cSJordan Brown size_t
sized_array_n(void * p)97*1fcced4cSJordan Brown sized_array_n(void *p)
98*1fcced4cSJordan Brown {
99*1fcced4cSJordan Brown 	struct sized_array *sa;
100*1fcced4cSJordan Brown 
101*1fcced4cSJordan Brown 	sa = ((struct sized_array *)p)-1;
102*1fcced4cSJordan Brown 
103*1fcced4cSJordan Brown #if	defined(COOKIE)
104*1fcced4cSJordan Brown 	assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0);
105*1fcced4cSJordan Brown #endif
106*1fcced4cSJordan Brown 
107*1fcced4cSJordan Brown 	return (sa->n);
108*1fcced4cSJordan Brown }
109*1fcced4cSJordan Brown 
110*1fcced4cSJordan Brown size_t
sized_array_sz(void * p)111*1fcced4cSJordan Brown sized_array_sz(void *p)
112*1fcced4cSJordan Brown {
113*1fcced4cSJordan Brown 	struct sized_array *sa;
114*1fcced4cSJordan Brown 
115*1fcced4cSJordan Brown 	sa = ((struct sized_array *)p)-1;
116*1fcced4cSJordan Brown 
117*1fcced4cSJordan Brown #if	defined(COOKIE)
118*1fcced4cSJordan Brown 	assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0);
119*1fcced4cSJordan Brown #endif
120*1fcced4cSJordan Brown 
121*1fcced4cSJordan Brown 	return (sa->sz);
122*1fcced4cSJordan Brown }
123