1 /* $NetBSD: prop_dictionary_util.c,v 1.8 2020/06/15 00:46:00 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 44 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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