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