static int unpack(scanner_t *s, json_t *root, va_list *ap) { switch(s->token) { case '{': return unpack_object(s, root, ap); case '[': return unpack_array(s, root, ap); case 's': if(root && !json_is_string(root)) { set_error(s, "<validation>", "Expected string, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) { const char **target; target = va_arg(*ap, const char **); if(!target) { set_error(s, "<args>", "NULL string argument"); return -1; } if(root) *target = json_string_value(root); } return 0; case 'i': if(root && !json_is_integer(root)) { set_error(s, "<validation>", "Expected integer, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) { int *target = va_arg(*ap, int*); if(root) *target = (int)json_integer_value(root); } return 0; case 'I': if(root && !json_is_integer(root)) { set_error(s, "<validation>", "Expected integer, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) { json_int_t *target = va_arg(*ap, json_int_t*); if(root) *target = json_integer_value(root); }
static int unpack(scanner_t *s, json_t *root, va_list *ap) { switch(s->token) { case '{': return unpack_object(s, root, ap); case '[': return unpack_array(s, root, ap); case 's': if(!json_is_string(root)) { set_error(s, "<validation>", "Expected string, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) { const char **str; str = va_arg(*ap, const char **); if(!str) { set_error(s, "<args>", "NULL string argument"); return -1; } *str = json_string_value(root); } return 0; case 'i': if(!json_is_integer(root)) { set_error(s, "<validation>", "Expected integer, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) *va_arg(*ap, int*) = (int) json_integer_value(root); return 0; case 'I': if(!json_is_integer(root)) { set_error(s, "<validation>", "Expected integer, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) *va_arg(*ap, json_int_t*) = json_integer_value(root); return 0; case 'b': if(!json_is_boolean(root)) { set_error(s, "<validation>", "Expected true or false, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) *va_arg(*ap, int*) = json_is_true(root); return 0; case 'f': if(!json_is_real(root)) { set_error(s, "<validation>", "Expected real, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) *va_arg(*ap, double*) = json_real_value(root); return 0; case 'F': if(!json_is_number(root)) { set_error(s, "<validation>", "Expected real or integer, got %s", type_name(root)); return -1; } if(!(s->flags & JSON_VALIDATE_ONLY)) *va_arg(*ap, double*) = json_number_value(root); return 0; case 'O': if(!(s->flags & JSON_VALIDATE_ONLY)) json_incref(root); /* Fall through */ case 'o': if(!(s->flags & JSON_VALIDATE_ONLY)) *va_arg(*ap, json_t**) = root; return 0; case 'n': /* Never assign, just validate */ if(!json_is_null(root)) { set_error(s, "<validation>", "Expected null, got %s", type_name(root)); return -1; } return 0; default: set_error(s, "<format>", "Unexpected format character '%c'", s->token); return -1; } }