/* $NetBSD: prop_bool.c,v 1.9 2006/10/16 03:21:07 thorpej Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "prop_object_impl.h" struct _prop_bool { struct _prop_object pb_obj; boolean_t pb_value; }; static struct _prop_bool _prop_bool_true; static struct _prop_bool _prop_bool_false; _PROP_MUTEX_DECL_STATIC(_prop_bool_initialized_mutex) static boolean_t _prop_bool_initialized; static void _prop_bool_free(void *); static boolean_t _prop_bool_equals(void *, void *); static const struct _prop_object_type _prop_object_type_bool = { .pot_type = PROP_TYPE_BOOL, .pot_free = _prop_bool_free, .pot_equals = _prop_bool_equals, }; #define prop_object_is_bool(x) \ ((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool) static void /*ARGSUSED*/ _prop_bool_free(void *v _PROP_ARG_UNUSED) { /* * This should never happen as we "leak" our initial reference * count. */ /* XXX forced assertion failure? */ } static boolean_t _prop_bool_equals(void *v1, void *v2) { prop_bool_t b1 = v1; prop_bool_t b2 = v2; if (! (prop_object_is_bool(b1) && prop_object_is_bool(b2))) return (FALSE); /* * Since we only ever allocate one true and one false, * save ourselves a couple of memory operations. */ return (b1 == b2); } static prop_bool_t _prop_bool_alloc(boolean_t val) { prop_bool_t pb; if (! _prop_bool_initialized) { _PROP_MUTEX_LOCK(_prop_bool_initialized_mutex); if (! _prop_bool_initialized) { _prop_object_init(&_prop_bool_true.pb_obj, &_prop_object_type_bool); _prop_bool_true.pb_value = TRUE; _prop_object_init(&_prop_bool_false.pb_obj, &_prop_object_type_bool); _prop_bool_false.pb_value = FALSE; _prop_bool_initialized = TRUE; } _PROP_MUTEX_UNLOCK(_prop_bool_initialized_mutex); } pb = val ? &_prop_bool_true : &_prop_bool_false; prop_object_retain(pb); return (pb); } /* * prop_bool_create -- * Create a prop_bool_t and initialize it with the * provided boolean value. */ prop_bool_t prop_bool_create(boolean_t val) { return (_prop_bool_alloc(val)); } /* * prop_bool_copy -- * Copy a prop_bool_t. */ prop_bool_t prop_bool_copy(prop_bool_t opb) { if (! prop_object_is_bool(opb)) return (NULL); /* * Because we only ever allocate one true and one false, this * can be reduced to a simple retain operation. */ prop_object_retain(opb); return (opb); } /* * prop_bool_true -- * Get the value of a prop_bool_t. */ boolean_t prop_bool_true(prop_bool_t pb) { if (! prop_object_is_bool(pb)) return (FALSE); return (pb->pb_value); } /* * prop_bool_equals -- * Return TRUE if the boolean values are equivalent. */ boolean_t prop_bool_equals(prop_bool_t b1, prop_bool_t b2) { return (_prop_bool_equals(b1, b2)); }