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