1 /*        $NetBSD: prop_array_util.c,v 1.10 2025/04/26 17:13:23 thorpej 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 array.
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" /* hide kernel vs. not-kernel vs. standalone */
42 #include <prop/proplib.h>
43 
44 _PROP_EXPORT bool
prop_array_get_bool(prop_array_t array,unsigned int indx,bool * valp)45 prop_array_get_bool(prop_array_t array, unsigned int indx, bool *valp)
46 {
47           prop_bool_t b;
48 
49           b = prop_array_get(array, indx);
50           if (prop_object_type(b) != PROP_TYPE_BOOL)
51                     return (false);
52 
53           *valp = prop_bool_true(b);
54 
55           return (true);
56 }
57 
58 _PROP_EXPORT bool
prop_array_set_bool(prop_array_t array,unsigned int indx,bool val)59 prop_array_set_bool(prop_array_t array, unsigned int indx, bool val)
60 {
61 
62           return prop_array_set_and_rel(array, indx, prop_bool_create(val));
63 }
64 
65 _PROP_EXPORT bool
prop_array_add_bool(prop_array_t array,bool val)66 prop_array_add_bool(prop_array_t array, bool val)
67 {
68 
69           return prop_array_add_and_rel(array, prop_bool_create(val));
70 }
71 
72 #define   TEMPLATE(name, typ)                                                   \
73 _PROP_EXPORT bool                                                               \
74 prop_array_get_ ## name (prop_array_t array,                                    \
75                                unsigned int indx,                               \
76                                typ *valp)                                                 \
77 {                                                                                         \
78           return prop_number_ ## name ## _value(                                \
79               prop_array_get(array, indx), valp);                               \
80 }
TEMPLATE(schar,signed char)81 TEMPLATE(schar,    signed char)
82 TEMPLATE(short,    short)
83 TEMPLATE(int,      int)
84 TEMPLATE(long,     long)
85 TEMPLATE(longlong, long long)
86 TEMPLATE(intptr,   intptr_t)
87 TEMPLATE(int8,     int8_t)
88 TEMPLATE(int16,    int16_t)
89 TEMPLATE(int32,    int32_t)
90 TEMPLATE(int64,    int64_t)
91 
92 TEMPLATE(uchar,     unsigned char)
93 TEMPLATE(ushort,    unsigned short)
94 TEMPLATE(uint,      unsigned int)
95 TEMPLATE(ulong,     unsigned long)
96 TEMPLATE(ulonglong, unsigned long long)
97 TEMPLATE(uintptr,   uintptr_t)
98 TEMPLATE(uint8,     uint8_t)
99 TEMPLATE(uint16,    uint16_t)
100 TEMPLATE(uint32,    uint32_t)
101 TEMPLATE(uint64,    uint64_t)
102 
103 #undef TEMPLATE
104 
105 static bool
106 prop_array_set_signed_number(prop_array_t array, unsigned int indx,
107                                    intmax_t val)
108 {
109           return prop_array_set_and_rel(array, indx,
110                                                prop_number_create_signed(val));
111 }
112 
113 static bool
prop_array_add_signed_number(prop_array_t array,intmax_t val)114 prop_array_add_signed_number(prop_array_t array, intmax_t val)
115 {
116           return prop_array_add_and_rel(array, prop_number_create_signed(val));
117 }
118 
119 static bool
prop_array_set_unsigned_number(prop_array_t array,unsigned int indx,uintmax_t val)120 prop_array_set_unsigned_number(prop_array_t array, unsigned int indx,
121                                      uintmax_t val)
122 {
123           return prop_array_set_and_rel(array, indx,
124                                                prop_number_create_unsigned(val));
125 }
126 
127 static bool
prop_array_add_unsigned_number(prop_array_t array,uintmax_t val)128 prop_array_add_unsigned_number(prop_array_t array, uintmax_t val)
129 {
130           return prop_array_add_and_rel(array, prop_number_create_unsigned(val));
131 }
132 
133 #define TEMPLATE(name, which, typ)                                              \
134 _PROP_EXPORT bool                                                               \
135 prop_array_set_ ## name (prop_array_t array,                                    \
136                                unsigned int indx,                               \
137                                typ val)                                         \
138 {                                                                                         \
139           /*LINTED: for conversion from 'long long' to 'long'*/                 \
140           return prop_array_set_ ## which ## _number(array, indx, val);         \
141 }                                                                                         \
142                                                                                           \
143 _PROP_EXPORT bool                                                               \
144 prop_array_add_ ## name (prop_array_t array,                                    \
145                                typ val)                                         \
146 {                                                                                         \
147           /*LINTED: for conversion from 'long long' to 'long'*/                 \
148           return prop_array_add_ ## which ## _number(array, val);               \
149 }
150 
151 #define   STEMPLATE(name, typ)          TEMPLATE(name, signed, typ)
152 #define   UTEMPLATE(name, typ)          TEMPLATE(name, unsigned, typ)
153 
STEMPLATE(schar,signed char)154 STEMPLATE(schar,    signed char)
155 STEMPLATE(short,    short)
156 STEMPLATE(int,      int)
157 STEMPLATE(long,     long)
158 STEMPLATE(longlong, long long)
159 STEMPLATE(intptr,   intptr_t)
160 STEMPLATE(int8,     int8_t)
161 STEMPLATE(int16,    int16_t)
162 STEMPLATE(int32,    int32_t)
163 STEMPLATE(int64,    int64_t)
164 
165 UTEMPLATE(uchar,     unsigned char)
166 UTEMPLATE(ushort,    unsigned short)
167 UTEMPLATE(uint,      unsigned int)
168 UTEMPLATE(ulong,     unsigned long)
169 UTEMPLATE(ulonglong, unsigned long long)
170 UTEMPLATE(uintptr,   uintptr_t)
171 UTEMPLATE(uint8,     uint8_t)
172 UTEMPLATE(uint16,    uint16_t)
173 UTEMPLATE(uint32,    uint32_t)
174 UTEMPLATE(uint64,    uint64_t)
175 
176 #undef STEMPLATE
177 #undef UTEMPLATE
178 #undef TEMPLATE
179 
180 _PROP_EXPORT bool
181 prop_array_get_string(prop_array_t array, unsigned int indx, const char **cpp)
182 {
183           prop_string_t str;
184           const char *cp;
185 
186           str = prop_array_get(array, indx);
187           if (prop_object_type(str) != PROP_TYPE_STRING)
188                     return (false);
189 
190           cp = prop_string_value(str);
191           if (cp == NULL)
192                     return (false);
193 
194           *cpp = cp;
195           return (true);
196 }
197 
198 _PROP_EXPORT bool
prop_array_set_string(prop_array_t array,unsigned int indx,const char * cp)199 prop_array_set_string(prop_array_t array, unsigned int indx, const char *cp)
200 {
201           return prop_array_set_and_rel(array, indx,
202                                               prop_string_create_copy(cp));
203 }
204 
205 _PROP_EXPORT bool
prop_array_add_string(prop_array_t array,const char * cp)206 prop_array_add_string(prop_array_t array, const char *cp)
207 {
208           return prop_array_add_and_rel(array, prop_string_create_copy(cp));
209 }
210 
211 _PROP_EXPORT bool
prop_array_set_string_nocopy(prop_array_t array,unsigned int indx,const char * cp)212 prop_array_set_string_nocopy(prop_array_t array, unsigned int indx,
213                                    const char *cp)
214 {
215           return prop_array_set_and_rel(array, indx,
216                                               prop_string_create_nocopy(cp));
217 }
218 
219 _PROP_EXPORT bool
prop_array_add_string_nocopy(prop_array_t array,const char * cp)220 prop_array_add_string_nocopy(prop_array_t array, const char *cp)
221 {
222           return prop_array_add_and_rel(array, prop_string_create_nocopy(cp));
223 }
224 
225 _PROP_EXPORT bool
prop_array_get_data(prop_array_t array,unsigned int indx,const void ** vp,size_t * sizep)226 prop_array_get_data(prop_array_t array, unsigned int indx, const void **vp,
227                         size_t *sizep)
228 {
229           prop_data_t data;
230           const void *v;
231 
232           data = prop_array_get(array, indx);
233           if (prop_object_type(data) != PROP_TYPE_DATA)
234                     return (false);
235 
236           v = prop_data_value(data);
237           if (v == NULL)
238                     return (false);
239 
240           *vp = v;
241           if (sizep != NULL)
242                     *sizep = prop_data_size(data);
243           return (true);
244 }
245 
246 _PROP_EXPORT bool
prop_array_set_data(prop_array_t array,unsigned int indx,const void * v,size_t size)247 prop_array_set_data(prop_array_t array, unsigned int indx, const void *v,
248                         size_t size)
249 {
250           return prop_array_set_and_rel(array, indx,
251                                               prop_data_create_copy(v, size));
252 }
253 
254 _PROP_EXPORT bool
prop_array_set_data_nocopy(prop_array_t array,unsigned int indx,const void * v,size_t size)255 prop_array_set_data_nocopy(prop_array_t array, unsigned int indx, const void *v,
256                                  size_t size)
257 {
258           return prop_array_set_and_rel(array, indx,
259                                               prop_data_create_nocopy(v, size));
260 }
261 
262 _PROP_EXPORT bool
prop_array_add_data(prop_array_t array,const void * v,size_t size)263 prop_array_add_data(prop_array_t array, const void *v, size_t size)
264 {
265           return prop_array_add_and_rel(array,
266                                               prop_data_create_copy(v, size));
267 }
268 
269 _PROP_EXPORT bool
prop_array_add_data_nocopy(prop_array_t array,const void * v,size_t size)270 prop_array_add_data_nocopy(prop_array_t array, const void *v, size_t size)
271 {
272           return prop_array_add_and_rel(array,
273                                               prop_data_create_nocopy(v, size));
274 }
275 
276 _PROP_DEPRECATED(prop_array_get_cstring,
277     "this program uses prop_array_get_cstring(), "
278     "which is deprecated; use prop_array_get_string() and copy instead.")
279 _PROP_EXPORT bool
prop_array_get_cstring(prop_array_t array,unsigned int indx,char ** cpp)280 prop_array_get_cstring(prop_array_t array, unsigned int indx, char **cpp)
281 {
282           prop_string_t str;
283           char *cp;
284           size_t len;
285           bool rv;
286 
287           str = prop_array_get(array, indx);
288           if (prop_object_type(str) != PROP_TYPE_STRING)
289                     return (false);
290 
291           len = prop_string_size(str);
292           cp = _PROP_MALLOC(len + 1, M_TEMP);
293           if (cp == NULL)
294                     return (false);
295 
296           rv = prop_string_copy_value(str, cp, len + 1);
297           if (rv)
298                     *cpp = cp;
299           else
300                     _PROP_FREE(cp, M_TEMP);
301 
302           return (rv);
303 }
304 
305 _PROP_DEPRECATED(prop_array_get_cstring_nocopy,
306     "this program uses prop_array_get_cstring_nocopy(), "
307     "which is deprecated; use prop_array_get_string() instead.")
308 _PROP_EXPORT bool
prop_array_get_cstring_nocopy(prop_array_t array,unsigned int indx,const char ** cpp)309 prop_array_get_cstring_nocopy(prop_array_t array, unsigned int indx,
310                                     const char **cpp)
311 {
312           return prop_array_get_string(array, indx, cpp);
313 }
314 
315 _PROP_DEPRECATED(prop_array_set_cstring,
316     "this program uses prop_array_set_cstring(), "
317     "which is deprecated; use prop_array_set_string() instead.")
318 _PROP_EXPORT bool
prop_array_set_cstring(prop_array_t array,unsigned int indx,const char * cp)319 prop_array_set_cstring(prop_array_t array, unsigned int indx, const char *cp)
320 {
321           return prop_array_set_string(array, indx, cp);
322 }
323 
324 _PROP_DEPRECATED(prop_array_add_cstring,
325     "this program uses prop_array_add_cstring(), "
326     "which is deprecated; use prop_array_add_string() instead.")
327 _PROP_EXPORT bool
prop_array_add_cstring(prop_array_t array,const char * cp)328 prop_array_add_cstring(prop_array_t array, const char *cp)
329 {
330           return prop_array_add_string(array, cp);
331 }
332 
333 _PROP_DEPRECATED(prop_array_set_cstring_nocopy,
334     "this program uses prop_array_set_cstring_nocopy(), "
335     "which is deprecated; use prop_array_set_string_nocopy() instead.")
336 _PROP_EXPORT bool
prop_array_set_cstring_nocopy(prop_array_t array,unsigned int indx,const char * cp)337 prop_array_set_cstring_nocopy(prop_array_t array, unsigned int indx,
338                                     const char *cp)
339 {
340           return prop_array_set_string_nocopy(array, indx, cp);
341 }
342 
343 _PROP_DEPRECATED(prop_array_add_cstring_nocopy,
344     "this program uses prop_array_add_cstring_nocopy(), "
345     "which is deprecated; use prop_array_add_string_nocopy() instead.")
346 _PROP_EXPORT bool
prop_array_add_cstring_nocopy(prop_array_t array,const char * cp)347 prop_array_add_cstring_nocopy(prop_array_t array, const char *cp)
348 {
349           return prop_array_add_string_nocopy(array, cp);
350 }
351 
352 _PROP_EXPORT bool
prop_array_add_and_rel(prop_array_t array,prop_object_t po)353 prop_array_add_and_rel(prop_array_t array, prop_object_t po)
354 {
355           bool rv;
356 
357           if (po == NULL)
358                     return false;
359           rv = prop_array_add(array, po);
360           prop_object_release(po);
361           return rv;
362 }
363 
364 _PROP_EXPORT bool
prop_array_set_and_rel(prop_array_t array,unsigned int indx,prop_object_t po)365 prop_array_set_and_rel(prop_array_t array, unsigned int indx,
366                            prop_object_t po)
367 {
368           bool rv;
369 
370           if (po == NULL)
371                     return false;
372           rv = prop_array_set(array, indx, po);
373           prop_object_release(po);
374           return rv;
375 }
376