xref: /freebsd/sys/contrib/libnv/cnvlist.c (revision 8e6e287f8d1f4f58bb94cc71b3b46c543569f83f)
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 const char *
57 cnvlist_name(void *cookiep)
58 {
59 
60 	return (nvpair_name(cookiep));
61 }
62 
63 int
64 cnvlist_type(void *cookiep)
65 {
66 
67 	return (nvpair_type(cookiep));
68 }
69 
70 #define	CNVLIST_GET(ftype, type, NVTYPE)				\
71 ftype									\
72 cnvlist_get_##type(void *cookiep)					\
73 {									\
74 									\
75 	if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) {			\
76 		nvlist_report_missing(NV_TYPE_##NVTYPE,			\
77 		    nvpair_name(cookiep));				\
78 	}								\
79         return (nvpair_get_##type(cookiep));				\
80 }
81 
82 CNVLIST_GET(bool, bool, BOOL)
83 CNVLIST_GET(uint64_t, number, NUMBER)
84 CNVLIST_GET(const char *, string, STRING)
85 CNVLIST_GET(const nvlist_t *, nvlist, NVLIST)
86 #ifndef _KERNEL
87 CNVLIST_GET(int, descriptor, DESCRIPTOR)
88 #endif
89 
90 #undef	CNVLIST_GET
91 
92 #define	CNVLIST_GET_ARRAY(ftype, type, NVTYPE)				\
93 ftype									\
94 cnvlist_get_##type(void *cookiep, size_t *nitemsp)			\
95 {									\
96 									\
97 	if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) {			\
98 		nvlist_report_missing(NV_TYPE_##NVTYPE,			\
99 		    nvpair_name(cookiep));				\
100 	}								\
101 	return (nvpair_get_##type(cookiep, nitemsp));			\
102 }
103 
104 CNVLIST_GET_ARRAY(const bool *, bool_array, BOOL_ARRAY)
105 CNVLIST_GET_ARRAY(const uint64_t *, number_array, NUMBER_ARRAY)
106 CNVLIST_GET_ARRAY(const char * const *, string_array, STRING_ARRAY)
107 CNVLIST_GET_ARRAY(const nvlist_t * const *, nvlist_array, NVLIST_ARRAY)
108 #ifndef _KERNEL
109 CNVLIST_GET_ARRAY(const int *, descriptor_array, DESCRIPTOR_ARRAY)
110 #endif
111 
112 #undef	CNVLIST_GET_ARRAY
113 
114 const void *
115 cnvlist_get_binary(void *cookiep, size_t *sizep)
116 {
117 
118 	if (nvpair_type(cookiep) != NV_TYPE_BINARY)
119 		nvlist_report_missing(NV_TYPE_BINARY, nvpair_name(cookiep));
120 	return (nvpair_get_binary(cookiep, sizep));
121 }
122 
123 #define CNVLIST_TAKE(ftype, type, NVTYPE)				\
124 ftype									\
125 cnvlist_take_##type(nvlist_t *nvl, void *cookiep)			\
126 {									\
127 	ftype value;							\
128 									\
129 	if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) {			\
130 		nvlist_report_missing(NV_TYPE_##NVTYPE,			\
131 		    nvpair_name(cookiep));				\
132 	}								\
133 	value = (ftype)(intptr_t)nvpair_get_##type(cookiep);		\
134 	nvlist_remove_nvpair(nvl, cookiep);				\
135 	nvpair_free_structure(cookiep);					\
136 	return (value);							\
137 }
138 
139 CNVLIST_TAKE(bool, bool, BOOL)
140 CNVLIST_TAKE(uint64_t, number, NUMBER)
141 CNVLIST_TAKE(char *, string, STRING)
142 CNVLIST_TAKE(nvlist_t *, nvlist, NVLIST)
143 #ifndef _KERNEL
144 CNVLIST_TAKE(int, descriptor, DESCRIPTOR)
145 #endif
146 
147 #undef	CNVLIST_TAKE
148 
149 #define	CNVLIST_TAKE_ARRAY(ftype, type, NVTYPE)				\
150 ftype									\
151 cnvlist_take_##type(nvlist_t *nvl, void *cookiep, size_t *nitemsp)	\
152 {									\
153 	ftype value;							\
154 									\
155 	if (nvpair_type(cookiep) != NV_TYPE_##NVTYPE) {			\
156 		nvlist_report_missing(NV_TYPE_##NVTYPE,			\
157 		    nvpair_name(cookiep));				\
158 	}								\
159 	value = (ftype)(intptr_t)nvpair_get_##type(cookiep, nitemsp);	\
160 	nvlist_remove_nvpair(nvl, cookiep);				\
161 	nvpair_free_structure(cookiep);					\
162 	return (value);							\
163 }
164 
165 CNVLIST_TAKE_ARRAY(bool *, bool_array, BOOL_ARRAY)
166 CNVLIST_TAKE_ARRAY(uint64_t *, number_array, NUMBER_ARRAY)
167 CNVLIST_TAKE_ARRAY(char **, string_array, STRING_ARRAY)
168 CNVLIST_TAKE_ARRAY(nvlist_t **, nvlist_array, NVLIST_ARRAY)
169 #ifndef _KERNEL
170 CNVLIST_TAKE_ARRAY(int *, descriptor_array, DESCRIPTOR_ARRAY);
171 #endif
172 
173 #undef	CNVLIST_TAKE_ARRAY
174 
175 void *
176 cnvlist_take_binary(nvlist_t *nvl, void *cookiep, size_t *sizep)
177 {
178 	void *value;
179 
180 	if (nvpair_type(cookiep) != NV_TYPE_BINARY)
181 		nvlist_report_missing(NV_TYPE_BINARY, nvpair_name(cookiep));
182 	value = (void *)(intptr_t)nvpair_get_binary(cookiep, sizep);
183 	nvlist_remove_nvpair(nvl, cookiep);
184 	nvpair_free_structure(cookiep);
185 	return (value);
186 }
187 
188 
189 #define	CNVLIST_FREE(type)						\
190 void									\
191 cnvlist_free_##type(nvlist_t *nvl, void *cookiep)			\
192 {									\
193 									\
194 	nvlist_free_nvpair(nvl, cookiep);				\
195 }
196 
197 CNVLIST_FREE(bool)
198 CNVLIST_FREE(number)
199 CNVLIST_FREE(string)
200 CNVLIST_FREE(nvlist)
201 CNVLIST_FREE(binary);
202 CNVLIST_FREE(bool_array)
203 CNVLIST_FREE(number_array)
204 CNVLIST_FREE(string_array)
205 CNVLIST_FREE(nvlist_array)
206 #ifndef _KERNEL
207 CNVLIST_FREE(descriptor)
208 CNVLIST_FREE(descriptor_array)
209 #endif
210 
211 #undef	CNVLIST_FREE
212