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