xref: /onnv-gate/usr/src/lib/libpool/common/pool_value.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <strings.h>
33*0Sstevel@tonic-gate #include <pool.h>
34*0Sstevel@tonic-gate #include "pool_internal.h"
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate /*
37*0Sstevel@tonic-gate  * libpool Value Manipulation Routines
38*0Sstevel@tonic-gate  *
39*0Sstevel@tonic-gate  * pool_value.c implements the value (pool_value_t) functionality for
40*0Sstevel@tonic-gate  * libpool. The datatypes supported are: uint64_t, int64_t, double,
41*0Sstevel@tonic-gate  * uchar_t (boolean), const char * (string). Values are used to
42*0Sstevel@tonic-gate  * represent data stored to and retrieved from the datastore in a
43*0Sstevel@tonic-gate  * simple discriminated union.
44*0Sstevel@tonic-gate  *
45*0Sstevel@tonic-gate  * Values are dynamically allocated using pool_value_alloc() and
46*0Sstevel@tonic-gate  * destroyed using pool_value_free().
47*0Sstevel@tonic-gate  *
48*0Sstevel@tonic-gate  * Values may be allocated statically for internal use in
49*0Sstevel@tonic-gate  * libpool. Statically allocated pool_value_t variables must be
50*0Sstevel@tonic-gate  * initialised with the POOL_VALUE_INITIALIZER macro, otherwise the
51*0Sstevel@tonic-gate  * results are unpredictable.
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * A pool_value_t variable can be used to store values in any of the
54*0Sstevel@tonic-gate  * supported datatypes.
55*0Sstevel@tonic-gate  *
56*0Sstevel@tonic-gate  * A pool_value_t's name and string value are limited in size to
57*0Sstevel@tonic-gate  * PV_NAME_MAX_LEN and PV_VALUE_MAX_LEN respectively. Attempting to
58*0Sstevel@tonic-gate  * store values which are greater than this in length will fail with a
59*0Sstevel@tonic-gate  * POE_BADPARAM error.
60*0Sstevel@tonic-gate  */
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate /*
63*0Sstevel@tonic-gate  * Get the uint64_t data held by the value. If the data type isn't
64*0Sstevel@tonic-gate  * uint64_t return PO_FAIL and set pool_error to be POE_BAD_PROP_TYPE.
65*0Sstevel@tonic-gate  */
66*0Sstevel@tonic-gate int
pool_value_get_uint64(const pool_value_t * pv,uint64_t * result)67*0Sstevel@tonic-gate pool_value_get_uint64(const pool_value_t *pv, uint64_t *result)
68*0Sstevel@tonic-gate {
69*0Sstevel@tonic-gate 	if (pv->pv_class != POC_UINT) {
70*0Sstevel@tonic-gate 		pool_seterror(POE_BAD_PROP_TYPE);
71*0Sstevel@tonic-gate 		return (PO_FAIL);
72*0Sstevel@tonic-gate 	}
73*0Sstevel@tonic-gate 	*result = pv->pv_u.u;
74*0Sstevel@tonic-gate 	return (PO_SUCCESS);
75*0Sstevel@tonic-gate }
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate /*
78*0Sstevel@tonic-gate  * Get the int64_t data held by the value. If the data type isn't
79*0Sstevel@tonic-gate  * int64_t return PO_FAIL and set pool_error to be POE_BAD_PROP_TYPE.
80*0Sstevel@tonic-gate  */
81*0Sstevel@tonic-gate int
pool_value_get_int64(const pool_value_t * pv,int64_t * result)82*0Sstevel@tonic-gate pool_value_get_int64(const pool_value_t *pv, int64_t *result)
83*0Sstevel@tonic-gate {
84*0Sstevel@tonic-gate 	if (pv->pv_class != POC_INT) {
85*0Sstevel@tonic-gate 		pool_seterror(POE_BAD_PROP_TYPE);
86*0Sstevel@tonic-gate 		return (PO_FAIL);
87*0Sstevel@tonic-gate 	}
88*0Sstevel@tonic-gate 	*result = pv->pv_u.i;
89*0Sstevel@tonic-gate 	return (PO_SUCCESS);
90*0Sstevel@tonic-gate }
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate /*
93*0Sstevel@tonic-gate  * Get the double data held by the value. If the data type isn't
94*0Sstevel@tonic-gate  * double return PO_FAIL and set pool_error to be POE_BAD_PROP_TYPE.
95*0Sstevel@tonic-gate  */
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate int
pool_value_get_double(const pool_value_t * pv,double * result)98*0Sstevel@tonic-gate pool_value_get_double(const pool_value_t *pv, double *result)
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate 	if (pv->pv_class != POC_DOUBLE) {
101*0Sstevel@tonic-gate 		pool_seterror(POE_BAD_PROP_TYPE);
102*0Sstevel@tonic-gate 		return (PO_FAIL);
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 	*result = pv->pv_u.d;
105*0Sstevel@tonic-gate 	return (PO_SUCCESS);
106*0Sstevel@tonic-gate }
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate /*
109*0Sstevel@tonic-gate  * Get the boolean data held by the value. If the data type isn't
110*0Sstevel@tonic-gate  * boolean return PO_FAIL and set pool_error to be POE_BAD_PROP_TYPE.
111*0Sstevel@tonic-gate  */
112*0Sstevel@tonic-gate int
pool_value_get_bool(const pool_value_t * pv,uchar_t * result)113*0Sstevel@tonic-gate pool_value_get_bool(const pool_value_t *pv, uchar_t *result)
114*0Sstevel@tonic-gate {
115*0Sstevel@tonic-gate 	if (pv->pv_class != POC_BOOL) {
116*0Sstevel@tonic-gate 		pool_seterror(POE_BAD_PROP_TYPE);
117*0Sstevel@tonic-gate 		return (PO_FAIL);
118*0Sstevel@tonic-gate 	}
119*0Sstevel@tonic-gate 	*result = pv->pv_u.b;
120*0Sstevel@tonic-gate 	return (PO_SUCCESS);
121*0Sstevel@tonic-gate }
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate /*
124*0Sstevel@tonic-gate  * Get the string data held by the value. If the data type isn't
125*0Sstevel@tonic-gate  * string return PO_FAIL and set pool_error to be POE_BAD_PROP_TYPE.
126*0Sstevel@tonic-gate  */
127*0Sstevel@tonic-gate int
pool_value_get_string(const pool_value_t * pv,const char ** result)128*0Sstevel@tonic-gate pool_value_get_string(const pool_value_t *pv, const char **result)
129*0Sstevel@tonic-gate {
130*0Sstevel@tonic-gate 	if (pv->pv_class != POC_STRING) {
131*0Sstevel@tonic-gate 		pool_seterror(POE_BAD_PROP_TYPE);
132*0Sstevel@tonic-gate 		return (PO_FAIL);
133*0Sstevel@tonic-gate 	}
134*0Sstevel@tonic-gate 	*result = pv->pv_u.s;
135*0Sstevel@tonic-gate 	return (PO_SUCCESS);
136*0Sstevel@tonic-gate }
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate /*
139*0Sstevel@tonic-gate  * Get the type of the data held by the value. If the value has never
140*0Sstevel@tonic-gate  * been used to store data, then the type is POC_INVAL.
141*0Sstevel@tonic-gate  */
142*0Sstevel@tonic-gate pool_value_class_t
pool_value_get_type(const pool_value_t * pv)143*0Sstevel@tonic-gate pool_value_get_type(const pool_value_t *pv)
144*0Sstevel@tonic-gate {
145*0Sstevel@tonic-gate 	return (pv->pv_class);
146*0Sstevel@tonic-gate }
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate /*
149*0Sstevel@tonic-gate  * Set the value's data to the supplied uint64_t data. Update the type
150*0Sstevel@tonic-gate  * of the value data to POC_UINT.
151*0Sstevel@tonic-gate  */
152*0Sstevel@tonic-gate void
pool_value_set_uint64(pool_value_t * pv,uint64_t val)153*0Sstevel@tonic-gate pool_value_set_uint64(pool_value_t *pv, uint64_t val)
154*0Sstevel@tonic-gate {
155*0Sstevel@tonic-gate 	if (pv->pv_class == POC_STRING)
156*0Sstevel@tonic-gate 		atom_free(pv->pv_u.s);
157*0Sstevel@tonic-gate 	pv->pv_class = POC_UINT;
158*0Sstevel@tonic-gate 	pv->pv_u.u = val;
159*0Sstevel@tonic-gate }
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate /*
162*0Sstevel@tonic-gate  * Set the value's data to the supplied int64_t data. Update the type
163*0Sstevel@tonic-gate  * of the value data to POC_INT.
164*0Sstevel@tonic-gate  */
165*0Sstevel@tonic-gate void
pool_value_set_int64(pool_value_t * pv,int64_t val)166*0Sstevel@tonic-gate pool_value_set_int64(pool_value_t *pv, int64_t val)
167*0Sstevel@tonic-gate {
168*0Sstevel@tonic-gate 	if (pv->pv_class == POC_STRING)
169*0Sstevel@tonic-gate 		atom_free(pv->pv_u.s);
170*0Sstevel@tonic-gate 	pv->pv_class = POC_INT;
171*0Sstevel@tonic-gate 	pv->pv_u.i = val;
172*0Sstevel@tonic-gate }
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate /*
175*0Sstevel@tonic-gate  * Set the value's data to the supplied double data. Update the type
176*0Sstevel@tonic-gate  * of the value data to POC_DOUBLE.
177*0Sstevel@tonic-gate  */
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate void
pool_value_set_double(pool_value_t * pv,double val)180*0Sstevel@tonic-gate pool_value_set_double(pool_value_t *pv, double val)
181*0Sstevel@tonic-gate {
182*0Sstevel@tonic-gate 	if (pv->pv_class == POC_STRING)
183*0Sstevel@tonic-gate 		atom_free(pv->pv_u.s);
184*0Sstevel@tonic-gate 	pv->pv_class = POC_DOUBLE;
185*0Sstevel@tonic-gate 	pv->pv_u.d = val;
186*0Sstevel@tonic-gate }
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate /*
189*0Sstevel@tonic-gate  * Set the value's data to the supplied uchar_t data. Update the type
190*0Sstevel@tonic-gate  * of the value data to POC_BOOL.
191*0Sstevel@tonic-gate  */
192*0Sstevel@tonic-gate void
pool_value_set_bool(pool_value_t * pv,uchar_t val)193*0Sstevel@tonic-gate pool_value_set_bool(pool_value_t *pv, uchar_t val)
194*0Sstevel@tonic-gate {
195*0Sstevel@tonic-gate 	if (pv->pv_class == POC_STRING)
196*0Sstevel@tonic-gate 		atom_free(pv->pv_u.s);
197*0Sstevel@tonic-gate 	pv->pv_class = POC_BOOL;
198*0Sstevel@tonic-gate 	pv->pv_u.b = !!val;	/* Lock value at 0 or 1 */
199*0Sstevel@tonic-gate }
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate /*
202*0Sstevel@tonic-gate  * Try to make an internal copy of the val, returning PO_SUCCESS or
203*0Sstevel@tonic-gate  * PO_FAIL if the copy works or fails.
204*0Sstevel@tonic-gate  */
205*0Sstevel@tonic-gate int
pool_value_set_string(pool_value_t * pv,const char * val)206*0Sstevel@tonic-gate pool_value_set_string(pool_value_t *pv, const char *val)
207*0Sstevel@tonic-gate {
208*0Sstevel@tonic-gate 	if (pv->pv_class == POC_STRING)
209*0Sstevel@tonic-gate 		atom_free(pv->pv_u.s);
210*0Sstevel@tonic-gate 	pv->pv_class = POC_STRING;
211*0Sstevel@tonic-gate 	if (val == NULL || strlen(val) >= PV_VALUE_MAX_LEN) {
212*0Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
213*0Sstevel@tonic-gate 		return (PO_FAIL);
214*0Sstevel@tonic-gate 	} else {
215*0Sstevel@tonic-gate 		if ((pv->pv_u.s = atom_string(val)) == NULL)
216*0Sstevel@tonic-gate 			return (PO_FAIL);
217*0Sstevel@tonic-gate 	}
218*0Sstevel@tonic-gate 	return (PO_SUCCESS);
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate 
221*0Sstevel@tonic-gate /*
222*0Sstevel@tonic-gate  * Allocate a pool_value_t structure and initialise it to 0. Set the
223*0Sstevel@tonic-gate  * type to POC_INVAL and return a pointer to the new pool_value_t. If
224*0Sstevel@tonic-gate  * memory allocation fails, set POE_SYSTEM and return NULL.
225*0Sstevel@tonic-gate  */
226*0Sstevel@tonic-gate pool_value_t *
pool_value_alloc(void)227*0Sstevel@tonic-gate pool_value_alloc(void)
228*0Sstevel@tonic-gate {
229*0Sstevel@tonic-gate 	pool_value_t *val;
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	if ((val = malloc(sizeof (pool_value_t))) == NULL) {
232*0Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
233*0Sstevel@tonic-gate 		return (NULL);
234*0Sstevel@tonic-gate 	}
235*0Sstevel@tonic-gate 	(void) memset(val, 0, sizeof (pool_value_t));
236*0Sstevel@tonic-gate 	val->pv_class = POC_INVAL;
237*0Sstevel@tonic-gate 	return (val);
238*0Sstevel@tonic-gate }
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate /*
241*0Sstevel@tonic-gate  * Free any atoms associated with the value and then free the value
242*0Sstevel@tonic-gate  * itself.
243*0Sstevel@tonic-gate  */
244*0Sstevel@tonic-gate void
pool_value_free(pool_value_t * pv)245*0Sstevel@tonic-gate pool_value_free(pool_value_t *pv)
246*0Sstevel@tonic-gate {
247*0Sstevel@tonic-gate 	if (pv->pv_name)
248*0Sstevel@tonic-gate 		atom_free(pv->pv_name);
249*0Sstevel@tonic-gate 	if (pv->pv_class == POC_STRING)
250*0Sstevel@tonic-gate 		atom_free(pv->pv_u.s);
251*0Sstevel@tonic-gate 	free(pv);
252*0Sstevel@tonic-gate }
253*0Sstevel@tonic-gate 
254*0Sstevel@tonic-gate /*
255*0Sstevel@tonic-gate  * Return a pointer to the name of the value. This may be NULL if the
256*0Sstevel@tonic-gate  * name has never been set.
257*0Sstevel@tonic-gate  */
258*0Sstevel@tonic-gate const char *
pool_value_get_name(const pool_value_t * pv)259*0Sstevel@tonic-gate pool_value_get_name(const pool_value_t *pv)
260*0Sstevel@tonic-gate {
261*0Sstevel@tonic-gate 	return (pv->pv_name);
262*0Sstevel@tonic-gate }
263*0Sstevel@tonic-gate 
264*0Sstevel@tonic-gate /*
265*0Sstevel@tonic-gate  * Set the name of the value to the supplied name.
266*0Sstevel@tonic-gate  */
267*0Sstevel@tonic-gate int
pool_value_set_name(pool_value_t * pv,const char * name)268*0Sstevel@tonic-gate pool_value_set_name(pool_value_t *pv, const char *name)
269*0Sstevel@tonic-gate {
270*0Sstevel@tonic-gate 	if (name == NULL || strlen(name) >= PV_NAME_MAX_LEN) {
271*0Sstevel@tonic-gate 		pool_seterror(POE_BADPARAM);
272*0Sstevel@tonic-gate 		return (PO_FAIL);
273*0Sstevel@tonic-gate 	} else {
274*0Sstevel@tonic-gate 		if (pv->pv_name)
275*0Sstevel@tonic-gate 			atom_free(pv->pv_name);
276*0Sstevel@tonic-gate 		if ((pv->pv_name = atom_string(name)) == NULL)
277*0Sstevel@tonic-gate 			return (PO_FAIL);
278*0Sstevel@tonic-gate 	}
279*0Sstevel@tonic-gate 	return (PO_SUCCESS);
280*0Sstevel@tonic-gate }
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate /*
283*0Sstevel@tonic-gate  * Use the supplied nvpair_t to set the name, type and value of the
284*0Sstevel@tonic-gate  * supplied pool_value_t.
285*0Sstevel@tonic-gate  *
286*0Sstevel@tonic-gate  * Return: PO_SUCCESS/PO_FAIL
287*0Sstevel@tonic-gate  */
288*0Sstevel@tonic-gate int
pool_value_from_nvpair(pool_value_t * pv,nvpair_t * pn)289*0Sstevel@tonic-gate pool_value_from_nvpair(pool_value_t *pv, nvpair_t *pn)
290*0Sstevel@tonic-gate {
291*0Sstevel@tonic-gate 	uchar_t bval;
292*0Sstevel@tonic-gate 	uint64_t uval;
293*0Sstevel@tonic-gate 	int64_t ival;
294*0Sstevel@tonic-gate 	double dval;
295*0Sstevel@tonic-gate 	uint_t nelem;
296*0Sstevel@tonic-gate 	uchar_t *dval_b;
297*0Sstevel@tonic-gate 	char *sval;
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate 	if (pool_value_set_name(pv, nvpair_name(pn)) != PO_SUCCESS)
300*0Sstevel@tonic-gate 		return (PO_FAIL);
301*0Sstevel@tonic-gate 	switch (nvpair_type(pn)) {
302*0Sstevel@tonic-gate 	case DATA_TYPE_BYTE:
303*0Sstevel@tonic-gate 		if (nvpair_value_byte(pn, &bval) != 0) {
304*0Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
305*0Sstevel@tonic-gate 			return (PO_FAIL);
306*0Sstevel@tonic-gate 		}
307*0Sstevel@tonic-gate 		pool_value_set_bool(pv, bval);
308*0Sstevel@tonic-gate 		break;
309*0Sstevel@tonic-gate 	case DATA_TYPE_BYTE_ARRAY:
310*0Sstevel@tonic-gate 		if (nvpair_value_byte_array(pn, &dval_b, &nelem) != 0) {
311*0Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
312*0Sstevel@tonic-gate 			return (PO_FAIL);
313*0Sstevel@tonic-gate 		}
314*0Sstevel@tonic-gate 		(void) memcpy(&dval, dval_b, sizeof (double));
315*0Sstevel@tonic-gate 		pool_value_set_double(pv, dval);
316*0Sstevel@tonic-gate 		break;
317*0Sstevel@tonic-gate 	case DATA_TYPE_INT64:
318*0Sstevel@tonic-gate 		if (nvpair_value_int64(pn, &ival) != 0) {
319*0Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
320*0Sstevel@tonic-gate 			return (PO_FAIL);
321*0Sstevel@tonic-gate 		}
322*0Sstevel@tonic-gate 		pool_value_set_int64(pv, ival);
323*0Sstevel@tonic-gate 		break;
324*0Sstevel@tonic-gate 	case DATA_TYPE_UINT64:
325*0Sstevel@tonic-gate 		if (nvpair_value_uint64(pn, &uval) != 0) {
326*0Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
327*0Sstevel@tonic-gate 			return (PO_FAIL);
328*0Sstevel@tonic-gate 		}
329*0Sstevel@tonic-gate 		pool_value_set_uint64(pv, uval);
330*0Sstevel@tonic-gate 		break;
331*0Sstevel@tonic-gate 	case DATA_TYPE_STRING:
332*0Sstevel@tonic-gate 		if (nvpair_value_string(pn, &sval) != 0) {
333*0Sstevel@tonic-gate 			pool_seterror(POE_SYSTEM);
334*0Sstevel@tonic-gate 			return (PO_FAIL);
335*0Sstevel@tonic-gate 		}
336*0Sstevel@tonic-gate 		if (pool_value_set_string(pv, sval) != PO_SUCCESS)
337*0Sstevel@tonic-gate 			return (PO_FAIL);
338*0Sstevel@tonic-gate 		break;
339*0Sstevel@tonic-gate 	default:
340*0Sstevel@tonic-gate 		pool_seterror(POE_SYSTEM);
341*0Sstevel@tonic-gate 		return (PO_FAIL);
342*0Sstevel@tonic-gate 	}
343*0Sstevel@tonic-gate 	return (PO_SUCCESS);
344*0Sstevel@tonic-gate }
345*0Sstevel@tonic-gate 
346*0Sstevel@tonic-gate /*
347*0Sstevel@tonic-gate  * Check to see if the values held by two supplied values are
348*0Sstevel@tonic-gate  * equal. First compare the pointers to see if we are comparing to
349*0Sstevel@tonic-gate  * ourselves, if we are return PO_TRUE. If not, get the types and
350*0Sstevel@tonic-gate  * ensure they match, if they don't return PO_FALSE. Then do a type
351*0Sstevel@tonic-gate  * specific comparison returning PO_TRUE or PO_FALSE accordingly.
352*0Sstevel@tonic-gate  */
353*0Sstevel@tonic-gate int
pool_value_equal(pool_value_t * pv1,pool_value_t * pv2)354*0Sstevel@tonic-gate pool_value_equal(pool_value_t *pv1, pool_value_t *pv2)
355*0Sstevel@tonic-gate {
356*0Sstevel@tonic-gate 	uint64_t uval1, uval2;
357*0Sstevel@tonic-gate 	int64_t ival1, ival2;
358*0Sstevel@tonic-gate 	double dval1, dval2;
359*0Sstevel@tonic-gate 	uchar_t bval1, bval2;
360*0Sstevel@tonic-gate 	const char *sval1, *sval2;
361*0Sstevel@tonic-gate 	pool_value_class_t type;
362*0Sstevel@tonic-gate 
363*0Sstevel@tonic-gate 	if (pv1 == pv2) /* optimisation */
364*0Sstevel@tonic-gate 		return (PO_TRUE);
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 	type = pool_value_get_type(pv1);
367*0Sstevel@tonic-gate 	if (type != pool_value_get_type(pv2))
368*0Sstevel@tonic-gate 	    return (PO_FALSE);
369*0Sstevel@tonic-gate 
370*0Sstevel@tonic-gate 	switch (type) {
371*0Sstevel@tonic-gate 		case POC_UINT:
372*0Sstevel@tonic-gate 			(void) pool_value_get_uint64(pv1, &uval1);
373*0Sstevel@tonic-gate 			(void) pool_value_get_uint64(pv2, &uval2);
374*0Sstevel@tonic-gate 			if (uval1 == uval2)
375*0Sstevel@tonic-gate 				return (PO_TRUE);
376*0Sstevel@tonic-gate 			break;
377*0Sstevel@tonic-gate 		case POC_INT:
378*0Sstevel@tonic-gate 			(void) pool_value_get_int64(pv1, &ival1);
379*0Sstevel@tonic-gate 			(void) pool_value_get_int64(pv2, &ival2);
380*0Sstevel@tonic-gate 			if (ival1 == ival2)
381*0Sstevel@tonic-gate 				return (PO_TRUE);
382*0Sstevel@tonic-gate 			break;
383*0Sstevel@tonic-gate 		case POC_DOUBLE:
384*0Sstevel@tonic-gate 			(void) pool_value_get_double(pv1, &dval1);
385*0Sstevel@tonic-gate 			(void) pool_value_get_double(pv2, &dval2);
386*0Sstevel@tonic-gate 			if (dval1 == dval2)
387*0Sstevel@tonic-gate 				return (PO_TRUE);
388*0Sstevel@tonic-gate 			break;
389*0Sstevel@tonic-gate 		case POC_BOOL:
390*0Sstevel@tonic-gate 			(void) pool_value_get_bool(pv1, &bval1);
391*0Sstevel@tonic-gate 			(void) pool_value_get_bool(pv2, &bval2);
392*0Sstevel@tonic-gate 			if (bval1 == bval2)
393*0Sstevel@tonic-gate 				return (PO_TRUE);
394*0Sstevel@tonic-gate 			break;
395*0Sstevel@tonic-gate 		case POC_STRING:
396*0Sstevel@tonic-gate 			(void) pool_value_get_string(pv1, &sval1);
397*0Sstevel@tonic-gate 			(void) pool_value_get_string(pv2, &sval2);
398*0Sstevel@tonic-gate 			if (strcmp(sval1, sval2) == 0)
399*0Sstevel@tonic-gate 				return (PO_TRUE);
400*0Sstevel@tonic-gate 			break;
401*0Sstevel@tonic-gate 	}
402*0Sstevel@tonic-gate 	return (PO_FALSE);
403*0Sstevel@tonic-gate }
404*0Sstevel@tonic-gate 
405*0Sstevel@tonic-gate #ifdef DEBUG
406*0Sstevel@tonic-gate /*
407*0Sstevel@tonic-gate  * Trace pool_value_t details using dprintf
408*0Sstevel@tonic-gate  */
409*0Sstevel@tonic-gate void
pool_value_dprintf(const pool_value_t * pv)410*0Sstevel@tonic-gate pool_value_dprintf(const pool_value_t *pv)
411*0Sstevel@tonic-gate {
412*0Sstevel@tonic-gate 	const char *class_name[] = {
413*0Sstevel@tonic-gate 		"POC_UINT",
414*0Sstevel@tonic-gate 		"POC_INT",
415*0Sstevel@tonic-gate 		"POC_DOUBLE",
416*0Sstevel@tonic-gate 		"POC_BOOL",
417*0Sstevel@tonic-gate 		"POC_STRING"
418*0Sstevel@tonic-gate 	};
419*0Sstevel@tonic-gate 
420*0Sstevel@tonic-gate 	dprintf("name: %s\n", pv->pv_name ? pv->pv_name : "NULL");
421*0Sstevel@tonic-gate 	if (pv->pv_class >= POC_UINT && pv->pv_class <= POC_STRING)
422*0Sstevel@tonic-gate 		dprintf("type: %s\n", class_name[pv->pv_class]);
423*0Sstevel@tonic-gate 	else
424*0Sstevel@tonic-gate 		dprintf("type: POC_INVAL\n");
425*0Sstevel@tonic-gate 	switch (pv->pv_class) {
426*0Sstevel@tonic-gate 	case POC_UINT:
427*0Sstevel@tonic-gate 		dprintf("value: %llu\n", pv->pv_u.u);
428*0Sstevel@tonic-gate 		break;
429*0Sstevel@tonic-gate 	case POC_INT:
430*0Sstevel@tonic-gate 		dprintf("value: %lld\n", pv->pv_u.i);
431*0Sstevel@tonic-gate 		break;
432*0Sstevel@tonic-gate 	case POC_DOUBLE:
433*0Sstevel@tonic-gate 		dprintf("value: %f\n", pv->pv_u.d);
434*0Sstevel@tonic-gate 		break;
435*0Sstevel@tonic-gate 	case POC_BOOL:
436*0Sstevel@tonic-gate 		dprintf("value: %s\n", pv->pv_u.b ? "true" : "false");
437*0Sstevel@tonic-gate 		break;
438*0Sstevel@tonic-gate 	case POC_STRING:
439*0Sstevel@tonic-gate 		dprintf("value: %s\n", pv->pv_u.s);
440*0Sstevel@tonic-gate 		break;
441*0Sstevel@tonic-gate 	default:
442*0Sstevel@tonic-gate 		dprintf("value: invalid\n");
443*0Sstevel@tonic-gate 		break;
444*0Sstevel@tonic-gate 	}
445*0Sstevel@tonic-gate }
446*0Sstevel@tonic-gate #endif	/* DEBUG */
447