xref: /titanic_52/usr/src/lib/libnvpair/nvpair_json.c (revision 2db6d663182655cb393dc2c15668bc9293364594)
1*2db6d663SJoshua M. Clulow /*
2*2db6d663SJoshua M. Clulow  * This file and its contents are supplied under the terms of the
3*2db6d663SJoshua M. Clulow  * Common Development and Distribution License ("CDDL"), version 1.0.
4*2db6d663SJoshua M. Clulow  * You may only use this file in accordance with the terms of version
5*2db6d663SJoshua M. Clulow  * 1.0 of the CDDL.
6*2db6d663SJoshua M. Clulow  *
7*2db6d663SJoshua M. Clulow  * A full copy of the text of the CDDL should have accompanied this
8*2db6d663SJoshua M. Clulow  * source.  A copy of the CDDL is also available via the Internet at
9*2db6d663SJoshua M. Clulow  * http://www.illumos.org/license/CDDL.
10*2db6d663SJoshua M. Clulow  */
11*2db6d663SJoshua M. Clulow /*
12*2db6d663SJoshua M. Clulow  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
13*2db6d663SJoshua M. Clulow  */
14*2db6d663SJoshua M. Clulow 
15*2db6d663SJoshua M. Clulow #include <stdio.h>
16*2db6d663SJoshua M. Clulow #include <stdlib.h>
17*2db6d663SJoshua M. Clulow #include <strings.h>
18*2db6d663SJoshua M. Clulow #include <wchar.h>
19*2db6d663SJoshua M. Clulow #include <sys/debug.h>
20*2db6d663SJoshua M. Clulow 
21*2db6d663SJoshua M. Clulow #include "libnvpair.h"
22*2db6d663SJoshua M. Clulow 
23*2db6d663SJoshua M. Clulow #define	FPRINTF(fp, ...)			\
24*2db6d663SJoshua M. Clulow 	if (fprintf(fp, __VA_ARGS__) < 0)	\
25*2db6d663SJoshua M. Clulow 		return (-1)			\
26*2db6d663SJoshua M. Clulow 
27*2db6d663SJoshua M. Clulow /*
28*2db6d663SJoshua M. Clulow  * When formatting a string for JSON output we must escape certain characters,
29*2db6d663SJoshua M. Clulow  * as described in RFC4627.  This applies to both member names and
30*2db6d663SJoshua M. Clulow  * DATA_TYPE_STRING values.
31*2db6d663SJoshua M. Clulow  *
32*2db6d663SJoshua M. Clulow  * This function will only operate correctly if the following conditions are
33*2db6d663SJoshua M. Clulow  * met:
34*2db6d663SJoshua M. Clulow  *
35*2db6d663SJoshua M. Clulow  *       1. The input String is encoded in the current locale.
36*2db6d663SJoshua M. Clulow  *
37*2db6d663SJoshua M. Clulow  *       2. The current locale includes the Basic Multilingual Plane (plane 0)
38*2db6d663SJoshua M. Clulow  *          as defined in the Unicode standard.
39*2db6d663SJoshua M. Clulow  *
40*2db6d663SJoshua M. Clulow  * The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all
41*2db6d663SJoshua M. Clulow  * representable Unicode characters included in their escaped numeric form.
42*2db6d663SJoshua M. Clulow  */
43*2db6d663SJoshua M. Clulow static int
44*2db6d663SJoshua M. Clulow nvlist_print_json_string(FILE *fp, const char *input)
45*2db6d663SJoshua M. Clulow {
46*2db6d663SJoshua M. Clulow 	mbstate_t mbr;
47*2db6d663SJoshua M. Clulow 	wchar_t c;
48*2db6d663SJoshua M. Clulow 	size_t sz;
49*2db6d663SJoshua M. Clulow 
50*2db6d663SJoshua M. Clulow 	bzero(&mbr, sizeof (mbr));
51*2db6d663SJoshua M. Clulow 
52*2db6d663SJoshua M. Clulow 	FPRINTF(fp, "\"");
53*2db6d663SJoshua M. Clulow 	while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) {
54*2db6d663SJoshua M. Clulow 		switch (c) {
55*2db6d663SJoshua M. Clulow 		case '"':
56*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\\"");
57*2db6d663SJoshua M. Clulow 			break;
58*2db6d663SJoshua M. Clulow 		case '\n':
59*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\n");
60*2db6d663SJoshua M. Clulow 			break;
61*2db6d663SJoshua M. Clulow 		case '\r':
62*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\r");
63*2db6d663SJoshua M. Clulow 			break;
64*2db6d663SJoshua M. Clulow 		case '\\':
65*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\\\");
66*2db6d663SJoshua M. Clulow 			break;
67*2db6d663SJoshua M. Clulow 		case '\f':
68*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\f");
69*2db6d663SJoshua M. Clulow 			break;
70*2db6d663SJoshua M. Clulow 		case '\t':
71*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\t");
72*2db6d663SJoshua M. Clulow 			break;
73*2db6d663SJoshua M. Clulow 		case '\b':
74*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "\\b");
75*2db6d663SJoshua M. Clulow 			break;
76*2db6d663SJoshua M. Clulow 		default:
77*2db6d663SJoshua M. Clulow 			if ((c >= 0x00 && c <= 0x1f) ||
78*2db6d663SJoshua M. Clulow 			    (c > 0x7f && c <= 0xffff)) {
79*2db6d663SJoshua M. Clulow 				/*
80*2db6d663SJoshua M. Clulow 				 * Render both Control Characters and Unicode
81*2db6d663SJoshua M. Clulow 				 * characters in the Basic Multilingual Plane
82*2db6d663SJoshua M. Clulow 				 * as JSON-escaped multibyte characters.
83*2db6d663SJoshua M. Clulow 				 */
84*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "\\u%04x", (int)(0xffff & c));
85*2db6d663SJoshua M. Clulow 			} else if (c >= 0x20 && c <= 0x7f) {
86*2db6d663SJoshua M. Clulow 				/*
87*2db6d663SJoshua M. Clulow 				 * Render other 7-bit ASCII characters directly
88*2db6d663SJoshua M. Clulow 				 * and drop other, unrepresentable characters.
89*2db6d663SJoshua M. Clulow 				 */
90*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%c", (int)(0xff & c));
91*2db6d663SJoshua M. Clulow 			}
92*2db6d663SJoshua M. Clulow 			break;
93*2db6d663SJoshua M. Clulow 		}
94*2db6d663SJoshua M. Clulow 		input += sz;
95*2db6d663SJoshua M. Clulow 	}
96*2db6d663SJoshua M. Clulow 
97*2db6d663SJoshua M. Clulow 	if (sz == (size_t)-1 || sz == (size_t)-2) {
98*2db6d663SJoshua M. Clulow 		/*
99*2db6d663SJoshua M. Clulow 		 * We last read an invalid multibyte character sequence,
100*2db6d663SJoshua M. Clulow 		 * so return an error.
101*2db6d663SJoshua M. Clulow 		 */
102*2db6d663SJoshua M. Clulow 		return (-1);
103*2db6d663SJoshua M. Clulow 	}
104*2db6d663SJoshua M. Clulow 
105*2db6d663SJoshua M. Clulow 	FPRINTF(fp, "\"");
106*2db6d663SJoshua M. Clulow 	return (0);
107*2db6d663SJoshua M. Clulow }
108*2db6d663SJoshua M. Clulow 
109*2db6d663SJoshua M. Clulow /*
110*2db6d663SJoshua M. Clulow  * Dump a JSON-formatted representation of an nvlist to the provided FILE *.
111*2db6d663SJoshua M. Clulow  * This routine does not output any new-lines or additional whitespace other
112*2db6d663SJoshua M. Clulow  * than that contained in strings, nor does it call fflush(3C).
113*2db6d663SJoshua M. Clulow  */
114*2db6d663SJoshua M. Clulow int
115*2db6d663SJoshua M. Clulow nvlist_print_json(FILE *fp, nvlist_t *nvl)
116*2db6d663SJoshua M. Clulow {
117*2db6d663SJoshua M. Clulow 	nvpair_t *curr;
118*2db6d663SJoshua M. Clulow 	boolean_t first = B_TRUE;
119*2db6d663SJoshua M. Clulow 
120*2db6d663SJoshua M. Clulow 	FPRINTF(fp, "{");
121*2db6d663SJoshua M. Clulow 
122*2db6d663SJoshua M. Clulow 	for (curr = nvlist_next_nvpair(nvl, NULL); curr;
123*2db6d663SJoshua M. Clulow 	    curr = nvlist_next_nvpair(nvl, curr)) {
124*2db6d663SJoshua M. Clulow 		data_type_t type = nvpair_type(curr);
125*2db6d663SJoshua M. Clulow 
126*2db6d663SJoshua M. Clulow 		if (!first)
127*2db6d663SJoshua M. Clulow 			FPRINTF(fp, ",");
128*2db6d663SJoshua M. Clulow 		else
129*2db6d663SJoshua M. Clulow 			first = B_FALSE;
130*2db6d663SJoshua M. Clulow 
131*2db6d663SJoshua M. Clulow 		if (nvlist_print_json_string(fp, nvpair_name(curr)) == -1)
132*2db6d663SJoshua M. Clulow 			return (-1);
133*2db6d663SJoshua M. Clulow 		FPRINTF(fp, ":");
134*2db6d663SJoshua M. Clulow 
135*2db6d663SJoshua M. Clulow 		switch (type) {
136*2db6d663SJoshua M. Clulow 		case DATA_TYPE_STRING: {
137*2db6d663SJoshua M. Clulow 			char *string = fnvpair_value_string(curr);
138*2db6d663SJoshua M. Clulow 			if (nvlist_print_json_string(fp, string) == -1)
139*2db6d663SJoshua M. Clulow 				return (-1);
140*2db6d663SJoshua M. Clulow 			break;
141*2db6d663SJoshua M. Clulow 		}
142*2db6d663SJoshua M. Clulow 
143*2db6d663SJoshua M. Clulow 		case DATA_TYPE_BOOLEAN: {
144*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "true");
145*2db6d663SJoshua M. Clulow 			break;
146*2db6d663SJoshua M. Clulow 		}
147*2db6d663SJoshua M. Clulow 
148*2db6d663SJoshua M. Clulow 		case DATA_TYPE_BOOLEAN_VALUE: {
149*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) ==
150*2db6d663SJoshua M. Clulow 			    B_TRUE ? "true" : "false");
151*2db6d663SJoshua M. Clulow 			break;
152*2db6d663SJoshua M. Clulow 		}
153*2db6d663SJoshua M. Clulow 
154*2db6d663SJoshua M. Clulow 		case DATA_TYPE_BYTE: {
155*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%hhu", fnvpair_value_byte(curr));
156*2db6d663SJoshua M. Clulow 			break;
157*2db6d663SJoshua M. Clulow 		}
158*2db6d663SJoshua M. Clulow 
159*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT8: {
160*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%hhd", fnvpair_value_int8(curr));
161*2db6d663SJoshua M. Clulow 			break;
162*2db6d663SJoshua M. Clulow 		}
163*2db6d663SJoshua M. Clulow 
164*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT8: {
165*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr));
166*2db6d663SJoshua M. Clulow 			break;
167*2db6d663SJoshua M. Clulow 		}
168*2db6d663SJoshua M. Clulow 
169*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT16: {
170*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%hd", fnvpair_value_int16(curr));
171*2db6d663SJoshua M. Clulow 			break;
172*2db6d663SJoshua M. Clulow 		}
173*2db6d663SJoshua M. Clulow 
174*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT16: {
175*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%hu", fnvpair_value_uint16(curr));
176*2db6d663SJoshua M. Clulow 			break;
177*2db6d663SJoshua M. Clulow 		}
178*2db6d663SJoshua M. Clulow 
179*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT32: {
180*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%d", fnvpair_value_int32(curr));
181*2db6d663SJoshua M. Clulow 			break;
182*2db6d663SJoshua M. Clulow 		}
183*2db6d663SJoshua M. Clulow 
184*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT32: {
185*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%u", fnvpair_value_uint32(curr));
186*2db6d663SJoshua M. Clulow 			break;
187*2db6d663SJoshua M. Clulow 		}
188*2db6d663SJoshua M. Clulow 
189*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT64: {
190*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%lld",
191*2db6d663SJoshua M. Clulow 			    (long long)fnvpair_value_int64(curr));
192*2db6d663SJoshua M. Clulow 			break;
193*2db6d663SJoshua M. Clulow 		}
194*2db6d663SJoshua M. Clulow 
195*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT64: {
196*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%llu",
197*2db6d663SJoshua M. Clulow 			    (unsigned long long)fnvpair_value_uint64(curr));
198*2db6d663SJoshua M. Clulow 			break;
199*2db6d663SJoshua M. Clulow 		}
200*2db6d663SJoshua M. Clulow 
201*2db6d663SJoshua M. Clulow 		case DATA_TYPE_HRTIME: {
202*2db6d663SJoshua M. Clulow 			hrtime_t val;
203*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_hrtime(curr, &val));
204*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%llu", (unsigned long long)val);
205*2db6d663SJoshua M. Clulow 			break;
206*2db6d663SJoshua M. Clulow 		}
207*2db6d663SJoshua M. Clulow 
208*2db6d663SJoshua M. Clulow 		case DATA_TYPE_DOUBLE: {
209*2db6d663SJoshua M. Clulow 			double val;
210*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_double(curr, &val));
211*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "%f", val);
212*2db6d663SJoshua M. Clulow 			break;
213*2db6d663SJoshua M. Clulow 		}
214*2db6d663SJoshua M. Clulow 
215*2db6d663SJoshua M. Clulow 		case DATA_TYPE_NVLIST: {
216*2db6d663SJoshua M. Clulow 			if (nvlist_print_json(fp,
217*2db6d663SJoshua M. Clulow 			    fnvpair_value_nvlist(curr)) == -1)
218*2db6d663SJoshua M. Clulow 				return (-1);
219*2db6d663SJoshua M. Clulow 			break;
220*2db6d663SJoshua M. Clulow 		}
221*2db6d663SJoshua M. Clulow 
222*2db6d663SJoshua M. Clulow 		case DATA_TYPE_STRING_ARRAY: {
223*2db6d663SJoshua M. Clulow 			char **val;
224*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
225*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_string_array(curr, &val, &valsz));
226*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
227*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
228*2db6d663SJoshua M. Clulow 				if (i > 0)
229*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
230*2db6d663SJoshua M. Clulow 				if (nvlist_print_json_string(fp, val[i]) == -1)
231*2db6d663SJoshua M. Clulow 					return (-1);
232*2db6d663SJoshua M. Clulow 			}
233*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
234*2db6d663SJoshua M. Clulow 			break;
235*2db6d663SJoshua M. Clulow 		}
236*2db6d663SJoshua M. Clulow 
237*2db6d663SJoshua M. Clulow 		case DATA_TYPE_NVLIST_ARRAY: {
238*2db6d663SJoshua M. Clulow 			nvlist_t **val;
239*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
240*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz));
241*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
242*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
243*2db6d663SJoshua M. Clulow 				if (i > 0)
244*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
245*2db6d663SJoshua M. Clulow 				if (nvlist_print_json(fp, val[i]) == -1)
246*2db6d663SJoshua M. Clulow 					return (-1);
247*2db6d663SJoshua M. Clulow 			}
248*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
249*2db6d663SJoshua M. Clulow 			break;
250*2db6d663SJoshua M. Clulow 		}
251*2db6d663SJoshua M. Clulow 
252*2db6d663SJoshua M. Clulow 		case DATA_TYPE_BOOLEAN_ARRAY: {
253*2db6d663SJoshua M. Clulow 			boolean_t *val;
254*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
255*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz));
256*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
257*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
258*2db6d663SJoshua M. Clulow 				if (i > 0)
259*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
260*2db6d663SJoshua M. Clulow 				FPRINTF(fp, val[i] == B_TRUE ?
261*2db6d663SJoshua M. Clulow 				    "true" : "false");
262*2db6d663SJoshua M. Clulow 			}
263*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
264*2db6d663SJoshua M. Clulow 			break;
265*2db6d663SJoshua M. Clulow 		}
266*2db6d663SJoshua M. Clulow 
267*2db6d663SJoshua M. Clulow 		case DATA_TYPE_BYTE_ARRAY: {
268*2db6d663SJoshua M. Clulow 			uchar_t *val;
269*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
270*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_byte_array(curr, &val, &valsz));
271*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
272*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
273*2db6d663SJoshua M. Clulow 				if (i > 0)
274*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
275*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%hhu", val[i]);
276*2db6d663SJoshua M. Clulow 			}
277*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
278*2db6d663SJoshua M. Clulow 			break;
279*2db6d663SJoshua M. Clulow 		}
280*2db6d663SJoshua M. Clulow 
281*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT8_ARRAY: {
282*2db6d663SJoshua M. Clulow 			uint8_t *val;
283*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
284*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz));
285*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
286*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
287*2db6d663SJoshua M. Clulow 				if (i > 0)
288*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
289*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%hhu", val[i]);
290*2db6d663SJoshua M. Clulow 			}
291*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
292*2db6d663SJoshua M. Clulow 			break;
293*2db6d663SJoshua M. Clulow 		}
294*2db6d663SJoshua M. Clulow 
295*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT8_ARRAY: {
296*2db6d663SJoshua M. Clulow 			int8_t *val;
297*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
298*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_int8_array(curr, &val, &valsz));
299*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
300*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
301*2db6d663SJoshua M. Clulow 				if (i > 0)
302*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
303*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%hd", val[i]);
304*2db6d663SJoshua M. Clulow 			}
305*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
306*2db6d663SJoshua M. Clulow 			break;
307*2db6d663SJoshua M. Clulow 		}
308*2db6d663SJoshua M. Clulow 
309*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT16_ARRAY: {
310*2db6d663SJoshua M. Clulow 			uint16_t *val;
311*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
312*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz));
313*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
314*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
315*2db6d663SJoshua M. Clulow 				if (i > 0)
316*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
317*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%hu", val[i]);
318*2db6d663SJoshua M. Clulow 			}
319*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
320*2db6d663SJoshua M. Clulow 			break;
321*2db6d663SJoshua M. Clulow 		}
322*2db6d663SJoshua M. Clulow 
323*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT16_ARRAY: {
324*2db6d663SJoshua M. Clulow 			int16_t *val;
325*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
326*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_int16_array(curr, &val, &valsz));
327*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
328*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
329*2db6d663SJoshua M. Clulow 				if (i > 0)
330*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
331*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%hhd", val[i]);
332*2db6d663SJoshua M. Clulow 			}
333*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
334*2db6d663SJoshua M. Clulow 			break;
335*2db6d663SJoshua M. Clulow 		}
336*2db6d663SJoshua M. Clulow 
337*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT32_ARRAY: {
338*2db6d663SJoshua M. Clulow 			uint32_t *val;
339*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
340*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz));
341*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
342*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
343*2db6d663SJoshua M. Clulow 				if (i > 0)
344*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
345*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%u", val[i]);
346*2db6d663SJoshua M. Clulow 			}
347*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
348*2db6d663SJoshua M. Clulow 			break;
349*2db6d663SJoshua M. Clulow 		}
350*2db6d663SJoshua M. Clulow 
351*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT32_ARRAY: {
352*2db6d663SJoshua M. Clulow 			int32_t *val;
353*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
354*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_int32_array(curr, &val, &valsz));
355*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
356*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
357*2db6d663SJoshua M. Clulow 				if (i > 0)
358*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
359*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%d", val[i]);
360*2db6d663SJoshua M. Clulow 			}
361*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
362*2db6d663SJoshua M. Clulow 			break;
363*2db6d663SJoshua M. Clulow 		}
364*2db6d663SJoshua M. Clulow 
365*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UINT64_ARRAY: {
366*2db6d663SJoshua M. Clulow 			uint64_t *val;
367*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
368*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz));
369*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
370*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
371*2db6d663SJoshua M. Clulow 				if (i > 0)
372*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
373*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%llu",
374*2db6d663SJoshua M. Clulow 				    (unsigned long long)val[i]);
375*2db6d663SJoshua M. Clulow 			}
376*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
377*2db6d663SJoshua M. Clulow 			break;
378*2db6d663SJoshua M. Clulow 		}
379*2db6d663SJoshua M. Clulow 
380*2db6d663SJoshua M. Clulow 		case DATA_TYPE_INT64_ARRAY: {
381*2db6d663SJoshua M. Clulow 			int64_t *val;
382*2db6d663SJoshua M. Clulow 			uint_t valsz, i;
383*2db6d663SJoshua M. Clulow 			VERIFY0(nvpair_value_int64_array(curr, &val, &valsz));
384*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "[");
385*2db6d663SJoshua M. Clulow 			for (i = 0; i < valsz; i++) {
386*2db6d663SJoshua M. Clulow 				if (i > 0)
387*2db6d663SJoshua M. Clulow 					FPRINTF(fp, ",");
388*2db6d663SJoshua M. Clulow 				FPRINTF(fp, "%lld", (long long)val[i]);
389*2db6d663SJoshua M. Clulow 			}
390*2db6d663SJoshua M. Clulow 			FPRINTF(fp, "]");
391*2db6d663SJoshua M. Clulow 			break;
392*2db6d663SJoshua M. Clulow 		}
393*2db6d663SJoshua M. Clulow 
394*2db6d663SJoshua M. Clulow 		case DATA_TYPE_UNKNOWN:
395*2db6d663SJoshua M. Clulow 			return (-1);
396*2db6d663SJoshua M. Clulow 		}
397*2db6d663SJoshua M. Clulow 	}
398*2db6d663SJoshua M. Clulow 
399*2db6d663SJoshua M. Clulow 	FPRINTF(fp, "}");
400*2db6d663SJoshua M. Clulow 	return (0);
401*2db6d663SJoshua M. Clulow }
402