prop_dictionary_util.c revision 1.7
1/* $NetBSD: prop_dictionary_util.c,v 1.7 2020/06/14 21:31:01 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 44bool 45prop_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 58bool 59prop_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 72bool 73prop_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) \ 80bool \ 81prop_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} 88TEMPLATE(schar, signed char) 89TEMPLATE(short, short) 90TEMPLATE(int, int) 91TEMPLATE(long, long) 92TEMPLATE(longlong, long long) 93TEMPLATE(intptr, intptr_t) 94TEMPLATE(int8, int8_t) 95TEMPLATE(int16, int16_t) 96TEMPLATE(int32, int32_t) 97TEMPLATE(int64, int64_t) 98 99TEMPLATE(uchar, unsigned char) 100TEMPLATE(ushort, unsigned short) 101TEMPLATE(uint, unsigned int) 102TEMPLATE(ulong, unsigned long) 103TEMPLATE(ulonglong, unsigned long long) 104TEMPLATE(uintptr, uintptr_t) 105TEMPLATE(uint8, uint8_t) 106TEMPLATE(uint16, uint16_t) 107TEMPLATE(uint32, uint32_t) 108TEMPLATE(uint64, uint64_t) 109 110#undef TEMPLATE 111 112static bool 113prop_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 120static bool 121prop_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) \ 130bool \ 131prop_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 142STEMPLATE(schar, signed char) 143STEMPLATE(short, short) 144STEMPLATE(int, int) 145STEMPLATE(long, long) 146STEMPLATE(longlong, long long) 147STEMPLATE(intptr, intptr_t) 148STEMPLATE(int8, int8_t) 149STEMPLATE(int16, int16_t) 150STEMPLATE(int32, int32_t) 151STEMPLATE(int64, int64_t) 152 153UTEMPLATE(uchar, unsigned char) 154UTEMPLATE(ushort, unsigned short) 155UTEMPLATE(uint, unsigned int) 156UTEMPLATE(ulong, unsigned long) 157/*###155 [lint] warning conversion to 'unsigned long' due to prototype, arg #3 [259]%%%*/ 158/*###155 [lint] warning conversion from 'unsigned long long' to 'unsigned long' may lose accuracy, arg #3 [298]%%%*/ 159UTEMPLATE(ulonglong, unsigned long long) 160UTEMPLATE(uintptr, uintptr_t) 161UTEMPLATE(uint8, uint8_t) 162UTEMPLATE(uint16, uint16_t) 163UTEMPLATE(uint32, uint32_t) 164UTEMPLATE(uint64, uint64_t) 165 166#undef STEMPLATE 167#undef UTEMPLATE 168#undef TEMPLATE 169 170bool 171prop_dictionary_get_string(prop_dictionary_t dict, const char *key, 172 const char **cpp) 173{ 174 prop_string_t str; 175 const char *cp; 176 177 str = prop_dictionary_get(dict, key); 178 if (prop_object_type(str) != PROP_TYPE_STRING) 179 return (false); 180 181 cp = prop_string_value(str); 182 if (cp == NULL) 183 return (false); 184 185 *cpp = cp; 186 return (true); 187} 188 189bool 190prop_dictionary_set_string(prop_dictionary_t dict, const char *key, 191 const char *cp) 192{ 193 return prop_dictionary_set_and_rel(dict, key, 194 prop_string_create_copy(cp)); 195} 196 197bool 198prop_dictionary_set_string_nocopy(prop_dictionary_t dict, 199 const char *key, 200 const char *cp) 201{ 202 return prop_dictionary_set_and_rel(dict, key, 203 prop_string_create_nocopy(cp)); 204} 205 206bool 207prop_dictionary_get_data(prop_dictionary_t dict, const char *key, 208 const void **vp, size_t *sizep) 209{ 210 prop_data_t data; 211 const void *v; 212 213 data = prop_dictionary_get(dict, key); 214 if (prop_object_type(data) != PROP_TYPE_DATA) 215 return (false); 216 217 v = prop_data_value(data); 218 if (v == NULL) 219 return (false); 220 221 *vp = v; 222 if (sizep != NULL) 223 *sizep = prop_data_size(data); 224 return (true); 225} 226 227bool 228prop_dictionary_set_data(prop_dictionary_t dict, const char *key, 229 const void *v, size_t size) 230{ 231 return prop_dictionary_set_and_rel(dict, key, 232 prop_data_create_copy(v, size)); 233} 234 235bool 236prop_dictionary_set_data_nocopy(prop_dictionary_t dict, const char *key, 237 const void *v, size_t size) 238{ 239 return prop_dictionary_set_and_rel(dict, key, 240 prop_data_create_nocopy(v, size)); 241} 242 243_PROP_DEPRECATED(prop_dictionary_get_cstring, 244 "this program uses prop_dictionary_get_cstring(), " 245 "which is deprecated; use prop_dictionary_get_string() and copy instead.") 246bool 247prop_dictionary_get_cstring(prop_dictionary_t dict, 248 const char *key, 249 char **cpp) 250{ 251 prop_string_t str; 252 char *cp; 253 size_t len; 254 bool rv; 255 256 str = prop_dictionary_get(dict, key); 257 if (prop_object_type(str) != PROP_TYPE_STRING) 258 return (false); 259 260 len = prop_string_size(str); 261 cp = _PROP_MALLOC(len + 1, M_TEMP); 262 if (cp == NULL) 263 return (false); 264 265 rv = prop_string_copy_value(str, cp, len + 1); 266 if (rv) 267 *cpp = cp; 268 else 269 _PROP_FREE(cp, M_TEMP); 270 271 return (rv); 272} 273 274_PROP_DEPRECATED(prop_string_get_cstring_nocopy, 275 "this program uses prop_string_get_cstring_nocopy(), " 276 "which is deprecated; use prop_dictionary_get_string() instead.") 277bool 278prop_dictionary_get_cstring_nocopy(prop_dictionary_t dict, 279 const char *key, 280 const char **cpp) 281{ 282 return prop_dictionary_get_string(dict, key, cpp); 283} 284 285_PROP_DEPRECATED(prop_dictionary_set_cstring, 286 "this program uses prop_dictionary_set_cstring(), " 287 "which is deprecated; use prop_dictionary_set_string() instead.") 288bool 289prop_dictionary_set_cstring(prop_dictionary_t dict, 290 const char *key, 291 const char *cp) 292{ 293 return prop_dictionary_set_string(dict, key, cp); 294} 295 296_PROP_DEPRECATED(prop_dictionary_set_cstring_nocopy, 297 "this program uses prop_dictionary_set_cstring_nocopy(), " 298 "which is deprecated; use prop_dictionary_set_string_nocopy() instead.") 299bool 300prop_dictionary_set_cstring_nocopy(prop_dictionary_t dict, 301 const char *key, 302 const char *cp) 303{ 304 return prop_dictionary_set_string_nocopy(dict, key, cp); 305} 306 307bool 308prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key, 309 prop_object_t po) 310{ 311 bool rv; 312 313 if (po == NULL) 314 return false; 315 rv = prop_dictionary_set(dict, key, po); 316 prop_object_release(po); 317 return rv; 318} 319