Пример #1
0
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);
}
Пример #2
0
bool
prop_object_equals_with_error(prop_object_t obj1, prop_object_t obj2,
    bool *error_flag)
{
	struct _prop_object *po1;
	struct _prop_object *po2;
	void *stored_pointer1, *stored_pointer2;
	prop_object_t next_obj1, next_obj2;
	struct _prop_stack stack;
	_prop_object_equals_rv_t ret;

	_prop_stack_init(&stack);
	if (error_flag)
		*error_flag = false;

 start_subtree:
	stored_pointer1 = NULL;
	stored_pointer2 = NULL;
	po1 = obj1;
	po2 = obj2;

	if (po1->po_type != po2->po_type)
		return (false);
    
 continue_subtree:
	ret = (*po1->po_type->pot_equals)(obj1, obj2,
					  &stored_pointer1, &stored_pointer2,
					  &next_obj1, &next_obj2);
	if (ret == _PROP_OBJECT_EQUALS_FALSE)
		goto finish;
	if (ret == _PROP_OBJECT_EQUALS_TRUE) {
		if (!_prop_stack_pop(&stack, &obj1, &obj2,
				     &stored_pointer1, &stored_pointer2))
			return true;
		po1 = obj1;
		po2 = obj2;
		goto continue_subtree;
	}
	_PROP_ASSERT(ret == _PROP_OBJECT_EQUALS_RECURSE);

	if (!_prop_stack_push(&stack, obj1, obj2,
			      stored_pointer1, stored_pointer2)) {
		if (error_flag)
			*error_flag = true;
		goto finish;
	}
	obj1 = next_obj1;
	obj2 = next_obj2;
	goto start_subtree;

finish:
	while (_prop_stack_pop(&stack, &obj1, &obj2, NULL, NULL)) {
		po1 = obj1;
		(*po1->po_type->pot_equals_finish)(obj1, obj2);
	}
	return (false);		
}
Пример #3
0
static _prop_object_free_rv_t
_prop_array_free(prop_stack_t stack, prop_object_t *obj)
{
	prop_array_t pa = *obj;
	prop_object_t po;

	_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
	_PROP_ASSERT((pa->pa_capacity == 0 && pa->pa_array == NULL) ||
		     (pa->pa_capacity != 0 && pa->pa_array != NULL));

	/* The easy case is an empty array, just free and return. */
	if (pa->pa_count == 0) {
		if (pa->pa_array != NULL)
			_PROP_FREE(pa->pa_array, M_PROP_ARRAY);

		_PROP_RWLOCK_DESTROY(pa->pa_rwlock);

		_PROP_POOL_PUT(_prop_array_pool, pa);

		return (_PROP_OBJECT_FREE_DONE);
	}
	if (pa->pa_array == NULL)
		return _PROP_OBJECT_FREE_DONE;

	po = pa->pa_array[pa->pa_count - 1];
	_PROP_ASSERT(po != NULL);

	if (stack == NULL) {
		/*
		 * If we are in emergency release mode,
		 * just let caller recurse down.
		 */
		*obj = po;
		return (_PROP_OBJECT_FREE_FAILED);
	}

	/* Otherwise, try to push the current object on the stack. */
	if (!_prop_stack_push(stack, pa, NULL, NULL, NULL)) {
		/* Push failed, entering emergency release mode. */
		return (_PROP_OBJECT_FREE_FAILED);
	}
	/* Object pushed on stack, caller will release it. */
	--pa->pa_count;
	*obj = po;
	return (_PROP_OBJECT_FREE_RECURSE);
}