prop_object_t _prop_generic_internalize(const char *xml, const char *master_tag) { prop_object_t obj = NULL; struct _prop_object_internalize_context *ctx; ctx = _prop_object_internalize_context_alloc(xml); if (ctx == NULL) return (NULL); /* We start with a <plist> tag. */ if (_prop_object_internalize_find_tag(ctx, "plist", _PROP_TAG_TYPE_START) == false) goto out; /* Plist elements cannot be empty. */ if (ctx->poic_is_empty_element) goto out; /* * We don't understand any plist attributes, but Apple XML * property lists often have a "version" attribute. If we * see that one, we simply ignore it. */ if (ctx->poic_tagattr != NULL && !_PROP_TAGATTR_MATCH(ctx, "version")) goto out; /* Next we expect to see opening master_tag. */ if (_prop_object_internalize_find_tag(ctx, master_tag, _PROP_TAG_TYPE_START) == false) goto out; obj = _prop_object_internalize_by_tag(ctx); if (obj == NULL) goto out; /* * We've advanced past the closing master_tag. * Now we want </plist>. */ if (_prop_object_internalize_find_tag(ctx, "plist", _PROP_TAG_TYPE_END) == false) { prop_object_release(obj); obj = NULL; } out: _prop_object_internalize_context_free(ctx); return (obj); }
static bool _prop_array_internalize_body(prop_stack_t stack, prop_object_t *obj, struct _prop_object_internalize_context *ctx) { prop_array_t array = *obj; _PROP_ASSERT(array != NULL); /* Fetch the next tag. */ if (_prop_object_internalize_find_tag(ctx, NULL, _PROP_TAG_TYPE_EITHER) == false) goto bad; /* Check to see if this is the end of the array. */ if (_PROP_TAG_MATCH(ctx, "array") && ctx->poic_tag_type == _PROP_TAG_TYPE_END) { /* It is, so don't iterate any further. */ return (true); } if (_prop_stack_push(stack, array, _prop_array_internalize_continue, NULL, NULL)) return (false); bad: prop_object_release(array); *obj = NULL; return (true); }
/* ARGSUSED */ bool _prop_string_internalize(prop_stack_t stack, prop_object_t *obj, struct _prop_object_internalize_context *ctx) { prop_string_t string; char *str; size_t len, alen; if (ctx->poic_is_empty_element) { *obj = prop_string_create(); return (true); } /* No attributes recognized here. */ if (ctx->poic_tagattr != NULL) return (true); /* Compute the length of the result. */ if (_prop_object_internalize_decode_string(ctx, NULL, 0, &len, NULL) == false) return (true); str = _PROP_MALLOC(len + 1, M_PROP_STRING); if (str == NULL) return (true); if (_prop_object_internalize_decode_string(ctx, str, len, &alen, &ctx->poic_cp) == false || alen != len) { _PROP_FREE(str, M_PROP_STRING); return (true); } str[len] = '\0'; if (_prop_object_internalize_find_tag(ctx, "string", _PROP_TAG_TYPE_END) == false) { _PROP_FREE(str, M_PROP_STRING); return (true); } string = _prop_string_alloc(); if (string == NULL) { _PROP_FREE(str, M_PROP_STRING); return (true); } string->ps_mutable = str; string->ps_size = len; *obj = string; return (true); }