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