xref: /freebsd/sys/contrib/libnv/cnvlist.c (revision e453e498cbb88570a3ff7b3679de65c88707da95)
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