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