diff options
| author | Joey Adams | 2010-08-06 08:06:01 +0000 |
|---|---|---|
| committer | Joey Adams | 2010-08-06 08:06:01 +0000 |
| commit | f9f677a465a5746874dc2f2c86cc444ffa28a020 (patch) | |
| tree | daae58795aaf5c7facc04fa5939a8a5e25884aac /json.c | |
| parent | e87340e2b0c533d1c1d08ddee6471757bc27b74f (diff) | |
Added more comments to json.c / json.h and cleaned it up a bit.
Also made json_delete a little less confusing (but it still uses gotos).
Diffstat (limited to 'json.c')
| -rw-r--r-- | json.c | 93 |
1 files changed, 72 insertions, 21 deletions
@@ -51,7 +51,7 @@ end_parenthesis(JSON * node) /* * Reads exactly 4 hex characters (capital or lowercase). * Writes the result to *out . - * Returns true on success, false on failure. + * Returns true on success, false if any input chars are not [0-9A-Fa-f] . */ static bool read_hex16(const char *in, unsigned int *out) @@ -81,6 +81,10 @@ read_hex16(const char *in, unsigned int *out) return true; } +/* + * Encodes a 16-bit number into hexadecimal, + * writing exactly 4 hex chars. + */ static void write_hex16(char *out, unsigned int val) { @@ -137,7 +141,8 @@ json_mknumber(const char *number, size_t length) return node; } -/* Indicate that the node's value has changed, +/* + * Indicate that the node's value has changed, * marking ancestors as necessary. * * Call json_touch_value so that json_encode(, JSONOPT_ORIG) @@ -153,6 +158,12 @@ json_touch_value(JSON * node) } } +/* + * Add child to parent, but don't clear orig pointers of ancestors. + * + * This is used by json_decode to ensure that original text segments + * are preserved while building the JSON tree. + */ static void json_append_notouch(JSON * parent, JSON * child) { @@ -175,6 +186,12 @@ json_append_notouch(JSON * parent, JSON * child) } } +/* + * json_append + * Add child to parent, putting it at the end of its child list. + * + * Child must not already have another parent. + */ void json_append(JSON * parent, JSON * child) { @@ -182,6 +199,10 @@ json_append(JSON * parent, JSON * child) json_touch_value(parent); } +/* + * json_remove + * Remove node from its parent, but do not delete it. + */ void json_remove(JSON * node) { @@ -209,6 +230,16 @@ json_remove(JSON * node) json_touch_value(parent); } +/* + * Update the value of a node, preserving position and key information. + * + * Note well: If replacement is an array or object with children, the parent + * pointers of those children will be incorrect + * (they'll still refer to their original parent). + * + * Untrustworthy parent pointers is the price to pay for + * being able to copy JSON values by reference. + */ void json_replace_value(JSON * node, JSON * replacement) { @@ -289,7 +320,14 @@ free_node(JSON * node) pfree(node); } -void +/* + * Free a JSON node and all its descendants. + * + * Do not use this function if you have performed json_replace_value on + * a descendant, as this function relies on each node's ->parent field + * being trustworthy. + */ +static void json_delete(JSON * node) { JSON *parent, @@ -301,12 +339,9 @@ json_delete(JSON * node) /* Remove node from parent (if it has one). */ json_remove(node); - goto descend; - descend: while (is_internal(node) && node->v.children.head) node = node->v.children.head; - goto advance; advance: parent = node->parent; @@ -315,16 +350,17 @@ advance: node = next; if (node) + { goto descend; + } else - goto ascend; - -ascend: - node = parent; - if (node) - goto advance; - else - return; + { + node = parent; + if (node) + goto advance; + else + return; + } } @@ -701,9 +737,9 @@ decode_number(const char **sp) * Also, no whitespace skipping is done, so the caller should only * call this function when it expects **sp to be either " or ' * - * On success, returns the decoded string, passes that string's length - * through *length (which must not be NULL), and advances *sp to point - * to the end of string literal (including the quote character). + * On success, returns the decoded string, passes the decoded string's + * length through *length (which must not be NULL), and advances *sp to point + * to the end of string literal (after the closing quote character). * * On failure (parse error), returns NULL and * leaves *length and *sp untouched. @@ -825,6 +861,12 @@ failed: return NULL; } +/* + * json_text_type + * Determines the type of a JSON string without fully decoding it. + * Expects the given string to be valid JSON. + * Might return JSON_INVALID if something is wrong with the input. + */ json_type json_text_type(const char *str, size_t nbytes) { @@ -871,8 +913,9 @@ encode_string(StringInfo out, const char *string, size_t length, char quote, const char *s = string; const char *e = s + length; - Assert(utf8_validate(string, length)); Assert(quote != '\\'); + if (escape_unicode) + Assert(utf8_validate(string, length)); appendStringInfoChar(out, quote); @@ -990,6 +1033,13 @@ typedef struct static bool json_encode_recurse(JSON * node, json_encode_ctx * ctx); +/* + * json_encode + * Encode a JSON node. + * + * The JSONOPT_ESCAPE_UNICODE option may only be used + * if the strings in the JSON tree are UTF-8-encoded. + */ char * json_encode(JSON * node, int options) { @@ -1127,9 +1177,10 @@ json_encode_recurse(JSON * node, json_encode_ctx * ctx) * Note that using anything but '"' as the quote character will result * in invalid JSON. * - * @str must be valid UTF-8, though it may contain null characters - * (hence the length argument). - * @quote must not be a backslash. + * If escape_unicode is true, str must be valid UTF-8. + * In any case, str may contain null characters (hence the length argument). + * + * quote must not be a backslash. */ char * json_encode_string(const char *str, size_t length, char quote, |
