xref: /netbsd/common/lib/libppath/ppath.c (revision 6dd14d72)
1*6dd14d72Sthorpej /* $NetBSD: ppath.c,v 1.5 2020/06/06 22:28:07 thorpej Exp $ */
28c12f608Schristos 
3913c639aSdyoung /*-
4913c639aSdyoung  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5913c639aSdyoung  * All rights reserved.
6913c639aSdyoung  *
7913c639aSdyoung  * This code is derived from software contributed to The NetBSD Foundation
8913c639aSdyoung  * by David Young <dyoung@NetBSD.org>.
9913c639aSdyoung  *
10913c639aSdyoung  * Redistribution and use in source and binary forms, with or without
11913c639aSdyoung  * modification, are permitted provided that the following conditions
12913c639aSdyoung  * are met:
13913c639aSdyoung  * 1. Redistributions of source code must retain the above copyright
14913c639aSdyoung  *    notice, this list of conditions and the following disclaimer.
15913c639aSdyoung  * 2. Redistributions in binary form must reproduce the above copyright
16913c639aSdyoung  *    notice, this list of conditions and the following disclaimer in the
17913c639aSdyoung  *    documentation and/or other materials provided with the distribution.
18913c639aSdyoung  *
19913c639aSdyoung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20913c639aSdyoung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21913c639aSdyoung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22913c639aSdyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23913c639aSdyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24913c639aSdyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25913c639aSdyoung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26913c639aSdyoung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27913c639aSdyoung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28913c639aSdyoung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29913c639aSdyoung  * POSSIBILITY OF SUCH DAMAGE.
30913c639aSdyoung  */
31913c639aSdyoung 
32913c639aSdyoung #include <sys/cdefs.h>
33*6dd14d72Sthorpej __RCSID("$NetBSD: ppath.c,v 1.5 2020/06/06 22:28:07 thorpej Exp $");
34913c639aSdyoung 
358f0861f2Smrg #ifdef _KERNEL
36166d3abaSchristos #include <sys/systm.h>
378f0861f2Smrg #endif
38913c639aSdyoung #include <ppath/ppath.h>
39913c639aSdyoung #include <ppath/ppath_impl.h>
40913c639aSdyoung 
41913c639aSdyoung enum _ppath_type {
42913c639aSdyoung 	  PPATH_T_IDX = 0
43913c639aSdyoung 	, PPATH_T_KEY = 1
44913c639aSdyoung };
45913c639aSdyoung 
46913c639aSdyoung typedef enum _ppath_type ppath_type_t;
47913c639aSdyoung 
48913c639aSdyoung struct _ppath_component {
49913c639aSdyoung 	unsigned int	pc_refcnt;
50913c639aSdyoung 	ppath_type_t	pc_type;
51913c639aSdyoung 	union {
52913c639aSdyoung 		char *u_key;
53913c639aSdyoung 		unsigned int u_idx;
54913c639aSdyoung 	} pc_u;
55913c639aSdyoung #define pc_key pc_u.u_key
56913c639aSdyoung #define pc_idx pc_u.u_idx
57913c639aSdyoung };
58913c639aSdyoung 
59913c639aSdyoung struct _ppath {
60913c639aSdyoung 	unsigned int	p_refcnt;
61913c639aSdyoung 	unsigned int	p_len;
62913c639aSdyoung 	ppath_component_t *p_cmpt[PPATH_MAX_COMPONENTS];
63913c639aSdyoung };
64913c639aSdyoung 
65913c639aSdyoung static int ppath_copydel_object_of_type(prop_object_t, prop_object_t *,
66913c639aSdyoung     const ppath_t *, prop_type_t);
67913c639aSdyoung static int ppath_copyset_object_helper(prop_object_t, prop_object_t *,
68913c639aSdyoung     const ppath_t *, const prop_object_t);
69913c639aSdyoung 
70913c639aSdyoung static void
ppath_strfree(char * s)71913c639aSdyoung ppath_strfree(char *s)
72913c639aSdyoung {
73913c639aSdyoung 	size_t size = strlen(s) + 1;
74913c639aSdyoung 
75913c639aSdyoung 	ppath_free(s, size);
76913c639aSdyoung }
77913c639aSdyoung 
78913c639aSdyoung static char *
ppath_strdup(const char * s)79913c639aSdyoung ppath_strdup(const char *s)
80913c639aSdyoung {
81913c639aSdyoung 	size_t size = strlen(s) + 1;
82913c639aSdyoung 	char *p;
83913c639aSdyoung 
84913c639aSdyoung 	if ((p = ppath_alloc(size)) == NULL)
85913c639aSdyoung 		return NULL;
86913c639aSdyoung 
87913c639aSdyoung 	return strcpy(p, s);
88913c639aSdyoung }
89913c639aSdyoung 
90913c639aSdyoung int
ppath_component_idx(const ppath_component_t * pc)91913c639aSdyoung ppath_component_idx(const ppath_component_t *pc)
92913c639aSdyoung {
93913c639aSdyoung 	if (pc->pc_type != PPATH_T_IDX)
94913c639aSdyoung 		return -1;
95913c639aSdyoung 	return pc->pc_idx;
96913c639aSdyoung }
97913c639aSdyoung 
98913c639aSdyoung const char *
ppath_component_key(const ppath_component_t * pc)99913c639aSdyoung ppath_component_key(const ppath_component_t *pc)
100913c639aSdyoung {
101913c639aSdyoung 	if (pc->pc_type != PPATH_T_KEY)
102913c639aSdyoung 		return NULL;
103913c639aSdyoung 	return pc->pc_key;
104913c639aSdyoung }
105913c639aSdyoung 
106913c639aSdyoung ppath_component_t *
ppath_idx(unsigned int idx)107913c639aSdyoung ppath_idx(unsigned int idx)
108913c639aSdyoung {
109913c639aSdyoung 	ppath_component_t *pc;
110913c639aSdyoung 
111913c639aSdyoung 	if ((pc = ppath_alloc(sizeof(*pc))) == NULL)
112913c639aSdyoung 		return NULL;
113913c639aSdyoung 	pc->pc_idx = idx;
114913c639aSdyoung 	pc->pc_type = PPATH_T_IDX;
115913c639aSdyoung 	pc->pc_refcnt = 1;
116913c639aSdyoung 	ppath_component_extant_inc();
117913c639aSdyoung 	return pc;
118913c639aSdyoung }
119913c639aSdyoung 
120913c639aSdyoung ppath_component_t *
ppath_key(const char * key)121913c639aSdyoung ppath_key(const char *key)
122913c639aSdyoung {
123913c639aSdyoung 	ppath_component_t *pc;
124913c639aSdyoung 
125913c639aSdyoung 	if ((pc = ppath_alloc(sizeof(*pc))) == NULL)
126913c639aSdyoung 		return NULL;
127913c639aSdyoung 
128913c639aSdyoung 	if ((pc->pc_key = ppath_strdup(key)) == NULL) {
129913c639aSdyoung 		ppath_free(pc, sizeof(*pc));
130913c639aSdyoung 		return NULL;
131913c639aSdyoung 	}
132913c639aSdyoung 	pc->pc_type = PPATH_T_KEY;
133913c639aSdyoung 	pc->pc_refcnt = 1;
134913c639aSdyoung 	ppath_component_extant_inc();
135913c639aSdyoung 	return pc;
136913c639aSdyoung }
137913c639aSdyoung 
138913c639aSdyoung ppath_component_t *
ppath_component_retain(ppath_component_t * pc)139913c639aSdyoung ppath_component_retain(ppath_component_t *pc)
140913c639aSdyoung {
141913c639aSdyoung 	ppath_assert(pc->pc_refcnt != 0);
142913c639aSdyoung 	pc->pc_refcnt++;
143913c639aSdyoung 
144913c639aSdyoung 	return pc;
145913c639aSdyoung }
146913c639aSdyoung 
147913c639aSdyoung void
ppath_component_release(ppath_component_t * pc)148913c639aSdyoung ppath_component_release(ppath_component_t *pc)
149913c639aSdyoung {
150913c639aSdyoung 	ppath_assert(pc->pc_refcnt != 0);
151913c639aSdyoung 
152913c639aSdyoung 	if (--pc->pc_refcnt != 0)
153913c639aSdyoung 		return;
154913c639aSdyoung 	if (pc->pc_type == PPATH_T_KEY)
155913c639aSdyoung 		ppath_strfree(pc->pc_key);
156913c639aSdyoung 	ppath_component_extant_dec();
157913c639aSdyoung 	ppath_free(pc, sizeof(*pc));
158913c639aSdyoung }
159913c639aSdyoung 
160913c639aSdyoung ppath_t *
ppath_create(void)161913c639aSdyoung ppath_create(void)
162913c639aSdyoung {
163913c639aSdyoung 	ppath_t *p;
164913c639aSdyoung 
165913c639aSdyoung 	if ((p = ppath_alloc(sizeof(*p))) == NULL)
166913c639aSdyoung 		return NULL;
167913c639aSdyoung 
168913c639aSdyoung 	p->p_refcnt = 1;
169913c639aSdyoung 	ppath_extant_inc();
170913c639aSdyoung 
171913c639aSdyoung 	return p;
172913c639aSdyoung }
173913c639aSdyoung 
174913c639aSdyoung ppath_t *
ppath_pop(ppath_t * p,ppath_component_t ** pcp)175913c639aSdyoung ppath_pop(ppath_t *p, ppath_component_t **pcp)
176913c639aSdyoung {
177913c639aSdyoung 	ppath_component_t *pc;
178913c639aSdyoung 
179913c639aSdyoung 	if (p == NULL || p->p_len == 0)
180913c639aSdyoung 		return NULL;
181913c639aSdyoung 
182913c639aSdyoung 	pc = p->p_cmpt[--p->p_len];
183913c639aSdyoung 
184913c639aSdyoung 	if (pcp != NULL)
185913c639aSdyoung 		*pcp = pc;
186913c639aSdyoung 	else
187913c639aSdyoung 		ppath_component_release(pc);
188913c639aSdyoung 
189913c639aSdyoung 	return p;
190913c639aSdyoung }
191913c639aSdyoung 
192913c639aSdyoung ppath_t *
ppath_push(ppath_t * p,ppath_component_t * pc)193913c639aSdyoung ppath_push(ppath_t *p, ppath_component_t *pc)
194913c639aSdyoung {
195913c639aSdyoung 	if (p == NULL || p->p_len == __arraycount(p->p_cmpt))
196913c639aSdyoung 		return NULL;
197913c639aSdyoung 
198913c639aSdyoung 	p->p_cmpt[p->p_len++] = ppath_component_retain(pc);
199913c639aSdyoung 
200913c639aSdyoung 	return p;
201913c639aSdyoung }
202913c639aSdyoung 
203913c639aSdyoung ppath_component_t *
ppath_component_at(const ppath_t * p,unsigned int i)204913c639aSdyoung ppath_component_at(const ppath_t *p, unsigned int i)
205913c639aSdyoung {
206913c639aSdyoung 	ppath_component_t *pc;
207913c639aSdyoung 
208913c639aSdyoung 	if (p == NULL || i >= p->p_len)
209913c639aSdyoung 		return NULL;
210913c639aSdyoung 
211913c639aSdyoung 	pc = p->p_cmpt[i];
212913c639aSdyoung 
213913c639aSdyoung 	return ppath_component_retain(pc);
214913c639aSdyoung }
215913c639aSdyoung 
216913c639aSdyoung unsigned int
ppath_length(const ppath_t * p)217913c639aSdyoung ppath_length(const ppath_t *p)
218913c639aSdyoung {
219913c639aSdyoung 	return p->p_len;
220913c639aSdyoung }
221913c639aSdyoung 
222913c639aSdyoung ppath_t *
ppath_subpath(const ppath_t * p,unsigned int first,unsigned int exclast)223913c639aSdyoung ppath_subpath(const ppath_t *p, unsigned int first, unsigned int exclast)
224913c639aSdyoung {
225913c639aSdyoung 	unsigned int i;
226913c639aSdyoung 	ppath_t *np;
227913c639aSdyoung 	ppath_component_t *pc;
228913c639aSdyoung 
229913c639aSdyoung 	if (p == NULL || (np = ppath_create()) == NULL)
230913c639aSdyoung 		return NULL;
231913c639aSdyoung 
232913c639aSdyoung 	for (i = first; i < exclast; i++) {
233913c639aSdyoung 		if ((pc = ppath_component_at(p, i)) == NULL)
234913c639aSdyoung 			break;
235913c639aSdyoung 		ppath_push(np, pc);
236913c639aSdyoung 		ppath_component_release(pc);
237913c639aSdyoung 	}
238913c639aSdyoung 	return np;
239913c639aSdyoung }
240913c639aSdyoung 
241913c639aSdyoung ppath_t *
ppath_push_idx(ppath_t * p0,unsigned int idx)242913c639aSdyoung ppath_push_idx(ppath_t *p0, unsigned int idx)
243913c639aSdyoung {
244913c639aSdyoung 	ppath_component_t *pc;
245913c639aSdyoung 	ppath_t *p;
246913c639aSdyoung 
247913c639aSdyoung 	if ((pc = ppath_idx(idx)) == NULL)
248913c639aSdyoung 		return NULL;
249913c639aSdyoung 
250913c639aSdyoung 	p = ppath_push(p0, pc);
251913c639aSdyoung 	ppath_component_release(pc);
252913c639aSdyoung 	return p;
253913c639aSdyoung }
254913c639aSdyoung 
255913c639aSdyoung ppath_t *
ppath_push_key(ppath_t * p0,const char * key)256913c639aSdyoung ppath_push_key(ppath_t *p0, const char *key)
257913c639aSdyoung {
258913c639aSdyoung 	ppath_component_t *pc;
259913c639aSdyoung 	ppath_t *p;
260913c639aSdyoung 
261913c639aSdyoung 	if ((pc = ppath_key(key)) == NULL)
262913c639aSdyoung 		return NULL;
263913c639aSdyoung 
264913c639aSdyoung 	p = ppath_push(p0, pc);
265913c639aSdyoung 	ppath_component_release(pc);
266913c639aSdyoung 	return p;
267913c639aSdyoung }
268913c639aSdyoung 
269913c639aSdyoung ppath_t *
ppath_replace_idx(ppath_t * p,unsigned int idx)270913c639aSdyoung ppath_replace_idx(ppath_t *p, unsigned int idx)
271913c639aSdyoung {
272913c639aSdyoung 	ppath_component_t *pc0, *pc;
273913c639aSdyoung 
274913c639aSdyoung 	if (p == NULL || p->p_len == 0)
275913c639aSdyoung 		return NULL;
276913c639aSdyoung 
277913c639aSdyoung 	pc0 = p->p_cmpt[p->p_len - 1];
278913c639aSdyoung 
279913c639aSdyoung 	if (pc0->pc_type != PPATH_T_IDX)
280913c639aSdyoung 		return NULL;
281913c639aSdyoung 
282913c639aSdyoung 	if ((pc = ppath_idx(idx)) == NULL)
283913c639aSdyoung 		return NULL;
284913c639aSdyoung 
285913c639aSdyoung 	p->p_cmpt[p->p_len - 1] = pc;
286913c639aSdyoung 	ppath_component_release(pc0);
287913c639aSdyoung 
288913c639aSdyoung 	return p;
289913c639aSdyoung }
290913c639aSdyoung 
291913c639aSdyoung ppath_t *
ppath_replace_key(ppath_t * p,const char * key)292913c639aSdyoung ppath_replace_key(ppath_t *p, const char *key)
293913c639aSdyoung {
294913c639aSdyoung 	ppath_component_t *pc0, *pc;
295913c639aSdyoung 
296913c639aSdyoung 	if (p == NULL || p->p_len == 0)
297913c639aSdyoung 		return NULL;
298913c639aSdyoung 
299913c639aSdyoung 	pc0 = p->p_cmpt[p->p_len - 1];
300913c639aSdyoung 
301913c639aSdyoung 	if (pc0->pc_type != PPATH_T_KEY)
302913c639aSdyoung 		return NULL;
303913c639aSdyoung 
304913c639aSdyoung 	if ((pc = ppath_key(key)) == NULL)
305913c639aSdyoung 		return NULL;
306913c639aSdyoung 
307913c639aSdyoung 	p->p_cmpt[p->p_len - 1] = pc;
308913c639aSdyoung 	ppath_component_release(pc0);
309913c639aSdyoung 
310913c639aSdyoung 	return p;
311913c639aSdyoung }
312913c639aSdyoung 
313913c639aSdyoung ppath_t *
ppath_copy(const ppath_t * p0)314913c639aSdyoung ppath_copy(const ppath_t *p0)
315913c639aSdyoung {
316913c639aSdyoung 	ppath_t *p;
317913c639aSdyoung 	unsigned int i;
318913c639aSdyoung 
319913c639aSdyoung 	if ((p = ppath_create()) == NULL)
320913c639aSdyoung 		return NULL;
321913c639aSdyoung 
322913c639aSdyoung 	for (i = 0; i < p0->p_len; i++)
323913c639aSdyoung 		p->p_cmpt[i] = ppath_component_retain(p0->p_cmpt[i]);
324913c639aSdyoung 	p->p_len = p0->p_len;
325913c639aSdyoung 	return p;
326913c639aSdyoung }
327913c639aSdyoung 
328913c639aSdyoung ppath_t *
ppath_retain(ppath_t * p)329913c639aSdyoung ppath_retain(ppath_t *p)
330913c639aSdyoung {
331913c639aSdyoung 	assert(p->p_refcnt != 0);
332913c639aSdyoung 
333913c639aSdyoung 	p->p_refcnt++;
334913c639aSdyoung 
335913c639aSdyoung 	return p;
336913c639aSdyoung }
337913c639aSdyoung 
338913c639aSdyoung void
ppath_release(ppath_t * p)339913c639aSdyoung ppath_release(ppath_t *p)
340913c639aSdyoung {
341913c639aSdyoung 	unsigned int i;
342913c639aSdyoung 
343913c639aSdyoung 	assert(p->p_refcnt != 0);
344913c639aSdyoung 
345913c639aSdyoung 	if (--p->p_refcnt != 0)
346913c639aSdyoung 		return;
347913c639aSdyoung 
348913c639aSdyoung 	for (i = 0; i < p->p_len; i++)
349913c639aSdyoung 		ppath_component_release(p->p_cmpt[i]);
350913c639aSdyoung 
351913c639aSdyoung 	ppath_extant_dec();
352913c639aSdyoung 	ppath_free(p, sizeof(*p));
353913c639aSdyoung }
354913c639aSdyoung 
355913c639aSdyoung 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)356913c639aSdyoung ppath_lookup_helper(prop_object_t o0, const ppath_t *p, prop_object_t *pop,
357913c639aSdyoung     ppath_component_t **pcp, unsigned int *ip)
358913c639aSdyoung {
359913c639aSdyoung 	unsigned int i;
360913c639aSdyoung 	prop_object_t o, po;
361913c639aSdyoung 	ppath_type_t t;
362913c639aSdyoung 	ppath_component_t *pc = NULL;
363913c639aSdyoung 
364913c639aSdyoung 	for (po = NULL, o = o0, i = 0; i < p->p_len && o != NULL; i++) {
365913c639aSdyoung 		pc = p->p_cmpt[i];
366913c639aSdyoung 		t = pc->pc_type;
367913c639aSdyoung 		switch (prop_object_type(o)) {
368913c639aSdyoung 		case PROP_TYPE_ARRAY:
369913c639aSdyoung 			po = o;
370913c639aSdyoung 			o = (t == PPATH_T_IDX)
371913c639aSdyoung 			    ? prop_array_get(o, pc->pc_idx)
372913c639aSdyoung 			    : NULL;
373913c639aSdyoung 			break;
374913c639aSdyoung 		case PROP_TYPE_DICTIONARY:
375913c639aSdyoung 			po = o;
376913c639aSdyoung 			o = (t == PPATH_T_KEY)
377913c639aSdyoung 			    ? prop_dictionary_get(o, pc->pc_key)
378913c639aSdyoung 			    : NULL;
379913c639aSdyoung 			break;
380913c639aSdyoung 		default:
381913c639aSdyoung 			o = NULL;
382913c639aSdyoung 			break;
383913c639aSdyoung 		}
384913c639aSdyoung 	}
385913c639aSdyoung 	if (pop != NULL)
386913c639aSdyoung 		*pop = po;
387913c639aSdyoung 	if (pcp != NULL)
388913c639aSdyoung 		*pcp = pc;
389913c639aSdyoung 	if (ip != NULL)
390913c639aSdyoung 		*ip = i;
391913c639aSdyoung 	return o;
392913c639aSdyoung }
393913c639aSdyoung 
394913c639aSdyoung prop_object_t
ppath_lookup(prop_object_t o,const ppath_t * p)395913c639aSdyoung ppath_lookup(prop_object_t o, const ppath_t *p)
396913c639aSdyoung {
397913c639aSdyoung 	return ppath_lookup_helper(o, p, NULL, NULL, NULL);
398913c639aSdyoung }
399913c639aSdyoung 
400913c639aSdyoung static int
ppath_create_object_and_release(prop_object_t o,const ppath_t * p,prop_object_t v)401913c639aSdyoung ppath_create_object_and_release(prop_object_t o, const ppath_t *p,
402913c639aSdyoung     prop_object_t v)
403913c639aSdyoung {
404913c639aSdyoung 	int rc;
405913c639aSdyoung 
406913c639aSdyoung 	rc = ppath_create_object(o, p, v);
407913c639aSdyoung 	prop_object_release(v);
408913c639aSdyoung 	return rc;
409913c639aSdyoung }
410913c639aSdyoung 
411913c639aSdyoung int
ppath_create_string(prop_object_t o,const ppath_t * p,const char * s)412913c639aSdyoung ppath_create_string(prop_object_t o, const ppath_t *p, const char *s)
413913c639aSdyoung {
414913c639aSdyoung 	return ppath_create_object_and_release(o, p,
415*6dd14d72Sthorpej 	    prop_string_create_copy(s));
416913c639aSdyoung }
417913c639aSdyoung 
418913c639aSdyoung int
ppath_create_data(prop_object_t o,const ppath_t * p,const void * data,size_t size)419913c639aSdyoung ppath_create_data(prop_object_t o, const ppath_t *p,
420913c639aSdyoung     const void *data, size_t size)
421913c639aSdyoung {
422913c639aSdyoung 	return ppath_create_object_and_release(o, p,
423*6dd14d72Sthorpej 	    prop_data_create_copy(data, size));
424913c639aSdyoung }
425913c639aSdyoung 
426913c639aSdyoung int
ppath_create_uint64(prop_object_t o,const ppath_t * p,uint64_t u)427913c639aSdyoung ppath_create_uint64(prop_object_t o, const ppath_t *p, uint64_t u)
428913c639aSdyoung {
429913c639aSdyoung 	return ppath_create_object_and_release(o, p,
430*6dd14d72Sthorpej 	    prop_number_create_unsigned(u));
431913c639aSdyoung }
432913c639aSdyoung 
433913c639aSdyoung int
ppath_create_int64(prop_object_t o,const ppath_t * p,int64_t i)434913c639aSdyoung ppath_create_int64(prop_object_t o, const ppath_t *p, int64_t i)
435913c639aSdyoung {
436913c639aSdyoung 	return ppath_create_object_and_release(o, p,
437*6dd14d72Sthorpej 	    prop_number_create_signed(i));
438913c639aSdyoung }
439913c639aSdyoung 
440913c639aSdyoung int
ppath_create_bool(prop_object_t o,const ppath_t * p,bool b)441913c639aSdyoung ppath_create_bool(prop_object_t o, const ppath_t *p, bool b)
442913c639aSdyoung {
443913c639aSdyoung 	return ppath_create_object_and_release(o, p, prop_bool_create(b));
444913c639aSdyoung }
445913c639aSdyoung 
446913c639aSdyoung int
ppath_create_object(prop_object_t o,const ppath_t * p,prop_object_t v)447913c639aSdyoung ppath_create_object(prop_object_t o, const ppath_t *p, prop_object_t v)
448913c639aSdyoung {
449913c639aSdyoung 	unsigned int i;
450913c639aSdyoung 	ppath_component_t *pc;
451913c639aSdyoung 	prop_object_t po;
452913c639aSdyoung 
453913c639aSdyoung 	if (ppath_lookup_helper(o, p, &po, &pc, &i) != NULL)
454913c639aSdyoung 		return EEXIST;
455913c639aSdyoung 
456913c639aSdyoung 	if (i != ppath_length(p))
457913c639aSdyoung 		return ENOENT;
458913c639aSdyoung 
459913c639aSdyoung 	switch (pc->pc_type) {
460913c639aSdyoung 	case PPATH_T_IDX:
461913c639aSdyoung 		return prop_array_set(po, pc->pc_idx, v) ? 0 : ENOMEM;
462913c639aSdyoung 	case PPATH_T_KEY:
463913c639aSdyoung 		return prop_dictionary_set(po, pc->pc_key, v) ? 0 : ENOMEM;
464913c639aSdyoung 	default:
465913c639aSdyoung 		return ENOENT;
466913c639aSdyoung 	}
467913c639aSdyoung }
468913c639aSdyoung 
469913c639aSdyoung int
ppath_set_object(prop_object_t o,const ppath_t * p,prop_object_t v)470913c639aSdyoung ppath_set_object(prop_object_t o, const ppath_t *p, prop_object_t v)
471913c639aSdyoung {
472913c639aSdyoung 	ppath_component_t *pc;
473913c639aSdyoung 	prop_object_t po;
474913c639aSdyoung 
475913c639aSdyoung 	if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
476913c639aSdyoung 		return ENOENT;
477913c639aSdyoung 
478913c639aSdyoung 	switch (pc->pc_type) {
479913c639aSdyoung 	case PPATH_T_IDX:
480913c639aSdyoung 		return prop_array_set(po, pc->pc_idx, v) ? 0 : ENOMEM;
481913c639aSdyoung 	case PPATH_T_KEY:
482913c639aSdyoung 		return prop_dictionary_set(po, pc->pc_key, v) ? 0 : ENOMEM;
483913c639aSdyoung 	default:
484913c639aSdyoung 		return ENOENT;
485913c639aSdyoung 	}
486913c639aSdyoung }
487913c639aSdyoung 
488913c639aSdyoung static int
ppath_set_object_and_release(prop_object_t o,const ppath_t * p,prop_object_t v)489913c639aSdyoung ppath_set_object_and_release(prop_object_t o, const ppath_t *p, prop_object_t v)
490913c639aSdyoung {
491913c639aSdyoung 	prop_object_t ov;
492913c639aSdyoung 	int rc;
493913c639aSdyoung 
494913c639aSdyoung 	if (v == NULL)
495913c639aSdyoung 		return ENOMEM;
496913c639aSdyoung 
497913c639aSdyoung 	if ((ov = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
498913c639aSdyoung 		return ENOENT;
499913c639aSdyoung 
500913c639aSdyoung 	if (prop_object_type(ov) != prop_object_type(v))
501913c639aSdyoung 		return EFTYPE;
502913c639aSdyoung 
503913c639aSdyoung 	rc = ppath_set_object(o, p, v);
504913c639aSdyoung 	prop_object_release(v);
505913c639aSdyoung 	return rc;
506913c639aSdyoung }
507913c639aSdyoung 
508913c639aSdyoung int
ppath_get_object(prop_object_t o,const ppath_t * p,prop_object_t * vp)509913c639aSdyoung ppath_get_object(prop_object_t o, const ppath_t *p, prop_object_t *vp)
510913c639aSdyoung {
511913c639aSdyoung 	prop_object_t v;
512913c639aSdyoung 
513913c639aSdyoung 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
514913c639aSdyoung 		return ENOENT;
515913c639aSdyoung 
516913c639aSdyoung 	if (vp != NULL)
517913c639aSdyoung 		*vp = v;
518913c639aSdyoung 	return 0;
519913c639aSdyoung }
520913c639aSdyoung 
521913c639aSdyoung static int
ppath_get_object_of_type(prop_object_t o,const ppath_t * p,prop_object_t * vp,prop_type_t t)522913c639aSdyoung ppath_get_object_of_type(prop_object_t o, const ppath_t *p, prop_object_t *vp,
523913c639aSdyoung     prop_type_t t)
524913c639aSdyoung {
525913c639aSdyoung 	int rc;
526913c639aSdyoung 
527913c639aSdyoung 	if ((rc = ppath_get_object(o, p, vp)) != 0)
528913c639aSdyoung 		return rc;
529913c639aSdyoung 
530913c639aSdyoung 	return (prop_object_type(*vp) == t) ? 0 : EFTYPE;
531913c639aSdyoung }
532913c639aSdyoung 
533913c639aSdyoung int
ppath_delete_object(prop_object_t o,const ppath_t * p)534913c639aSdyoung ppath_delete_object(prop_object_t o, const ppath_t *p)
535913c639aSdyoung {
536913c639aSdyoung 	ppath_component_t *pc;
537913c639aSdyoung 	prop_object_t po;
538913c639aSdyoung 
539913c639aSdyoung 	if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
540913c639aSdyoung 		return ENOENT;
541913c639aSdyoung 
542913c639aSdyoung 	switch (pc->pc_type) {
543913c639aSdyoung 	case PPATH_T_IDX:
544913c639aSdyoung 		prop_array_remove(po, pc->pc_idx);
545913c639aSdyoung 		return 0;
546913c639aSdyoung 	case PPATH_T_KEY:
547913c639aSdyoung 		prop_dictionary_remove(po, pc->pc_key);
548913c639aSdyoung 		return 0;
549913c639aSdyoung 	default:
550913c639aSdyoung 		return ENOENT;
551913c639aSdyoung 	}
552913c639aSdyoung }
553913c639aSdyoung 
554913c639aSdyoung static int
ppath_delete_object_of_type(prop_object_t o,const ppath_t * p,prop_type_t t)555913c639aSdyoung ppath_delete_object_of_type(prop_object_t o, const ppath_t *p, prop_type_t t)
556913c639aSdyoung {
557913c639aSdyoung 	prop_object_t v;
558913c639aSdyoung 
559913c639aSdyoung 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
560913c639aSdyoung 		return ENOENT;
561913c639aSdyoung 
562913c639aSdyoung 	if (prop_object_type(v) != t)
563913c639aSdyoung 		return EFTYPE;
564913c639aSdyoung 
565913c639aSdyoung 	return ppath_delete_object(o, p);
566913c639aSdyoung }
567913c639aSdyoung 
568913c639aSdyoung int
ppath_copydel_string(prop_object_t o,prop_object_t * op,const ppath_t * p)569913c639aSdyoung ppath_copydel_string(prop_object_t o, prop_object_t *op, const ppath_t *p)
570913c639aSdyoung {
571913c639aSdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_STRING);
572913c639aSdyoung }
573913c639aSdyoung 
574913c639aSdyoung int
ppath_copydel_data(prop_object_t o,prop_object_t * op,const ppath_t * p)575913c639aSdyoung ppath_copydel_data(prop_object_t o, prop_object_t *op, const ppath_t *p)
576913c639aSdyoung {
577913c639aSdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_DATA);
578913c639aSdyoung }
579913c639aSdyoung 
580913c639aSdyoung int
ppath_copydel_uint64(prop_object_t o,prop_object_t * op,const ppath_t * p)581913c639aSdyoung ppath_copydel_uint64(prop_object_t o, prop_object_t *op, const ppath_t *p)
582913c639aSdyoung {
583913c639aSdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_NUMBER);
584913c639aSdyoung }
585913c639aSdyoung 
586913c639aSdyoung int
ppath_copydel_int64(prop_object_t o,prop_object_t * op,const ppath_t * p)587913c639aSdyoung ppath_copydel_int64(prop_object_t o, prop_object_t *op, const ppath_t *p)
588913c639aSdyoung {
589913c639aSdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_NUMBER);
590913c639aSdyoung }
591913c639aSdyoung 
592913c639aSdyoung int
ppath_copydel_bool(prop_object_t o,prop_object_t * op,const ppath_t * p)593913c639aSdyoung ppath_copydel_bool(prop_object_t o, prop_object_t *op, const ppath_t *p)
594913c639aSdyoung {
595913c639aSdyoung 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_BOOL);
596913c639aSdyoung }
597913c639aSdyoung 
598913c639aSdyoung static int
ppath_copydel_object_of_type(prop_object_t o,prop_object_t * op,const ppath_t * p,prop_type_t t)599913c639aSdyoung ppath_copydel_object_of_type(prop_object_t o, prop_object_t *op,
600913c639aSdyoung     const ppath_t *p, prop_type_t t)
601913c639aSdyoung {
602913c639aSdyoung 	prop_object_t v;
603913c639aSdyoung 
604913c639aSdyoung 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
605913c639aSdyoung 		return ENOENT;
606913c639aSdyoung 
607913c639aSdyoung 	if (prop_object_type(v) != t)
608913c639aSdyoung 		return EFTYPE;
609913c639aSdyoung 
610913c639aSdyoung 	return ppath_copydel_object(o, op, p);
611913c639aSdyoung }
612913c639aSdyoung 
613913c639aSdyoung int
ppath_copydel_object(prop_object_t o,prop_object_t * op,const ppath_t * p)614913c639aSdyoung ppath_copydel_object(prop_object_t o, prop_object_t *op, const ppath_t *p)
615913c639aSdyoung {
616913c639aSdyoung 	return ppath_copyset_object_helper(o, op, p, NULL);
617913c639aSdyoung }
618913c639aSdyoung 
619913c639aSdyoung int
ppath_copyset_object(prop_object_t o,prop_object_t * op,const ppath_t * p,const prop_object_t v)620913c639aSdyoung ppath_copyset_object(prop_object_t o, prop_object_t *op, const ppath_t *p,
621913c639aSdyoung     const prop_object_t v)
622913c639aSdyoung {
623913c639aSdyoung 	ppath_assert(v != NULL);
624913c639aSdyoung 	return ppath_copyset_object_helper(o, op, p, v);
625913c639aSdyoung }
626913c639aSdyoung 
627913c639aSdyoung static int
ppath_copyset_object_helper(prop_object_t o,prop_object_t * op,const ppath_t * p0,const prop_object_t v0)628913c639aSdyoung ppath_copyset_object_helper(prop_object_t o, prop_object_t *op,
629913c639aSdyoung     const ppath_t *p0, const prop_object_t v0)
630913c639aSdyoung {
631913c639aSdyoung 	bool copy, success;
632913c639aSdyoung 	ppath_component_t *npc, *pc;
633913c639aSdyoung 	ppath_t *cp, *p;
634913c639aSdyoung 	prop_object_t npo = NULL, po, v;
635913c639aSdyoung 
636913c639aSdyoung 	for (cp = p = ppath_copy(p0), v = v0;
637913c639aSdyoung 	     p != NULL;
638913c639aSdyoung 	     p = ppath_pop(p, NULL), v = npo) {
639913c639aSdyoung 
640913c639aSdyoung 		if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
641913c639aSdyoung 			return ENOENT;
642913c639aSdyoung 
643913c639aSdyoung 		if (pc == NULL)
644913c639aSdyoung 			break;
645913c639aSdyoung 
646913c639aSdyoung 		if (ppath_lookup_helper(*op, p, &npo, &npc, NULL) == NULL)
647913c639aSdyoung 			npo = po;
648913c639aSdyoung 
649913c639aSdyoung 		copy = (npo == po);
650913c639aSdyoung 
651913c639aSdyoung 		switch (pc->pc_type) {
652913c639aSdyoung 		case PPATH_T_IDX:
653913c639aSdyoung 			if (copy && (npo = prop_array_copy_mutable(po)) == NULL)
654913c639aSdyoung 				return ENOMEM;
655913c639aSdyoung 			success = (v == NULL)
656913c639aSdyoung 			    ? (prop_array_remove(npo, pc->pc_idx), true)
657913c639aSdyoung 			    : prop_array_set(npo, pc->pc_idx, v);
658913c639aSdyoung 			break;
659913c639aSdyoung 		case PPATH_T_KEY:
660913c639aSdyoung 			if (copy &&
661913c639aSdyoung 			    (npo = prop_dictionary_copy_mutable(po)) == NULL)
662913c639aSdyoung 				return ENOMEM;
663913c639aSdyoung 			success = (v == NULL)
664913c639aSdyoung 			    ? (prop_dictionary_remove(npo, pc->pc_key), true)
665913c639aSdyoung 			    : prop_dictionary_set(npo, pc->pc_key, v);
666913c639aSdyoung 			break;
667913c639aSdyoung 		default:
668913c639aSdyoung 			return ENOENT;
669913c639aSdyoung 		}
670913c639aSdyoung 		if (!success) {
671913c639aSdyoung 			if (copy)
672913c639aSdyoung 				prop_object_release(npo);
673913c639aSdyoung 			return ENOMEM;
674913c639aSdyoung 		}
675913c639aSdyoung 	}
676913c639aSdyoung 
677913c639aSdyoung 	if (cp == NULL)
678913c639aSdyoung 		return ENOMEM;
679913c639aSdyoung 
680913c639aSdyoung 	ppath_release(cp);
681913c639aSdyoung 
682913c639aSdyoung 	if (op != NULL && npo != NULL)
683913c639aSdyoung 		*op = npo;
684913c639aSdyoung 	else if (npo != NULL)
685913c639aSdyoung 		prop_object_release(npo);
686913c639aSdyoung 
687913c639aSdyoung 	return 0;
688913c639aSdyoung }
689913c639aSdyoung 
690913c639aSdyoung static int
ppath_copyset_object_and_release(prop_object_t o,prop_object_t * op,const ppath_t * p,prop_object_t v)691913c639aSdyoung ppath_copyset_object_and_release(prop_object_t o, prop_object_t *op,
692913c639aSdyoung     const ppath_t *p, prop_object_t v)
693913c639aSdyoung {
694913c639aSdyoung 	prop_object_t ov;
695913c639aSdyoung 	int rc;
696913c639aSdyoung 
697913c639aSdyoung 	if (v == NULL)
698913c639aSdyoung 		return ENOMEM;
699913c639aSdyoung 
700913c639aSdyoung 	if ((ov = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
701913c639aSdyoung 		return ENOENT;
702913c639aSdyoung 
703913c639aSdyoung 	if (prop_object_type(ov) != prop_object_type(v))
704913c639aSdyoung 		return EFTYPE;
705913c639aSdyoung 
706913c639aSdyoung 	rc = ppath_copyset_object(o, op, p, v);
707913c639aSdyoung 	prop_object_release(v);
708913c639aSdyoung 	return rc;
709913c639aSdyoung }
710913c639aSdyoung 
711913c639aSdyoung int
ppath_copyset_bool(prop_object_t o,prop_object_t * op,const ppath_t * p,bool b)712913c639aSdyoung ppath_copyset_bool(prop_object_t o, prop_object_t *op, const ppath_t *p, bool b)
713913c639aSdyoung {
714913c639aSdyoung 	return ppath_copyset_object_and_release(o, op, p, prop_bool_create(b));
715913c639aSdyoung }
716913c639aSdyoung 
717913c639aSdyoung int
ppath_set_bool(prop_object_t o,const ppath_t * p,bool b)718913c639aSdyoung ppath_set_bool(prop_object_t o, const ppath_t *p, bool b)
719913c639aSdyoung {
720913c639aSdyoung 	return ppath_set_object_and_release(o, p, prop_bool_create(b));
721913c639aSdyoung }
722913c639aSdyoung 
723913c639aSdyoung int
ppath_get_bool(prop_object_t o,const ppath_t * p,bool * bp)724913c639aSdyoung ppath_get_bool(prop_object_t o, const ppath_t *p, bool *bp)
725913c639aSdyoung {
726913c639aSdyoung 	prop_object_t v;
727913c639aSdyoung 	int rc;
728913c639aSdyoung 
729913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_BOOL)) != 0)
730913c639aSdyoung 		return rc;
731913c639aSdyoung 
732913c639aSdyoung 	if (bp != NULL)
733913c639aSdyoung 		*bp = prop_bool_true(v);
734913c639aSdyoung 
735913c639aSdyoung 	return 0;
736913c639aSdyoung }
737913c639aSdyoung 
738913c639aSdyoung int
ppath_delete_bool(prop_object_t o,const ppath_t * p)739913c639aSdyoung ppath_delete_bool(prop_object_t o, const ppath_t *p)
740913c639aSdyoung {
741913c639aSdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_BOOL);
742913c639aSdyoung }
743913c639aSdyoung 
744913c639aSdyoung int
ppath_copyset_data(prop_object_t o,prop_object_t * op,const ppath_t * p,const void * data,size_t size)745913c639aSdyoung ppath_copyset_data(prop_object_t o, prop_object_t *op, const ppath_t *p,
746913c639aSdyoung     const void *data, size_t size)
747913c639aSdyoung {
748913c639aSdyoung 	return ppath_copyset_object_and_release(o, op, p,
749*6dd14d72Sthorpej 	    prop_data_create_copy(data, size));
750913c639aSdyoung }
751913c639aSdyoung 
752913c639aSdyoung int
ppath_set_data(prop_object_t o,const ppath_t * p,const void * data,size_t size)753913c639aSdyoung ppath_set_data(prop_object_t o, const ppath_t *p, const void *data, size_t size)
754913c639aSdyoung {
755913c639aSdyoung 	return ppath_set_object_and_release(o, p,
756*6dd14d72Sthorpej 	    prop_data_create_copy(data, size));
757913c639aSdyoung }
758913c639aSdyoung 
759913c639aSdyoung int
ppath_get_data(prop_object_t o,const ppath_t * p,const void ** datap,size_t * sizep)760913c639aSdyoung ppath_get_data(prop_object_t o, const ppath_t *p, const void **datap,
761913c639aSdyoung     size_t *sizep)
762913c639aSdyoung {
763913c639aSdyoung 	prop_object_t v;
764913c639aSdyoung 	int rc;
765913c639aSdyoung 
766913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
767913c639aSdyoung 		return rc;
768913c639aSdyoung 
769913c639aSdyoung 	if (datap != NULL)
770*6dd14d72Sthorpej 		*datap = prop_data_value(v);
771913c639aSdyoung 	if (sizep != NULL)
772913c639aSdyoung 		*sizep = prop_data_size(v);
773913c639aSdyoung 
774913c639aSdyoung 	return 0;
775913c639aSdyoung }
776913c639aSdyoung 
777913c639aSdyoung int
ppath_dup_data(prop_object_t o,const ppath_t * p,void ** datap,size_t * sizep)778913c639aSdyoung ppath_dup_data(prop_object_t o, const ppath_t *p, void **datap, size_t *sizep)
779913c639aSdyoung {
780913c639aSdyoung 	prop_object_t v;
781913c639aSdyoung 	int rc;
782913c639aSdyoung 
783913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
784913c639aSdyoung 		return rc;
785913c639aSdyoung 
786*6dd14d72Sthorpej 	const size_t data_size = prop_data_size(v);
787*6dd14d72Sthorpej 
788*6dd14d72Sthorpej 	if (datap != NULL) {
789*6dd14d72Sthorpej 		void *buf = ppath_alloc(data_size);
790*6dd14d72Sthorpej 		if (buf != NULL)
791*6dd14d72Sthorpej 			(void) prop_data_copy_value(v, buf, data_size);
792*6dd14d72Sthorpej 		*datap = buf;
793*6dd14d72Sthorpej 	}
794913c639aSdyoung 	if (sizep != NULL)
795*6dd14d72Sthorpej 		*sizep = data_size;
796913c639aSdyoung 
797913c639aSdyoung 	return 0;
798913c639aSdyoung }
799913c639aSdyoung 
800913c639aSdyoung int
ppath_delete_data(prop_object_t o,const ppath_t * p)801913c639aSdyoung ppath_delete_data(prop_object_t o, const ppath_t *p)
802913c639aSdyoung {
803913c639aSdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_DATA);
804913c639aSdyoung }
805913c639aSdyoung 
806913c639aSdyoung int
ppath_copyset_int64(prop_object_t o,prop_object_t * op,const ppath_t * p,int64_t i)807913c639aSdyoung ppath_copyset_int64(prop_object_t o, prop_object_t *op, const ppath_t *p,
808913c639aSdyoung     int64_t i)
809913c639aSdyoung {
810913c639aSdyoung 	return ppath_copyset_object_and_release(o, op, p,
811*6dd14d72Sthorpej 	    prop_number_create_signed(i));
812913c639aSdyoung }
813913c639aSdyoung 
814913c639aSdyoung int
ppath_set_int64(prop_object_t o,const ppath_t * p,int64_t i)815913c639aSdyoung ppath_set_int64(prop_object_t o, const ppath_t *p, int64_t i)
816913c639aSdyoung {
817913c639aSdyoung 	return ppath_set_object_and_release(o, p,
818*6dd14d72Sthorpej 	    prop_number_create_signed(i));
819913c639aSdyoung }
820913c639aSdyoung 
821913c639aSdyoung int
ppath_get_int64(prop_object_t o,const ppath_t * p,int64_t * ip)822913c639aSdyoung ppath_get_int64(prop_object_t o, const ppath_t *p, int64_t *ip)
823913c639aSdyoung {
824913c639aSdyoung 	prop_object_t v;
825913c639aSdyoung 	int rc;
826913c639aSdyoung 
827913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
828913c639aSdyoung 		return rc;
829913c639aSdyoung 
830913c639aSdyoung 	if (prop_number_unsigned(v))
831913c639aSdyoung 		return EFTYPE;
832913c639aSdyoung 
833913c639aSdyoung 	if (ip != NULL)
834*6dd14d72Sthorpej 		*ip = prop_number_signed_value(v);
835913c639aSdyoung 
836913c639aSdyoung 	return 0;
837913c639aSdyoung }
838913c639aSdyoung 
839913c639aSdyoung int
ppath_delete_int64(prop_object_t o,const ppath_t * p)840913c639aSdyoung ppath_delete_int64(prop_object_t o, const ppath_t *p)
841913c639aSdyoung {
842913c639aSdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_NUMBER);
843913c639aSdyoung }
844913c639aSdyoung 
845913c639aSdyoung int
ppath_copyset_string(prop_object_t o,prop_object_t * op,const ppath_t * p,const char * s)846913c639aSdyoung ppath_copyset_string(prop_object_t o, prop_object_t *op, const ppath_t *p,
847913c639aSdyoung     const char *s)
848913c639aSdyoung {
849913c639aSdyoung 	return ppath_copyset_object_and_release(o, op, p,
850*6dd14d72Sthorpej 	    prop_string_create_copy(s));
851913c639aSdyoung }
852913c639aSdyoung 
853913c639aSdyoung int
ppath_set_string(prop_object_t o,const ppath_t * p,const char * s)854913c639aSdyoung ppath_set_string(prop_object_t o, const ppath_t *p, const char *s)
855913c639aSdyoung {
856913c639aSdyoung 	return ppath_set_object_and_release(o, p,
857*6dd14d72Sthorpej 	    prop_string_create_copy(s));
858913c639aSdyoung }
859913c639aSdyoung 
860913c639aSdyoung int
ppath_get_string(prop_object_t o,const ppath_t * p,const char ** sp)861913c639aSdyoung ppath_get_string(prop_object_t o, const ppath_t *p, const char **sp)
862913c639aSdyoung {
863913c639aSdyoung 	int rc;
864913c639aSdyoung 	prop_object_t v;
865913c639aSdyoung 
866913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_STRING)) != 0)
867913c639aSdyoung 		return rc;
868913c639aSdyoung 
869913c639aSdyoung 	if (sp != NULL)
870*6dd14d72Sthorpej 		*sp = prop_string_value(v);
871913c639aSdyoung 
872913c639aSdyoung 	return 0;
873913c639aSdyoung }
874913c639aSdyoung 
875913c639aSdyoung int
ppath_dup_string(prop_object_t o,const ppath_t * p,char ** sp)876913c639aSdyoung ppath_dup_string(prop_object_t o, const ppath_t *p, char **sp)
877913c639aSdyoung {
878913c639aSdyoung 	int rc;
879913c639aSdyoung 	prop_object_t v;
880913c639aSdyoung 
881913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_STRING)) != 0)
882913c639aSdyoung 		return rc;
883913c639aSdyoung 
884*6dd14d72Sthorpej 	const size_t string_size = prop_string_size(v);
885*6dd14d72Sthorpej 
886*6dd14d72Sthorpej 	if (sp != NULL) {
887*6dd14d72Sthorpej 		char *cp = ppath_alloc(string_size + 1);
888*6dd14d72Sthorpej 		if (cp != NULL)
889*6dd14d72Sthorpej 			(void)prop_string_copy_value(v, cp, string_size + 1);
890*6dd14d72Sthorpej 		*sp = cp;
891*6dd14d72Sthorpej 	}
892913c639aSdyoung 
893913c639aSdyoung 	return 0;
894913c639aSdyoung }
895913c639aSdyoung 
896913c639aSdyoung int
ppath_delete_string(prop_object_t o,const ppath_t * p)897913c639aSdyoung ppath_delete_string(prop_object_t o, const ppath_t *p)
898913c639aSdyoung {
899913c639aSdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_STRING);
900913c639aSdyoung }
901913c639aSdyoung 
902913c639aSdyoung int
ppath_copyset_uint64(prop_object_t o,prop_object_t * op,const ppath_t * p,uint64_t u)903913c639aSdyoung ppath_copyset_uint64(prop_object_t o, prop_object_t *op, const ppath_t *p,
904913c639aSdyoung     uint64_t u)
905913c639aSdyoung {
906913c639aSdyoung 	return ppath_copyset_object_and_release(o, op, p,
907*6dd14d72Sthorpej 	    prop_number_create_unsigned(u));
908913c639aSdyoung }
909913c639aSdyoung 
910913c639aSdyoung int
ppath_set_uint64(prop_object_t o,const ppath_t * p,uint64_t u)911913c639aSdyoung ppath_set_uint64(prop_object_t o, const ppath_t *p, uint64_t u)
912913c639aSdyoung {
913913c639aSdyoung 	return ppath_set_object_and_release(o, p,
914*6dd14d72Sthorpej 	    prop_number_create_unsigned(u));
915913c639aSdyoung }
916913c639aSdyoung 
917913c639aSdyoung int
ppath_get_uint64(prop_object_t o,const ppath_t * p,uint64_t * up)918913c639aSdyoung ppath_get_uint64(prop_object_t o, const ppath_t *p, uint64_t *up)
919913c639aSdyoung {
920913c639aSdyoung 	prop_object_t v;
921913c639aSdyoung 	int rc;
922913c639aSdyoung 
923913c639aSdyoung 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
924913c639aSdyoung 		return rc;
925913c639aSdyoung 
926913c639aSdyoung 	if (!prop_number_unsigned(v))
927913c639aSdyoung 		return EFTYPE;
928913c639aSdyoung 
929913c639aSdyoung 	if (up != NULL)
930*6dd14d72Sthorpej 		*up = prop_number_unsigned_value(v);
931913c639aSdyoung 
932913c639aSdyoung 	return 0;
933913c639aSdyoung }
934913c639aSdyoung 
935913c639aSdyoung int
ppath_delete_uint64(prop_object_t o,const ppath_t * p)936913c639aSdyoung ppath_delete_uint64(prop_object_t o, const ppath_t *p)
937913c639aSdyoung {
938913c639aSdyoung 	return ppath_delete_object_of_type(o, p, PROP_TYPE_NUMBER);
939913c639aSdyoung }
940