prop_dictionary_util.c revision 1.8
1/*	$NetBSD: prop_dictionary_util.c,v 1.8 2020/06/15 00:46:00 christos Exp $	*/
2
3/*-
4 * Copyright (c) 2006, 2020 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 *
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.
30 */
31
32/*
33 * Utility routines to make it more convenient to work with values
34 * stored in dictionaries.
35 *
36 * Note: There is no special magic going on here.  We use the standard
37 * proplib(3) APIs to do all of this work.  Any application could do
38 * exactly what we're doing here.
39 */
40
41#include "prop_object_impl.h"	/* only to hide kernel vs. not-kernel */
42#include <prop/proplib.h>
43
44bool
45prop_dictionary_get_dict(prop_dictionary_t dict, const char *key,
46			 prop_dictionary_t *dp)
47{
48	prop_object_t o;
49
50	o = prop_dictionary_get(dict, key);
51	if (prop_object_type(o) != PROP_TYPE_DICTIONARY)
52		return false;
53	*dp = o;
54	return true;
55
56}
57
58bool
59prop_dictionary_get_bool(prop_dictionary_t dict, const char *key, bool *valp)
60{
61	prop_bool_t b;
62
63	b = prop_dictionary_get(dict, key);
64	if (prop_object_type(b) != PROP_TYPE_BOOL)
65		return (false);
66
67	*valp = prop_bool_true(b);
68
69	return (true);
70}
71
72bool
73prop_dictionary_set_bool(prop_dictionary_t dict, const char *key, bool val)
74{
75
76	return prop_dictionary_set_and_rel(dict, key, prop_bool_create(val));
77}
78
79#define	TEMPLATE(name, typ)						\
80bool									\
81prop_dictionary_get_ ## name (prop_dictionary_t dict,			\
82			      const char *key,				\
83			      typ *valp)				\
84{									\
85	return prop_number_ ## name ## _value(				\
86	    prop_dictionary_get(dict, key), valp);			\
87}
88TEMPLATE(schar,    signed char)
89TEMPLATE(short,    short)
90TEMPLATE(int,      int)
91TEMPLATE(long,     long)
92TEMPLATE(longlong, long long)
93TEMPLATE(intptr,   intptr_t)
94TEMPLATE(int8,     int8_t)
95TEMPLATE(int16,    int16_t)
96TEMPLATE(int32,    int32_t)
97TEMPLATE(int64,    int64_t)
98
99TEMPLATE(uchar,     unsigned char)
100TEMPLATE(ushort,    unsigned short)
101TEMPLATE(uint,      unsigned int)
102TEMPLATE(ulong,     unsigned long)
103TEMPLATE(ulonglong, unsigned long long)
104TEMPLATE(uintptr,   uintptr_t)
105TEMPLATE(uint8,     uint8_t)
106TEMPLATE(uint16,    uint16_t)
107TEMPLATE(uint32,    uint32_t)
108TEMPLATE(uint64,    uint64_t)
109
110#undef TEMPLATE
111
112static bool
113prop_dictionary_set_signed_number(prop_dictionary_t dict, const char *key,
114				  intmax_t val)
115{
116	return prop_dictionary_set_and_rel(dict, key,
117					   prop_number_create_signed(val));
118}
119
120static bool
121prop_dictionary_set_unsigned_number(prop_dictionary_t dict, const char *key,
122				    uintmax_t val)
123{
124	/*LINTED: for conversion from 'long long' to 'long'*/		\
125	return prop_dictionary_set_and_rel(dict, key,
126					   prop_number_create_unsigned(val));
127}
128
129#define	TEMPLATE(name, which, typ)					\
130bool									\
131prop_dictionary_set_ ## name (prop_dictionary_t dict,			\
132			      const char *key,				\
133			      typ val)					\
134{									\
135	/*LINTED: for conversion from long long to 'long'*/		\
136	return prop_dictionary_set_ ## which ## _number(dict, key, val);\
137}
138
139#define	STEMPLATE(name, typ)	TEMPLATE(name, signed, typ)
140#define	UTEMPLATE(name, typ)	TEMPLATE(name, unsigned, typ)
141
142STEMPLATE(schar,    signed char)
143STEMPLATE(short,    short)
144STEMPLATE(int,      int)
145STEMPLATE(long,     long)
146STEMPLATE(longlong, long long)
147STEMPLATE(intptr,   intptr_t)
148STEMPLATE(int8,     int8_t)
149STEMPLATE(int16,    int16_t)
150STEMPLATE(int32,    int32_t)
151STEMPLATE(int64,    int64_t)
152
153UTEMPLATE(uchar,     unsigned char)
154UTEMPLATE(ushort,    unsigned short)
155UTEMPLATE(uint,      unsigned int)
156UTEMPLATE(ulong,     unsigned long)
157UTEMPLATE(ulonglong, unsigned long long)
158UTEMPLATE(uintptr,   uintptr_t)
159UTEMPLATE(uint8,     uint8_t)
160UTEMPLATE(uint16,    uint16_t)
161UTEMPLATE(uint32,    uint32_t)
162UTEMPLATE(uint64,    uint64_t)
163
164#undef STEMPLATE
165#undef UTEMPLATE
166#undef TEMPLATE
167
168bool
169prop_dictionary_get_string(prop_dictionary_t dict, const char *key,
170			   const char **cpp)
171{
172	prop_string_t str;
173	const char *cp;
174
175	str = prop_dictionary_get(dict, key);
176	if (prop_object_type(str) != PROP_TYPE_STRING)
177		return (false);
178
179	cp = prop_string_value(str);
180	if (cp == NULL)
181		return (false);
182
183	*cpp = cp;
184	return (true);
185}
186
187bool
188prop_dictionary_set_string(prop_dictionary_t dict, const char *key,
189			   const char *cp)
190{
191	return prop_dictionary_set_and_rel(dict, key,
192					   prop_string_create_copy(cp));
193}
194
195bool
196prop_dictionary_set_string_nocopy(prop_dictionary_t dict,
197				  const char *key,
198				  const char *cp)
199{
200	return prop_dictionary_set_and_rel(dict, key,
201					   prop_string_create_nocopy(cp));
202}
203
204bool
205prop_dictionary_get_data(prop_dictionary_t dict, const char *key,
206			 const void **vp, size_t *sizep)
207{
208	prop_data_t data;
209	const void *v;
210
211	data = prop_dictionary_get(dict, key);
212	if (prop_object_type(data) != PROP_TYPE_DATA)
213		return (false);
214
215	v = prop_data_value(data);
216	if (v == NULL)
217		return (false);
218
219	*vp = v;
220	if (sizep != NULL)
221		*sizep = prop_data_size(data);
222	return (true);
223}
224
225bool
226prop_dictionary_set_data(prop_dictionary_t dict, const char *key,
227			 const void *v, size_t size)
228{
229	return prop_dictionary_set_and_rel(dict, key,
230					   prop_data_create_copy(v, size));
231}
232
233bool
234prop_dictionary_set_data_nocopy(prop_dictionary_t dict, const char *key,
235			        const void *v, size_t size)
236{
237	return prop_dictionary_set_and_rel(dict, key,
238					   prop_data_create_nocopy(v, size));
239}
240
241_PROP_DEPRECATED(prop_dictionary_get_cstring,
242    "this program uses prop_dictionary_get_cstring(), "
243    "which is deprecated; use prop_dictionary_get_string() and copy instead.")
244bool
245prop_dictionary_get_cstring(prop_dictionary_t dict,
246			    const char *key,
247			    char **cpp)
248{
249	prop_string_t str;
250	char *cp;
251	size_t len;
252	bool rv;
253
254	str = prop_dictionary_get(dict, key);
255	if (prop_object_type(str) != PROP_TYPE_STRING)
256		return (false);
257
258	len = prop_string_size(str);
259	cp = _PROP_MALLOC(len + 1, M_TEMP);
260	if (cp == NULL)
261		return (false);
262
263	rv = prop_string_copy_value(str, cp, len + 1);
264	if (rv)
265		*cpp = cp;
266	else
267		_PROP_FREE(cp, M_TEMP);
268
269	return (rv);
270}
271
272_PROP_DEPRECATED(prop_string_get_cstring_nocopy,
273    "this program uses prop_string_get_cstring_nocopy(), "
274    "which is deprecated; use prop_dictionary_get_string() instead.")
275bool
276prop_dictionary_get_cstring_nocopy(prop_dictionary_t dict,
277				   const char *key,
278				   const char **cpp)
279{
280	return prop_dictionary_get_string(dict, key, cpp);
281}
282
283_PROP_DEPRECATED(prop_dictionary_set_cstring,
284    "this program uses prop_dictionary_set_cstring(), "
285    "which is deprecated; use prop_dictionary_set_string() instead.")
286bool
287prop_dictionary_set_cstring(prop_dictionary_t dict,
288			    const char *key,
289			    const char *cp)
290{
291	return prop_dictionary_set_string(dict, key, cp);
292}
293
294_PROP_DEPRECATED(prop_dictionary_set_cstring_nocopy,
295    "this program uses prop_dictionary_set_cstring_nocopy(), "
296    "which is deprecated; use prop_dictionary_set_string_nocopy() instead.")
297bool
298prop_dictionary_set_cstring_nocopy(prop_dictionary_t dict,
299				   const char *key,
300				   const char *cp)
301{
302	return prop_dictionary_set_string_nocopy(dict, key, cp);
303}
304
305bool
306prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
307			    prop_object_t po)
308{
309	bool rv;
310
311	if (po == NULL)
312		return false;
313	rv = prop_dictionary_set(dict, key, po);
314	prop_object_release(po);
315	return rv;
316}
317