1 /*- 2 * Copyright (c) 2016 Adam Starak <starak.adam@gmail.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #ifdef _KERNEL 33 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/kernel.h> 37 #include <sys/systm.h> 38 #include <sys/malloc.h> 39 40 #include <machine/stdarg.h> 41 42 #else 43 #include <stdarg.h> 44 #include <stdbool.h> 45 #include <stdint.h> 46 #include <stdlib.h> 47 #endif 48 49 #include <sys/cnv.h> 50 #include <sys/nv.h> 51 52 #include "nv_impl.h" 53 #include "nvlist_impl.h" 54 #include "nvpair_impl.h" 55 56 #define CNVLIST_GET(ftype, type, NVTYPE) \ 57 ftype \ 58 cnvlist_get_##type(void *cookiep) \ 59 { \ 60 \ 61 if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) { \ 62 nvlist_report_missing(NV_TYPE_##NVTYPE, \ 63 nvpair_name(cookiep)); \ 64 } \ 65 return (nvpair_get_##type(cookiep)); \ 66 } 67 68 CNVLIST_GET(bool, bool, BOOL) 69 CNVLIST_GET(uint64_t, number, NUMBER) 70 CNVLIST_GET(const char *, string, STRING) 71 CNVLIST_GET(const nvlist_t *, nvlist, NVLIST) 72 #ifndef _KERNEL 73 CNVLIST_GET(int, descriptor, DESCRIPTOR) 74 #endif 75 76 #undef CNVLIST_GET 77 78 #define CNVLIST_GET_ARRAY(ftype, type, NVTYPE) \ 79 ftype \ 80 cnvlist_get_##type(void *cookiep, size_t *nitemsp) \ 81 { \ 82 \ 83 if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) { \ 84 nvlist_report_missing(NV_TYPE_##NVTYPE, \ 85 nvpair_name(cookiep)); \ 86 } \ 87 return (nvpair_get_##type(cookiep, nitemsp)); \ 88 } 89 90 CNVLIST_GET_ARRAY(const bool *, bool_array, BOOL_ARRAY) 91 CNVLIST_GET_ARRAY(const uint64_t *, number_array, NUMBER_ARRAY) 92 CNVLIST_GET_ARRAY(const char * const *, string_array, STRING_ARRAY) 93 CNVLIST_GET_ARRAY(const nvlist_t * const *, nvlist_array, NVLIST_ARRAY) 94 #ifndef _KERNEL 95 CNVLIST_GET_ARRAY(const int *, descriptor_array, DESCRIPTOR_ARRAY) 96 #endif 97 98 #undef CNVLIST_GET_ARRAY 99 100 const void * 101 cnvlist_get_binary(void *cookiep, size_t *sizep) 102 { 103 104 if (nvpair_type(cookiep) != NV_TYPE_BINARY) 105 nvlist_report_missing(NV_TYPE_BINARY, nvpair_name(cookiep)); 106 return (nvpair_get_binary(cookiep, sizep)); 107 } 108 109 #define CNVLIST_TAKE(ftype, type, NVTYPE) \ 110 ftype \ 111 cnvlist_take_##type(nvlist_t *nvl, void *cookiep) \ 112 { \ 113 ftype value; \ 114 \ 115 if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) { \ 116 nvlist_report_missing(NV_TYPE_##NVTYPE, \ 117 nvpair_name(cookiep)); \ 118 } \ 119 value = (ftype)(intptr_t)nvpair_get_##type(cookiep); \ 120 nvlist_remove_nvpair(nvl, cookiep); \ 121 nvpair_free_structure(cookiep); \ 122 return (value); \ 123 } 124 125 CNVLIST_TAKE(bool, bool, BOOL) 126 CNVLIST_TAKE(uint64_t, number, NUMBER) 127 CNVLIST_TAKE(char *, string, STRING) 128 CNVLIST_TAKE(nvlist_t *, nvlist, NVLIST) 129 #ifndef _KERNEL 130 CNVLIST_TAKE(int, descriptor, DESCRIPTOR) 131 #endif 132 133 #undef CNVLIST_TAKE 134 135 #define CNVLIST_TAKE_ARRAY(ftype, type, NVTYPE) \ 136 ftype \ 137 cnvlist_take_##type(nvlist_t *nvl, void *cookiep, size_t *nitemsp) \ 138 { \ 139 ftype value; \ 140 \ 141 if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) { \ 142 nvlist_report_missing(NV_TYPE_##NVTYPE, \ 143 nvpair_name(cookiep)); \ 144 } \ 145 value = (ftype)(intptr_t)nvpair_get_##type(cookiep, nitemsp); \ 146 nvlist_remove_nvpair(nvl, cookiep); \ 147 nvpair_free_structure(cookiep); \ 148 return (value); \ 149 } 150 151 CNVLIST_TAKE_ARRAY(bool *, bool_array, BOOL_ARRAY) 152 CNVLIST_TAKE_ARRAY(uint64_t *, number_array, NUMBER_ARRAY) 153 CNVLIST_TAKE_ARRAY(char **, string_array, STRING_ARRAY) 154 CNVLIST_TAKE_ARRAY(nvlist_t **, nvlist_array, NVLIST_ARRAY) 155 #ifndef _KERNEL 156 CNVLIST_TAKE_ARRAY(int *, descriptor_array, DESCRIPTOR_ARRAY); 157 #endif 158 159 #undef CNVLIST_TAKE_ARRAY 160 161 void * 162 cnvlist_take_binary(nvlist_t *nvl, void *cookiep, size_t *sizep) 163 { 164 void *value; 165 166 if (nvpair_type(cookiep) != NV_TYPE_BINARY) 167 nvlist_report_missing(NV_TYPE_BINARY, nvpair_name(cookiep)); 168 value = (void *)(intptr_t)nvpair_get_binary(cookiep, sizep); 169 nvlist_remove_nvpair(nvl, cookiep); 170 nvpair_free_structure(cookiep); 171 return (value); 172 } 173 174 175 #define CNVLIST_FREE(type) \ 176 void \ 177 cnvlist_free_##type(nvlist_t *nvl, void *cookiep) \ 178 { \ 179 \ 180 nvlist_free_nvpair(nvl, cookiep); \ 181 } 182 183 CNVLIST_FREE(bool) 184 CNVLIST_FREE(number) 185 CNVLIST_FREE(string) 186 CNVLIST_FREE(nvlist) 187 CNVLIST_FREE(binary); 188 CNVLIST_FREE(bool_array) 189 CNVLIST_FREE(number_array) 190 CNVLIST_FREE(string_array) 191 CNVLIST_FREE(nvlist_array) 192 #ifndef _KERNEL 193 CNVLIST_FREE(descriptor) 194 CNVLIST_FREE(descriptor_array) 195 #endif 196 197 #undef CNVLIST_FREE 198