예제 #1
0
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);
    }
  }
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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);

}
예제 #5
0
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;
}
예제 #6
0
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;
}