ppath.c revision 1.4 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 (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("$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