1 /* $NetBSD: prop_array.c,v 1.20 2008/08/11 05:54:21 christos Exp $ */
4 * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
32 #include <prop/prop_array.h>
33 #include "prop_object_impl.h"
35 #if !defined(_KERNEL) && !defined(_STANDALONE)
37 #define __unused /* empty */
41 struct _prop_object pa_obj
;
42 _PROP_RWLOCK_DECL(pa_rwlock
)
43 prop_object_t
* pa_array
;
44 unsigned int pa_capacity
;
45 unsigned int pa_count
;
51 #define PA_F_IMMUTABLE 0x01 /* array is immutable */
53 _PROP_POOL_INIT(_prop_array_pool
, sizeof(struct _prop_array
), "proparay")
54 _PROP_MALLOC_DEFINE(M_PROP_ARRAY
, "prop array",
55 "property array container object")
57 static _prop_object_free_rv_t
58 _prop_array_free(prop_stack_t
, prop_object_t
*);
59 static void _prop_array_emergency_free(prop_object_t
);
60 static bool _prop_array_externalize(
61 struct _prop_object_externalize_context
*,
63 static _prop_object_equals_rv_t
64 _prop_array_equals(prop_object_t
, prop_object_t
,
66 prop_object_t
*, prop_object_t
*);
67 static void _prop_array_equals_finish(prop_object_t
, prop_object_t
);
68 static prop_object_iterator_t
69 _prop_array_iterator_locked(prop_array_t
);
71 _prop_array_iterator_next_object_locked(void *);
72 static void _prop_array_iterator_reset_locked(void *);
74 static const struct _prop_object_type _prop_object_type_array
= {
75 .pot_type
= PROP_TYPE_ARRAY
,
76 .pot_free
= _prop_array_free
,
77 .pot_emergency_free
= _prop_array_emergency_free
,
78 .pot_extern
= _prop_array_externalize
,
79 .pot_equals
= _prop_array_equals
,
80 .pot_equals_finish
= _prop_array_equals_finish
,
83 #define prop_object_is_array(x) \
84 ((x) != NULL && (x)->pa_obj.po_type == &_prop_object_type_array)
86 #define prop_array_is_immutable(x) (((x)->pa_flags & PA_F_IMMUTABLE) != 0)
88 struct _prop_array_iterator
{
89 struct _prop_object_iterator pai_base
;
90 unsigned int pai_index
;
93 #define EXPAND_STEP 16
95 static _prop_object_free_rv_t
96 _prop_array_free(prop_stack_t stack
, prop_object_t
*obj
)
98 prop_array_t pa
= *obj
;
101 _PROP_ASSERT(pa
->pa_count
<= pa
->pa_capacity
);
102 _PROP_ASSERT((pa
->pa_capacity
== 0 && pa
->pa_array
== NULL
) ||
103 (pa
->pa_capacity
!= 0 && pa
->pa_array
!= NULL
));
105 /* The easy case is an empty array, just free and return. */
106 if (pa
->pa_count
== 0) {
107 if (pa
->pa_array
!= NULL
)
108 _PROP_FREE(pa
->pa_array
, M_PROP_ARRAY
);
110 _PROP_RWLOCK_DESTROY(pa
->pa_rwlock
);
112 _PROP_POOL_PUT(_prop_array_pool
, pa
);
114 return (_PROP_OBJECT_FREE_DONE
);
117 po
= pa
->pa_array
[pa
->pa_count
- 1];
118 _PROP_ASSERT(po
!= NULL
);
122 * If we are in emergency release mode,
123 * just let caller recurse down.
126 return (_PROP_OBJECT_FREE_FAILED
);
129 /* Otherwise, try to push the current object on the stack. */
130 if (!_prop_stack_push(stack
, pa
, NULL
, NULL
, NULL
)) {
131 /* Push failed, entering emergency release mode. */
132 return (_PROP_OBJECT_FREE_FAILED
);
134 /* Object pushed on stack, caller will release it. */
137 return (_PROP_OBJECT_FREE_RECURSE
);
141 _prop_array_emergency_free(prop_object_t obj
)
143 prop_array_t pa
= obj
;
145 _PROP_ASSERT(pa
->pa_count
!= 0);
150 _prop_array_externalize(struct _prop_object_externalize_context
*ctx
,
154 struct _prop_object
*po
;
155 prop_object_iterator_t pi
;
159 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
161 if (pa
->pa_count
== 0) {
162 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
163 return (_prop_object_externalize_empty_tag(ctx
, "array"));
166 /* XXXJRT Hint "count" for the internalize step? */
167 if (_prop_object_externalize_start_tag(ctx
, "array") == false ||
168 _prop_object_externalize_append_char(ctx
, '\n') == false)
171 pi
= _prop_array_iterator_locked(pa
);
176 _PROP_ASSERT(ctx
->poec_depth
!= 0);
178 while ((po
= _prop_array_iterator_next_object_locked(pi
)) != NULL
) {
179 if ((*po
->po_type
->pot_extern
)(ctx
, po
) == false) {
180 prop_object_iterator_release(pi
);
185 prop_object_iterator_release(pi
);
188 for (i
= 0; i
< ctx
->poec_depth
; i
++) {
189 if (_prop_object_externalize_append_char(ctx
, '\t') == false)
192 if (_prop_object_externalize_end_tag(ctx
, "array") == false)
198 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
203 static _prop_object_equals_rv_t
204 _prop_array_equals(prop_object_t v1
, prop_object_t v2
,
205 void **stored_pointer1
, void **stored_pointer2
,
206 prop_object_t
*next_obj1
, prop_object_t
*next_obj2
)
208 prop_array_t array1
= v1
;
209 prop_array_t array2
= v2
;
211 _prop_object_equals_rv_t rv
= _PROP_OBJECT_EQUALS_FALSE
;
213 if (array1
== array2
)
214 return (_PROP_OBJECT_EQUALS_TRUE
);
216 _PROP_ASSERT(*stored_pointer1
== *stored_pointer2
);
217 idx
= (uintptr_t)*stored_pointer1
;
219 /* For the first iteration, lock the objects. */
221 if ((uintptr_t)array1
< (uintptr_t)array2
) {
222 _PROP_RWLOCK_RDLOCK(array1
->pa_rwlock
);
223 _PROP_RWLOCK_RDLOCK(array2
->pa_rwlock
);
225 _PROP_RWLOCK_RDLOCK(array2
->pa_rwlock
);
226 _PROP_RWLOCK_RDLOCK(array1
->pa_rwlock
);
230 if (array1
->pa_count
!= array2
->pa_count
)
232 if (idx
== array1
->pa_count
) {
233 rv
= _PROP_OBJECT_EQUALS_TRUE
;
236 _PROP_ASSERT(idx
< array1
->pa_count
);
238 *stored_pointer1
= (void *)(idx
+ 1);
239 *stored_pointer2
= (void *)(idx
+ 1);
241 *next_obj1
= array1
->pa_array
[idx
];
242 *next_obj2
= array2
->pa_array
[idx
];
244 return (_PROP_OBJECT_EQUALS_RECURSE
);
247 _PROP_RWLOCK_UNLOCK(array1
->pa_rwlock
);
248 _PROP_RWLOCK_UNLOCK(array2
->pa_rwlock
);
253 _prop_array_equals_finish(prop_object_t v1
, prop_object_t v2
)
255 _PROP_RWLOCK_UNLOCK(((prop_array_t
)v1
)->pa_rwlock
);
256 _PROP_RWLOCK_UNLOCK(((prop_array_t
)v2
)->pa_rwlock
);
260 _prop_array_alloc(unsigned int capacity
)
263 prop_object_t
*array
;
266 array
= _PROP_CALLOC(capacity
* sizeof(prop_object_t
),
273 pa
= _PROP_POOL_GET(_prop_array_pool
);
275 _prop_object_init(&pa
->pa_obj
, &_prop_object_type_array
);
276 pa
->pa_obj
.po_type
= &_prop_object_type_array
;
278 _PROP_RWLOCK_INIT(pa
->pa_rwlock
);
279 pa
->pa_array
= array
;
280 pa
->pa_capacity
= capacity
;
285 } else if (array
!= NULL
)
286 _PROP_FREE(array
, M_PROP_ARRAY
);
292 _prop_array_expand(prop_array_t pa
, unsigned int capacity
)
294 prop_object_t
*array
, *oarray
;
297 * Array must be WRITE-LOCKED.
300 oarray
= pa
->pa_array
;
302 array
= _PROP_CALLOC(capacity
* sizeof(*array
), M_PROP_ARRAY
);
306 memcpy(array
, oarray
, pa
->pa_capacity
* sizeof(*array
));
307 pa
->pa_array
= array
;
308 pa
->pa_capacity
= capacity
;
311 _PROP_FREE(oarray
, M_PROP_ARRAY
);
317 _prop_array_iterator_next_object_locked(void *v
)
319 struct _prop_array_iterator
*pai
= v
;
320 prop_array_t pa
= pai
->pai_base
.pi_obj
;
321 prop_object_t po
= NULL
;
323 _PROP_ASSERT(prop_object_is_array(pa
));
325 if (pa
->pa_version
!= pai
->pai_base
.pi_version
)
326 goto out
; /* array changed during iteration */
328 _PROP_ASSERT(pai
->pai_index
<= pa
->pa_count
);
330 if (pai
->pai_index
== pa
->pa_count
)
331 goto out
; /* we've iterated all objects */
333 po
= pa
->pa_array
[pai
->pai_index
];
341 _prop_array_iterator_next_object(void *v
)
343 struct _prop_array_iterator
*pai
= v
;
344 prop_array_t pa __unused
= pai
->pai_base
.pi_obj
;
347 _PROP_ASSERT(prop_object_is_array(pa
));
349 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
350 po
= _prop_array_iterator_next_object_locked(pai
);
351 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
356 _prop_array_iterator_reset_locked(void *v
)
358 struct _prop_array_iterator
*pai
= v
;
359 prop_array_t pa
= pai
->pai_base
.pi_obj
;
361 _PROP_ASSERT(prop_object_is_array(pa
));
364 pai
->pai_base
.pi_version
= pa
->pa_version
;
368 _prop_array_iterator_reset(void *v
)
370 struct _prop_array_iterator
*pai
= v
;
371 prop_array_t pa __unused
= pai
->pai_base
.pi_obj
;
373 _PROP_ASSERT(prop_object_is_array(pa
));
375 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
376 _prop_array_iterator_reset_locked(pai
);
377 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
381 * prop_array_create --
382 * Create an empty array.
385 prop_array_create(void)
388 return (_prop_array_alloc(0));
392 * prop_array_create_with_capacity --
393 * Create an array with the capacity to store N objects.
396 prop_array_create_with_capacity(unsigned int capacity
)
399 return (_prop_array_alloc(capacity
));
404 * Copy an array. The new array has an initial capacity equal to
405 * the number of objects stored in the original array. The new
406 * array contains references to the original array's objects, not
407 * copies of those objects (i.e. a shallow copy).
410 prop_array_copy(prop_array_t opa
)
416 if (! prop_object_is_array(opa
))
419 _PROP_RWLOCK_RDLOCK(opa
->pa_rwlock
);
421 pa
= _prop_array_alloc(opa
->pa_count
);
423 for (idx
= 0; idx
< opa
->pa_count
; idx
++) {
424 po
= opa
->pa_array
[idx
];
425 prop_object_retain(po
);
426 pa
->pa_array
[idx
] = po
;
428 pa
->pa_count
= opa
->pa_count
;
429 pa
->pa_flags
= opa
->pa_flags
;
431 _PROP_RWLOCK_UNLOCK(opa
->pa_rwlock
);
436 * prop_array_copy_mutable --
437 * Like prop_array_copy(), but the resulting array is mutable.
440 prop_array_copy_mutable(prop_array_t opa
)
444 pa
= prop_array_copy(opa
);
446 pa
->pa_flags
&= ~PA_F_IMMUTABLE
;
452 * prop_array_capacity --
453 * Return the capacity of the array.
456 prop_array_capacity(prop_array_t pa
)
460 if (! prop_object_is_array(pa
))
463 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
464 rv
= pa
->pa_capacity
;
465 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
471 * prop_array_count --
472 * Return the number of objects stored in the array.
475 prop_array_count(prop_array_t pa
)
479 if (! prop_object_is_array(pa
))
482 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
484 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
490 * prop_array_ensure_capacity --
491 * Ensure that the array has the capacity to store the specified
492 * total number of objects (inluding the objects already stored
496 prop_array_ensure_capacity(prop_array_t pa
, unsigned int capacity
)
500 if (! prop_object_is_array(pa
))
503 _PROP_RWLOCK_WRLOCK(pa
->pa_rwlock
);
504 if (capacity
> pa
->pa_capacity
)
505 rv
= _prop_array_expand(pa
, capacity
);
508 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
513 static prop_object_iterator_t
514 _prop_array_iterator_locked(prop_array_t pa
)
516 struct _prop_array_iterator
*pai
;
518 if (! prop_object_is_array(pa
))
521 pai
= _PROP_CALLOC(sizeof(*pai
), M_TEMP
);
524 pai
->pai_base
.pi_next_object
= _prop_array_iterator_next_object
;
525 pai
->pai_base
.pi_reset
= _prop_array_iterator_reset
;
526 prop_object_retain(pa
);
527 pai
->pai_base
.pi_obj
= pa
;
528 _prop_array_iterator_reset_locked(pai
);
530 return (&pai
->pai_base
);
534 * prop_array_iterator --
535 * Return an iterator for the array. The array is retained by
538 prop_object_iterator_t
539 prop_array_iterator(prop_array_t pa
)
541 prop_object_iterator_t pi
;
543 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
544 pi
= _prop_array_iterator_locked(pa
);
545 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
550 * prop_array_make_immutable --
551 * Make the array immutable.
554 prop_array_make_immutable(prop_array_t pa
)
557 _PROP_RWLOCK_WRLOCK(pa
->pa_rwlock
);
558 if (prop_array_is_immutable(pa
) == false)
559 pa
->pa_flags
|= PA_F_IMMUTABLE
;
560 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
564 * prop_array_mutable --
565 * Returns true if the array is mutable.
568 prop_array_mutable(prop_array_t pa
)
572 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
573 rv
= prop_array_is_immutable(pa
) == false;
574 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
581 * Return the object stored at the specified array index.
584 prop_array_get(prop_array_t pa
, unsigned int idx
)
586 prop_object_t po
= NULL
;
588 if (! prop_object_is_array(pa
))
591 _PROP_RWLOCK_RDLOCK(pa
->pa_rwlock
);
592 if (idx
>= pa
->pa_count
)
594 po
= pa
->pa_array
[idx
];
595 _PROP_ASSERT(po
!= NULL
);
597 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
602 _prop_array_add(prop_array_t pa
, prop_object_t po
)
606 * Array must be WRITE-LOCKED.
609 _PROP_ASSERT(pa
->pa_count
<= pa
->pa_capacity
);
611 if (prop_array_is_immutable(pa
) ||
612 (pa
->pa_count
== pa
->pa_capacity
&&
613 _prop_array_expand(pa
, pa
->pa_capacity
+ EXPAND_STEP
) == false))
616 prop_object_retain(po
);
617 pa
->pa_array
[pa
->pa_count
++] = po
;
625 * Store a reference to an object at the specified array index.
626 * This method is not allowed to create holes in the array; the
627 * caller must either be setting the object just beyond the existing
628 * count or replacing an already existing object reference.
631 prop_array_set(prop_array_t pa
, unsigned int idx
, prop_object_t po
)
636 if (! prop_object_is_array(pa
))
639 _PROP_RWLOCK_WRLOCK(pa
->pa_rwlock
);
641 if (prop_array_is_immutable(pa
))
644 if (idx
== pa
->pa_count
) {
645 rv
= _prop_array_add(pa
, po
);
649 _PROP_ASSERT(idx
< pa
->pa_count
);
651 opo
= pa
->pa_array
[idx
];
652 _PROP_ASSERT(opo
!= NULL
);
654 prop_object_retain(po
);
655 pa
->pa_array
[idx
] = po
;
658 prop_object_release(opo
);
663 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
669 * Add a reference to an object to the specified array, appending
670 * to the end and growing the array's capacity, if necessary.
673 prop_array_add(prop_array_t pa
, prop_object_t po
)
677 if (! prop_object_is_array(pa
))
680 _PROP_RWLOCK_WRLOCK(pa
->pa_rwlock
);
681 rv
= _prop_array_add(pa
, po
);
682 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
688 * prop_array_remove --
689 * Remove the reference to an object from an array at the specified
690 * index. The array will be compacted following the removal.
693 prop_array_remove(prop_array_t pa
, unsigned int idx
)
697 if (! prop_object_is_array(pa
))
700 _PROP_RWLOCK_WRLOCK(pa
->pa_rwlock
);
702 _PROP_ASSERT(idx
< pa
->pa_count
);
704 /* XXX Should this be a _PROP_ASSERT()? */
705 if (prop_array_is_immutable(pa
)) {
706 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
710 po
= pa
->pa_array
[idx
];
711 _PROP_ASSERT(po
!= NULL
);
713 for (++idx
; idx
< pa
->pa_count
; idx
++)
714 pa
->pa_array
[idx
- 1] = pa
->pa_array
[idx
];
718 _PROP_RWLOCK_UNLOCK(pa
->pa_rwlock
);
720 prop_object_release(po
);
724 * prop_array_equals --
725 * Return true if the two arrays are equivalent. Note we do a
726 * by-value comparison of the objects in the array.
729 prop_array_equals(prop_array_t array1
, prop_array_t array2
)
731 if (!prop_object_is_array(array1
) || !prop_object_is_array(array2
))
734 return (prop_object_equals(array1
, array2
));
738 * prop_array_externalize --
739 * Externalize an array, return a NUL-terminated buffer
740 * containing the XML-style representation. The buffer is allocated
741 * with the M_TEMP memory type.
744 prop_array_externalize(prop_array_t pa
)
746 struct _prop_object_externalize_context
*ctx
;
749 ctx
= _prop_object_externalize_context_alloc();
753 if (_prop_object_externalize_header(ctx
) == false ||
754 (*pa
->pa_obj
.po_type
->pot_extern
)(ctx
, pa
) == false ||
755 _prop_object_externalize_footer(ctx
) == false) {
756 /* We are responsible for releasing the buffer. */
757 _PROP_FREE(ctx
->poec_buf
, M_TEMP
);
758 _prop_object_externalize_context_free(ctx
);
763 _prop_object_externalize_context_free(ctx
);
769 * _prop_array_internalize --
770 * Parse an <array>...</array> and return the object created from the
771 * external representation.
773 static bool _prop_array_internalize_body(prop_stack_t
, prop_object_t
*,
774 struct _prop_object_internalize_context
*);
777 _prop_array_internalize(prop_stack_t stack
, prop_object_t
*obj
,
778 struct _prop_object_internalize_context
*ctx
)
780 /* We don't currently understand any attributes. */
781 if (ctx
->poic_tagattr
!= NULL
)
784 *obj
= prop_array_create();
786 * We are done if the create failed or no child elements exist.
788 if (*obj
== NULL
|| ctx
->poic_is_empty_element
)
792 * Opening tag is found, now continue to the first element.
794 return (_prop_array_internalize_body(stack
, obj
, ctx
));
798 _prop_array_internalize_continue(prop_stack_t stack
,
800 struct _prop_object_internalize_context
*ctx
,
801 void *data
, prop_object_t child
)
805 _PROP_ASSERT(data
== NULL
);
808 goto bad
; /* Element could not be parsed. */
812 if (prop_array_add(array
, child
) == false) {
813 prop_object_release(child
);
816 prop_object_release(child
);
819 * Current element is processed and added, look for next.
821 return (_prop_array_internalize_body(stack
, obj
, ctx
));
824 prop_object_release(*obj
);
830 _prop_array_internalize_body(prop_stack_t stack
, prop_object_t
*obj
,
831 struct _prop_object_internalize_context
*ctx
)
833 prop_array_t array
= *obj
;
835 _PROP_ASSERT(array
!= NULL
);
837 /* Fetch the next tag. */
838 if (_prop_object_internalize_find_tag(ctx
, NULL
,
839 _PROP_TAG_TYPE_EITHER
) == false)
842 /* Check to see if this is the end of the array. */
843 if (_PROP_TAG_MATCH(ctx
, "array") &&
844 ctx
->poic_tag_type
== _PROP_TAG_TYPE_END
) {
845 /* It is, so don't iterate any further. */
849 if (_prop_stack_push(stack
, array
,
850 _prop_array_internalize_continue
, NULL
, NULL
))
854 prop_object_release(array
);
860 * prop_array_internalize --
861 * Create an array by parsing the XML-style representation.
864 prop_array_internalize(const char *xml
)
866 return _prop_generic_internalize(xml
, "array");
869 #if !defined(_KERNEL) && !defined(_STANDALONE)
871 * prop_array_externalize_to_file --
872 * Externalize an array to the specified file.
875 prop_array_externalize_to_file(prop_array_t array
, const char *fname
)
879 int save_errno
= 0; /* XXXGCC -Wuninitialized [mips, ...] */
881 xml
= prop_array_externalize(array
);
884 rv
= _prop_object_externalize_write_file(fname
, xml
, strlen(xml
), false);
887 _PROP_FREE(xml
, M_TEMP
);
895 * prop_array_internalize_from_file --
896 * Internalize an array from a file.
899 prop_array_internalize_from_file(const char *fname
)
901 struct _prop_object_internalize_mapped_file
*mf
;
904 mf
= _prop_object_internalize_map_file(fname
);
907 array
= prop_array_internalize(mf
->poimf_xml
);
908 _prop_object_internalize_unmap_file(mf
);
912 #endif /* _KERNEL && !_STANDALONE */