Home | History | Annotate | Line # | Download | only in libprop
prop_number.c revision 1.1
      1 /*	$NetBSD: prop_number.c,v 1.1 2006/04/27 20:11:27 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *      This product includes software developed by the NetBSD
     21  *      Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <prop/prop_number.h>
     40 #include "prop_object_impl.h"
     41 
     42 #if defined(_KERNEL)
     43 #include <sys/inttypes.h>
     44 #include <sys/systm.h>
     45 #elif defined(_STANDALONE)
     46 #include <sys/param.h>
     47 #include <lib/libkern/libkern.h>
     48 #else
     49 #include <errno.h>
     50 #include <stdlib.h>
     51 #include <inttypes.h>
     52 #endif
     53 
     54 struct _prop_number {
     55 	struct _prop_object	pn_obj;
     56 	uintmax_t		pn_number;
     57 };
     58 
     59 _PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
     60 
     61 #define	prop_object_is_number(x) ((x)->pn_obj.po_type == PROP_TYPE_NUMBER)
     62 
     63 static void
     64 _prop_number_free(void *v)
     65 {
     66 
     67 	_PROP_POOL_PUT(_prop_number_pool, v);
     68 }
     69 
     70 static boolean_t
     71 _prop_number_externalize(struct _prop_object_externalize_context *ctx,
     72 			 void *v)
     73 {
     74 	prop_number_t pn = v;
     75 	char tmpstr[32];
     76 
     77 	sprintf(tmpstr, "0x%" PRIxMAX, pn->pn_number);
     78 
     79 	if (_prop_object_externalize_start_tag(ctx, "integer") == FALSE ||
     80 	    _prop_object_externalize_append_cstring(ctx, tmpstr) == FALSE ||
     81 	    _prop_object_externalize_end_tag(ctx, "integer") == FALSE)
     82 		return (FALSE);
     83 
     84 	return (TRUE);
     85 }
     86 
     87 static prop_number_t
     88 _prop_number_alloc(uintmax_t val)
     89 {
     90 	prop_number_t pn;
     91 
     92 	pn = _PROP_POOL_GET(_prop_number_pool);
     93 	if (pn != NULL) {
     94 		_prop_object_init(&pn->pn_obj);
     95 		pn->pn_obj.po_type = PROP_TYPE_NUMBER;
     96 		pn->pn_obj.po_free = _prop_number_free;
     97 		pn->pn_obj.po_extern = _prop_number_externalize;
     98 
     99 		pn->pn_number = val;
    100 	}
    101 
    102 	return (pn);
    103 }
    104 
    105 /*
    106  * prop_number_create_integer --
    107  *	Create a prop_number_t and initialize it with the
    108  *	provided integer value.
    109  */
    110 prop_number_t
    111 prop_number_create_integer(uintmax_t val)
    112 {
    113 
    114 	return (_prop_number_alloc(val));
    115 }
    116 
    117 /*
    118  * prop_number_copy --
    119  *	Copy a prop_number_t.
    120  */
    121 prop_number_t
    122 prop_number_copy(prop_number_t opn)
    123 {
    124 
    125 	_PROP_ASSERT(prop_object_is_number(opn));
    126 
    127 	return (_prop_number_alloc(opn->pn_number));
    128 }
    129 
    130 /*
    131  * prop_number_size --
    132  *	Return the size, in bits, required to hold the value of
    133  *	the specified number.
    134  */
    135 int
    136 prop_number_size(prop_number_t pn)
    137 {
    138 
    139 	_PROP_ASSERT(prop_object_is_number(pn));
    140 	if (pn->pn_number > UINT32_MAX)
    141 		return (64);
    142 	if (pn->pn_number > UINT16_MAX)
    143 		return (32);
    144 	if (pn->pn_number > UINT8_MAX)
    145 		return (16);
    146 	return (8);
    147 }
    148 
    149 /*
    150  * prop_number_integer_value --
    151  *	Get the integer value of a prop_number_t.
    152  */
    153 uintmax_t
    154 prop_number_integer_value(prop_number_t pn)
    155 {
    156 
    157 	_PROP_ASSERT(prop_object_is_number(pn));
    158 	return (pn->pn_number);
    159 }
    160 
    161 /*
    162  * prop_number_equals --
    163  *	Return TRUE if two numbers are equivalent.
    164  */
    165 boolean_t
    166 prop_number_equals(prop_number_t num1, prop_number_t num2)
    167 {
    168 
    169 	_PROP_ASSERT(prop_object_is_number(num1));
    170 	_PROP_ASSERT(prop_object_is_number(num2));
    171 	return (num1->pn_number == num2->pn_number);
    172 }
    173 
    174 /*
    175  * prop_number_equals_integer --
    176  *	Return TRUE if the number is equivalent to the specified integer.
    177  */
    178 boolean_t
    179 prop_number_equals_integer(prop_number_t pn, uintmax_t val)
    180 {
    181 
    182 	_PROP_ASSERT(prop_object_is_number(pn));
    183 	return (pn->pn_number == val);
    184 }
    185 
    186 /*
    187  * _prop_number_internalize --
    188  *	Parse a <number>...</number> and return the object created from
    189  *	the external representation.
    190  */
    191 prop_object_t
    192 _prop_number_internalize(struct _prop_object_internalize_context *ctx)
    193 {
    194 	uintmax_t val = 0;
    195 	char *cp;
    196 
    197 	/* No attributes, no empty elements. */
    198 	if (ctx->poic_tagattr != NULL || ctx->poic_is_empty_element)
    199 		return (NULL);
    200 
    201 #ifndef _KERNEL
    202 	errno = 0;
    203 #endif
    204 	val = strtoumax(ctx->poic_cp, &cp, 0);
    205 #ifndef _KERNEL		/* XXX can't check for ERANGE in the kernel */
    206 	if (val == UINTMAX_MAX && errno == ERANGE)
    207 		return (NULL);
    208 #endif
    209 	ctx->poic_cp = cp;
    210 
    211 	if (_prop_object_internalize_find_tag(ctx, "integer",
    212 					      _PROP_TAG_TYPE_END) == FALSE)
    213 		return (NULL);
    214 
    215 	return (_prop_number_alloc(val));
    216 }
    217