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