1 /* $NetBSD: prop_dictionary_util.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 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 <libprop/proplib.h> 42 #include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */ 43 44 bool 45 prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, prop_dictionary_t *dp) 46 { 47 prop_object_t o; 48 o = prop_dictionary_get(dict, key); 49 if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY) 50 return false; 51 *dp = o; 52 return true; 53 54 } 55 56 bool 57 prop_dictionary_get_bool(prop_dictionary_t dict, 58 const char *key, 59 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, 74 const char *key, 75 bool val) 76 { 77 prop_bool_t b; 78 int rv; 79 80 b = prop_bool_create(val); 81 if (b == NULL) 82 return (false); 83 rv = prop_dictionary_set(dict, key, b); 84 prop_object_release(b); 85 86 return (rv); 87 } 88 89 #define TEMPLATE(size) \ 90 bool \ 91 prop_dictionary_get_int ## size (prop_dictionary_t dict, \ 92 const char *key, \ 93 int ## size ## _t *valp) \ 94 { \ 95 prop_number_t num; \ 96 \ 97 num = prop_dictionary_get(dict, key); \ 98 if (prop_object_type(num) != PROP_TYPE_NUMBER) \ 99 return (false); \ 100 \ 101 if (prop_number_unsigned(num) && \ 102 prop_number_unsigned_integer_value(num) > \ 103 /*CONSTCOND*/((size) == 8 ? INT8_MAX : \ 104 (size) == 16 ? INT16_MAX : \ 105 (size) == 32 ? INT32_MAX : INT64_MAX)) { \ 106 return (false); \ 107 } \ 108 \ 109 if (prop_number_size(num) > (size)) \ 110 return (false); \ 111 \ 112 *valp = (int ## size ## _t) prop_number_integer_value(num); \ 113 \ 114 return (true); \ 115 } \ 116 \ 117 bool \ 118 prop_dictionary_get_uint ## size (prop_dictionary_t dict, \ 119 const char *key, \ 120 uint ## size ## _t *valp) \ 121 { \ 122 prop_number_t num; \ 123 \ 124 num = prop_dictionary_get(dict, key); \ 125 if (prop_object_type(num) != PROP_TYPE_NUMBER) \ 126 return (false); \ 127 \ 128 if (prop_number_unsigned(num) == false && \ 129 prop_number_integer_value(num) < 0) { \ 130 return (false); \ 131 } \ 132 \ 133 if (prop_number_size(num) > (size)) \ 134 return (false); \ 135 \ 136 *valp = (uint ## size ## _t) \ 137 prop_number_unsigned_integer_value(num); \ 138 \ 139 return (true); \ 140 } \ 141 \ 142 bool \ 143 prop_dictionary_set_int ## size (prop_dictionary_t dict, \ 144 const char *key, \ 145 int ## size ## _t val) \ 146 { \ 147 prop_number_t num; \ 148 int rv; \ 149 \ 150 num = prop_number_create_integer((int64_t) val); \ 151 if (num == NULL) \ 152 return (false); \ 153 rv = prop_dictionary_set(dict, key, num); \ 154 prop_object_release(num); \ 155 \ 156 return (rv); \ 157 } \ 158 \ 159 bool \ 160 prop_dictionary_set_uint ## size (prop_dictionary_t dict, \ 161 const char *key, \ 162 uint ## size ## _t val) \ 163 { \ 164 prop_number_t num; \ 165 int rv; \ 166 \ 167 num = prop_number_create_unsigned_integer((uint64_t) val); \ 168 if (num == NULL) \ 169 return (false); \ 170 rv = prop_dictionary_set(dict, key, num); \ 171 prop_object_release(num); \ 172 \ 173 return (rv); \ 174 } 175 176 TEMPLATE(8) 177 TEMPLATE(16) 178 TEMPLATE(32) 179 TEMPLATE(64) 180 181 #undef TEMPLATE 182 183 #define TEMPLATE(variant, qualifier) \ 184 bool \ 185 prop_dictionary_get_cstring ## variant (prop_dictionary_t dict, \ 186 const char *key, \ 187 qualifier char **cpp) \ 188 { \ 189 prop_string_t str; \ 190 \ 191 str = prop_dictionary_get(dict, key); \ 192 if (prop_object_type(str) != PROP_TYPE_STRING) \ 193 return (false); \ 194 \ 195 *cpp = prop_string_cstring ## variant (str); \ 196 \ 197 return (*cpp == NULL ? false : true); \ 198 } \ 199 \ 200 bool \ 201 prop_dictionary_set_cstring ## variant (prop_dictionary_t dict, \ 202 const char *key, \ 203 const char *cp) \ 204 { \ 205 prop_string_t str; \ 206 int rv; \ 207 \ 208 str = prop_string_create_cstring ## variant (cp); \ 209 if (str == NULL) \ 210 return (false); \ 211 rv = prop_dictionary_set(dict, key, str); \ 212 prop_object_release(str); \ 213 \ 214 return (rv); \ 215 } 216 217 TEMPLATE(,) 218 TEMPLATE(_nocopy,const) 219 220 #undef TEMPLATE 221 222 bool 223 prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key, 224 prop_object_t po) 225 { 226 bool ret; 227 if (po == NULL) 228 return false; 229 ret = prop_dictionary_set(dict, key, po); 230 prop_object_release(po); 231 return ret; 232 } 233