Home | History | Annotate | Line # | Download | only in libprop
      1 /*	$NetBSD: prop_dictionary_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 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 _PROP_EXPORT bool
     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 _PROP_EXPORT bool
     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 _PROP_EXPORT bool
     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 _PROP_EXPORT 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 }
     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
    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 _PROP_EXPORT 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 
    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 _PROP_EXPORT 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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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 _PROP_EXPORT bool
    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