void ajv_state_mark_seen(ajv_state s, const ajv_node *node) { ajv_node_state ns; ns = (ajv_node_state)orderly_ps_current(s->node_state); if (node->parent && node->parent->node->t == orderly_node_union) { orderly_ps_push(s->AF, ns->seen, (void *)(node->parent)); } else { orderly_ps_push(s->AF, ns->seen, (void *)(node)); } /* advance the current pointer if we're checking a tuple typed array */ if (node->parent && node->parent->node->t == orderly_node_array && node->parent->node->tuple_typed) { if (node->sibling) { s->node = s->node->sibling; } else { /* otherwise, put us into schemaless mode */ ((orderly_node *)(s->any.node))->t = ajv_state_parent(s)->node->additional_properties; s->any.sibling = &(s->any); s->depth = 0; s->any.parent = ajv_state_parent(s); s->node = &(s->any); } } }
int o_json_parse_end_map(void * ctx) { o_json_parse_context * pc = (o_json_parse_context *) ctx; orderly_json * n = orderly_ps_current(pc->nodeStack); orderly_ps_pop(pc->nodeStack); PUSH_NODE(pc, n); return 1; }
int ajv_state_array_complete (ajv_state state) { const ajv_node *array; ajv_node_state s = state->node_state.stack[state->node_state.used - 1]; array = s->node; if (!ajv_check_integer_range(state,array, orderly_ps_length(s->seen))) { return 0; } /* with tuple typed nodes, we need to check that we've seen things */ if (array->node->tuple_typed) { assert(state->node->parent == array); ajv_node_state s = orderly_ps_current(state->node_state); if ((! orderly_ps_length(s->seen) /* seen nothing */ || orderly_ps_current(s->seen) != state->node) && state->node != &(state->any)) { const ajv_node *cur = state->node; do { if (cur->node->default_value) { int ret; ret = orderly_synthesize_callbacks(state->cb, state->cbctx, cur->node->default_value); if (ret == 0) { /*parse was cancelled */ return 0; } } else { int remaining = 0; char buf[128]; do {remaining++; } while ((cur = cur->sibling)); snprintf(buf,128,"%d",remaining); ajv_set_error(state,ajv_e_incomplete_container,array,buf,strlen(buf)); return 0; } cur = cur->sibling; } while (cur); } } ajv_state_pop(state); return 1; }
void ajv_free(ajv_handle hand) { const orderly_alloc_funcs *AF = hand->AF; ajv_node_state cur; ajv_clear_error(hand); orderly_free_node(hand->AF,(orderly_node **)&(hand->any.node)); while (orderly_ps_length(hand->node_state)) { cur = orderly_ps_current(hand->node_state); ajv_free_node_state(hand->AF,&cur); orderly_ps_pop(hand->node_state); } orderly_ps_free(hand->AF,hand->node_state); orderly_free_node(hand->AF,(orderly_node **)&(hand->any.node)); yajl_free(hand->yajl); OR_FREE(AF,hand); }
orderly_json * orderly_read_json(orderly_alloc_funcs * alloc, const char * jsonText, unsigned int * len) { static yajl_callbacks callbacks = { o_json_parse_null, o_json_parse_boolean, o_json_parse_integer, o_json_parse_double, NULL, o_json_parse_string, o_json_parse_start_map, o_json_parse_map_key, o_json_parse_end_map, o_json_parse_start_array, o_json_parse_end_array }; yajl_handle hand; yajl_status stat; /* allow comments! */ yajl_parser_config cfg = { 1, 1 }; o_json_parse_context pc; orderly_json * j = NULL; memset((void *) &pc, 0, sizeof(pc)); pc.alloc = alloc; /* allocate a parser */ hand = yajl_alloc(&callbacks, &cfg, (const yajl_alloc_funcs *) alloc, (void *) &pc); /* read file data, pass to parser */ stat = yajl_parse(hand, (const unsigned char *) jsonText, *len); *len = yajl_get_bytes_consumed(hand); if (stat == yajl_status_insufficient_data) { stat = yajl_parse_complete(hand); } if (stat != yajl_status_ok) { /* unsigned char * str = yajl_get_error(hand, 1, (const unsigned char *) jsonText, *len); */ /* fprintf(stderr, (const char *) str); */ /* yajl_free_error(hand, str); */ } else if (!orderly_ps_length(pc.nodeStack)) { /* XXX: ERROR! */ } else { /* we're ok! */ j = orderly_ps_current(pc.nodeStack); } yajl_free(hand); orderly_ps_free(alloc, pc.nodeStack); orderly_ps_free(alloc, pc.keyStack); return j; }
unsigned char * ajv_get_error(ajv_handle hand, int verbose, const unsigned char * jsonText, unsigned int jsonTextLength) { char * yajl_err; orderly_buf ret = orderly_buf_alloc(hand->AF); ajv_state s = hand; unsigned char *cret; struct ajv_error_t *e = &(s->error); int yajl_length; const char *fn; if (e->node) { fn = ajv_node_format(e->node->node); } if (e->code == ajv_e_no_error) { return yajl_get_error(hand->yajl,verbose,jsonText,jsonTextLength); } /* include the yajl error message when verbose */ if (verbose == 1) { yajl_err = (char *)yajl_get_error(hand->yajl,verbose, (unsigned char *)jsonText,jsonTextLength); yajl_length = strlen(yajl_err); } if (e->code == ajv_e_out_of_range) { const orderly_node *on = e->node->node; const char *type = orderly_node_type_to_string(on->t); orderly_buf_append_string(ret,type); if (on->t == orderly_node_array || on->t == orderly_node_string) { orderly_buf_append_string(ret," length"); } orderly_buf_append_string(ret," "); orderly_buf_append_string(ret,e->extra_info); orderly_buf_append_string(ret," not in range "); if (ORDERLY_RANGE_SPECIFIED(on->range)) { char buf[128]; orderly_buf_append_string(ret, "{"); buf[0] = 0; if (ORDERLY_RANGE_LHS_DOUBLE & on->range.info) sprintf(buf, "%.15g", on->range.lhs.d); else if (ORDERLY_RANGE_LHS_INT & on->range.info) sprintf(buf, "%ld", on->range.lhs.i); if (buf[0]) orderly_buf_append_string(ret, buf); orderly_buf_append_string(ret, ","); buf[0] = 0; if (ORDERLY_RANGE_RHS_DOUBLE & on->range.info) sprintf(buf, "%.15g", on->range.rhs.d); else if (ORDERLY_RANGE_RHS_INT & on->range.info) sprintf(buf, "%ld", on->range.rhs.i); if (buf[0]) orderly_buf_append_string(ret, buf); orderly_buf_append_string(ret, "}"); } } else { orderly_buf_append_string(ret, (const char *)ajv_error_to_string(e->code)); } if (e->code == ajv_e_invalid_format) { orderly_buf_append_string(ret, " '"); orderly_buf_append_string(ret, fn); orderly_buf_append_string(ret, "':"); } if (e->extra_info) { if (e->code == ajv_e_incomplete_container) { if (e->node) { if (e->node->node->t == orderly_node_object) { orderly_buf_append_string(ret, ", object missing required property"); } else { orderly_buf_append_string(ret, ", tuple missing "); orderly_buf_append_string(ret, e->extra_info); orderly_buf_append_string(ret, " elements"); } } } if (e->code == ajv_e_illegal_value) { orderly_buf_append_string(ret, ":"); } if (e->code != ajv_e_out_of_range && !(e->code == ajv_e_incomplete_container && e->node && e->node->node->t == orderly_node_array)) { orderly_buf_append_string(ret, " '"); orderly_buf_append_string(ret, e->extra_info); orderly_buf_append_string(ret, "'"); } } if (e->node) { if (e->code == ajv_e_type_mismatch) { if (e->node->node->name) { orderly_buf_append_string(ret, " for property '"); orderly_buf_append_string(ret, e->node->node->name); orderly_buf_append_string(ret, "'"); } if (e->node->parent && e->node->parent->node->tuple_typed == 1) { ajv_node_state ns = (ajv_node_state)orderly_ps_current(s->node_state); char buf[128]; orderly_buf_append_string(ret, " for array element "); snprintf(buf,128,"%d",orderly_ps_length(ns->seen)+1); orderly_buf_append_string(ret,buf); } orderly_buf_append_string(ret, ", expected '"); orderly_buf_append_string(ret, orderly_node_type_to_string(e->node->node->t)); orderly_buf_append_string(ret, "'"); } } if (e->code == ajv_e_unexpected_key) { orderly_buf_append_string(ret, ", while additionalProperties forbidden"); } orderly_buf_append_string(ret,"."); BUF_STRDUP(cret, hand->AF, orderly_buf_data(ret), orderly_buf_len(ret)); orderly_buf_free(ret); return cret; }