コード例 #1
0
static int test3(void)
{
	size_t i;
	int ret;
	char err[512] = { 0 };
	const char in_str[] = "{ \"a\": 1, \"b\": 2.500000, "
		"\"c\": \"hi there\", \"d\": { \"a\": 0 }, "
		"\"e\": false, \"f\": [ { \"a\": 1 }, "
		"{ \"a\": 2 } ], \"x\" : 5, \"y\" : 1.5 }";
	int expected_array_val[] = { 1, 2, 6 };
	struct json_object* jo = NULL;
	struct bob *my_bob = NULL;
	struct abbie* final_abbie;

	jo = parse_json_string(in_str, err, sizeof(err));
	if (err[0]) {
		fprintf(stderr, "parse_json_string error: %s\n", err);
		ret = EXIT_FAILURE;
		goto done;
	}
	my_bob = JORM_FROMJSON_bob(jo);
	if (!my_bob) {
		fprintf(stderr, "JORM_FROMJSON: OOM\n");
		ret = EXIT_FAILURE;
		goto done;
	}
	ret = 0;
	EXPECT_NONZERO(my_bob->a == 1);
	EXPECT_NONZERO(my_bob->b == 2.5);
	EXPECT_ZERO(my_bob->extra_data);
	final_abbie = JORM_ARRAY_APPEND_abbie(&my_bob->f);
	EXPECT_NOT_EQUAL(final_abbie, NULL);
	final_abbie->a = 6;
	for (i = 0; i < sizeof(expected_array_val) /
			sizeof(expected_array_val[0]); ++i) {
		EXPECT_EQUAL(my_bob->f[i]->a, expected_array_val[i]);
	}
	EXPECT_EQUAL(my_bob->g->x, 5);
	EXPECT_EQUAL(my_bob->g->y, 1.5);
done:
	if (jo) {
		json_object_put(jo);
		jo = NULL;
	}
	if (my_bob) {
		JORM_FREE_bob(my_bob);
		my_bob = NULL;
	}
	return ret;
}
コード例 #2
0
ファイル: json.cpp プロジェクト: gaoxiaojun/dync
// Allow object keys to be without quotation,
// but then restrict to ([a-zA-Z0-9_])+
bool JSON::parse_json_key() {
  const char* begin;
  JSON_VAL v;
  u_char c;

  mark_pos();
  c = peek();
  if (c == '"') {
    return parse_json_string(true);
  }

  begin = pos;
  c = peek();
  if (c == 0) {
    error(SYNTAX_ERROR, "Got EOS when expecting an object key.");
    return false;
  } else if (is_word(c) == false) {
    error(SYNTAX_ERROR, "Expected an object key, which can be a double-quoted (\") string or a simple string (only alphanumeric characters and underscore, separated by whitespace) that doesn't need to be quoted.");
    return false;
  }

  for (;;) {
    c = peek();
    // Allow the key to be delimited by control characters and the object key-value separator ':'
    if (c <= ' ' || c == ':') {
      break;
    } else if (is_word(c) == false) {
      error(SYNTAX_ERROR, "Object key need to be quoted, or consist entirely of alphanumeric characters and underscores.");
      return false;
    }
    next();
  }

  v.str.start = begin;
  v.str.length = pos - begin;
  return callback(JSON_KEY, &v, level);
}
コード例 #3
0
ファイル: json.cpp プロジェクト: gaoxiaojun/dync
bool JSON::parse_json_value() {
  int c;

  c = skip_to_token();
  if (c == -1) {
    return false;
  }

  // Must start with object or array
  if (level == 0) {

    switch (c) {
    case '{':
      if (parse_json_object() == false) {
        return false;
      }
      c = skip_to_token();
      if (c > 0) {
        mark_pos();
        error(SYNTAX_ERROR, "Only one top level object/array is allowed.");
        return false;
      } else if (c < 0) {
        return false;
      }
      return true;

    case '[':
      if (parse_json_array() == false) {
        return false;
      }
      c = skip_to_token();
      if (c > 0) {
        mark_pos();
        error(SYNTAX_ERROR, "Only one top level object/array is allowed.");
        return false;
      } else if (c < 0) {
        return false;
      }
      return true;

    case 0:
      error(SYNTAX_ERROR, "EOS was encountered before any json declarations");
      return false;

    default:
      error(SYNTAX_ERROR, "Json must start with an object or an array.");
      return false;
    }
  } else { // level > 0
    switch (c) {
    case '{':
      return parse_json_object();

    case '[':
      return parse_json_array();

    case '"':
      return parse_json_string();

    case '-': case '0':
    case '1': case '2': case '3':
    case '4': case '5': case '6':
    case '7': case '8': case '9':
      return parse_json_number();

    case 't':
      return parse_json_symbol("true", JSON_TRUE);

    case 'f':
      return parse_json_symbol("false", JSON_FALSE);

    case 'n':
      return parse_json_symbol("null", JSON_NULL);

    case 0:
      error(SYNTAX_ERROR, "EOS was encountered when expecting a json value.");
      return false;

    default:
      error(SYNTAX_ERROR, "Could not parse as a json value (did you forget to quote your strings?).");
      return false;
    }
  }
}
コード例 #4
0
ファイル: json.c プロジェクト: AmesianX/wine
/* ECMA-262 5.1 Edition    15.12.1.2 */
static HRESULT parse_json_value(json_parse_ctx_t *ctx, jsval_t *r)
{
    HRESULT hres;

    switch(skip_spaces(ctx)) {

    /* JSONNullLiteral */
    case 'n':
        if(!is_keyword(ctx, nullW))
            break;
        *r = jsval_null();
        return S_OK;

    /* JSONBooleanLiteral */
    case 't':
        if(!is_keyword(ctx, trueW))
            break;
        *r = jsval_bool(TRUE);
        return S_OK;
    case 'f':
        if(!is_keyword(ctx, falseW))
            break;
        *r = jsval_bool(FALSE);
        return S_OK;

    /* JSONObject */
    case '{': {
        WCHAR *prop_name;
        jsdisp_t *obj;
        jsval_t val;

        hres = create_object(ctx->ctx, NULL, &obj);
        if(FAILED(hres))
            return hres;

        ctx->ptr++;
        if(skip_spaces(ctx) == '}') {
            ctx->ptr++;
            *r = jsval_obj(obj);
            return S_OK;
        }

        while(1) {
            if(*ctx->ptr != '"')
                break;
            hres = parse_json_string(ctx, &prop_name);
            if(FAILED(hres))
                break;

            if(skip_spaces(ctx) != ':') {
                FIXME("missing ':'\n");
                heap_free(prop_name);
                break;
            }

            ctx->ptr++;
            hres = parse_json_value(ctx, &val);
            if(SUCCEEDED(hres)) {
                hres = jsdisp_propput_name(obj, prop_name, val);
                jsval_release(val);
            }
            heap_free(prop_name);
            if(FAILED(hres))
                break;

            if(skip_spaces(ctx) == '}') {
                ctx->ptr++;
                *r = jsval_obj(obj);
                return S_OK;
            }

            if(*ctx->ptr++ != ',') {
                FIXME("expected ','\n");
                break;
            }
            skip_spaces(ctx);
        }

        jsdisp_release(obj);
        break;
    }

    /* JSONString */
    case '"': {
        WCHAR *string;
        jsstr_t *str;

        hres = parse_json_string(ctx, &string);
        if(FAILED(hres))
            return hres;

        /* FIXME: avoid reallocation */
        str = jsstr_alloc(string);
        heap_free(string);
        if(!str)
            return E_OUTOFMEMORY;

        *r = jsval_string(str);
        return S_OK;
    }

    /* JSONArray */
    case '[': {
        jsdisp_t *array;
        unsigned i = 0;
        jsval_t val;

        hres = create_array(ctx->ctx, 0, &array);
        if(FAILED(hres))
            return hres;

        ctx->ptr++;
        if(skip_spaces(ctx) == ']') {
            ctx->ptr++;
            *r = jsval_obj(array);
            return S_OK;
        }

        while(1) {
            hres = parse_json_value(ctx, &val);
            if(FAILED(hres))
                break;

            hres = jsdisp_propput_idx(array, i, val);
            jsval_release(val);
            if(FAILED(hres))
                break;

            if(skip_spaces(ctx) == ']') {
                ctx->ptr++;
                *r = jsval_obj(array);
                return S_OK;
            }

            if(*ctx->ptr != ',') {
                FIXME("expected ','\n");
                break;
            }

            ctx->ptr++;
            i++;
        }

        jsdisp_release(array);
        break;
    }

    /* JSONNumber */
    default: {
        int sign = 1;
        double n;

        if(*ctx->ptr == '-') {
            sign = -1;
            ctx->ptr++;
            skip_spaces(ctx);
        }

        if(!isdigitW(*ctx->ptr))
            break;

        if(*ctx->ptr == '0') {
            ctx->ptr++;
            n = 0;
            if(is_identifier_char(*ctx->ptr))
                break;
        }else {
            hres = parse_decimal(&ctx->ptr, ctx->end, &n);
            if(FAILED(hres))
                return hres;
        }

        *r = jsval_number(sign*n);
        return S_OK;
    }
    }

    FIXME("Syntax error at %s\n", debugstr_w(ctx->ptr));
    return E_FAIL;
}
コード例 #5
0
static int test5(void)
{
	int ret;
	char acc[512] = { 0 }, err[512] = { 0 };
	struct json_object *jo = NULL;
	const char in_str[] = "{ \"a\": \"1\", \"b\": 2.500000, "
		"\"c\": 5.0, \"d\": { \"a\": false }, "
		"\"e\": false, \"f\": [ { \"a\": 1 }, "
		"{ \"a\": 2 } ], \"x\" : 5, \"y\" : 1 }";
	const char in_str2[] = "{ \"d\": false, \"f\" : 1 }";
	const char in_str3[] = "{ \"f\" : [ { \"a\" : 2.5 }, 1 ] }";
	jo = parse_json_string(in_str, err, sizeof(err));
	if (err[0]) {
		fprintf(stderr, "parse_json_string error: %s\n", err);
		ret = EXIT_FAILURE;
		goto done;
	}
	JORM_TYCHECK_bob(jo, acc, sizeof(acc), err, sizeof(err));
	EXPECT_ZERO(strcmp(err, "WARNING: ignoring field \"a\" because "
		"it has type string, but it should have type int.\n"
		"WARNING: ignoring field \"c\" because it has type double, "
		"but it should have type string.\n"
		"WARNING: ignoring field \"d/a\" because it has type boolean, "
		"but it should have type int.\n"
		"WARNING: ignoring field \"y\" because it has type int, "
		"but it should have type double.\n"));

	acc[0] = '\0';
	err[0] = '\0';
	json_object_put(jo);
	jo = parse_json_string(in_str2, err, sizeof(err));
	if (err[0]) {
		fprintf(stderr, "parse_json_string2 error: %s\n", err);
		ret = EXIT_FAILURE;
		goto done;
	}
	JORM_TYCHECK_bob(jo, acc, sizeof(acc), err, sizeof(err));
	EXPECT_ZERO(strcmp(err, "WARNING: ignoring field \"d\" because "
		"it has type boolean, but it should have type object.\n"
		"WARNING: ignoring field \"f\" because it has type "
		"int, but it should have type array.\n"));

	acc[0] = '\0';
	err[0] = '\0';
	json_object_put(jo);
	jo = parse_json_string(in_str3, err, sizeof(err));
	if (err[0]) {
		fprintf(stderr, "parse_json_string3 error: %s\n", err);
		ret = EXIT_FAILURE;
		goto done;
	}
	JORM_TYCHECK_bob(jo, acc, sizeof(acc), err, sizeof(err));
	EXPECT_ZERO(strcmp(err, "WARNING: ignoring field \"f[0]/a\" because "
		"it has type double, but it should have type int.\n"
		"WARNING: ignoring field \"f[1]\" because "
		"it has type array, but it should have type int.\n"));

	ret = 0;
done:
	if (jo)
		json_object_put(jo);
	return 0;
}