Browse Source

Add json_tokener_get_error() and json_tokener_error_desc() to better encapsulate the process of retrieving errors while parsing.

Add documentation for the json_tokener_parse_ex() function.
tags/json-c-0.10-20120530
Eric Haszlakiewicz 13 years ago
parent
commit
2f9091f559
2 changed files with 102 additions and 0 deletions
  1. +13
    -0
      json_tokener.c
  2. +89
    -0
      json_tokener.h

+ 13
- 0
json_tokener.c View File

@@ -43,6 +43,7 @@ static const char* json_null_str = "null";
static const char* json_true_str = "true";
static const char* json_false_str = "false";

// XXX after v0.10 this array will become static:
const char* json_tokener_errors[] = {
"success",
"continue",
@@ -60,6 +61,18 @@ const char* json_tokener_errors[] = {
"expected comment",
};

const char *json_tokener_error_desc(enum json_tokener_error jerr)
{
if (jerr < 0 || jerr > sizeof(json_tokener_errors))
return "Unknown error, invalid json_tokener_error value passed to json_tokener_error_desc()";
return json_tokener_errors[jerr];
}

enum json_tokener_error json_tokener_get_error(json_tokener *tok)
{
return tok->err;
}

/* Stuff for decoding unicode sequences */
#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00)


+ 89
- 0
json_tokener.h View File

@@ -82,13 +82,102 @@ struct json_tokener
struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH];
};

/**
* Given an error previously returned by json_tokener_get_error(),
* return a human readable description of the error.
*
* @return a generic error message is returned if an invalid error value is provided.
*/
const char *json_tokeners_errors(enum json_tokener_error jerr);

/**
* @b XXX do not use json_tokener_errors directly.
* After v0.10 this will be removed.
*
* See json_tokeners_errors() instead.
*/
extern const char* json_tokener_errors[];

/**
* Retrieve the error caused by the last call to json_tokener_parse_ex(),
* or json_tokener_success if there is no error.
*
* When parsing a JSON string in pieces, if the tokener is in the middle
* of parsing this will return json_tokener_continue.
*
* See also json_tokener_error_desc().
*/
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);

extern struct json_tokener* json_tokener_new(void);
extern void json_tokener_free(struct json_tokener *tok);
extern void json_tokener_reset(struct json_tokener *tok);
extern struct json_object* json_tokener_parse(const char *str);
extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);

/**
* Parse a string and return a non-NULL json_object if a valid JSON value
* is found. The string does not need to be a JSON object or array;
* it can also be a string, number or boolean value.
*
* A partial JSON string can be parsed. If the parsing is incomplete,
* NULL will be returned and json_tokener_get_error() will be return
* json_tokener_continue.
* json_tokener_parse_ex() can then be called with additional bytes in str
* to continue the parsing.
*
* If json_tokener_parse_ex() returns NULL and the error anything other than
* json_tokener_continue, a fatal error has occurred and parsing must be
* halted. Then tok object must not be re-used until json_tokener_reset() is
* called.
*
* When a valid JSON value is parsed, a non-NULL json_object will be
* returned. Also, json_tokener_get_error() will return json_tokener_success.
* Be sure to check the type with json_object_is_type() or
* json_object_get_type() before using the object.
*
* @b XXX this shouldn't use internal fields:
* Trailing characters after the parsed value do not automatically cause an
* error. It is up to the caller to decide whether to treat this as an
* error or to handle the additional characters, perhaps by parsing another
* json value starting from that point.
*
* Extra characters can be detected by comparing the tok->char_offset against
* the length of the last len parameter passed in.
*
* The tokener does \b not maintain an internal buffer so the caller is
* responsible for calling json_tokener_parse_ex with an appropriate str
* parameter starting with the extra characters.
*
* Example:
* @code
json_object *jobj = NULL;
const char *mystring = NULL;
int stringlen = 0;
enum json_tokener_error jerr;
do {
mystring = ... // get JSON string, e.g. read from file, etc...
stringlen = strlen(mystring);
jobj = json_tokener_parse_ex(tok, mystring, stringlen);
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
if (jerr != json_tokener_success)
{
fprintf(stderr, "Error: %s\n", json_tokener_errors[jerr]);
// Handle errors, as appropriate for your application.
}
if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
{
// Handle extra characters after parsed object as desired.
// e.g. issue an error, parse another object from that point, etc...
}
// Success, use jobj here.

@endcode
*
* @param tok a json_tokener previously allocated with json_tokener_new()
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
* @param len the length of str
*/
extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
const char *str, int len);



Loading…
Cancel
Save