prop_dictionary_util.c revision 1.7
1/*	$NetBSD: prop_dictionary_util.c,v 1.7 2020/06/14 21:31:01 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)
157/*###155 [lint] warning conversion to 'unsigned long' due to prototype, arg #3 [259]%%%*/
158/*###155 [lint] warning conversion from 'unsigned long long' to 'unsigned long' may lose accuracy, arg #3 [298]%%%*/
159UTEMPLATE(ulonglong, unsigned long long)
160UTEMPLATE(uintptr,   uintptr_t)
161UTEMPLATE(uint8,     uint8_t)
162UTEMPLATE(uint16,    uint16_t)
163UTEMPLATE(uint32,    uint32_t)
164UTEMPLATE(uint64,    uint64_t)
165
166#undef STEMPLATE
167#undef UTEMPLATE
168#undef TEMPLATE
169
170bool
171prop_dictionary_get_string(prop_dictionary_t dict, const char *key,
172			   const char **cpp)
173{
174	prop_string_t str;
175	const char *cp;
176
177	str = prop_dictionary_get(dict, key);
178	if (prop_object_type(str) != PROP_TYPE_STRING)
179		return (false);
180
181	cp = prop_string_value(str);
182	if (cp == NULL)
183		return (false);
184
185	*cpp = cp;
186	return (true);
187}
188
189bool
190prop_dictionary_set_string(prop_dictionary_t dict, const char *key,
191			   const char *cp)
192{
193	return prop_dictionary_set_and_rel(dict, key,
194					   prop_string_create_copy(cp));
195}
196
197bool
198prop_dictionary_set_string_nocopy(prop_dictionary_t dict,
199				  const char *key,
200				  const char *cp)
201{
202	return prop_dictionary_set_and_rel(dict, key,
203					   prop_string_create_nocopy(cp));
204}
205
206bool
207prop_dictionary_get_data(prop_dictionary_t dict, const char *key,
208			 const void **vp, size_t *sizep)
209{
210	prop_data_t data;
211	const void *v;
212
213	data = prop_dictionary_get(dict, key);
214	if (prop_object_type(data) != PROP_TYPE_DATA)
215		return (false);
216
217	v = prop_data_value(data);
218	if (v == NULL)
219		return (false);
220
221	*vp = v;
222	if (sizep != NULL)
223		*sizep = prop_data_size(data);
224	return (true);
225}
226
227bool
228prop_dictionary_set_data(prop_dictionary_t dict, const char *key,
229			 const void *v, size_t size)
230{
231	return prop_dictionary_set_and_rel(dict, key,
232					   prop_data_create_copy(v, size));
233}
234
235bool
236prop_dictionary_set_data_nocopy(prop_dictionary_t dict, const char *key,
237			        const void *v, size_t size)
238{
239	return prop_dictionary_set_and_rel(dict, key,
240					   prop_data_create_nocopy(v, size));
241}
242
243_PROP_DEPRECATED(prop_dictionary_get_cstring,
244    "this program uses prop_dictionary_get_cstring(), "
245    "which is deprecated; use prop_dictionary_get_string() and copy instead.")
246bool
247prop_dictionary_get_cstring(prop_dictionary_t dict,
248			    const char *key,
249			    char **cpp)
250{
251	prop_string_t str;
252	char *cp;
253	size_t len;
254	bool rv;
255
256	str = prop_dictionary_get(dict, key);
257	if (prop_object_type(str) != PROP_TYPE_STRING)
258		return (false);
259
260	len = prop_string_size(str);
261	cp = _PROP_MALLOC(len + 1, M_TEMP);
262	if (cp == NULL)
263		return (false);
264
265	rv = prop_string_copy_value(str, cp, len + 1);
266	if (rv)
267		*cpp = cp;
268	else
269		_PROP_FREE(cp, M_TEMP);
270
271	return (rv);
272}
273
274_PROP_DEPRECATED(prop_string_get_cstring_nocopy,
275    "this program uses prop_string_get_cstring_nocopy(), "
276    "which is deprecated; use prop_dictionary_get_string() instead.")
277bool
278prop_dictionary_get_cstring_nocopy(prop_dictionary_t dict,
279				   const char *key,
280				   const char **cpp)
281{
282	return prop_dictionary_get_string(dict, key, cpp);
283}
284
285_PROP_DEPRECATED(prop_dictionary_set_cstring,
286    "this program uses prop_dictionary_set_cstring(), "
287    "which is deprecated; use prop_dictionary_set_string() instead.")
288bool
289prop_dictionary_set_cstring(prop_dictionary_t dict,
290			    const char *key,
291			    const char *cp)
292{
293	return prop_dictionary_set_string(dict, key, cp);
294}
295
296_PROP_DEPRECATED(prop_dictionary_set_cstring_nocopy,
297    "this program uses prop_dictionary_set_cstring_nocopy(), "
298    "which is deprecated; use prop_dictionary_set_string_nocopy() instead.")
299bool
300prop_dictionary_set_cstring_nocopy(prop_dictionary_t dict,
301				   const char *key,
302				   const char *cp)
303{
304	return prop_dictionary_set_string_nocopy(dict, key, cp);
305}
306
307bool
308prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
309			    prop_object_t po)
310{
311	bool rv;
312
313	if (po == NULL)
314		return false;
315	rv = prop_dictionary_set(dict, key, po);
316	prop_object_release(po);
317	return rv;
318}
319