xref: /netbsd-src/common/lib/libppath/ppath.c (revision bde2909f8627fc36c3bcabc0ec2f04f769bb5ff0)
1*bde2909fSthorpej /* $NetBSD: ppath.c,v 1.5 2020/06/06 22:28:07 thorpej Exp $ */
2064bbf20Schristos 
333ce21e2Sdyoung /*-
433ce21e2Sdyoung  * Copyright (c) 2011 The NetBSD Foundation, Inc.
533ce21e2Sdyoung  * All rights reserved.
633ce21e2Sdyoung  *
733ce21e2Sdyoung  * This code is derived from software contributed to The NetBSD Foundation
833ce21e2Sdyoung  * by David Young <dyoung@NetBSD.org>.
933ce21e2Sdyoung  *
1033ce21e2Sdyoung  * Redistribution and use in source and binary forms, with or without
1133ce21e2Sdyoung  * modification, are permitted provided that the following conditions
1233ce21e2Sdyoung  * are met:
1333ce21e2Sdyoung  * 1. Redistributions of source code must retain the above copyright
1433ce21e2Sdyoung  *    notice, this list of conditions and the following disclaimer.
1533ce21e2Sdyoung  * 2. Redistributions in binary form must reproduce the above copyright
1633ce21e2Sdyoung  *    notice, this list of conditions and the following disclaimer in the
1733ce21e2Sdyoung  *    documentation and/or other materials provided with the distribution.
1833ce21e2Sdyoung  *
1933ce21e2Sdyoung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2033ce21e2Sdyoung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2133ce21e2Sdyoung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2233ce21e2Sdyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2333ce21e2Sdyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2433ce21e2Sdyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2533ce21e2Sdyoung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2633ce21e2Sdyoung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2733ce21e2Sdyoung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2833ce21e2Sdyoung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2933ce21e2Sdyoung  * POSSIBILITY OF SUCH DAMAGE.
3033ce21e2Sdyoung  */
3133ce21e2Sdyoung 
3233ce21e2Sdyoung #include <sys/cdefs.h>
33*bde2909fSthorpej __RCSID("$NetBSD: ppath.c,v 1.5 2020/06/06 22:28:07 thorpej Exp $");
3433ce21e2Sdyoung 
35af1a6015Smrg #ifdef _KERNEL
36feec5d31Schristos #include <sys/systm.h>
37af1a6015Smrg #endif
3833ce21e2Sdyoung #include <ppath/ppath.h>
3933ce21e2Sdyoung #include <ppath/ppath_impl.h>
4033ce21e2Sdyoung 
4133ce21e2Sdyoung enum _ppath_type {
4233ce21e2Sdyoung 	  PPATH_T_IDX = 0
4333ce21e2Sdyoung 	, PPATH_T_KEY = 1
4433ce21e2Sdyoung };
4533ce21e2Sdyoung 
4633ce21e2Sdyoung typedef enum _ppath_type ppath_type_t;
4733ce21e2Sdyoung 
4833ce21e2Sdyoung struct _ppath_component {
4933ce21e2Sdyoung 	unsigned int	pc_refcnt;
5033ce21e2Sdyoung 	ppath_type_t	pc_type;
5133ce21e2Sdyoung 	union {
5233ce21e2Sdyoung 		char *u_key;
5333ce21e2Sdyoung 		unsigned int u_idx;
5433ce21e2Sdyoung 	} pc_u;
5533ce21e2Sdyoung #define pc_key pc_u.u_key
5633ce21e2Sdyoung #define pc_idx pc_u.u_idx
5733ce21e2Sdyoung };
5833ce21e2Sdyoung 
5933ce21e2Sdyoung struct _ppath {
6033ce21e2Sdyoung 	unsigned int	p_refcnt;
6133ce21e2Sdyoung 	unsigned int	p_len;
6233ce21e2Sdyoung 	ppath_component_t *p_cmpt[PPATH_MAX_COMPONENTS];
6333ce21e2Sdyoung };
6433ce21e2Sdyoung 
6533ce21e2Sdyoung static int ppath_copydel_object_of_type(prop_object_t, prop_object_t *,
6633ce21e2Sdyoung     const ppath_t *, prop_type_t);
6733ce21e2Sdyoung static int ppath_copyset_object_helper(prop_object_t, prop_object_t *,
6833ce21e2Sdyoung     const ppath_t *, const prop_object_t);
6933ce21e2Sdyoung 
7033ce21e2Sdyoung static void
ppath_strfree(char * s)7133ce21e2Sdyoung ppath_strfree(char *s)
7233ce21e2Sdyoung {
7333ce21e2Sdyoung 	size_t size = strlen(s) + 1;
7433ce21e2Sdyoung 
7533ce21e2Sdyoung 	ppath_free(s, size);
7633ce21e2Sdyoung }
7733ce21e2Sdyoung 
7833ce21e2Sdyoung static char *
ppath_strdup(const char * s)7933ce21e2Sdyoung ppath_strdup(const char *s)
8033ce21e2Sdyoung {
8133ce21e2Sdyoung 	size_t size = strlen(s) + 1;
8233ce21e2Sdyoung 	char *p;
8333ce21e2Sdyoung 
8433ce21e2Sdyoung 	if ((p = ppath_alloc(size)) == NULL)
8533ce21e2Sdyoung 		return NULL;
8633ce21e2Sdyoung 
8733ce21e2Sdyoung 	return strcpy(p, s);
8833ce21e2Sdyoung }
8933ce21e2Sdyoung 
9033ce21e2Sdyoung int
ppath_component_idx(const ppath_component_t * pc)9133ce21e2Sdyoung ppath_component_idx(const ppath_component_t *pc)
9233ce21e2Sdyoung {
9333ce21e2Sdyoung 	if (pc->pc_type != PPATH_T_IDX)
9433ce21e2Sdyoung 		return -1;
9533ce21e2Sdyoung 	return pc->pc_idx;
9633ce21e2Sdyoung }
9733ce21e2Sdyoung 
9833ce21e2Sdyoung const char *
ppath_component_key(const ppath_component_t * pc)9933ce21e2Sdyoung ppath_component_key(const ppath_component_t *pc)
10033ce21e2Sdyoung {
10133ce21e2Sdyoung 	if (pc->pc_type != PPATH_T_KEY)
10233ce21e2Sdyoung 		return NULL;
10333ce21e2Sdyoung 	return pc->pc_key;
10433ce21e2Sdyoung }
10533ce21e2Sdyoung 
10633ce21e2Sdyoung ppath_component_t *
ppath_idx(unsigned int idx)10733ce21e2Sdyoung ppath_idx(unsigned int idx)
10833ce21e2Sdyoung {
10933ce21e2Sdyoung 	ppath_component_t *pc;
11033ce21e2Sdyoung 
11133ce21e2Sdyoung 	if ((pc = ppath_alloc(sizeof(*pc))) == NULL)
11233ce21e2Sdyoung 		return NULL;
11333ce21e2Sdyoung 	pc->pc_idx = idx;
11433ce21e2Sdyoung 	pc->pc_type = PPATH_T_IDX;
11533ce21e2Sdyoung 	pc->pc_refcnt = 1;
11633ce21e2Sdyoung 	ppath_component_extant_inc();
11733ce21e2Sdyoung 	return pc;
11833ce21e2Sdyoung }
11933ce21e2Sdyoung 
12033ce21e2Sdyoung ppath_component_t *
ppath_key(const char * key)12133ce21e2Sdyoung ppath_key(const char *key)
12233ce21e2Sdyoung {
12333ce21e2Sdyoung 	ppath_component_t *pc;
12433ce21e2Sdyoung 
12533ce21e2Sdyoung 	if ((pc = ppath_alloc(sizeof(*pc))) == NULL)
12633ce21e2Sdyoung 		return NULL;
12733ce21e2Sdyoung 
12833ce21e2Sdyoung 	if ((pc->pc_key = ppath_strdup(key)) == NULL) {
12933ce21e2Sdyoung 		ppath_free(pc, sizeof(*pc));
13033ce21e2Sdyoung 		return NULL;
13133ce21e2Sdyoung 	}
13233ce21e2Sdyoung 	pc->pc_type = PPATH_T_KEY;
13333ce21e2Sdyoung 	pc->pc_refcnt = 1;
13433ce21e2Sdyoung 	ppath_component_extant_inc();
13533ce21e2Sdyoung 	return pc;
13633ce21e2Sdyoung }
13733ce21e2Sdyoung 
13833ce21e2Sdyoung ppath_component_t *
ppath_component_retain(ppath_component_t * pc)13933ce21e2Sdyoung ppath_component_retain(ppath_component_t *pc)
14033ce21e2Sdyoung {
14133ce21e2Sdyoung 	ppath_assert(pc->pc_refcnt != 0);
14233ce21e2Sdyoung 	pc->pc_refcnt++;
14333ce21e2Sdyoung 
14433ce21e2Sdyoung 	return pc;
14533ce21e2Sdyoung }
14633ce21e2Sdyoung 
14733ce21e2Sdyoung void
ppath_component_release(ppath_component_t * pc)14833ce21e2Sdyoung ppath_component_release(ppath_component_t *pc)
14933ce21e2Sdyoung {
15033ce21e2Sdyoung 	ppath_assert(pc->pc_refcnt != 0);
15133ce21e2Sdyoung 
15233ce21e2Sdyoung 	if (--pc->pc_refcnt != 0)
15333ce21e2Sdyoung 		return;
15433ce21e2Sdyoung 	if (pc->pc_type == PPATH_T_KEY)
15533ce21e2Sdyoung 		ppath_strfree(pc->pc_key);
15633ce21e2Sdyoung 	ppath_component_extant_dec();
15733ce21e2Sdyoung 	ppath_free(pc, sizeof(*pc));
15833ce21e2Sdyoung }
15933ce21e2Sdyoung 
16033ce21e2Sdyoung ppath_t *
ppath_create(void)16133ce21e2Sdyoung ppath_create(void)
16233ce21e2Sdyoung {
16333ce21e2Sdyoung 	ppath_t *p;
16433ce21e2Sdyoung 
16533ce21e2Sdyoung 	if ((p = ppath_alloc(sizeof(*p))) == NULL)
16633ce21e2Sdyoung 		return NULL;
16733ce21e2Sdyoung 
16833ce21e2Sdyoung 	p->p_refcnt = 1;
16933ce21e2Sdyoung 	ppath_extant_inc();
17033ce21e2Sdyoung 
17133ce21e2Sdyoung 	return p;
17233ce21e2Sdyoung }
17333ce21e2Sdyoung 
17433ce21e2Sdyoung ppath_t *
ppath_pop(ppath_t * p,ppath_component_t ** pcp)17533ce21e2Sdyoung ppath_pop(ppath_t *p, ppath_component_t **pcp)
17633ce21e2Sdyoung {
17733ce21e2Sdyoung 	ppath_component_t *pc;
17833ce21e2Sdyoung 
17933ce21e2Sdyoung 	if (p == NULL || p->p_len == 0)
18033ce21e2Sdyoung 		return NULL;
18133ce21e2Sdyoung 
18233ce21e2Sdyoung 	pc = p->p_cmpt[--p->p_len];
18333ce21e2Sdyoung 
18433ce21e2Sdyoung 	if (pcp != NULL)
18533ce21e2Sdyoung 		*pcp = pc;
18633ce21e2Sdyoung 	else
18733ce21e2Sdyoung 		ppath_component_release(pc);
18833ce21e2Sdyoung 
18933ce21e2Sdyoung 	return p;
19033ce21e2Sdyoung }
19133ce21e2Sdyoung 
19233ce21e2Sdyoung ppath_t *
ppath_push(ppath_t * p,ppath_component_t * pc)19333ce21e2Sdyoung ppath_push(ppath_t *p, ppath_component_t *pc)
19433ce21e2Sdyoung {
19533ce21e2Sdyoung 	if (p == NULL || p->p_len == __arraycount(p->p_cmpt))
19633ce21e2Sdyoung 		return NULL;
19733ce21e2Sdyoung 
19833ce21e2Sdyoung 	p->p_cmpt[p->p_len++] = ppath_component_retain(pc);
19933ce21e2Sdyoung 
20033ce21e2Sdyoung 	return p;
20133ce21e2Sdyoung }
20233ce21e2Sdyoung 
20333ce21e2Sdyoung ppath_component_t *
ppath_component_at(const ppath_t * p,unsigned int i)20433ce21e2Sdyoung ppath_component_at(const ppath_t *p, unsigned int i)
20533ce21e2Sdyoung {
20633ce21e2Sdyoung 	ppath_component_t *pc;
20733ce21e2Sdyoung 
20833ce21e2Sdyoung 	if (p == NULL || i >= p->p_len)
20933ce21e2Sdyoung 		return NULL;
21033ce21e2Sdyoung 
21133ce21e2Sdyoung 	pc = p->p_cmpt[i];
21233ce21e2Sdyoung 
21333ce21e2Sdyoung 	return ppath_component_retain(pc);
21433ce21e2Sdyoung }
21533ce21e2Sdyoung 
21633ce21e2Sdyoung unsigned int
ppath_length(const ppath_t * p)21733ce21e2Sdyoung ppath_length(const ppath_t *p)
21833ce21e2Sdyoung {
21933ce21e2Sdyoung 	return p->p_len;
22033ce21e2Sdyoung }
22133ce21e2Sdyoung 
22233ce21e2Sdyoung ppath_t *
ppath_subpath(const ppath_t * p,unsigned int first,unsigned int exclast)22333ce21e2Sdyoung ppath_subpath(const ppath_t *p, unsigned int first, unsigned int exclast)
22433ce21e2Sdyoung {
22533ce21e2Sdyoung 	unsigned int i;
22633ce21e2Sdyoung 	ppath_t *np;
22733ce21e2Sdyoung 	ppath_component_t *pc;
22833ce21e2Sdyoung 
22933ce21e2Sdyoung 	if (p == NULL || (np = ppath_create()) == NULL)
23033ce21e2Sdyoung 		return NULL;
23133ce21e2Sdyoung 
23233ce21e2Sdyoung 	for (i = first; i < exclast; i++) {
23333ce21e2Sdyoung 		if ((pc = ppath_component_at(p, i)) == NULL)
23433ce21e2Sdyoung 			break;
23533ce21e2Sdyoung 		ppath_push(np, pc);
23633ce21e2Sdyoung 		ppath_component_release(pc);
23733ce21e2Sdyoung 	}
23833ce21e2Sdyoung 	return np;
23933ce21e2Sdyoung }
24033ce21e2Sdyoung 
24133ce21e2Sdyoung ppath_t *
ppath_push_idx(ppath_t * p0,unsigned int idx)24233ce21e2Sdyoung ppath_push_idx(ppath_t *p0, unsigned int idx)
24333ce21e2Sdyoung {
24433ce21e2Sdyoung 	ppath_component_t *pc;
24533ce21e2Sdyoung 	ppath_t *p;
24633ce21e2Sdyoung 
24733ce21e2Sdyoung 	if ((pc = ppath_idx(idx)) == NULL)
24833ce21e2Sdyoung 		return NULL;
24933ce21e2Sdyoung 
25033ce21e2Sdyoung 	p = ppath_push(p0, pc);
25133ce21e2Sdyoung 	ppath_component_release(pc);
25233ce21e2Sdyoung 	return p;
25333ce21e2Sdyoung }
25433ce21e2Sdyoung 
25533ce21e2Sdyoung ppath_t *
ppath_push_key(ppath_t * p0,const char * key)25633ce21e2Sdyoung ppath_push_key(ppath_t *p0, const char *key)
25733ce21e2Sdyoung {
25833ce21e2Sdyoung 	ppath_component_t *pc;
25933ce21e2Sdyoung 	ppath_t *p;
26033ce21e2Sdyoung 
26133ce21e2Sdyoung 	if ((pc = ppath_key(key)) == NULL)
26233ce21e2Sdyoung 		return NULL;
26333ce21e2Sdyoung 
26433ce21e2Sdyoung 	p = ppath_push(p0, pc);
26533ce21e2Sdyoung 	ppath_component_release(pc);
26633ce21e2Sdyoung 	return p;
26733ce21e2Sdyoung }
26833ce21e2Sdyoung 
26933ce21e2Sdyoung ppath_t *
ppath_replace_idx(ppath_t * p,unsigned int idx)27033ce21e2Sdyoung ppath_replace_idx(ppath_t *p, unsigned int idx)
27133ce21e2Sdyoung {
27233ce21e2Sdyoung 	ppath_component_t *pc0, *pc;
27333ce21e2Sdyoung 
27433ce21e2Sdyoung 	if (p == NULL || p->p_len == 0)
27533ce21e2Sdyoung 		return NULL;
27633ce21e2Sdyoung 
27733ce21e2Sdyoung 	pc0 = p->p_cmpt[p->p_len - 1];
27833ce21e2Sdyoung 
27933ce21e2Sdyoung 	if (pc0->pc_type != PPATH_T_IDX)
28033ce21e2Sdyoung 		return NULL;
28133ce21e2Sdyoung 
28233ce21e2Sdyoung 	if ((pc = ppath_idx(idx)) == NULL)
28333ce21e2Sdyoung 		return NULL;
28433ce21e2Sdyoung 
28533ce21e2Sdyoung 	p->p_cmpt[p->p_len - 1] = pc;
28633ce21e2Sdyoung 	ppath_component_release(pc0);
28733ce21e2Sdyoung 
28833ce21e2Sdyoung 	return p;
28933ce21e2Sdyoung }
29033ce21e2Sdyoung 
29133ce21e2Sdyoung ppath_t *
ppath_replace_key(ppath_t * p,const char * key)29233ce21e2Sdyoung ppath_replace_key(ppath_t *p, const char *key)
29333ce21e2Sdyoung {
29433ce21e2Sdyoung 	ppath_component_t *pc0, *pc;
29533ce21e2Sdyoung 
29633ce21e2Sdyoung 	if (p == NULL || p->p_len == 0)
29733ce21e2Sdyoung 		return NULL;
29833ce21e2Sdyoung 
29933ce21e2Sdyoung 	pc0 = p->p_cmpt[p->p_len - 1];
30033ce21e2Sdyoung 
30133ce21e2Sdyoung 	if (pc0->pc_type != PPATH_T_KEY)
30233ce21e2Sdyoung 		return NULL;
30333ce21e2Sdyoung 
30433ce21e2Sdyoung 	if ((pc = ppath_key(key)) == NULL)
30533ce21e2Sdyoung 		return NULL;
30633ce21e2Sdyoung 
30733ce21e2Sdyoung 	p->p_cmpt[p->p_len - 1] = pc;
30833ce21e2Sdyoung 	ppath_component_release(pc0);
30933ce21e2Sdyoung 
31033ce21e2Sdyoung 	return p;
31133ce21e2Sdyoung }
31233ce21e2Sdyoung 
31333ce21e2Sdyoung ppath_t *
ppath_copy(const ppath_t * p0)31433ce21e2Sdyoung ppath_copy(const ppath_t *p0)
31533ce21e2Sdyoung {
31633ce21e2Sdyoung 	ppath_t *p;
31733ce21e2Sdyoung 	unsigned int i;
31833ce21e2Sdyoung 
31933ce21e2Sdyoung 	if ((p = ppath_create()) == NULL)
32033ce21e2Sdyoung 		return NULL;
32133ce21e2Sdyoung 
32233ce21e2Sdyoung 	for (i = 0; i < p0->p_len; i++)
32333ce21e2Sdyoung 		p->p_cmpt[i] = ppath_component_retain(p0->p_cmpt[i]);
32433ce21e2Sdyoung 	p->p_len = p0->p_len;
32533ce21e2Sdyoung 	return p;
32633ce21e2Sdyoung }
32733ce21e2Sdyoung 
32833ce21e2Sdyoung ppath_t *
ppath_retain(ppath_t * p)32933ce21e2Sdyoung ppath_retain(ppath_t *p)
33033ce21e2Sdyoung {
33133ce21e2Sdyoung 	assert(p->p_refcnt != 0);
33233ce21e2Sdyoung 
33333ce21e2Sdyoung 	p->p_refcnt++;
33433ce21e2Sdyoung 
33533ce21e2Sdyoung 	return p;
33633ce21e2Sdyoung }
33733ce21e2Sdyoung 
33833ce21e2Sdyoung void
ppath_release(ppath_t * p)33933ce21e2Sdyoung ppath_release(ppath_t *p)
34033ce21e2Sdyoung {
34133ce21e2Sdyoung 	unsigned int i;
34233ce21e2Sdyoung 
34333ce21e2Sdyoung 	assert(p->p_refcnt != 0);
34433ce21e2Sdyoung 
34533ce21e2Sdyoung 	if (--p->p_refcnt != 0)
34633ce21e2Sdyoung 		return;
34733ce21e2Sdyoung 
34833ce21e2Sdyoung 	for (i = 0; i < p->p_len; i++)
34933ce21e2Sdyoung 		ppath_component_release(p->p_cmpt[i]);
35033ce21e2Sdyoung 
35133ce21e2Sdyoung 	ppath_extant_dec();
35233ce21e2Sdyoung 	ppath_free(p, sizeof(*p));
35333ce21e2Sdyoung }
35433ce21e2Sdyoung 
35533ce21e2Sdyoung static prop_object_t
ppath_lookup_helper(prop_object_t o0,const ppath_t * p,prop_object_t * pop,ppath_component_t ** pcp,unsigned int * ip)35633ce21e2Sdyoung ppath_lookup_helper(prop_object_t o0, const ppath_t *p, prop_object_t *pop,
35733ce21e2Sdyoung     ppath_component_t **pcp, unsigned int *ip)
35833ce21e2Sdyoung {
35933ce21e2Sdyoung 	unsigned int i;
36033ce21e2Sdyoung 	prop_object_t o, po;
36133ce21e2Sdyoung 	ppath_type_t t;
36233ce21e2Sdyoung 	ppath_component_t *pc = NULL;
36333ce21e2Sdyoung 
36433ce21e2Sdyoung 	for (po = NULL, o = o0, i = 0; i < p->p_len && o != NULL; i++) {
36533ce21e2Sdyoung 		pc = p->p_cmpt[i];
36633ce21e2Sdyoung 		t = pc->pc_type;
36733ce21e2Sdyoung 		switch (prop_object_type(o)) {
36833ce21e2Sdyoung 		case PROP_TYPE_ARRAY:
36933ce21e2Sdyoung 			po = o;
37033ce21e2Sdyoung 			o = (t == PPATH_T_IDX)
37133ce21e2Sdyoung 			    ? prop_array_get(o, pc->pc_idx)
37233ce21e2Sdyoung 			    : NULL;
37333ce21e2Sdyoung 			break;
37433ce21e2Sdyoung 		case PROP_TYPE_DICTIONARY:
37533ce21e2Sdyoung 			po = o;
37633ce21e2Sdyoung 			o = (t == PPATH_T_KEY)
37733ce21e2Sdyoung 			    ? prop_dictionary_get(o, pc->pc_key)
37833ce21e2Sdyoung 			    : NULL;
37933ce21e2Sdyoung 			break;
38033ce21e2Sdyoung 		default:
38133ce21e2Sdyoung 			o = NULL;
38233ce21e2Sdyoung 			break;
38333ce21e2Sdyoung 		}
38433ce21e2Sdyoung 	}
38533ce21e2Sdyoung 	if (pop != NULL)
38633ce21e2Sdyoung 		*pop = po;
38733ce21e2Sdyoung 	if (pcp != NULL)
38833ce21e2Sdyoung 		*pcp = pc;
38933ce21e2Sdyoung 	if (ip != NULL)
39033ce21e2Sdyoung 		*ip = i;
39133ce21e2Sdyoung 	return o;
39233ce21e2Sdyoung }
39333ce21e2Sdyoung 
39433ce21e2Sdyoung prop_object_t
ppath_lookup(prop_object_t o,const ppath_t * p)39533ce21e2Sdyoung ppath_lookup(prop_object_t o, const ppath_t *p)
39633ce21e2Sdyoung {
39733ce21e2Sdyoung 	return ppath_lookup_helper(o, p, NULL, NULL, NULL);
39833ce21e2Sdyoung }
39933ce21e2Sdyoung 
40033ce21e2Sdyoung static int
ppath_create_object_and_release(prop_object_t o,const ppath_t * p,prop_object_t v)40133ce21e2Sdyoung ppath_create_object_and_release(prop_object_t o, const ppath_t *p,
40233ce21e2Sdyoung     prop_object_t v)
40333ce21e2Sdyoung {
40433ce21e2Sdyoung 	int rc;
40533ce21e2Sdyoung 
40633ce21e2Sdyoung 	rc = ppath_create_object(o, p, v);
40733ce21e2Sdyoung 	prop_object_release(v);
40833ce21e2Sdyoung 	return rc;
40933ce21e2Sdyoung }
41033ce21e2Sdyoung 
41133ce21e2Sdyoung int
ppath_create_string(prop_object_t o,const ppath_t * p,const char * s)41233ce21e2Sdyoung ppath_create_string(prop_object_t o, const ppath_t *p, const char *s)
41333ce21e2Sdyoung {
41433ce21e2Sdyoung 	return ppath_create_object_and_release(o, p,
415*bde2909fSthorpej 	    prop_string_create_copy(s));
41633ce21e2Sdyoung }
41733ce21e2Sdyoung 
41833ce21e2Sdyoung int
ppath_create_data(prop_object_t o,const ppath_t * p,const void * data,size_t size)41933ce21e2Sdyoung ppath_create_data(prop_object_t o, const ppath_t *p,
42033ce21e2Sdyoung     const void *data, size_t size)
42133ce21e2Sdyoung {
42233ce21e2Sdyoung 	return ppath_create_object_and_release(o, p,
423*bde2909fSthorpej 	    prop_data_create_copy(data, size));
42433ce21e2Sdyoung }
42533ce21e2Sdyoung 
42633ce21e2Sdyoung int
ppath_create_uint64(prop_object_t o,const ppath_t * p,uint64_t u)42733ce21e2Sdyoung ppath_create_uint64(prop_object_t o, const ppath_t *p, uint64_t u)
42833ce21e2Sdyoung {
42933ce21e2Sdyoung 	return ppath_create_object_and_release(o, p,
430*bde2909fSthorpej 	    prop_number_create_unsigned(u));
43133ce21e2Sdyoung }
43233ce21e2Sdyoung 
43333ce21e2Sdyoung int
ppath_create_int64(prop_object_t o,const ppath_t * p,int64_t i)43433ce21e2Sdyoung ppath_create_int64(prop_object_t o, const ppath_t *p, int64_t i)
43533ce21e2Sdyoung {
43633ce21e2Sdyoung 	return ppath_create_object_and_release(o, p,
437*bde2909fSthorpej 	    prop_number_create_signed(i));
43833ce21e2Sdyoung }
43933ce21e2Sdyoung 
44033ce21e2Sdyoung int
ppath_create_bool(prop_object_t o,const ppath_t * p,bool b)44133ce21e2Sdyoung ppath_create_bool(prop_object_t o, const ppath_t *p, bool b)
44233ce21e2Sdyoung {
44333ce21e2Sdyoung 	return ppath_create_object_and_release(o, p, prop_bool_create(b));
44433ce21e2Sdyoung }
44533ce21e2Sdyoung 
44633ce21e2Sdyoung int
ppath_create_object(prop_object_t o,const ppath_t * p,prop_object_t v)44733ce21e2Sdyoung ppath_create_object(prop_object_t o, const ppath_t *p, prop_object_t v)
44833ce21e2Sdyoung {
44933ce21e2Sdyoung 	unsigned int i;
45033ce21e2Sdyoung 	ppath_component_t *pc;
45133ce21e2Sdyoung 	prop_object_t po;
45233ce21e2Sdyoung 
45333ce21e2Sdyoung 	if (ppath_lookup_helper(o, p, &po, &pc, &i) != NULL)
45433ce21e2Sdyoung 		return EEXIST;
45533ce21e2Sdyoung 
45633ce21e2Sdyoung 	if (i != ppath_length(p))
45733ce21e2Sdyoung 		return ENOENT;
45833ce21e2Sdyoung 
45933ce21e2Sdyoung 	switch (pc->pc_type) {
46033ce21e2Sdyoung 	case PPATH_T_IDX:
46133ce21e2Sdyoung 		return prop_array_set(po, pc->pc_idx, v) ? 0 : ENOMEM;
46233ce21e2Sdyoung 	case PPATH_T_KEY:
46333ce21e2Sdyoung 		return prop_dictionary_set(po, pc->pc_key, v) ? 0 : ENOMEM;
46433ce21e2Sdyoung 	default:
46533ce21e2Sdyoung 		return ENOENT;
46633ce21e2Sdyoung 	}
46733ce21e2Sdyoung }
46833ce21e2Sdyoung 
46933ce21e2Sdyoung int
ppath_set_object(prop_object_t o,const ppath_t * p,prop_object_t v)47033ce21e2Sdyoung ppath_set_object(prop_object_t o, const ppath_t *p, prop_object_t v)
47133ce21e2Sdyoung {
47233ce21e2Sdyoung 	ppath_component_t *pc;
47333ce21e2Sdyoung 	prop_object_t po;
47433ce21e2Sdyoung 
47533ce21e2Sdyoung 	if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
47633ce21e2Sdyoung 		return ENOENT;
47733ce21e2Sdyoung 
47833ce21e2Sdyoung 	switch (pc->pc_type) {
47933ce21e2Sdyoung 	case PPATH_T_IDX:
48033ce21e2Sdyoung 		return prop_array_set(po, pc->pc_idx, v) ? 0 : ENOMEM;
48133ce21e2Sdyoung 	case PPATH_T_KEY:
48233ce21e2Sdyoung 		return prop_dictionary_set(po, pc->pc_key, v) ? 0 : ENOMEM;
48333ce21e2Sdyoung 	default:
48433ce21e2Sdyoung 		return ENOENT;
48533ce21e2Sdyoung 	}
48633ce21e2Sdyoung }
48733ce21e2Sdyoung 
48833ce21e2Sdyoung static int
ppath_set_object_and_release(prop_object_t o,const ppath_t * p,prop_object_t v)48933ce21e2Sdyoung ppath_set_object_and_release(prop_object_t o, const ppath_t *p, prop_object_t v)
49033ce21e2Sdyoung {
49133ce21e2Sdyoung 	prop_object_t ov;
49233ce21e2Sdyoung 	int rc;
49333ce21e2Sdyoung 
49433ce21e2Sdyoung 	if (v == NULL)
49533ce21e2Sdyoung 		return ENOMEM;
49633ce21e2Sdyoung 
49733ce21e2Sdyoung 	if ((ov = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
49833ce21e2Sdyoung 		return ENOENT;
49933ce21e2Sdyoung 
50033ce21e2Sdyoung 	if (prop_object_type(ov) != prop_object_type(v))
50133ce21e2Sdyoung 		return EFTYPE;
50233ce21e2Sdyoung 
50333ce21e2Sdyoung 	rc = ppath_set_object(o, p, v);
50433ce21e2Sdyoung 	prop_object_release(v);
50533ce21e2Sdyoung 	return rc;
50633ce21e2Sdyoung }
50733ce21e2Sdyoung 
50833ce21e2Sdyoung int
ppath_get_object(prop_object_t o,const ppath_t * p,prop_object_t * vp)50933ce21e2Sdyoung ppath_get_object(prop_object_t o, const ppath_t *p, prop_object_t *vp)
51033ce21e2Sdyoung {
51133ce21e2Sdyoung 	prop_object_t v;
51233ce21e2Sdyoung 
51333ce21e2Sdyoung 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
51433ce21e2Sdyoung 		return ENOENT;
51533ce21e2Sdyoung 
51633ce21e2Sdyoung 	if (vp != NULL)
51733ce21e2Sdyoung 		*vp = v;
51833ce21e2Sdyoung 	return 0;
51933ce21e2Sdyoung }
52033ce21e2Sdyoung 
52133ce21e2Sdyoung static int
ppath_get_object_of_type(prop_object_t o,const ppath_t * p,prop_object_t * vp,prop_type_t t)52233ce21e2Sdyoung ppath_get_object_of_type(prop_object_t o, const ppath_t *p, prop_object_t *vp,
52333ce21e2Sdyoung     prop_type_t t)
52433ce21e2Sdyoung {
52533ce21e2Sdyoung 	int rc;
52633ce21e2Sdyoung 
52733ce21e2Sdyoung 	if ((rc = ppath_get_object(o, p, vp)) != 0)
52833ce21e2Sdyoung 		return rc;
52933ce21e2Sdyoung 
53033ce21e2Sdyoung 	return (prop_object_type(*vp) == t) ? 0 : EFTYPE;
53133ce21e2Sdyoung }
53233ce21e2Sdyoung 
53333ce21e2Sdyoung int
ppath_delete_object(prop_object_t o,const ppath_t * p)53433ce21e2Sdyoung ppath_delete_object(prop_object_t o, const ppath_t *p)
53533ce21e2Sdyoung {
53633ce21e2Sdyoung 	ppath_component_t *pc;
53733ce21e2Sdyoung 	prop_object_t po;
53833ce21e2Sdyoung 
53933ce21e2Sdyoung 	if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
54033ce21e2Sdyoung 		return ENOENT;
54133ce21e2Sdyoung 
54233ce21e2Sdyoung 	switch (pc->pc_type) {
54333ce21e2Sdyoung 	case PPATH_T_IDX:
54433ce21e2Sdyoung 		prop_array_remove(po, pc->pc_idx);
54533ce21e2Sdyoung 		return 0;
54633ce21e2Sdyoung 	case PPATH_T_KEY:
54733ce21e2Sdyoung 		prop_dictionary_remove(po, pc->pc_key);
54833ce21e2Sdyoung 		return 0;
54933ce21e2Sdyoung 	default:
55033ce21e2Sdyoung 		return ENOENT;
55133ce21e2Sdyoung 	}
55233ce21e2Sdyoung }
55333ce21e2Sdyoung 
55433ce21e2Sdyoung static int
ppath_delete_object_of_type(prop_object_t o,const ppath_t * p,prop_type_t t)55533ce21e2Sdyoung ppath_delete_object_of_type(prop_object_t o, const ppath_t *p, prop_type_t t)
55633ce21e2Sdyoung {
55733ce21e2Sdyoung 	prop_object_t v;
55833ce21e2Sdyoung 
55933ce21e2Sdyoung 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
56033ce21e2Sdyoung 		return ENOENT;
56133ce21e2Sdyoung 
56233ce21e2Sdyoung 	if (prop_object_type(v) != t)
56333ce21e2Sdyoung 		return EFTYPE;
56433ce21e2Sdyoung 
56533ce21e2Sdyoung 	return ppath_delete_object(o, p);
56633ce21e2Sdyoung }
56733ce21e2Sdyoung 
56833ce21e2Sdyoung int
ppath_copydel_string(prop_object_t o,prop_object_t * op,const ppath_t * p)56933ce21e2Sdyoung ppath_copydel_string(prop_object_t o, prop_object_t *op, const ppath_t *p)
57033ce21e2Sdyoung {
57133ce21e2Sdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_STRING);
57233ce21e2Sdyoung }
57333ce21e2Sdyoung 
57433ce21e2Sdyoung int
ppath_copydel_data(prop_object_t o,prop_object_t * op,const ppath_t * p)57533ce21e2Sdyoung ppath_copydel_data(prop_object_t o, prop_object_t *op, const ppath_t *p)
57633ce21e2Sdyoung {
57733ce21e2Sdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_DATA);
57833ce21e2Sdyoung }
57933ce21e2Sdyoung 
58033ce21e2Sdyoung int
ppath_copydel_uint64(prop_object_t o,prop_object_t * op,const ppath_t * p)58133ce21e2Sdyoung ppath_copydel_uint64(prop_object_t o, prop_object_t *op, const ppath_t *p)
58233ce21e2Sdyoung {
58333ce21e2Sdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_NUMBER);
58433ce21e2Sdyoung }
58533ce21e2Sdyoung 
58633ce21e2Sdyoung int
ppath_copydel_int64(prop_object_t o,prop_object_t * op,const ppath_t * p)58733ce21e2Sdyoung ppath_copydel_int64(prop_object_t o, prop_object_t *op, const ppath_t *p)
58833ce21e2Sdyoung {
58933ce21e2Sdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_NUMBER);
59033ce21e2Sdyoung }
59133ce21e2Sdyoung 
59233ce21e2Sdyoung int
ppath_copydel_bool(prop_object_t o,prop_object_t * op,const ppath_t * p)59333ce21e2Sdyoung ppath_copydel_bool(prop_object_t o, prop_object_t *op, const ppath_t *p)
59433ce21e2Sdyoung {
59533ce21e2Sdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_BOOL);
59633ce21e2Sdyoung }
59733ce21e2Sdyoung 
59833ce21e2Sdyoung static int
ppath_copydel_object_of_type(prop_object_t o,prop_object_t * op,const ppath_t * p,prop_type_t t)59933ce21e2Sdyoung ppath_copydel_object_of_type(prop_object_t o, prop_object_t *op,
60033ce21e2Sdyoung     const ppath_t *p, prop_type_t t)
60133ce21e2Sdyoung {
60233ce21e2Sdyoung 	prop_object_t v;
60333ce21e2Sdyoung 
60433ce21e2Sdyoung 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
60533ce21e2Sdyoung 		return ENOENT;
60633ce21e2Sdyoung 
60733ce21e2Sdyoung 	if (prop_object_type(v) != t)
60833ce21e2Sdyoung 		return EFTYPE;
60933ce21e2Sdyoung 
61033ce21e2Sdyoung 	return ppath_copydel_object(o, op, p);
61133ce21e2Sdyoung }
61233ce21e2Sdyoung 
61333ce21e2Sdyoung int
ppath_copydel_object(prop_object_t o,prop_object_t * op,const ppath_t * p)61433ce21e2Sdyoung ppath_copydel_object(prop_object_t o, prop_object_t *op, const ppath_t *p)
61533ce21e2Sdyoung {
61633ce21e2Sdyoung 	return ppath_copyset_object_helper(o, op, p, NULL);
61733ce21e2Sdyoung }
61833ce21e2Sdyoung 
61933ce21e2Sdyoung int
ppath_copyset_object(prop_object_t o,prop_object_t * op,const ppath_t * p,const prop_object_t v)62033ce21e2Sdyoung ppath_copyset_object(prop_object_t o, prop_object_t *op, const ppath_t *p,
62133ce21e2Sdyoung     const prop_object_t v)
62233ce21e2Sdyoung {
62333ce21e2Sdyoung 	ppath_assert(v != NULL);
62433ce21e2Sdyoung 	return ppath_copyset_object_helper(o, op, p, v);
62533ce21e2Sdyoung }
62633ce21e2Sdyoung 
62733ce21e2Sdyoung static int
ppath_copyset_object_helper(prop_object_t o,prop_object_t * op,const ppath_t * p0,const prop_object_t v0)62833ce21e2Sdyoung ppath_copyset_object_helper(prop_object_t o, prop_object_t *op,
62933ce21e2Sdyoung     const ppath_t *p0, const prop_object_t v0)
63033ce21e2Sdyoung {
63133ce21e2Sdyoung 	bool copy, success;
63233ce21e2Sdyoung 	ppath_component_t *npc, *pc;
63333ce21e2Sdyoung 	ppath_t *cp, *p;
63433ce21e2Sdyoung 	prop_object_t npo = NULL, po, v;
63533ce21e2Sdyoung 
63633ce21e2Sdyoung 	for (cp = p = ppath_copy(p0), v = v0;
63733ce21e2Sdyoung 	     p != NULL;
63833ce21e2Sdyoung 	     p = ppath_pop(p, NULL), v = npo) {
63933ce21e2Sdyoung 
64033ce21e2Sdyoung 		if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
64133ce21e2Sdyoung 			return ENOENT;
64233ce21e2Sdyoung 
64333ce21e2Sdyoung 		if (pc == NULL)
64433ce21e2Sdyoung 			break;
64533ce21e2Sdyoung 
64633ce21e2Sdyoung 		if (ppath_lookup_helper(*op, p, &npo, &npc, NULL) == NULL)
64733ce21e2Sdyoung 			npo = po;
64833ce21e2Sdyoung 
64933ce21e2Sdyoung 		copy = (npo == po);
65033ce21e2Sdyoung 
65133ce21e2Sdyoung 		switch (pc->pc_type) {
65233ce21e2Sdyoung 		case PPATH_T_IDX:
65333ce21e2Sdyoung 			if (copy && (npo = prop_array_copy_mutable(po)) == NULL)
65433ce21e2Sdyoung 				return ENOMEM;
65533ce21e2Sdyoung 			success = (v == NULL)
65633ce21e2Sdyoung 			    ? (prop_array_remove(npo, pc->pc_idx), true)
65733ce21e2Sdyoung 			    : prop_array_set(npo, pc->pc_idx, v);
65833ce21e2Sdyoung 			break;
65933ce21e2Sdyoung 		case PPATH_T_KEY:
66033ce21e2Sdyoung 			if (copy &&
66133ce21e2Sdyoung 			    (npo = prop_dictionary_copy_mutable(po)) == NULL)
66233ce21e2Sdyoung 				return ENOMEM;
66333ce21e2Sdyoung 			success = (v == NULL)
66433ce21e2Sdyoung 			    ? (prop_dictionary_remove(npo, pc->pc_key), true)
66533ce21e2Sdyoung 			    : prop_dictionary_set(npo, pc->pc_key, v);
66633ce21e2Sdyoung 			break;
66733ce21e2Sdyoung 		default:
66833ce21e2Sdyoung 			return ENOENT;
66933ce21e2Sdyoung 		}
67033ce21e2Sdyoung 		if (!success) {
67133ce21e2Sdyoung 			if (copy)
67233ce21e2Sdyoung 				prop_object_release(npo);
67333ce21e2Sdyoung 			return ENOMEM;
67433ce21e2Sdyoung 		}
67533ce21e2Sdyoung 	}
67633ce21e2Sdyoung 
67733ce21e2Sdyoung 	if (cp == NULL)
67833ce21e2Sdyoung 		return ENOMEM;
67933ce21e2Sdyoung 
68033ce21e2Sdyoung 	ppath_release(cp);
68133ce21e2Sdyoung 
68233ce21e2Sdyoung 	if (op != NULL && npo != NULL)
68333ce21e2Sdyoung 		*op = npo;
68433ce21e2Sdyoung 	else if (npo != NULL)
68533ce21e2Sdyoung 		prop_object_release(npo);
68633ce21e2Sdyoung 
68733ce21e2Sdyoung 	return 0;
68833ce21e2Sdyoung }
68933ce21e2Sdyoung 
69033ce21e2Sdyoung static int
ppath_copyset_object_and_release(prop_object_t o,prop_object_t * op,const ppath_t * p,prop_object_t v)69133ce21e2Sdyoung ppath_copyset_object_and_release(prop_object_t o, prop_object_t *op,
69233ce21e2Sdyoung     const ppath_t *p, prop_object_t v)
69333ce21e2Sdyoung {
69433ce21e2Sdyoung 	prop_object_t ov;
69533ce21e2Sdyoung 	int rc;
69633ce21e2Sdyoung 
69733ce21e2Sdyoung 	if (v == NULL)
69833ce21e2Sdyoung 		return ENOMEM;
69933ce21e2Sdyoung 
70033ce21e2Sdyoung 	if ((ov = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
70133ce21e2Sdyoung 		return ENOENT;
70233ce21e2Sdyoung 
70333ce21e2Sdyoung 	if (prop_object_type(ov) != prop_object_type(v))
70433ce21e2Sdyoung 		return EFTYPE;
70533ce21e2Sdyoung 
70633ce21e2Sdyoung 	rc = ppath_copyset_object(o, op, p, v);
70733ce21e2Sdyoung 	prop_object_release(v);
70833ce21e2Sdyoung 	return rc;
70933ce21e2Sdyoung }
71033ce21e2Sdyoung 
71133ce21e2Sdyoung int
ppath_copyset_bool(prop_object_t o,prop_object_t * op,const ppath_t * p,bool b)71233ce21e2Sdyoung ppath_copyset_bool(prop_object_t o, prop_object_t *op, const ppath_t *p, bool b)
71333ce21e2Sdyoung {
71433ce21e2Sdyoung 	return ppath_copyset_object_and_release(o, op, p, prop_bool_create(b));
71533ce21e2Sdyoung }
71633ce21e2Sdyoung 
71733ce21e2Sdyoung int
ppath_set_bool(prop_object_t o,const ppath_t * p,bool b)71833ce21e2Sdyoung ppath_set_bool(prop_object_t o, const ppath_t *p, bool b)
71933ce21e2Sdyoung {
72033ce21e2Sdyoung 	return ppath_set_object_and_release(o, p, prop_bool_create(b));
72133ce21e2Sdyoung }
72233ce21e2Sdyoung 
72333ce21e2Sdyoung int
ppath_get_bool(prop_object_t o,const ppath_t * p,bool * bp)72433ce21e2Sdyoung ppath_get_bool(prop_object_t o, const ppath_t *p, bool *bp)
72533ce21e2Sdyoung {
72633ce21e2Sdyoung 	prop_object_t v;
72733ce21e2Sdyoung 	int rc;
72833ce21e2Sdyoung 
72933ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_BOOL)) != 0)
73033ce21e2Sdyoung 		return rc;
73133ce21e2Sdyoung 
73233ce21e2Sdyoung 	if (bp != NULL)
73333ce21e2Sdyoung 		*bp = prop_bool_true(v);
73433ce21e2Sdyoung 
73533ce21e2Sdyoung 	return 0;
73633ce21e2Sdyoung }
73733ce21e2Sdyoung 
73833ce21e2Sdyoung int
ppath_delete_bool(prop_object_t o,const ppath_t * p)73933ce21e2Sdyoung ppath_delete_bool(prop_object_t o, const ppath_t *p)
74033ce21e2Sdyoung {
74133ce21e2Sdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_BOOL);
74233ce21e2Sdyoung }
74333ce21e2Sdyoung 
74433ce21e2Sdyoung int
ppath_copyset_data(prop_object_t o,prop_object_t * op,const ppath_t * p,const void * data,size_t size)74533ce21e2Sdyoung ppath_copyset_data(prop_object_t o, prop_object_t *op, const ppath_t *p,
74633ce21e2Sdyoung     const void *data, size_t size)
74733ce21e2Sdyoung {
74833ce21e2Sdyoung 	return ppath_copyset_object_and_release(o, op, p,
749*bde2909fSthorpej 	    prop_data_create_copy(data, size));
75033ce21e2Sdyoung }
75133ce21e2Sdyoung 
75233ce21e2Sdyoung int
ppath_set_data(prop_object_t o,const ppath_t * p,const void * data,size_t size)75333ce21e2Sdyoung ppath_set_data(prop_object_t o, const ppath_t *p, const void *data, size_t size)
75433ce21e2Sdyoung {
75533ce21e2Sdyoung 	return ppath_set_object_and_release(o, p,
756*bde2909fSthorpej 	    prop_data_create_copy(data, size));
75733ce21e2Sdyoung }
75833ce21e2Sdyoung 
75933ce21e2Sdyoung int
ppath_get_data(prop_object_t o,const ppath_t * p,const void ** datap,size_t * sizep)76033ce21e2Sdyoung ppath_get_data(prop_object_t o, const ppath_t *p, const void **datap,
76133ce21e2Sdyoung     size_t *sizep)
76233ce21e2Sdyoung {
76333ce21e2Sdyoung 	prop_object_t v;
76433ce21e2Sdyoung 	int rc;
76533ce21e2Sdyoung 
76633ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
76733ce21e2Sdyoung 		return rc;
76833ce21e2Sdyoung 
76933ce21e2Sdyoung 	if (datap != NULL)
770*bde2909fSthorpej 		*datap = prop_data_value(v);
77133ce21e2Sdyoung 	if (sizep != NULL)
77233ce21e2Sdyoung 		*sizep = prop_data_size(v);
77333ce21e2Sdyoung 
77433ce21e2Sdyoung 	return 0;
77533ce21e2Sdyoung }
77633ce21e2Sdyoung 
77733ce21e2Sdyoung int
ppath_dup_data(prop_object_t o,const ppath_t * p,void ** datap,size_t * sizep)77833ce21e2Sdyoung ppath_dup_data(prop_object_t o, const ppath_t *p, void **datap, size_t *sizep)
77933ce21e2Sdyoung {
78033ce21e2Sdyoung 	prop_object_t v;
78133ce21e2Sdyoung 	int rc;
78233ce21e2Sdyoung 
78333ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
78433ce21e2Sdyoung 		return rc;
78533ce21e2Sdyoung 
786*bde2909fSthorpej 	const size_t data_size = prop_data_size(v);
787*bde2909fSthorpej 
788*bde2909fSthorpej 	if (datap != NULL) {
789*bde2909fSthorpej 		void *buf = ppath_alloc(data_size);
790*bde2909fSthorpej 		if (buf != NULL)
791*bde2909fSthorpej 			(void) prop_data_copy_value(v, buf, data_size);
792*bde2909fSthorpej 		*datap = buf;
793*bde2909fSthorpej 	}
79433ce21e2Sdyoung 	if (sizep != NULL)
795*bde2909fSthorpej 		*sizep = data_size;
79633ce21e2Sdyoung 
79733ce21e2Sdyoung 	return 0;
79833ce21e2Sdyoung }
79933ce21e2Sdyoung 
80033ce21e2Sdyoung int
ppath_delete_data(prop_object_t o,const ppath_t * p)80133ce21e2Sdyoung ppath_delete_data(prop_object_t o, const ppath_t *p)
80233ce21e2Sdyoung {
80333ce21e2Sdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_DATA);
80433ce21e2Sdyoung }
80533ce21e2Sdyoung 
80633ce21e2Sdyoung int
ppath_copyset_int64(prop_object_t o,prop_object_t * op,const ppath_t * p,int64_t i)80733ce21e2Sdyoung ppath_copyset_int64(prop_object_t o, prop_object_t *op, const ppath_t *p,
80833ce21e2Sdyoung     int64_t i)
80933ce21e2Sdyoung {
81033ce21e2Sdyoung 	return ppath_copyset_object_and_release(o, op, p,
811*bde2909fSthorpej 	    prop_number_create_signed(i));
81233ce21e2Sdyoung }
81333ce21e2Sdyoung 
81433ce21e2Sdyoung int
ppath_set_int64(prop_object_t o,const ppath_t * p,int64_t i)81533ce21e2Sdyoung ppath_set_int64(prop_object_t o, const ppath_t *p, int64_t i)
81633ce21e2Sdyoung {
81733ce21e2Sdyoung 	return ppath_set_object_and_release(o, p,
818*bde2909fSthorpej 	    prop_number_create_signed(i));
81933ce21e2Sdyoung }
82033ce21e2Sdyoung 
82133ce21e2Sdyoung int
ppath_get_int64(prop_object_t o,const ppath_t * p,int64_t * ip)82233ce21e2Sdyoung ppath_get_int64(prop_object_t o, const ppath_t *p, int64_t *ip)
82333ce21e2Sdyoung {
82433ce21e2Sdyoung 	prop_object_t v;
82533ce21e2Sdyoung 	int rc;
82633ce21e2Sdyoung 
82733ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
82833ce21e2Sdyoung 		return rc;
82933ce21e2Sdyoung 
83033ce21e2Sdyoung 	if (prop_number_unsigned(v))
83133ce21e2Sdyoung 		return EFTYPE;
83233ce21e2Sdyoung 
83333ce21e2Sdyoung 	if (ip != NULL)
834*bde2909fSthorpej 		*ip = prop_number_signed_value(v);
83533ce21e2Sdyoung 
83633ce21e2Sdyoung 	return 0;
83733ce21e2Sdyoung }
83833ce21e2Sdyoung 
83933ce21e2Sdyoung int
ppath_delete_int64(prop_object_t o,const ppath_t * p)84033ce21e2Sdyoung ppath_delete_int64(prop_object_t o, const ppath_t *p)
84133ce21e2Sdyoung {
84233ce21e2Sdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_NUMBER);
84333ce21e2Sdyoung }
84433ce21e2Sdyoung 
84533ce21e2Sdyoung int
ppath_copyset_string(prop_object_t o,prop_object_t * op,const ppath_t * p,const char * s)84633ce21e2Sdyoung ppath_copyset_string(prop_object_t o, prop_object_t *op, const ppath_t *p,
84733ce21e2Sdyoung     const char *s)
84833ce21e2Sdyoung {
84933ce21e2Sdyoung 	return ppath_copyset_object_and_release(o, op, p,
850*bde2909fSthorpej 	    prop_string_create_copy(s));
85133ce21e2Sdyoung }
85233ce21e2Sdyoung 
85333ce21e2Sdyoung int
ppath_set_string(prop_object_t o,const ppath_t * p,const char * s)85433ce21e2Sdyoung ppath_set_string(prop_object_t o, const ppath_t *p, const char *s)
85533ce21e2Sdyoung {
85633ce21e2Sdyoung 	return ppath_set_object_and_release(o, p,
857*bde2909fSthorpej 	    prop_string_create_copy(s));
85833ce21e2Sdyoung }
85933ce21e2Sdyoung 
86033ce21e2Sdyoung int
ppath_get_string(prop_object_t o,const ppath_t * p,const char ** sp)86133ce21e2Sdyoung ppath_get_string(prop_object_t o, const ppath_t *p, const char **sp)
86233ce21e2Sdyoung {
86333ce21e2Sdyoung 	int rc;
86433ce21e2Sdyoung 	prop_object_t v;
86533ce21e2Sdyoung 
86633ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_STRING)) != 0)
86733ce21e2Sdyoung 		return rc;
86833ce21e2Sdyoung 
86933ce21e2Sdyoung 	if (sp != NULL)
870*bde2909fSthorpej 		*sp = prop_string_value(v);
87133ce21e2Sdyoung 
87233ce21e2Sdyoung 	return 0;
87333ce21e2Sdyoung }
87433ce21e2Sdyoung 
87533ce21e2Sdyoung int
ppath_dup_string(prop_object_t o,const ppath_t * p,char ** sp)87633ce21e2Sdyoung ppath_dup_string(prop_object_t o, const ppath_t *p, char **sp)
87733ce21e2Sdyoung {
87833ce21e2Sdyoung 	int rc;
87933ce21e2Sdyoung 	prop_object_t v;
88033ce21e2Sdyoung 
88133ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_STRING)) != 0)
88233ce21e2Sdyoung 		return rc;
88333ce21e2Sdyoung 
884*bde2909fSthorpej 	const size_t string_size = prop_string_size(v);
885*bde2909fSthorpej 
886*bde2909fSthorpej 	if (sp != NULL) {
887*bde2909fSthorpej 		char *cp = ppath_alloc(string_size + 1);
888*bde2909fSthorpej 		if (cp != NULL)
889*bde2909fSthorpej 			(void)prop_string_copy_value(v, cp, string_size + 1);
890*bde2909fSthorpej 		*sp = cp;
891*bde2909fSthorpej 	}
89233ce21e2Sdyoung 
89333ce21e2Sdyoung 	return 0;
89433ce21e2Sdyoung }
89533ce21e2Sdyoung 
89633ce21e2Sdyoung int
ppath_delete_string(prop_object_t o,const ppath_t * p)89733ce21e2Sdyoung ppath_delete_string(prop_object_t o, const ppath_t *p)
89833ce21e2Sdyoung {
89933ce21e2Sdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_STRING);
90033ce21e2Sdyoung }
90133ce21e2Sdyoung 
90233ce21e2Sdyoung int
ppath_copyset_uint64(prop_object_t o,prop_object_t * op,const ppath_t * p,uint64_t u)90333ce21e2Sdyoung ppath_copyset_uint64(prop_object_t o, prop_object_t *op, const ppath_t *p,
90433ce21e2Sdyoung     uint64_t u)
90533ce21e2Sdyoung {
90633ce21e2Sdyoung 	return ppath_copyset_object_and_release(o, op, p,
907*bde2909fSthorpej 	    prop_number_create_unsigned(u));
90833ce21e2Sdyoung }
90933ce21e2Sdyoung 
91033ce21e2Sdyoung int
ppath_set_uint64(prop_object_t o,const ppath_t * p,uint64_t u)91133ce21e2Sdyoung ppath_set_uint64(prop_object_t o, const ppath_t *p, uint64_t u)
91233ce21e2Sdyoung {
91333ce21e2Sdyoung 	return ppath_set_object_and_release(o, p,
914*bde2909fSthorpej 	    prop_number_create_unsigned(u));
91533ce21e2Sdyoung }
91633ce21e2Sdyoung 
91733ce21e2Sdyoung int
ppath_get_uint64(prop_object_t o,const ppath_t * p,uint64_t * up)91833ce21e2Sdyoung ppath_get_uint64(prop_object_t o, const ppath_t *p, uint64_t *up)
91933ce21e2Sdyoung {
92033ce21e2Sdyoung 	prop_object_t v;
92133ce21e2Sdyoung 	int rc;
92233ce21e2Sdyoung 
92333ce21e2Sdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
92433ce21e2Sdyoung 		return rc;
92533ce21e2Sdyoung 
92633ce21e2Sdyoung 	if (!prop_number_unsigned(v))
92733ce21e2Sdyoung 		return EFTYPE;
92833ce21e2Sdyoung 
92933ce21e2Sdyoung 	if (up != NULL)
930*bde2909fSthorpej 		*up = prop_number_unsigned_value(v);
93133ce21e2Sdyoung 
93233ce21e2Sdyoung 	return 0;
93333ce21e2Sdyoung }
93433ce21e2Sdyoung 
93533ce21e2Sdyoung int
ppath_delete_uint64(prop_object_t o,const ppath_t * p)93633ce21e2Sdyoung ppath_delete_uint64(prop_object_t o, const ppath_t *p)
93733ce21e2Sdyoung {
93833ce21e2Sdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_NUMBER);
93933ce21e2Sdyoung }
940