예제 #1
0
static bool _check(Validator *v, ValidationEvent const *e, ValidationState *s, void *ctxt)
{
	if (e->type != EV_NUM)
	{
		validation_state_notify_error(s, VEC_NOT_NUMBER, ctxt);
		validation_state_pop_validator(s);
		return false;
	}

	Number n;
	number_init(&n);
	if (number_set_n(&n, e->value.string.ptr, e->value.string.len))
	{
		number_clear(&n);
		// TODO: Number format error
		validation_state_notify_error(s, VEC_NOT_NUMBER, ctxt);
		validation_state_pop_validator(s);
		return false;
	}

	bool res = _check_conditions((NumberValidator *) v, &n, s, ctxt);

	number_clear(&n);
	validation_state_pop_validator(s);
	return res;
}
예제 #2
0
static bool check_generic(Validator *v, ValidationEvent const *e, ValidationState *s, void *ctxt)
{
	// depth is used to track when current and all nested arrays are closed
	// layout checks done by YAJL
	int depth = GPOINTER_TO_INT(validation_state_get_context(s));
	switch (e->type)
	{
	case EV_ARR_START:
		validation_state_set_context(s, GINT_TO_POINTER(++depth));
		return true;
	case EV_ARR_END:
		validation_state_set_context(s, GINT_TO_POINTER(--depth));
		if (!depth)
			// all arrays are closed. Last one was array validated by this object
			// so all validations are passed
			validation_state_pop_validator(s);
		return true;
	default:
		if (!depth)
		{
			// if there is non ARR_START event when depth is zero (a.k.a. basic array is not started yet)
			// than it's not array at all.
			// return error
			validation_state_notify_error(s, VEC_NOT_ARRAY, ctxt);
			validation_state_pop_validator(s);
			return false;
		}

		// if basic array is started (depth is non-zero) we don't care. All is fine
		return true;
	}
}
예제 #3
0
static bool check(Validator *v, ValidationEvent const *e, ValidationState *s, void *c)
{
	ArrayValidator *varr = (ArrayValidator *) v;
	MyContext *my_ctxt = (MyContext *) validation_state_get_context(s);
	if (!my_ctxt->has_started)
	{
		if (e->type != EV_ARR_START)
		{
			validation_state_notify_error(s, VEC_NOT_ARRAY, c);
			validation_state_pop_validator(s);
			return false;
		}
		my_ctxt->has_started = true;
		my_ctxt->cur_validator = varr->items ? varr->items->validators : NULL;
		return true;
	}

	if (e->type == EV_ARR_END)
	{
		bool res = true;
		if (varr->min_items != -1 && my_ctxt->items_count < varr->min_items)
		{
			validation_state_notify_error(s, VEC_ARRAY_TOO_SHORT, c);
			res = false;
		}
		else if (varr->unique_items && s->notify && s->notify->has_array_duplicates &&
		         s->notify->has_array_duplicates(s, c))
		{
			validation_state_notify_error(s, VEC_ARRAY_HAS_DUPLICATES, c);
			res = false;
		}
		validation_state_pop_validator(s);
		return res;
	}

	++my_ctxt->items_count;

	if (varr->max_items != -1 && my_ctxt->items_count > varr->max_items)
	{
		validation_state_notify_error(s, VEC_ARRAY_TOO_LONG, c);
		validation_state_pop_validator(s);
		return false;
	}

	Validator* vcur = _get_current_validator(varr, my_ctxt);
	if (vcur)
	{
		validation_state_push_validator(s, vcur);
		bool valid = validation_check(e, s, c);
		if (!valid)
			validation_state_pop_validator(s);
		return valid;
	}

	validation_state_notify_error(s, VEC_ARRAY_TOO_LONG, c);
	validation_state_pop_validator(s);
	return false;
}
예제 #4
0
static bool check_integer_generic(Validator *v, ValidationEvent const *e, ValidationState *s, void *ctxt)
{
	if (e->type != EV_NUM)
	{
		validation_state_notify_error(s, VEC_NOT_NUMBER, ctxt);
		validation_state_pop_validator(s);
		return false;
	}

	Number n;
	number_init(&n);

	bool res = check_integer_conditions(&n, e, s, ctxt);
	number_clear(&n);
	validation_state_pop_validator(s);
	return res;
}
예제 #5
0
static bool check_generic(Validator *v, ValidationEvent const *e, ValidationState *s, void *ctxt)
{
	validation_state_pop_validator(s);
	if (e->type != EV_NUM)
	{
		validation_state_notify_error(s, VEC_NOT_NUMBER, ctxt);
		return false;
	}
	return true;
}