Home | History | Annotate | Line # | Download | only in libppath
ppath.c revision 1.2
      1 /* $NetBSD: ppath.c,v 1.2 2011/09/29 20:53:30 christos Exp $ */
      2 /* $Id: ppath.c,v 1.2 2011/09/29 20:53:30 christos Exp $ */
      3 /*-
      4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by David Young <dyoung (at) NetBSD.org>.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __RCSID("$Id: ppath.c,v 1.2 2011/09/29 20:53:30 christos Exp $");
     34 
     35 #include <sys/systm.h>
     36 #include <ppath/ppath.h>
     37 #include <ppath/ppath_impl.h>
     38 
     39 enum _ppath_type {
     40 	  PPATH_T_IDX = 0
     41 	, PPATH_T_KEY = 1
     42 };
     43 
     44 typedef enum _ppath_type ppath_type_t;
     45 
     46 struct _ppath_component {
     47 	unsigned int	pc_refcnt;
     48 	ppath_type_t	pc_type;
     49 	union {
     50 		char *u_key;
     51 		unsigned int u_idx;
     52 	} pc_u;
     53 #define pc_key pc_u.u_key
     54 #define pc_idx pc_u.u_idx
     55 };
     56 
     57 struct _ppath {
     58 	unsigned int	p_refcnt;
     59 	unsigned int	p_len;
     60 	ppath_component_t *p_cmpt[PPATH_MAX_COMPONENTS];
     61 };
     62 
     63 static int ppath_copydel_object_of_type(prop_object_t, prop_object_t *,
     64     const ppath_t *, prop_type_t);
     65 static int ppath_copyset_object_helper(prop_object_t, prop_object_t *,
     66     const ppath_t *, const prop_object_t);
     67 
     68 static void
     69 ppath_strfree(char *s)
     70 {
     71 	size_t size = strlen(s) + 1;
     72 
     73 	ppath_free(s, size);
     74 }
     75 
     76 static char *
     77 ppath_strdup(const char *s)
     78 {
     79 	size_t size = strlen(s) + 1;
     80 	char *p;
     81 
     82 	if ((p = ppath_alloc(size)) == NULL)
     83 		return NULL;
     84 
     85 	return strcpy(p, s);
     86 }
     87 
     88 int
     89 ppath_component_idx(const ppath_component_t *pc)
     90 {
     91 	if (pc->pc_type != PPATH_T_IDX)
     92 		return -1;
     93 	return pc->pc_idx;
     94 }
     95 
     96 const char *
     97 ppath_component_key(const ppath_component_t *pc)
     98 {
     99 	if (pc->pc_type != PPATH_T_KEY)
    100 		return NULL;
    101 	return pc->pc_key;
    102 }
    103 
    104 ppath_component_t *
    105 ppath_idx(unsigned int idx)
    106 {
    107 	ppath_component_t *pc;
    108 
    109 	if ((pc = ppath_alloc(sizeof(*pc))) == NULL)
    110 		return NULL;
    111 	pc->pc_idx = idx;
    112 	pc->pc_type = PPATH_T_IDX;
    113 	pc->pc_refcnt = 1;
    114 	ppath_component_extant_inc();
    115 	return pc;
    116 }
    117 
    118 ppath_component_t *
    119 ppath_key(const char *key)
    120 {
    121 	ppath_component_t *pc;
    122 
    123 	if ((pc = ppath_alloc(sizeof(*pc))) == NULL)
    124 		return NULL;
    125 
    126 	if ((pc->pc_key = ppath_strdup(key)) == NULL) {
    127 		ppath_free(pc, sizeof(*pc));
    128 		return NULL;
    129 	}
    130 	pc->pc_type = PPATH_T_KEY;
    131 	pc->pc_refcnt = 1;
    132 	ppath_component_extant_inc();
    133 	return pc;
    134 }
    135 
    136 ppath_component_t *
    137 ppath_component_retain(ppath_component_t *pc)
    138 {
    139 	ppath_assert(pc->pc_refcnt != 0);
    140 	pc->pc_refcnt++;
    141 
    142 	return pc;
    143 }
    144 
    145 void
    146 ppath_component_release(ppath_component_t *pc)
    147 {
    148 	ppath_assert(pc->pc_refcnt != 0);
    149 
    150 	if (--pc->pc_refcnt != 0)
    151 		return;
    152 	if (pc->pc_type == PPATH_T_KEY)
    153 		ppath_strfree(pc->pc_key);
    154 	ppath_component_extant_dec();
    155 	ppath_free(pc, sizeof(*pc));
    156 }
    157 
    158 ppath_t *
    159 ppath_create(void)
    160 {
    161 	ppath_t *p;
    162 
    163 	if ((p = ppath_alloc(sizeof(*p))) == NULL)
    164 		return NULL;
    165 
    166 	p->p_refcnt = 1;
    167 	ppath_extant_inc();
    168 
    169 	return p;
    170 }
    171 
    172 ppath_t *
    173 ppath_pop(ppath_t *p, ppath_component_t **pcp)
    174 {
    175 	ppath_component_t *pc;
    176 
    177 	if (p == NULL || p->p_len == 0)
    178 		return NULL;
    179 
    180 	pc = p->p_cmpt[--p->p_len];
    181 
    182 	if (pcp != NULL)
    183 		*pcp = pc;
    184 	else
    185 		ppath_component_release(pc);
    186 
    187 	return p;
    188 }
    189 
    190 ppath_t *
    191 ppath_push(ppath_t *p, ppath_component_t *pc)
    192 {
    193 	if (p == NULL || p->p_len == __arraycount(p->p_cmpt))
    194 		return NULL;
    195 
    196 	p->p_cmpt[p->p_len++] = ppath_component_retain(pc);
    197 
    198 	return p;
    199 }
    200 
    201 ppath_component_t *
    202 ppath_component_at(const ppath_t *p, unsigned int i)
    203 {
    204 	ppath_component_t *pc;
    205 
    206 	if (p == NULL || i >= p->p_len)
    207 		return NULL;
    208 
    209 	pc = p->p_cmpt[i];
    210 
    211 	return ppath_component_retain(pc);
    212 }
    213 
    214 unsigned int
    215 ppath_length(const ppath_t *p)
    216 {
    217 	return p->p_len;
    218 }
    219 
    220 ppath_t *
    221 ppath_subpath(const ppath_t *p, unsigned int first, unsigned int exclast)
    222 {
    223 	unsigned int i;
    224 	ppath_t *np;
    225 	ppath_component_t *pc;
    226 
    227 	if (p == NULL || (np = ppath_create()) == NULL)
    228 		return NULL;
    229 
    230 	for (i = first; i < exclast; i++) {
    231 		if ((pc = ppath_component_at(p, i)) == NULL)
    232 			break;
    233 		ppath_push(np, pc);
    234 		ppath_component_release(pc);
    235 	}
    236 	return np;
    237 }
    238 
    239 ppath_t *
    240 ppath_push_idx(ppath_t *p0, unsigned int idx)
    241 {
    242 	ppath_component_t *pc;
    243 	ppath_t *p;
    244 
    245 	if ((pc = ppath_idx(idx)) == NULL)
    246 		return NULL;
    247 
    248 	p = ppath_push(p0, pc);
    249 	ppath_component_release(pc);
    250 	return p;
    251 }
    252 
    253 ppath_t *
    254 ppath_push_key(ppath_t *p0, const char *key)
    255 {
    256 	ppath_component_t *pc;
    257 	ppath_t *p;
    258 
    259 	if ((pc = ppath_key(key)) == NULL)
    260 		return NULL;
    261 
    262 	p = ppath_push(p0, pc);
    263 	ppath_component_release(pc);
    264 	return p;
    265 }
    266 
    267 ppath_t *
    268 ppath_replace_idx(ppath_t *p, unsigned int idx)
    269 {
    270 	ppath_component_t *pc0, *pc;
    271 
    272 	if (p == NULL || p->p_len == 0)
    273 		return NULL;
    274 
    275 	pc0 = p->p_cmpt[p->p_len - 1];
    276 
    277 	if (pc0->pc_type != PPATH_T_IDX)
    278 		return NULL;
    279 
    280 	if ((pc = ppath_idx(idx)) == NULL)
    281 		return NULL;
    282 
    283 	p->p_cmpt[p->p_len - 1] = pc;
    284 	ppath_component_release(pc0);
    285 
    286 	return p;
    287 }
    288 
    289 ppath_t *
    290 ppath_replace_key(ppath_t *p, const char *key)
    291 {
    292 	ppath_component_t *pc0, *pc;
    293 
    294 	if (p == NULL || p->p_len == 0)
    295 		return NULL;
    296 
    297 	pc0 = p->p_cmpt[p->p_len - 1];
    298 
    299 	if (pc0->pc_type != PPATH_T_KEY)
    300 		return NULL;
    301 
    302 	if ((pc = ppath_key(key)) == NULL)
    303 		return NULL;
    304 
    305 	p->p_cmpt[p->p_len - 1] = pc;
    306 	ppath_component_release(pc0);
    307 
    308 	return p;
    309 }
    310 
    311 ppath_t *
    312 ppath_copy(const ppath_t *p0)
    313 {
    314 	ppath_t *p;
    315 	unsigned int i;
    316 
    317 	if ((p = ppath_create()) == NULL)
    318 		return NULL;
    319 
    320 	for (i = 0; i < p0->p_len; i++)
    321 		p->p_cmpt[i] = ppath_component_retain(p0->p_cmpt[i]);
    322 	p->p_len = p0->p_len;
    323 	return p;
    324 }
    325 
    326 ppath_t *
    327 ppath_retain(ppath_t *p)
    328 {
    329 	assert(p->p_refcnt != 0);
    330 
    331 	p->p_refcnt++;
    332 
    333 	return p;
    334 }
    335 
    336 void
    337 ppath_release(ppath_t *p)
    338 {
    339 	unsigned int i;
    340 
    341 	assert(p->p_refcnt != 0);
    342 
    343 	if (--p->p_refcnt != 0)
    344 		return;
    345 
    346 	for (i = 0; i < p->p_len; i++)
    347 		ppath_component_release(p->p_cmpt[i]);
    348 
    349 	ppath_extant_dec();
    350 	ppath_free(p, sizeof(*p));
    351 }
    352 
    353 static prop_object_t
    354 ppath_lookup_helper(prop_object_t o0, const ppath_t *p, prop_object_t *pop,
    355     ppath_component_t **pcp, unsigned int *ip)
    356 {
    357 	unsigned int i;
    358 	prop_object_t o, po;
    359 	ppath_type_t t;
    360 	ppath_component_t *pc = NULL;
    361 
    362 	for (po = NULL, o = o0, i = 0; i < p->p_len && o != NULL; i++) {
    363 		pc = p->p_cmpt[i];
    364 		t = pc->pc_type;
    365 		switch (prop_object_type(o)) {
    366 		case PROP_TYPE_ARRAY:
    367 			po = o;
    368 			o = (t == PPATH_T_IDX)
    369 			    ? prop_array_get(o, pc->pc_idx)
    370 			    : NULL;
    371 			break;
    372 		case PROP_TYPE_DICTIONARY:
    373 			po = o;
    374 			o = (t == PPATH_T_KEY)
    375 			    ? prop_dictionary_get(o, pc->pc_key)
    376 			    : NULL;
    377 			break;
    378 		default:
    379 			o = NULL;
    380 			break;
    381 		}
    382 	}
    383 	if (pop != NULL)
    384 		*pop = po;
    385 	if (pcp != NULL)
    386 		*pcp = pc;
    387 	if (ip != NULL)
    388 		*ip = i;
    389 	return o;
    390 }
    391 
    392 prop_object_t
    393 ppath_lookup(prop_object_t o, const ppath_t *p)
    394 {
    395 	return ppath_lookup_helper(o, p, NULL, NULL, NULL);
    396 }
    397 
    398 static int
    399 ppath_create_object_and_release(prop_object_t o, const ppath_t *p,
    400     prop_object_t v)
    401 {
    402 	int rc;
    403 
    404 	rc = ppath_create_object(o, p, v);
    405 	prop_object_release(v);
    406 	return rc;
    407 }
    408 
    409 int
    410 ppath_create_string(prop_object_t o, const ppath_t *p, const char *s)
    411 {
    412 	return ppath_create_object_and_release(o, p,
    413 	    prop_string_create_cstring(s));
    414 }
    415 
    416 int
    417 ppath_create_data(prop_object_t o, const ppath_t *p,
    418     const void *data, size_t size)
    419 {
    420 	return ppath_create_object_and_release(o, p,
    421 	    prop_data_create_data(data, size));
    422 }
    423 
    424 int
    425 ppath_create_uint64(prop_object_t o, const ppath_t *p, uint64_t u)
    426 {
    427 	return ppath_create_object_and_release(o, p,
    428 	    prop_number_create_unsigned_integer(u));
    429 }
    430 
    431 int
    432 ppath_create_int64(prop_object_t o, const ppath_t *p, int64_t i)
    433 {
    434 	return ppath_create_object_and_release(o, p,
    435 	    prop_number_create_integer(i));
    436 }
    437 
    438 int
    439 ppath_create_bool(prop_object_t o, const ppath_t *p, bool b)
    440 {
    441 	return ppath_create_object_and_release(o, p, prop_bool_create(b));
    442 }
    443 
    444 int
    445 ppath_create_object(prop_object_t o, const ppath_t *p, prop_object_t v)
    446 {
    447 	unsigned int i;
    448 	ppath_component_t *pc;
    449 	prop_object_t po;
    450 
    451 	if (ppath_lookup_helper(o, p, &po, &pc, &i) != NULL)
    452 		return EEXIST;
    453 
    454 	if (i != ppath_length(p))
    455 		return ENOENT;
    456 
    457 	switch (pc->pc_type) {
    458 	case PPATH_T_IDX:
    459 		return prop_array_set(po, pc->pc_idx, v) ? 0 : ENOMEM;
    460 	case PPATH_T_KEY:
    461 		return prop_dictionary_set(po, pc->pc_key, v) ? 0 : ENOMEM;
    462 	default:
    463 		return ENOENT;
    464 	}
    465 }
    466 
    467 int
    468 ppath_set_object(prop_object_t o, const ppath_t *p, prop_object_t v)
    469 {
    470 	ppath_component_t *pc;
    471 	prop_object_t po;
    472 
    473 	if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
    474 		return ENOENT;
    475 
    476 	switch (pc->pc_type) {
    477 	case PPATH_T_IDX:
    478 		return prop_array_set(po, pc->pc_idx, v) ? 0 : ENOMEM;
    479 	case PPATH_T_KEY:
    480 		return prop_dictionary_set(po, pc->pc_key, v) ? 0 : ENOMEM;
    481 	default:
    482 		return ENOENT;
    483 	}
    484 }
    485 
    486 static int
    487 ppath_set_object_and_release(prop_object_t o, const ppath_t *p, prop_object_t v)
    488 {
    489 	prop_object_t ov;
    490 	int rc;
    491 
    492 	if (v == NULL)
    493 		return ENOMEM;
    494 
    495 	if ((ov = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
    496 		return ENOENT;
    497 
    498 	if (prop_object_type(ov) != prop_object_type(v))
    499 		return EFTYPE;
    500 
    501 	rc = ppath_set_object(o, p, v);
    502 	prop_object_release(v);
    503 	return rc;
    504 }
    505 
    506 int
    507 ppath_get_object(prop_object_t o, const ppath_t *p, prop_object_t *vp)
    508 {
    509 	prop_object_t v;
    510 
    511 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
    512 		return ENOENT;
    513 
    514 	if (vp != NULL)
    515 		*vp = v;
    516 	return 0;
    517 }
    518 
    519 static int
    520 ppath_get_object_of_type(prop_object_t o, const ppath_t *p, prop_object_t *vp,
    521     prop_type_t t)
    522 {
    523 	int rc;
    524 
    525 	if ((rc = ppath_get_object(o, p, vp)) != 0)
    526 		return rc;
    527 
    528 	return (prop_object_type(*vp) == t) ? 0 : EFTYPE;
    529 }
    530 
    531 int
    532 ppath_delete_object(prop_object_t o, const ppath_t *p)
    533 {
    534 	ppath_component_t *pc;
    535 	prop_object_t po;
    536 
    537 	if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
    538 		return ENOENT;
    539 
    540 	switch (pc->pc_type) {
    541 	case PPATH_T_IDX:
    542 		prop_array_remove(po, pc->pc_idx);
    543 		return 0;
    544 	case PPATH_T_KEY:
    545 		prop_dictionary_remove(po, pc->pc_key);
    546 		return 0;
    547 	default:
    548 		return ENOENT;
    549 	}
    550 }
    551 
    552 static int
    553 ppath_delete_object_of_type(prop_object_t o, const ppath_t *p, prop_type_t t)
    554 {
    555 	prop_object_t v;
    556 
    557 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
    558 		return ENOENT;
    559 
    560 	if (prop_object_type(v) != t)
    561 		return EFTYPE;
    562 
    563 	return ppath_delete_object(o, p);
    564 }
    565 
    566 int
    567 ppath_copydel_string(prop_object_t o, prop_object_t *op, const ppath_t *p)
    568 {
    569 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_STRING);
    570 }
    571 
    572 int
    573 ppath_copydel_data(prop_object_t o, prop_object_t *op, const ppath_t *p)
    574 {
    575 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_DATA);
    576 }
    577 
    578 int
    579 ppath_copydel_uint64(prop_object_t o, prop_object_t *op, const ppath_t *p)
    580 {
    581 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_NUMBER);
    582 }
    583 
    584 int
    585 ppath_copydel_int64(prop_object_t o, prop_object_t *op, const ppath_t *p)
    586 {
    587 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_NUMBER);
    588 }
    589 
    590 int
    591 ppath_copydel_bool(prop_object_t o, prop_object_t *op, const ppath_t *p)
    592 {
    593 	return ppath_copydel_object_of_type(o, op, p, PROP_TYPE_BOOL);
    594 }
    595 
    596 static int
    597 ppath_copydel_object_of_type(prop_object_t o, prop_object_t *op,
    598     const ppath_t *p, prop_type_t t)
    599 {
    600 	prop_object_t v;
    601 
    602 	if ((v = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
    603 		return ENOENT;
    604 
    605 	if (prop_object_type(v) != t)
    606 		return EFTYPE;
    607 
    608 	return ppath_copydel_object(o, op, p);
    609 }
    610 
    611 int
    612 ppath_copydel_object(prop_object_t o, prop_object_t *op, const ppath_t *p)
    613 {
    614 	return ppath_copyset_object_helper(o, op, p, NULL);
    615 }
    616 
    617 int
    618 ppath_copyset_object(prop_object_t o, prop_object_t *op, const ppath_t *p,
    619     const prop_object_t v)
    620 {
    621 	ppath_assert(v != NULL);
    622 	return ppath_copyset_object_helper(o, op, p, v);
    623 }
    624 
    625 static int
    626 ppath_copyset_object_helper(prop_object_t o, prop_object_t *op,
    627     const ppath_t *p0, const prop_object_t v0)
    628 {
    629 	bool copy, success;
    630 	ppath_component_t *npc, *pc;
    631 	ppath_t *cp, *p;
    632 	prop_object_t npo = NULL, po, v;
    633 
    634 	for (cp = p = ppath_copy(p0), v = v0;
    635 	     p != NULL;
    636 	     p = ppath_pop(p, NULL), v = npo) {
    637 
    638 		if (ppath_lookup_helper(o, p, &po, &pc, NULL) == NULL)
    639 			return ENOENT;
    640 
    641 		if (pc == NULL)
    642 			break;
    643 
    644 		if (ppath_lookup_helper(*op, p, &npo, &npc, NULL) == NULL)
    645 			npo = po;
    646 
    647 		copy = (npo == po);
    648 
    649 		switch (pc->pc_type) {
    650 		case PPATH_T_IDX:
    651 			if (copy && (npo = prop_array_copy_mutable(po)) == NULL)
    652 				return ENOMEM;
    653 			success = (v == NULL)
    654 			    ? (prop_array_remove(npo, pc->pc_idx), true)
    655 			    : prop_array_set(npo, pc->pc_idx, v);
    656 			break;
    657 		case PPATH_T_KEY:
    658 			if (copy &&
    659 			    (npo = prop_dictionary_copy_mutable(po)) == NULL)
    660 				return ENOMEM;
    661 			success = (v == NULL)
    662 			    ? (prop_dictionary_remove(npo, pc->pc_key), true)
    663 			    : prop_dictionary_set(npo, pc->pc_key, v);
    664 			break;
    665 		default:
    666 			return ENOENT;
    667 		}
    668 		if (!success) {
    669 			if (copy)
    670 				prop_object_release(npo);
    671 			return ENOMEM;
    672 		}
    673 	}
    674 
    675 	if (cp == NULL)
    676 		return ENOMEM;
    677 
    678 	ppath_release(cp);
    679 
    680 	if (op != NULL && npo != NULL)
    681 		*op = npo;
    682 	else if (npo != NULL)
    683 		prop_object_release(npo);
    684 
    685 	return 0;
    686 }
    687 
    688 static int
    689 ppath_copyset_object_and_release(prop_object_t o, prop_object_t *op,
    690     const ppath_t *p, prop_object_t v)
    691 {
    692 	prop_object_t ov;
    693 	int rc;
    694 
    695 	if (v == NULL)
    696 		return ENOMEM;
    697 
    698 	if ((ov = ppath_lookup_helper(o, p, NULL, NULL, NULL)) == NULL)
    699 		return ENOENT;
    700 
    701 	if (prop_object_type(ov) != prop_object_type(v))
    702 		return EFTYPE;
    703 
    704 	rc = ppath_copyset_object(o, op, p, v);
    705 	prop_object_release(v);
    706 	return rc;
    707 }
    708 
    709 int
    710 ppath_copyset_bool(prop_object_t o, prop_object_t *op, const ppath_t *p, bool b)
    711 {
    712 	return ppath_copyset_object_and_release(o, op, p, prop_bool_create(b));
    713 }
    714 
    715 int
    716 ppath_set_bool(prop_object_t o, const ppath_t *p, bool b)
    717 {
    718 	return ppath_set_object_and_release(o, p, prop_bool_create(b));
    719 }
    720 
    721 int
    722 ppath_get_bool(prop_object_t o, const ppath_t *p, bool *bp)
    723 {
    724 	prop_object_t v;
    725 	int rc;
    726 
    727 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_BOOL)) != 0)
    728 		return rc;
    729 
    730 	if (bp != NULL)
    731 		*bp = prop_bool_true(v);
    732 
    733 	return 0;
    734 }
    735 
    736 int
    737 ppath_delete_bool(prop_object_t o, const ppath_t *p)
    738 {
    739 	return ppath_delete_object_of_type(o, p, PROP_TYPE_BOOL);
    740 }
    741 
    742 int
    743 ppath_copyset_data(prop_object_t o, prop_object_t *op, const ppath_t *p,
    744     const void *data, size_t size)
    745 {
    746 	return ppath_copyset_object_and_release(o, op, p,
    747 	    prop_data_create_data(data, size));
    748 }
    749 
    750 int
    751 ppath_set_data(prop_object_t o, const ppath_t *p, const void *data, size_t size)
    752 {
    753 	return ppath_set_object_and_release(o, p,
    754 	    prop_data_create_data(data, size));
    755 }
    756 
    757 int
    758 ppath_get_data(prop_object_t o, const ppath_t *p, const void **datap,
    759     size_t *sizep)
    760 {
    761 	prop_object_t v;
    762 	int rc;
    763 
    764 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
    765 		return rc;
    766 
    767 	if (datap != NULL)
    768 		*datap = prop_data_data_nocopy(v);
    769 	if (sizep != NULL)
    770 		*sizep = prop_data_size(v);
    771 
    772 	return 0;
    773 }
    774 
    775 int
    776 ppath_dup_data(prop_object_t o, const ppath_t *p, void **datap, size_t *sizep)
    777 {
    778 	prop_object_t v;
    779 	int rc;
    780 
    781 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
    782 		return rc;
    783 
    784 	if (datap != NULL)
    785 		*datap = prop_data_data(v);
    786 	if (sizep != NULL)
    787 		*sizep = prop_data_size(v);
    788 
    789 	return 0;
    790 }
    791 
    792 int
    793 ppath_delete_data(prop_object_t o, const ppath_t *p)
    794 {
    795 	return ppath_delete_object_of_type(o, p, PROP_TYPE_DATA);
    796 }
    797 
    798 int
    799 ppath_copyset_int64(prop_object_t o, prop_object_t *op, const ppath_t *p,
    800     int64_t i)
    801 {
    802 	return ppath_copyset_object_and_release(o, op, p,
    803 	    prop_number_create_integer(i));
    804 }
    805 
    806 int
    807 ppath_set_int64(prop_object_t o, const ppath_t *p, int64_t i)
    808 {
    809 	return ppath_set_object_and_release(o, p,
    810 	    prop_number_create_integer(i));
    811 }
    812 
    813 int
    814 ppath_get_int64(prop_object_t o, const ppath_t *p, int64_t *ip)
    815 {
    816 	prop_object_t v;
    817 	int rc;
    818 
    819 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
    820 		return rc;
    821 
    822 	if (prop_number_unsigned(v))
    823 		return EFTYPE;
    824 
    825 	if (ip != NULL)
    826 		*ip = prop_number_integer_value(v);
    827 
    828 	return 0;
    829 }
    830 
    831 int
    832 ppath_delete_int64(prop_object_t o, const ppath_t *p)
    833 {
    834 	return ppath_delete_object_of_type(o, p, PROP_TYPE_NUMBER);
    835 }
    836 
    837 int
    838 ppath_copyset_string(prop_object_t o, prop_object_t *op, const ppath_t *p,
    839     const char *s)
    840 {
    841 	return ppath_copyset_object_and_release(o, op, p,
    842 	    prop_string_create_cstring(s));
    843 }
    844 
    845 int
    846 ppath_set_string(prop_object_t o, const ppath_t *p, const char *s)
    847 {
    848 	return ppath_set_object_and_release(o, p,
    849 	    prop_string_create_cstring(s));
    850 }
    851 
    852 int
    853 ppath_get_string(prop_object_t o, const ppath_t *p, const char **sp)
    854 {
    855 	int rc;
    856 	prop_object_t v;
    857 
    858 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_STRING)) != 0)
    859 		return rc;
    860 
    861 	if (sp != NULL)
    862 		*sp = prop_string_cstring_nocopy(v);
    863 
    864 	return 0;
    865 }
    866 
    867 int
    868 ppath_dup_string(prop_object_t o, const ppath_t *p, char **sp)
    869 {
    870 	int rc;
    871 	prop_object_t v;
    872 
    873 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_STRING)) != 0)
    874 		return rc;
    875 
    876 	if (sp != NULL)
    877 		*sp = prop_string_cstring(v);
    878 
    879 	return 0;
    880 }
    881 
    882 int
    883 ppath_delete_string(prop_object_t o, const ppath_t *p)
    884 {
    885 	return ppath_delete_object_of_type(o, p, PROP_TYPE_STRING);
    886 }
    887 
    888 int
    889 ppath_copyset_uint64(prop_object_t o, prop_object_t *op, const ppath_t *p,
    890     uint64_t u)
    891 {
    892 	return ppath_copyset_object_and_release(o, op, p,
    893 	    prop_number_create_unsigned_integer(u));
    894 }
    895 
    896 int
    897 ppath_set_uint64(prop_object_t o, const ppath_t *p, uint64_t u)
    898 {
    899 	return ppath_set_object_and_release(o, p,
    900 	    prop_number_create_unsigned_integer(u));
    901 }
    902 
    903 int
    904 ppath_get_uint64(prop_object_t o, const ppath_t *p, uint64_t *up)
    905 {
    906 	prop_object_t v;
    907 	int rc;
    908 
    909 	if ((rc = ppath_get_object_of_type(o, p, &v, PROP_TYPE_DATA)) != 0)
    910 		return rc;
    911 
    912 	if (!prop_number_unsigned(v))
    913 		return EFTYPE;
    914 
    915 	if (up != NULL)
    916 		*up = prop_number_unsigned_integer_value(v);
    917 
    918 	return 0;
    919 }
    920 
    921 int
    922 ppath_delete_uint64(prop_object_t o, const ppath_t *p)
    923 {
    924 	return ppath_delete_object_of_type(o, p, PROP_TYPE_NUMBER);
    925 }
    926