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 | |