1*6b6d114aSBen Gras /* $NetBSD: prop_bool.c,v 1.17 2009/01/03 18:31:33 pooka Exp $ */
2*6b6d114aSBen Gras
3*6b6d114aSBen Gras /*-
4*6b6d114aSBen Gras * Copyright (c) 2006 The NetBSD Foundation, Inc.
5*6b6d114aSBen Gras * All rights reserved.
6*6b6d114aSBen Gras *
7*6b6d114aSBen Gras * This code is derived from software contributed to The NetBSD Foundation
8*6b6d114aSBen Gras * by Jason R. Thorpe.
9*6b6d114aSBen Gras *
10*6b6d114aSBen Gras * Redistribution and use in source and binary forms, with or without
11*6b6d114aSBen Gras * modification, are permitted provided that the following conditions
12*6b6d114aSBen Gras * are met:
13*6b6d114aSBen Gras * 1. Redistributions of source code must retain the above copyright
14*6b6d114aSBen Gras * notice, this list of conditions and the following disclaimer.
15*6b6d114aSBen Gras * 2. Redistributions in binary form must reproduce the above copyright
16*6b6d114aSBen Gras * notice, this list of conditions and the following disclaimer in the
17*6b6d114aSBen Gras * documentation and/or other materials provided with the distribution.
18*6b6d114aSBen Gras *
19*6b6d114aSBen Gras * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*6b6d114aSBen Gras * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*6b6d114aSBen Gras * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*6b6d114aSBen Gras * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*6b6d114aSBen Gras * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*6b6d114aSBen Gras * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*6b6d114aSBen Gras * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*6b6d114aSBen Gras * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*6b6d114aSBen Gras * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*6b6d114aSBen Gras * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*6b6d114aSBen Gras * POSSIBILITY OF SUCH DAMAGE.
30*6b6d114aSBen Gras */
31*6b6d114aSBen Gras
32*6b6d114aSBen Gras #include <prop/prop_bool.h>
33*6b6d114aSBen Gras #include "prop_object_impl.h"
34*6b6d114aSBen Gras
35*6b6d114aSBen Gras struct _prop_bool {
36*6b6d114aSBen Gras struct _prop_object pb_obj;
37*6b6d114aSBen Gras bool pb_value;
38*6b6d114aSBen Gras };
39*6b6d114aSBen Gras
40*6b6d114aSBen Gras static struct _prop_bool _prop_bool_true;
41*6b6d114aSBen Gras static struct _prop_bool _prop_bool_false;
42*6b6d114aSBen Gras
43*6b6d114aSBen Gras static _prop_object_free_rv_t
44*6b6d114aSBen Gras _prop_bool_free(prop_stack_t, prop_object_t *);
45*6b6d114aSBen Gras static bool _prop_bool_externalize(
46*6b6d114aSBen Gras struct _prop_object_externalize_context *,
47*6b6d114aSBen Gras void *);
48*6b6d114aSBen Gras static _prop_object_equals_rv_t
49*6b6d114aSBen Gras _prop_bool_equals(prop_object_t, prop_object_t,
50*6b6d114aSBen Gras void **, void **,
51*6b6d114aSBen Gras prop_object_t *, prop_object_t *);
52*6b6d114aSBen Gras
53*6b6d114aSBen Gras static const struct _prop_object_type _prop_object_type_bool = {
54*6b6d114aSBen Gras .pot_type = PROP_TYPE_BOOL,
55*6b6d114aSBen Gras .pot_free = _prop_bool_free,
56*6b6d114aSBen Gras .pot_extern = _prop_bool_externalize,
57*6b6d114aSBen Gras .pot_equals = _prop_bool_equals,
58*6b6d114aSBen Gras };
59*6b6d114aSBen Gras
60*6b6d114aSBen Gras #define prop_object_is_bool(x) \
61*6b6d114aSBen Gras ((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool)
62*6b6d114aSBen Gras
63*6b6d114aSBen Gras /* ARGSUSED */
64*6b6d114aSBen Gras static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t stack,prop_object_t * obj)65*6b6d114aSBen Gras _prop_bool_free(prop_stack_t stack, prop_object_t *obj)
66*6b6d114aSBen Gras {
67*6b6d114aSBen Gras /*
68*6b6d114aSBen Gras * This should never happen as we "leak" our initial reference
69*6b6d114aSBen Gras * count.
70*6b6d114aSBen Gras */
71*6b6d114aSBen Gras
72*6b6d114aSBen Gras /* XXX forced assertion failure? */
73*6b6d114aSBen Gras return (_PROP_OBJECT_FREE_DONE);
74*6b6d114aSBen Gras }
75*6b6d114aSBen Gras
76*6b6d114aSBen Gras static bool
_prop_bool_externalize(struct _prop_object_externalize_context * ctx,void * v)77*6b6d114aSBen Gras _prop_bool_externalize(struct _prop_object_externalize_context *ctx,
78*6b6d114aSBen Gras void *v)
79*6b6d114aSBen Gras {
80*6b6d114aSBen Gras prop_bool_t pb = v;
81*6b6d114aSBen Gras
82*6b6d114aSBen Gras return (_prop_object_externalize_empty_tag(ctx,
83*6b6d114aSBen Gras pb->pb_value ? "true" : "false"));
84*6b6d114aSBen Gras }
85*6b6d114aSBen Gras
86*6b6d114aSBen Gras /* ARGSUSED */
87*6b6d114aSBen Gras static _prop_object_equals_rv_t
_prop_bool_equals(prop_object_t v1,prop_object_t v2,void ** stored_pointer1,void ** stored_pointer2,prop_object_t * next_obj1,prop_object_t * next_obj2)88*6b6d114aSBen Gras _prop_bool_equals(prop_object_t v1, prop_object_t v2,
89*6b6d114aSBen Gras void **stored_pointer1, void **stored_pointer2,
90*6b6d114aSBen Gras prop_object_t *next_obj1, prop_object_t *next_obj2)
91*6b6d114aSBen Gras {
92*6b6d114aSBen Gras prop_bool_t b1 = v1;
93*6b6d114aSBen Gras prop_bool_t b2 = v2;
94*6b6d114aSBen Gras
95*6b6d114aSBen Gras if (! (prop_object_is_bool(b1) &&
96*6b6d114aSBen Gras prop_object_is_bool(b2)))
97*6b6d114aSBen Gras return (_PROP_OBJECT_EQUALS_FALSE);
98*6b6d114aSBen Gras
99*6b6d114aSBen Gras /*
100*6b6d114aSBen Gras * Since we only ever allocate one true and one false,
101*6b6d114aSBen Gras * save ourselves a couple of memory operations.
102*6b6d114aSBen Gras */
103*6b6d114aSBen Gras if (b1 == b2)
104*6b6d114aSBen Gras return (_PROP_OBJECT_EQUALS_TRUE);
105*6b6d114aSBen Gras else
106*6b6d114aSBen Gras return (_PROP_OBJECT_EQUALS_FALSE);
107*6b6d114aSBen Gras }
108*6b6d114aSBen Gras
_PROP_ONCE_DECL(_prop_bool_init_once)109*6b6d114aSBen Gras _PROP_ONCE_DECL(_prop_bool_init_once)
110*6b6d114aSBen Gras
111*6b6d114aSBen Gras static int
112*6b6d114aSBen Gras _prop_bool_init(void)
113*6b6d114aSBen Gras {
114*6b6d114aSBen Gras
115*6b6d114aSBen Gras _prop_object_init(&_prop_bool_true.pb_obj,
116*6b6d114aSBen Gras &_prop_object_type_bool);
117*6b6d114aSBen Gras _prop_bool_true.pb_value = true;
118*6b6d114aSBen Gras
119*6b6d114aSBen Gras _prop_object_init(&_prop_bool_false.pb_obj,
120*6b6d114aSBen Gras &_prop_object_type_bool);
121*6b6d114aSBen Gras _prop_bool_false.pb_value = false;
122*6b6d114aSBen Gras
123*6b6d114aSBen Gras return 0;
124*6b6d114aSBen Gras }
125*6b6d114aSBen Gras
126*6b6d114aSBen Gras static prop_bool_t
_prop_bool_alloc(bool val)127*6b6d114aSBen Gras _prop_bool_alloc(bool val)
128*6b6d114aSBen Gras {
129*6b6d114aSBen Gras prop_bool_t pb;
130*6b6d114aSBen Gras
131*6b6d114aSBen Gras _PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
132*6b6d114aSBen Gras pb = val ? &_prop_bool_true : &_prop_bool_false;
133*6b6d114aSBen Gras prop_object_retain(pb);
134*6b6d114aSBen Gras
135*6b6d114aSBen Gras return (pb);
136*6b6d114aSBen Gras }
137*6b6d114aSBen Gras
138*6b6d114aSBen Gras /*
139*6b6d114aSBen Gras * prop_bool_create --
140*6b6d114aSBen Gras * Create a prop_bool_t and initialize it with the
141*6b6d114aSBen Gras * provided boolean value.
142*6b6d114aSBen Gras */
143*6b6d114aSBen Gras prop_bool_t
prop_bool_create(bool val)144*6b6d114aSBen Gras prop_bool_create(bool val)
145*6b6d114aSBen Gras {
146*6b6d114aSBen Gras
147*6b6d114aSBen Gras return (_prop_bool_alloc(val));
148*6b6d114aSBen Gras }
149*6b6d114aSBen Gras
150*6b6d114aSBen Gras /*
151*6b6d114aSBen Gras * prop_bool_copy --
152*6b6d114aSBen Gras * Copy a prop_bool_t.
153*6b6d114aSBen Gras */
154*6b6d114aSBen Gras prop_bool_t
prop_bool_copy(prop_bool_t opb)155*6b6d114aSBen Gras prop_bool_copy(prop_bool_t opb)
156*6b6d114aSBen Gras {
157*6b6d114aSBen Gras
158*6b6d114aSBen Gras if (! prop_object_is_bool(opb))
159*6b6d114aSBen Gras return (NULL);
160*6b6d114aSBen Gras
161*6b6d114aSBen Gras /*
162*6b6d114aSBen Gras * Because we only ever allocate one true and one false, this
163*6b6d114aSBen Gras * can be reduced to a simple retain operation.
164*6b6d114aSBen Gras */
165*6b6d114aSBen Gras prop_object_retain(opb);
166*6b6d114aSBen Gras return (opb);
167*6b6d114aSBen Gras }
168*6b6d114aSBen Gras
169*6b6d114aSBen Gras /*
170*6b6d114aSBen Gras * prop_bool_true --
171*6b6d114aSBen Gras * Get the value of a prop_bool_t.
172*6b6d114aSBen Gras */
173*6b6d114aSBen Gras bool
prop_bool_true(prop_bool_t pb)174*6b6d114aSBen Gras prop_bool_true(prop_bool_t pb)
175*6b6d114aSBen Gras {
176*6b6d114aSBen Gras
177*6b6d114aSBen Gras if (! prop_object_is_bool(pb))
178*6b6d114aSBen Gras return (false);
179*6b6d114aSBen Gras
180*6b6d114aSBen Gras return (pb->pb_value);
181*6b6d114aSBen Gras }
182*6b6d114aSBen Gras
183*6b6d114aSBen Gras /*
184*6b6d114aSBen Gras * prop_bool_equals --
185*6b6d114aSBen Gras * Return true if the boolean values are equivalent.
186*6b6d114aSBen Gras */
187*6b6d114aSBen Gras bool
prop_bool_equals(prop_bool_t b1,prop_bool_t b2)188*6b6d114aSBen Gras prop_bool_equals(prop_bool_t b1, prop_bool_t b2)
189*6b6d114aSBen Gras {
190*6b6d114aSBen Gras if (!prop_object_is_bool(b1) || !prop_object_is_bool(b2))
191*6b6d114aSBen Gras return (false);
192*6b6d114aSBen Gras
193*6b6d114aSBen Gras return (prop_object_equals(b1, b2));
194*6b6d114aSBen Gras }
195*6b6d114aSBen Gras
196*6b6d114aSBen Gras /*
197*6b6d114aSBen Gras * _prop_bool_internalize --
198*6b6d114aSBen Gras * Parse a <true/> or <false/> and return the object created from
199*6b6d114aSBen Gras * the external representation.
200*6b6d114aSBen Gras */
201*6b6d114aSBen Gras
202*6b6d114aSBen Gras /* ARGSUSED */
203*6b6d114aSBen Gras bool
_prop_bool_internalize(prop_stack_t stack,prop_object_t * obj,struct _prop_object_internalize_context * ctx)204*6b6d114aSBen Gras _prop_bool_internalize(prop_stack_t stack, prop_object_t *obj,
205*6b6d114aSBen Gras struct _prop_object_internalize_context *ctx)
206*6b6d114aSBen Gras {
207*6b6d114aSBen Gras bool val;
208*6b6d114aSBen Gras
209*6b6d114aSBen Gras /* No attributes, and it must be an empty element. */
210*6b6d114aSBen Gras if (ctx->poic_tagattr != NULL ||
211*6b6d114aSBen Gras ctx->poic_is_empty_element == false)
212*6b6d114aSBen Gras return (true);
213*6b6d114aSBen Gras
214*6b6d114aSBen Gras if (_PROP_TAG_MATCH(ctx, "true"))
215*6b6d114aSBen Gras val = true;
216*6b6d114aSBen Gras else {
217*6b6d114aSBen Gras _PROP_ASSERT(_PROP_TAG_MATCH(ctx, "false"));
218*6b6d114aSBen Gras val = false;
219*6b6d114aSBen Gras }
220*6b6d114aSBen Gras *obj = prop_bool_create(val);
221*6b6d114aSBen Gras return (true);
222*6b6d114aSBen Gras }
223