15ef231f6SMariusz Zaborski /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
31acf3485SMariusz Zaborski *
45ef231f6SMariusz Zaborski * Copyright (c) 2016 Adam Starak <starak.adam@gmail.com>
55ef231f6SMariusz Zaborski * All rights reserved.
65ef231f6SMariusz Zaborski *
75ef231f6SMariusz Zaborski * Redistribution and use in source and binary forms, with or without
85ef231f6SMariusz Zaborski * modification, are permitted provided that the following conditions
95ef231f6SMariusz Zaborski * are met:
105ef231f6SMariusz Zaborski * 1. Redistributions of source code must retain the above copyright
115ef231f6SMariusz Zaborski * notice, this list of conditions and the following disclaimer.
125ef231f6SMariusz Zaborski * 2. Redistributions in binary form must reproduce the above copyright
135ef231f6SMariusz Zaborski * notice, this list of conditions and the following disclaimer in the
145ef231f6SMariusz Zaborski * documentation and/or other materials provided with the distribution.
155ef231f6SMariusz Zaborski *
165ef231f6SMariusz Zaborski * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
175ef231f6SMariusz Zaborski * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185ef231f6SMariusz Zaborski * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
195ef231f6SMariusz Zaborski * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
205ef231f6SMariusz Zaborski * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215ef231f6SMariusz Zaborski * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
225ef231f6SMariusz Zaborski * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
235ef231f6SMariusz Zaborski * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245ef231f6SMariusz Zaborski * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
255ef231f6SMariusz Zaborski * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
265ef231f6SMariusz Zaborski * SUCH DAMAGE.
275ef231f6SMariusz Zaborski *
285ef231f6SMariusz Zaborski * $FreeBSD$
295ef231f6SMariusz Zaborski */
305ef231f6SMariusz Zaborski
315ef231f6SMariusz Zaborski #include <sys/cdefs.h>
325ef231f6SMariusz Zaborski __FBSDID("$FreeBSD$");
335ef231f6SMariusz Zaborski
345ef231f6SMariusz Zaborski #ifdef _KERNEL
355ef231f6SMariusz Zaborski
365ef231f6SMariusz Zaborski #include <sys/types.h>
375ef231f6SMariusz Zaborski #include <sys/param.h>
385ef231f6SMariusz Zaborski #include <sys/kernel.h>
395ef231f6SMariusz Zaborski #include <sys/systm.h>
405ef231f6SMariusz Zaborski #include <sys/malloc.h>
41*e453e498SBrooks Davis #include <sys/stdarg.h>
425ef231f6SMariusz Zaborski
435ef231f6SMariusz Zaborski #else
445ef231f6SMariusz Zaborski #include <stdarg.h>
455ef231f6SMariusz Zaborski #include <stdbool.h>
465ef231f6SMariusz Zaborski #include <stdint.h>
475ef231f6SMariusz Zaborski #include <stdlib.h>
485ef231f6SMariusz Zaborski #endif
495ef231f6SMariusz Zaborski
505ef231f6SMariusz Zaborski #include <sys/cnv.h>
515ef231f6SMariusz Zaborski #include <sys/nv.h>
525ef231f6SMariusz Zaborski
535ef231f6SMariusz Zaborski #include "nv_impl.h"
545ef231f6SMariusz Zaborski #include "nvlist_impl.h"
555ef231f6SMariusz Zaborski #include "nvpair_impl.h"
565ef231f6SMariusz Zaborski
5723c5a51eSMariusz Zaborski const char *
cnvlist_name(const void * cookie)5830665f3cSMariusz Zaborski cnvlist_name(const void *cookie)
5923c5a51eSMariusz Zaborski {
6023c5a51eSMariusz Zaborski
610db44d55SMariusz Zaborski return (nvpair_name(cookie));
6223c5a51eSMariusz Zaborski }
6323c5a51eSMariusz Zaborski
6423c5a51eSMariusz Zaborski int
cnvlist_type(const void * cookie)6530665f3cSMariusz Zaborski cnvlist_type(const void *cookie)
6623c5a51eSMariusz Zaborski {
6723c5a51eSMariusz Zaborski
680db44d55SMariusz Zaborski return (nvpair_type(cookie));
6923c5a51eSMariusz Zaborski }
7023c5a51eSMariusz Zaborski
71736bc737SMariusz Zaborski #define CNVLIST_GET(ftype, type, NVTYPE) \
725ef231f6SMariusz Zaborski ftype \
7330665f3cSMariusz Zaborski cnvlist_get_##type(const void *cookie) \
745ef231f6SMariusz Zaborski { \
755ef231f6SMariusz Zaborski \
760db44d55SMariusz Zaborski if (nvpair_type(cookie) != NV_TYPE_##NVTYPE) { \
77736bc737SMariusz Zaborski nvlist_report_missing(NV_TYPE_##NVTYPE, \
780db44d55SMariusz Zaborski nvpair_name(cookie)); \
79736bc737SMariusz Zaborski } \
800db44d55SMariusz Zaborski return (nvpair_get_##type(cookie)); \
815ef231f6SMariusz Zaborski }
825ef231f6SMariusz Zaborski
CNVLIST_GET(bool,bool,BOOL)835ef231f6SMariusz Zaborski CNVLIST_GET(bool, bool, BOOL)
845ef231f6SMariusz Zaborski CNVLIST_GET(uint64_t, number, NUMBER)
855ef231f6SMariusz Zaborski CNVLIST_GET(const char *, string, STRING)
865ef231f6SMariusz Zaborski CNVLIST_GET(const nvlist_t *, nvlist, NVLIST)
875ef231f6SMariusz Zaborski #ifndef _KERNEL
885ef231f6SMariusz Zaborski CNVLIST_GET(int, descriptor, DESCRIPTOR)
895ef231f6SMariusz Zaborski #endif
905ef231f6SMariusz Zaborski
915ef231f6SMariusz Zaborski #undef CNVLIST_GET
925ef231f6SMariusz Zaborski
93736bc737SMariusz Zaborski #define CNVLIST_GET_ARRAY(ftype, type, NVTYPE) \
945ef231f6SMariusz Zaborski ftype \
9530665f3cSMariusz Zaborski cnvlist_get_##type(const void *cookie, size_t *nitemsp) \
965ef231f6SMariusz Zaborski { \
975ef231f6SMariusz Zaborski \
980db44d55SMariusz Zaborski if (nvpair_type(cookie) != NV_TYPE_##NVTYPE) { \
99736bc737SMariusz Zaborski nvlist_report_missing(NV_TYPE_##NVTYPE, \
1000db44d55SMariusz Zaborski nvpair_name(cookie)); \
101736bc737SMariusz Zaborski } \
1020db44d55SMariusz Zaborski return (nvpair_get_##type(cookie, nitemsp)); \
1035ef231f6SMariusz Zaborski }
1045ef231f6SMariusz Zaborski
1055ef231f6SMariusz Zaborski CNVLIST_GET_ARRAY(const bool *, bool_array, BOOL_ARRAY)
1065ef231f6SMariusz Zaborski CNVLIST_GET_ARRAY(const uint64_t *, number_array, NUMBER_ARRAY)
1075ef231f6SMariusz Zaborski CNVLIST_GET_ARRAY(const char * const *, string_array, STRING_ARRAY)
1085ef231f6SMariusz Zaborski CNVLIST_GET_ARRAY(const nvlist_t * const *, nvlist_array, NVLIST_ARRAY)
1095ef231f6SMariusz Zaborski #ifndef _KERNEL
1105ef231f6SMariusz Zaborski CNVLIST_GET_ARRAY(const int *, descriptor_array, DESCRIPTOR_ARRAY)
1115ef231f6SMariusz Zaborski #endif
1125ef231f6SMariusz Zaborski
1135ef231f6SMariusz Zaborski #undef CNVLIST_GET_ARRAY
1145ef231f6SMariusz Zaborski
1155ef231f6SMariusz Zaborski const void *
11630665f3cSMariusz Zaborski cnvlist_get_binary(const void *cookie, size_t *sizep)
1175ef231f6SMariusz Zaborski {
1185ef231f6SMariusz Zaborski
1190db44d55SMariusz Zaborski if (nvpair_type(cookie) != NV_TYPE_BINARY)
1200db44d55SMariusz Zaborski nvlist_report_missing(NV_TYPE_BINARY, nvpair_name(cookie));
1210db44d55SMariusz Zaborski return (nvpair_get_binary(cookie, sizep));
1225ef231f6SMariusz Zaborski }
1235ef231f6SMariusz Zaborski
124736bc737SMariusz Zaborski #define CNVLIST_TAKE(ftype, type, NVTYPE) \
1255ef231f6SMariusz Zaborski ftype \
126d82e41b6SMariusz Zaborski cnvlist_take_##type(void *cookie) \
1275ef231f6SMariusz Zaborski { \
1285ef231f6SMariusz Zaborski ftype value; \
129d82e41b6SMariusz Zaborski nvlist_t *nvl; \
1305ef231f6SMariusz Zaborski \
1310db44d55SMariusz Zaborski if (nvpair_type(cookie) != NV_TYPE_##NVTYPE) { \
132736bc737SMariusz Zaborski nvlist_report_missing(NV_TYPE_##NVTYPE, \
1330db44d55SMariusz Zaborski nvpair_name(cookie)); \
134736bc737SMariusz Zaborski } \
135d82e41b6SMariusz Zaborski nvl = nvpair_nvlist(cookie); \
1360db44d55SMariusz Zaborski value = (ftype)(intptr_t)nvpair_get_##type(cookie); \
1370db44d55SMariusz Zaborski nvlist_remove_nvpair(nvl, cookie); \
1380db44d55SMariusz Zaborski nvpair_free_structure(cookie); \
1395ef231f6SMariusz Zaborski return (value); \
1405ef231f6SMariusz Zaborski }
1415ef231f6SMariusz Zaborski
1425ef231f6SMariusz Zaborski CNVLIST_TAKE(bool, bool, BOOL)
1435ef231f6SMariusz Zaborski CNVLIST_TAKE(uint64_t, number, NUMBER)
1445ef231f6SMariusz Zaborski CNVLIST_TAKE(char *, string, STRING)
1455ef231f6SMariusz Zaborski CNVLIST_TAKE(nvlist_t *, nvlist, NVLIST)
1465ef231f6SMariusz Zaborski #ifndef _KERNEL
1475ef231f6SMariusz Zaborski CNVLIST_TAKE(int, descriptor, DESCRIPTOR)
1485ef231f6SMariusz Zaborski #endif
1495ef231f6SMariusz Zaborski
1505ef231f6SMariusz Zaborski #undef CNVLIST_TAKE
1515ef231f6SMariusz Zaborski
152736bc737SMariusz Zaborski #define CNVLIST_TAKE_ARRAY(ftype, type, NVTYPE) \
1535ef231f6SMariusz Zaborski ftype \
154d82e41b6SMariusz Zaborski cnvlist_take_##type(void *cookie, size_t *nitemsp) \
1555ef231f6SMariusz Zaborski { \
1565ef231f6SMariusz Zaborski ftype value; \
157d82e41b6SMariusz Zaborski nvlist_t *nvl; \
1585ef231f6SMariusz Zaborski \
1590db44d55SMariusz Zaborski if (nvpair_type(cookie) != NV_TYPE_##NVTYPE) { \
160736bc737SMariusz Zaborski nvlist_report_missing(NV_TYPE_##NVTYPE, \
1610db44d55SMariusz Zaborski nvpair_name(cookie)); \
162736bc737SMariusz Zaborski } \
163d82e41b6SMariusz Zaborski nvl = nvpair_nvlist(cookie); \
1640db44d55SMariusz Zaborski value = (ftype)(intptr_t)nvpair_get_##type(cookie, nitemsp); \
1650db44d55SMariusz Zaborski nvlist_remove_nvpair(nvl, cookie); \
1660db44d55SMariusz Zaborski nvpair_free_structure(cookie); \
1675ef231f6SMariusz Zaborski return (value); \
1685ef231f6SMariusz Zaborski }
1695ef231f6SMariusz Zaborski
1705ef231f6SMariusz Zaborski CNVLIST_TAKE_ARRAY(bool *, bool_array, BOOL_ARRAY)
1715ef231f6SMariusz Zaborski CNVLIST_TAKE_ARRAY(uint64_t *, number_array, NUMBER_ARRAY)
1725ef231f6SMariusz Zaborski CNVLIST_TAKE_ARRAY(char **, string_array, STRING_ARRAY)
1735ef231f6SMariusz Zaborski CNVLIST_TAKE_ARRAY(nvlist_t **, nvlist_array, NVLIST_ARRAY)
1745ef231f6SMariusz Zaborski #ifndef _KERNEL
1755ef231f6SMariusz Zaborski CNVLIST_TAKE_ARRAY(int *, descriptor_array, DESCRIPTOR_ARRAY);
1765ef231f6SMariusz Zaborski #endif
1775ef231f6SMariusz Zaborski
1785ef231f6SMariusz Zaborski #undef CNVLIST_TAKE_ARRAY
1795ef231f6SMariusz Zaborski
1805ef231f6SMariusz Zaborski void *
cnvlist_take_binary(void * cookie,size_t * sizep)181d82e41b6SMariusz Zaborski cnvlist_take_binary(void *cookie, size_t *sizep)
1825ef231f6SMariusz Zaborski {
1835ef231f6SMariusz Zaborski void *value;
184d82e41b6SMariusz Zaborski nvlist_t *nvl;
1855ef231f6SMariusz Zaborski
1860db44d55SMariusz Zaborski if (nvpair_type(cookie) != NV_TYPE_BINARY)
1870db44d55SMariusz Zaborski nvlist_report_missing(NV_TYPE_BINARY, nvpair_name(cookie));
188d82e41b6SMariusz Zaborski nvl = nvpair_nvlist(cookie);
1890db44d55SMariusz Zaborski value = (void *)(intptr_t)nvpair_get_binary(cookie, sizep);
1900db44d55SMariusz Zaborski nvlist_remove_nvpair(nvl, cookie);
1910db44d55SMariusz Zaborski nvpair_free_structure(cookie);
1925ef231f6SMariusz Zaborski return (value);
1935ef231f6SMariusz Zaborski }
1945ef231f6SMariusz Zaborski
1955ef231f6SMariusz Zaborski
196736bc737SMariusz Zaborski #define CNVLIST_FREE(type) \
1975ef231f6SMariusz Zaborski void \
198d82e41b6SMariusz Zaborski cnvlist_free_##type(void *cookie) \
1995ef231f6SMariusz Zaborski { \
2005ef231f6SMariusz Zaborski \
201d82e41b6SMariusz Zaborski nvlist_free_nvpair(nvpair_nvlist(cookie), cookie); \
2025ef231f6SMariusz Zaborski }
2035ef231f6SMariusz Zaborski
204736bc737SMariusz Zaborski CNVLIST_FREE(bool)
205736bc737SMariusz Zaborski CNVLIST_FREE(number)
206736bc737SMariusz Zaborski CNVLIST_FREE(string)
207736bc737SMariusz Zaborski CNVLIST_FREE(nvlist)
208736bc737SMariusz Zaborski CNVLIST_FREE(binary);
209736bc737SMariusz Zaborski CNVLIST_FREE(bool_array)
210736bc737SMariusz Zaborski CNVLIST_FREE(number_array)
211736bc737SMariusz Zaborski CNVLIST_FREE(string_array)
212736bc737SMariusz Zaborski CNVLIST_FREE(nvlist_array)
2135ef231f6SMariusz Zaborski #ifndef _KERNEL
214736bc737SMariusz Zaborski CNVLIST_FREE(descriptor)
215736bc737SMariusz Zaborski CNVLIST_FREE(descriptor_array)
2165ef231f6SMariusz Zaborski #endif
2175ef231f6SMariusz Zaborski
2185ef231f6SMariusz Zaborski #undef CNVLIST_FREE
219