]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libnv/dnvlist.c
Handle empty nvlists correctly.
[FreeBSD/FreeBSD.git] / lib / libnv / dnvlist.c
1 /*-
2  * Copyright (c) 2013 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <stdarg.h>
34 #include <stdbool.h>
35 #include <stdint.h>
36
37 #include "nv.h"
38 #include "nv_impl.h"
39
40 #include "dnv.h"
41
42 #define DNVLIST_GET(ftype, type)                                        \
43 ftype                                                                   \
44 dnvlist_get_##type(const nvlist_t *nvl, const char *name, ftype defval) \
45 {                                                                       \
46                                                                         \
47         return (dnvlist_getf_##type(nvl, defval, "%s", name));          \
48 }
49
50 DNVLIST_GET(bool, bool)
51 DNVLIST_GET(uint64_t, number)
52 DNVLIST_GET(const char *, string)
53 DNVLIST_GET(const nvlist_t *, nvlist)
54 DNVLIST_GET(int, descriptor)
55
56 #undef  DNVLIST_GET
57
58 const void *
59 dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep,
60     const void *defval, size_t defsize)
61 {
62
63         return (dnvlist_getf_binary(nvl, sizep, defval, defsize, "%s", name));
64 }
65
66 #define DNVLIST_GETF(ftype, type)                                       \
67 ftype                                                                   \
68 dnvlist_getf_##type(const nvlist_t *nvl, ftype defval,                  \
69     const char *namefmt, ...)                                           \
70 {                                                                       \
71         va_list nameap;                                                 \
72         ftype value;                                                    \
73                                                                         \
74         va_start(nameap, namefmt);                                      \
75         value = dnvlist_getv_##type(nvl, defval, namefmt, nameap);      \
76         va_end(nameap);                                                 \
77                                                                         \
78         return (value);                                                 \
79 }
80
81 DNVLIST_GETF(bool, bool)
82 DNVLIST_GETF(uint64_t, number)
83 DNVLIST_GETF(const char *, string)
84 DNVLIST_GETF(const nvlist_t *, nvlist)
85 DNVLIST_GETF(int, descriptor)
86
87 #undef  DNVLIST_GETF
88
89 const void *
90 dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
91     size_t defsize, const char *namefmt, ...)
92 {
93         va_list nameap;
94         const void *value;
95
96         va_start(nameap, namefmt);
97         value = dnvlist_getv_binary(nvl, sizep, defval, defsize, namefmt,
98             nameap);
99         va_end(nameap);
100
101         return (value);
102 }
103
104 #define DNVLIST_GETV(ftype, type)                                       \
105 ftype                                                                   \
106 dnvlist_getv_##type(const nvlist_t *nvl, ftype defval,                  \
107     const char *namefmt, va_list nameap)                                \
108 {                                                                       \
109         va_list cnameap;                                                \
110         ftype value;                                                    \
111                                                                         \
112         va_copy(cnameap, nameap);                                       \
113         if (nvlist_existsv_##type(nvl, namefmt, cnameap))               \
114                 value = nvlist_getv_##type(nvl, namefmt, nameap);       \
115         else                                                            \
116                 value = defval;                                         \
117         va_end(cnameap);                                                \
118         return (value);                                                 \
119 }
120
121 DNVLIST_GETV(bool, bool)
122 DNVLIST_GETV(uint64_t, number)
123 DNVLIST_GETV(const char *, string)
124 DNVLIST_GETV(const nvlist_t *, nvlist)
125 DNVLIST_GETV(int, descriptor)
126
127 #undef  DNVLIST_GETV
128
129 const void *
130 dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
131     size_t defsize, const char *namefmt, va_list nameap)
132 {
133         va_list cnameap;
134         const void *value;
135
136         va_copy(cnameap, nameap);
137         if (nvlist_existsv_binary(nvl, namefmt, cnameap)) {
138                 value = nvlist_getv_binary(nvl, sizep, namefmt, nameap);
139         } else {
140                 if (sizep != NULL)
141                         *sizep = defsize;
142                 value = defval;
143         }
144         va_end(cnameap);
145         return (value);
146 }
147
148 #define DNVLIST_TAKE(ftype, type)                                       \
149 ftype                                                                   \
150 dnvlist_take_##type(nvlist_t *nvl, const char *name, ftype defval)      \
151 {                                                                       \
152                                                                         \
153         return (dnvlist_takef_##type(nvl, defval, "%s", name));         \
154 }
155
156 DNVLIST_TAKE(bool, bool)
157 DNVLIST_TAKE(uint64_t, number)
158 DNVLIST_TAKE(char *, string)
159 DNVLIST_TAKE(nvlist_t *, nvlist)
160 DNVLIST_TAKE(int, descriptor)
161
162 #undef  DNVLIST_TAKE
163
164 void *
165 dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep,
166     void *defval, size_t defsize)
167 {
168
169         return (dnvlist_takef_binary(nvl, sizep, defval, defsize, "%s", name));
170 }
171
172 #define DNVLIST_TAKEF(ftype, type)                                      \
173 ftype                                                                   \
174 dnvlist_takef_##type(nvlist_t *nvl, ftype defval,                       \
175     const char *namefmt, ...)                                           \
176 {                                                                       \
177         va_list nameap;                                                 \
178         ftype value;                                                    \
179                                                                         \
180         va_start(nameap, namefmt);                                      \
181         value = dnvlist_takev_##type(nvl, defval, namefmt, nameap);     \
182         va_end(nameap);                                                 \
183                                                                         \
184         return (value);                                                 \
185 }
186
187 DNVLIST_TAKEF(bool, bool)
188 DNVLIST_TAKEF(uint64_t, number)
189 DNVLIST_TAKEF(char *, string)
190 DNVLIST_TAKEF(nvlist_t *, nvlist)
191 DNVLIST_TAKEF(int, descriptor)
192
193 #undef  DNVLIST_TAKEF
194
195 void *
196 dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval,
197     size_t defsize, const char *namefmt, ...)
198 {
199         va_list nameap;
200         void *value;
201
202         va_start(nameap, namefmt);
203         value = dnvlist_takev_binary(nvl, sizep, defval, defsize, namefmt,
204             nameap);
205         va_end(nameap);
206
207         return (value);
208 }
209
210 #define DNVLIST_TAKEV(ftype, type)                                      \
211 ftype                                                                   \
212 dnvlist_takev_##type(nvlist_t *nvl, ftype defval, const char *namefmt,  \
213     va_list nameap)                                                     \
214 {                                                                       \
215         va_list cnameap;                                                \
216         ftype value;                                                    \
217                                                                         \
218         va_copy(cnameap, nameap);                                       \
219         if (nvlist_existsv_##type(nvl, namefmt, cnameap))               \
220                 value = nvlist_takev_##type(nvl, namefmt, nameap);      \
221         else                                                            \
222                 value = defval;                                         \
223         va_end(cnameap);                                                \
224         return (value);                                                 \
225 }
226
227 DNVLIST_TAKEV(bool, bool)
228 DNVLIST_TAKEV(uint64_t, number)
229 DNVLIST_TAKEV(char *, string)
230 DNVLIST_TAKEV(nvlist_t *, nvlist)
231 DNVLIST_TAKEV(int, descriptor)
232
233 #undef  DNVLIST_TAKEV
234
235 void *
236 dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval,
237     size_t defsize, const char *namefmt, va_list nameap)
238 {
239         va_list cnameap;
240         void *value;
241
242         va_copy(cnameap, nameap);
243         if (nvlist_existsv_binary(nvl, namefmt, cnameap)) {
244                 value = nvlist_takev_binary(nvl, sizep, namefmt, nameap);
245         } else {
246                 if (sizep != NULL)
247                         *sizep = defsize;
248                 value = defval;
249         }
250         va_end(cnameap);
251         return (value);
252 }