static int parse_item(heim_array_t array, struct parse_ctx *ctx) { heim_object_t value; if (white_spaces(ctx)) return -1; if (*ctx->p == ']') { ctx->p++; /* safe because parse_value() calls white_spaces() first */ return 0; } value = parse_value(ctx); if (value == NULL && (ctx->error || (ctx->flags & HEIM_JSON_F_NO_C_NULL))) return -1; heim_array_append_value(array, value); heim_release(value); if (white_spaces(ctx)) return -1; if (*ctx->p == ']') { ctx->p++; return 0; } else if (*ctx->p == ',') { ctx->p++; return 1; } return -1; }
static int parse_item(heim_array_t array, struct parse_ctx *ctx) { heim_object_t value; if (white_spaces(ctx)) return -1; if (*ctx->p == ']') return 0; value = parse_value(ctx); if (value == NULL) return -1; heim_array_append_value(array, value); heim_release(value); if (white_spaces(ctx)) return -1; if (*ctx->p == ']') { ctx->p++; return 0; } else if (*ctx->p == ',') { ctx->p++; return 1; } return -1; }
static int parse_pair(heim_dict_t dict, struct parse_ctx *ctx) { heim_string_t key; heim_object_t value; if (white_spaces(ctx)) return -1; if (*ctx->p == '}') return 0; key = parse_string(ctx); if (key == NULL) return -1; if (white_spaces(ctx)) return -1; if (*ctx->p != ':') { heim_release(key); return -1; } ctx->p += 1; if (white_spaces(ctx)) { heim_release(key); return -1; } value = parse_value(ctx); if (value == NULL) { heim_release(key); return -1; } heim_dict_set_value(dict, key, value); heim_release(key); heim_release(value); if (white_spaces(ctx)) return -1; if (*ctx->p == '}') { ctx->p++; return 0; } else if (*ctx->p == ',') { ctx->p++; return 1; } return -1; }
static heim_object_t parse_value(struct parse_ctx *ctx) { size_t len; heim_object_t o; if (white_spaces(ctx)) return NULL; if (*ctx->p == '"') { return parse_string(ctx); } else if (*ctx->p == '{') { if (ctx->depth-- == 1) { ctx->error = heim_error_create(EINVAL, "JSON object too deep"); return NULL; } o = parse_dict(ctx); ctx->depth++; return o; } else if (*ctx->p == '[') { if (ctx->depth-- == 1) { ctx->error = heim_error_create(EINVAL, "JSON object too deep"); return NULL; } o = parse_array(ctx); ctx->depth++; return o; } else if (is_number(*ctx->p) || *ctx->p == '-') { return parse_number(ctx); } len = ctx->pend - ctx->p; if ((ctx->flags & HEIM_JSON_F_NO_C_NULL) == 0 && len >= 6 && memcmp(ctx->p, "<NULL>", 6) == 0) { ctx->p += 6; return heim_null_create(); } else if (len >= 4 && memcmp(ctx->p, "null", 4) == 0) { ctx->p += 4; return heim_null_create(); } else if (len >= 4 && strncasecmp((char *)ctx->p, "true", 4) == 0) { ctx->p += 4; return heim_bool_create(1); } else if (len >= 5 && strncasecmp((char *)ctx->p, "false", 5) == 0) { ctx->p += 5; return heim_bool_create(0); } ctx->error = heim_error_create(EINVAL, "unknown char %c at %lu line %lu", (char)*ctx->p, (unsigned long)(ctx->p - ctx->pstart), ctx->lineno); return NULL; }
static heim_object_t parse_value(struct parse_ctx *ctx) { size_t len; if (white_spaces(ctx)) return NULL; if (*ctx->p == '"') { return parse_string(ctx); } else if (*ctx->p == '{') { return parse_dict(ctx); } else if (*ctx->p == '[') { return parse_array(ctx); } else if (is_number(*ctx->p) || *ctx->p == '-') { return parse_number(ctx); } len = ctx->pend - ctx->p; if (len >= 4 && memcmp(ctx->p, "null", 4) == 0) { ctx->p += 4; return heim_null_create(); } else if (len >= 4 && strncasecmp((char *)ctx->p, "true", 4) == 0) { ctx->p += 4; return heim_bool_create(1); } else if (len >= 5 && strncasecmp((char *)ctx->p, "false", 5) == 0) { ctx->p += 5; return heim_bool_create(0); } ctx->error = heim_error_create(EINVAL, "unknown char %c at %lu line %lu", (char)*ctx->p, (unsigned long)(ctx->p - ctx->pstart), ctx->lineno); return NULL; }
static int parse_pair(heim_dict_t dict, struct parse_ctx *ctx) { heim_string_t key; heim_object_t value; if (white_spaces(ctx)) return -1; if (*ctx->p == '}') { ctx->p++; return 0; } if (ctx->flags & HEIM_JSON_F_STRICT_DICT) /* JSON allows only string keys */ key = parse_string(ctx); else /* heim_dict_t allows any heim_object_t as key */ key = parse_value(ctx); if (key == NULL) /* Even heim_dict_t does not allow C NULLs as keys though! */ return -1; if (white_spaces(ctx)) { heim_release(key); return -1; } if (*ctx->p != ':') { heim_release(key); return -1; } ctx->p += 1; /* safe because we call white_spaces() next */ if (white_spaces(ctx)) { heim_release(key); return -1; } value = parse_value(ctx); if (value == NULL && (ctx->error != NULL || (ctx->flags & HEIM_JSON_F_NO_C_NULL))) { if (ctx->error == NULL) ctx->error = heim_error_create(EINVAL, "Invalid JSON encoding"); heim_release(key); return -1; } heim_dict_set_value(dict, key, value); heim_release(key); heim_release(value); if (white_spaces(ctx)) return -1; if (*ctx->p == '}') { /* * Return 1 but don't consume the '}' so we can count the one * pair in a one-pair dict */ return 1; } else if (*ctx->p == ',') { ctx->p++; return 1; } return -1; }