11fcced4Jordan Brown/*
21fcced4Jordan Brown * CDDL HEADER START
31fcced4Jordan Brown *
41fcced4Jordan Brown * The contents of this file are subject to the terms of the
51fcced4Jordan Brown * Common Development and Distribution License (the "License").
61fcced4Jordan Brown * You may not use this file except in compliance with the License.
71fcced4Jordan Brown *
81fcced4Jordan Brown * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91fcced4Jordan Brown * or http://www.opensolaris.org/os/licensing.
101fcced4Jordan Brown * See the License for the specific language governing permissions
111fcced4Jordan Brown * and limitations under the License.
121fcced4Jordan Brown *
131fcced4Jordan Brown * When distributing Covered Code, include this CDDL HEADER in each
141fcced4Jordan Brown * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151fcced4Jordan Brown * If applicable, add the following below this CDDL HEADER, with the
161fcced4Jordan Brown * fields enclosed by brackets "[]" replaced with your own identifying
171fcced4Jordan Brown * information: Portions Copyright [yyyy] [name of copyright owner]
181fcced4Jordan Brown *
191fcced4Jordan Brown * CDDL HEADER END
201fcced4Jordan Brown */
211fcced4Jordan Brown
221fcced4Jordan Brown/*
231fcced4Jordan Brown * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
241fcced4Jordan Brown * Use is subject to license terms.
251fcced4Jordan Brown */
261fcced4Jordan Brown
271fcced4Jordan Brown/*
281fcced4Jordan Brown * Much like calloc, but with functions to report the size of the
291fcced4Jordan Brown * allocation given only the pointer.
301fcced4Jordan Brown */
311fcced4Jordan Brown
321fcced4Jordan Brown#include <assert.h>
331fcced4Jordan Brown#include <string.h>
341fcced4Jordan Brown#include <malloc.h>
351fcced4Jordan Brown#include "sized_array.h"
361fcced4Jordan Brown
371fcced4Jordan Brown/*
381fcced4Jordan Brown * Assumes that int is at least 32 bits and that nothing needs more than
391fcced4Jordan Brown * 8-byte alignment.
401fcced4Jordan Brown */
411fcced4Jordan Brown
421fcced4Jordan Brown/* COOKIE provides some bad-pointer protection. */
431fcced4Jordan Brown#define	COOKIE	"SACOOKIE"
441fcced4Jordan Brown
451fcced4Jordan Brownstruct sized_array {
461fcced4Jordan Brown	int	n;
471fcced4Jordan Brown	int	sz;
481fcced4Jordan Brown#if	defined(COOKIE)
491fcced4Jordan Brown	char	cookie[8];
501fcced4Jordan Brown#endif
511fcced4Jordan Brown};
521fcced4Jordan Brown
531fcced4Jordan Brown
541fcced4Jordan Brownvoid *
551fcced4Jordan Brownsized_array(size_t n, size_t sz)
561fcced4Jordan Brown{
571fcced4Jordan Brown	struct sized_array *sa;
581fcced4Jordan Brown	size_t total;
591fcced4Jordan Brown
601fcced4Jordan Brown	total = sizeof (struct sized_array) + n*sz;
611fcced4Jordan Brown
621fcced4Jordan Brown	sa = malloc(total);
631fcced4Jordan Brown
641fcced4Jordan Brown	if (sa == NULL)
651fcced4Jordan Brown		return (NULL);
661fcced4Jordan Brown
671fcced4Jordan Brown	(void) memset(sa, 0, total);
681fcced4Jordan Brown
691fcced4Jordan Brown	sa->n = n;
701fcced4Jordan Brown	sa->sz = sz;
711fcced4Jordan Brown
721fcced4Jordan Brown#if	defined(COOKIE)
731fcced4Jordan Brown	(void) memcpy(sa->cookie, COOKIE, sizeof (sa->cookie));
741fcced4Jordan Brown#endif
751fcced4Jordan Brown
761fcced4Jordan Brown	return ((void *)(sa + 1));
771fcced4Jordan Brown}
781fcced4Jordan Brown
791fcced4Jordan Brownvoid
801fcced4Jordan Brownsized_array_free(void *p)
811fcced4Jordan Brown{
821fcced4Jordan Brown	struct sized_array *sa;
831fcced4Jordan Brown
841fcced4Jordan Brown	if (p == NULL)
851fcced4Jordan Brown		return;
861fcced4Jordan Brown
871fcced4Jordan Brown	sa = ((struct sized_array *)p)-1;
881fcced4Jordan Brown
891fcced4Jordan Brown#if	defined(COOKIE)
901fcced4Jordan Brown	assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0);
911fcced4Jordan Brown#endif
921fcced4Jordan Brown
931fcced4Jordan Brown	free(sa);
941fcced4Jordan Brown}
951fcced4Jordan Brown
961fcced4Jordan Brownsize_t
971fcced4Jordan Brownsized_array_n(void *p)
981fcced4Jordan Brown{
991fcced4Jordan Brown	struct sized_array *sa;
1001fcced4Jordan Brown
1011fcced4Jordan Brown	sa = ((struct sized_array *)p)-1;
1021fcced4Jordan Brown
1031fcced4Jordan Brown#if	defined(COOKIE)
1041fcced4Jordan Brown	assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0);
1051fcced4Jordan Brown#endif
1061fcced4Jordan Brown
1071fcced4Jordan Brown	return (sa->n);
1081fcced4Jordan Brown}
1091fcced4Jordan Brown
1101fcced4Jordan Brownsize_t
1111fcced4Jordan Brownsized_array_sz(void *p)
1121fcced4Jordan Brown{
1131fcced4Jordan Brown	struct sized_array *sa;
1141fcced4Jordan Brown
1151fcced4Jordan Brown	sa = ((struct sized_array *)p)-1;
1161fcced4Jordan Brown
1171fcced4Jordan Brown#if	defined(COOKIE)
1181fcced4Jordan Brown	assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0);
1191fcced4Jordan Brown#endif
1201fcced4Jordan Brown
1211fcced4Jordan Brown	return (sa->sz);
1221fcced4Jordan Brown}