]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Add json_tokener_get_error() and json_tokener_error_desc() to better encapsulate...
authorEric Haszlakiewicz <erh+git@nimenees.com>
Wed, 22 Feb 2012 14:24:40 +0000 (08:24 -0600)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Wed, 22 Feb 2012 14:24:40 +0000 (08:24 -0600)
Add documentation for the json_tokener_parse_ex() function.

json_tokener.c
json_tokener.h

index 1921de66abc85496aa46014f689b18badda3a3e0..6d973ecfd9d065b48d811d9fce504a4a149642e0 100644 (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)
index 162a152f07790d71cdaa24517d10357d1174f6f6..be7f87df39a22063a63f63cbf993b0b386950644 100644 (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);