1 /*	$NetBSD: prop_dictionary_util.c,v 1.9 2022/08/03 21:13:46 riastradh 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 
44 bool
prop_dictionary_get_dict(prop_dictionary_t dict,const char * key,prop_dictionary_t * dp)45 prop_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 
58 bool
prop_dictionary_get_bool(prop_dictionary_t dict,const char * key,bool * valp)59 prop_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 
72 bool
prop_dictionary_set_bool(prop_dictionary_t dict,const char * key,bool val)73 prop_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)						\
80 bool									\
81 prop_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 }
TEMPLATE(schar,signed char)88 TEMPLATE(schar,    signed char)
89 TEMPLATE(short,    short)
90 TEMPLATE(int,      int)
91 TEMPLATE(long,     long)
92 TEMPLATE(longlong, long long)
93 TEMPLATE(intptr,   intptr_t)
94 TEMPLATE(int8,     int8_t)
95 TEMPLATE(int16,    int16_t)
96 TEMPLATE(int32,    int32_t)
97 TEMPLATE(int64,    int64_t)
98 
99 TEMPLATE(uchar,     unsigned char)
100 TEMPLATE(ushort,    unsigned short)
101 TEMPLATE(uint,      unsigned int)
102 TEMPLATE(ulong,     unsigned long)
103 TEMPLATE(ulonglong, unsigned long long)
104 TEMPLATE(uintptr,   uintptr_t)
105 TEMPLATE(uint8,     uint8_t)
106 TEMPLATE(uint16,    uint16_t)
107 TEMPLATE(uint32,    uint32_t)
108 TEMPLATE(uint64,    uint64_t)
109 
110 #undef TEMPLATE
111 
112 static bool
113 prop_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 
120 static bool
prop_dictionary_set_unsigned_number(prop_dictionary_t dict,const char * key,uintmax_t val)121 prop_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)					\
130 bool									\
131 prop_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 
STEMPLATE(schar,signed char)142 STEMPLATE(schar,    signed char)
143 STEMPLATE(short,    short)
144 STEMPLATE(int,      int)
145 STEMPLATE(long,     long)
146 STEMPLATE(longlong, long long)
147 STEMPLATE(intptr,   intptr_t)
148 STEMPLATE(int8,     int8_t)
149 STEMPLATE(int16,    int16_t)
150 STEMPLATE(int32,    int32_t)
151 STEMPLATE(int64,    int64_t)
152 
153 UTEMPLATE(uchar,     unsigned char)
154 UTEMPLATE(ushort,    unsigned short)
155 UTEMPLATE(uint,      unsigned int)
156 UTEMPLATE(ulong,     unsigned long)
157 UTEMPLATE(ulonglong, unsigned long long)
158 UTEMPLATE(uintptr,   uintptr_t)
159 UTEMPLATE(uint8,     uint8_t)
160 UTEMPLATE(uint16,    uint16_t)
161 UTEMPLATE(uint32,    uint32_t)
162 UTEMPLATE(uint64,    uint64_t)
163 
164 #undef STEMPLATE
165 #undef UTEMPLATE
166 #undef TEMPLATE
167 
168 bool
169 prop_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 
187 bool
prop_dictionary_set_string(prop_dictionary_t dict,const char * key,const char * cp)188 prop_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 
195 bool
prop_dictionary_set_string_nocopy(prop_dictionary_t dict,const char * key,const char * cp)196 prop_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 
204 bool
prop_dictionary_get_data(prop_dictionary_t dict,const char * key,const void ** vp,size_t * sizep)205 prop_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 
225 bool
prop_dictionary_set_data(prop_dictionary_t dict,const char * key,const void * v,size_t size)226 prop_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 
233 bool
prop_dictionary_set_data_nocopy(prop_dictionary_t dict,const char * key,const void * v,size_t size)234 prop_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.")
244 bool
prop_dictionary_get_cstring(prop_dictionary_t dict,const char * key,char ** cpp)245 prop_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.")
275 bool
prop_dictionary_get_cstring_nocopy(prop_dictionary_t dict,const char * key,const char ** cpp)276 prop_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.")
286 bool
prop_dictionary_set_cstring(prop_dictionary_t dict,const char * key,const char * cp)287 prop_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.")
297 bool
prop_dictionary_set_cstring_nocopy(prop_dictionary_t dict,const char * key,const char * cp)298 prop_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 
305 bool
prop_dictionary_set_and_rel(prop_dictionary_t dict,const char * key,prop_object_t po)306 prop_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