1 /* $NetBSD: ppath.c,v 1.4 2012/12/29 20:08:23 christos Exp $ */ 2 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("$NetBSD: ppath.c,v 1.4 2012/12/29 20:08:23 christos Exp $"); 34 35 #ifdef _KERNEL 36 #include <sys/systm.h> 37 #endif 38 #include <ppath/ppath.h> 39 #include <ppath/ppath_impl.h> 40 41 enum _ppath_type { 42 PPATH_T_IDX = 0 43 , PPATH_T_KEY = 1 44 }; 45 46 typedef enum _ppath_type ppath_type_t; 47 48 struct _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 59 struct _ppath { 60 unsigned int p_refcnt; 61 unsigned int p_len; 62 ppath_component_t *p_cmpt[PPATH_MAX_COMPONENTS]; 63 }; 64 65 static int ppath_copydel_object_of_type(prop_object_t, prop_object_t *, 66 const ppath_t *, prop_type_t); 67 static int ppath_copyset_object_helper(prop_object_t, prop_object_t *, 68 const ppath_t *, const prop_object_t); 69 70 static void 71 ppath_strfree(char *s) 72 { 73 size_t size = strlen(s) + 1; 74 75 ppath_free(s, size); 76 } 77 78 static char * 79 ppath_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 90 int 91 ppath_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 98 const char * 99 ppath_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 106 ppath_component_t * 107 ppath_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 120 ppath_component_t * 121 ppath_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 138 ppath_component_t * 139 ppath_component_retain(ppath_component_t *pc) 140 { 141 ppath_assert(pc->pc_refcnt != 0); 142 pc->pc_refcnt++; 143 144 return pc; 145 } 146 147 void 148 ppath_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 160 ppath_t * 161 ppath_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 174 ppath_t * 175 ppath_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 192 ppath_t * 193 ppath_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 203 ppath_component_t * 204 ppath_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 216 unsigned int 217 ppath_length(const ppath_t *p) 218 { 219 return p->p_len; 220 } 221 222 ppath_t * 223 ppath_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 241 ppath_t * 242 ppath_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 255 ppath_t * 256 ppath_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 269 ppath_t * 270 ppath_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 291 ppath_t * 292 ppath_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 313 ppath_t * 314 ppath_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 328 ppath_t * 329 ppath_retain(ppath_t *p) 330 { 331 assert(p->p_refcnt != 0); 332 333 p->p_refcnt++; 334 335 return p; 336 } 337 338 void 339 ppath_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 355 static prop_object_t 356 ppath_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 394 prop_object_t 395 ppath_lookup(prop_object_t o, const ppath_t *p) 396 { 397 return ppath_lookup_helper(o, p, NULL, NULL, NULL); 398 } 399 400 static int 401 ppath_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 411 int 412 ppath_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 418 int 419 ppath_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 426 int 427 ppath_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 433 int 434 ppath_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 440 int 441 ppath_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 446 int 447 ppath_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 469 int 470 ppath_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 488 static int 489 ppath_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 508 int 509 ppath_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 521 static int 522 ppath_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 533 int 534 ppath_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 554 static int 555 ppath_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 568 int 569 ppath_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 574 int 575 ppath_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 580 int 581 ppath_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 586 int 587 ppath_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 592 int 593 ppath_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 598 static int 599 ppath_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 613 int 614 ppath_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 619 int 620 ppath_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 627 static int 628 ppath_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 690 static int 691 ppath_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 711 int 712 ppath_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 717 int 718 ppath_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 723 int 724 ppath_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 738 int 739 ppath_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 744 int 745 ppath_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 752 int 753 ppath_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 759 int 760 ppath_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 777 int 778 ppath_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 794 int 795 ppath_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 800 int 801 ppath_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 808 int 809 ppath_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 815 int 816 ppath_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 833 int 834 ppath_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 839 int 840 ppath_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 847 int 848 ppath_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 854 int 855 ppath_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 869 int 870 ppath_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 884 int 885 ppath_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 890 int 891 ppath_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 898 int 899 ppath_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 905 int 906 ppath_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 923 int 924 ppath_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