ppath.c revision 1.1 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 (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.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