1 /* $NetBSD: prop_bool.c,v 1.16 2008/08/03 04:00:12 thorpej Exp $ */
4 * Copyright (c) 2006 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <prop/prop_bool.h>
33 #include "prop_object_impl.h"
36 struct _prop_object pb_obj
;
40 static struct _prop_bool _prop_bool_true
;
41 static struct _prop_bool _prop_bool_false
;
43 _PROP_MUTEX_DECL_STATIC(_prop_bool_initialized_mutex
)
44 static bool _prop_bool_initialized
;
46 static _prop_object_free_rv_t
47 _prop_bool_free(prop_stack_t
, prop_object_t
*);
48 static bool _prop_bool_externalize(
49 struct _prop_object_externalize_context
*,
51 static _prop_object_equals_rv_t
52 _prop_bool_equals(prop_object_t
, prop_object_t
,
54 prop_object_t
*, prop_object_t
*);
56 static const struct _prop_object_type _prop_object_type_bool
= {
57 .pot_type
= PROP_TYPE_BOOL
,
58 .pot_free
= _prop_bool_free
,
59 .pot_extern
= _prop_bool_externalize
,
60 .pot_equals
= _prop_bool_equals
,
63 #define prop_object_is_bool(x) \
64 ((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool)
67 static _prop_object_free_rv_t
68 _prop_bool_free(prop_stack_t stack
, prop_object_t
*obj
)
71 * This should never happen as we "leak" our initial reference
75 /* XXX forced assertion failure? */
76 return (_PROP_OBJECT_FREE_DONE
);
80 _prop_bool_externalize(struct _prop_object_externalize_context
*ctx
,
85 return (_prop_object_externalize_empty_tag(ctx
,
86 pb
->pb_value
? "true" : "false"));
90 static _prop_object_equals_rv_t
91 _prop_bool_equals(prop_object_t v1
, prop_object_t v2
,
92 void **stored_pointer1
, void **stored_pointer2
,
93 prop_object_t
*next_obj1
, prop_object_t
*next_obj2
)
98 if (! (prop_object_is_bool(b1
) &&
99 prop_object_is_bool(b2
)))
100 return (_PROP_OBJECT_EQUALS_FALSE
);
103 * Since we only ever allocate one true and one false,
104 * save ourselves a couple of memory operations.
107 return (_PROP_OBJECT_EQUALS_TRUE
);
109 return (_PROP_OBJECT_EQUALS_FALSE
);
113 _prop_bool_alloc(bool val
)
117 if (! _prop_bool_initialized
) {
118 _PROP_MUTEX_LOCK(_prop_bool_initialized_mutex
);
119 if (! _prop_bool_initialized
) {
120 _prop_object_init(&_prop_bool_true
.pb_obj
,
121 &_prop_object_type_bool
);
122 _prop_bool_true
.pb_value
= true;
124 _prop_object_init(&_prop_bool_false
.pb_obj
,
125 &_prop_object_type_bool
);
126 _prop_bool_false
.pb_value
= false;
128 _prop_bool_initialized
= true;
130 _PROP_MUTEX_UNLOCK(_prop_bool_initialized_mutex
);
133 pb
= val
? &_prop_bool_true
: &_prop_bool_false
;
134 prop_object_retain(pb
);
140 * prop_bool_create --
141 * Create a prop_bool_t and initialize it with the
142 * provided boolean value.
145 prop_bool_create(bool val
)
148 return (_prop_bool_alloc(val
));
153 * Copy a prop_bool_t.
156 prop_bool_copy(prop_bool_t opb
)
159 if (! prop_object_is_bool(opb
))
163 * Because we only ever allocate one true and one false, this
164 * can be reduced to a simple retain operation.
166 prop_object_retain(opb
);
172 * Get the value of a prop_bool_t.
175 prop_bool_true(prop_bool_t pb
)
178 if (! prop_object_is_bool(pb
))
181 return (pb
->pb_value
);
185 * prop_bool_equals --
186 * Return true if the boolean values are equivalent.
189 prop_bool_equals(prop_bool_t b1
, prop_bool_t b2
)
191 if (!prop_object_is_bool(b1
) || !prop_object_is_bool(b2
))
194 return (prop_object_equals(b1
, b2
));
198 * _prop_bool_internalize --
199 * Parse a <true/> or <false/> and return the object created from
200 * the external representation.
205 _prop_bool_internalize(prop_stack_t stack
, prop_object_t
*obj
,
206 struct _prop_object_internalize_context
*ctx
)
210 /* No attributes, and it must be an empty element. */
211 if (ctx
->poic_tagattr
!= NULL
||
212 ctx
->poic_is_empty_element
== false)
215 if (_PROP_TAG_MATCH(ctx
, "true"))
218 _PROP_ASSERT(_PROP_TAG_MATCH(ctx
, "false"));
221 *obj
= prop_bool_create(val
);