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