diff options
Diffstat (limited to 'json.h')
| -rw-r--r-- | json.h | 169 |
1 files changed, 96 insertions, 73 deletions
@@ -42,12 +42,13 @@ typedef struct varlena jsontype; #define DatumGetJSONP(X) ((jsontype *) PG_DETOAST_DATUM(X)) #define JSONPGetDatum(X) PointerGetDatum(X) -#define PG_GETARG_JSON_P(n) DatumGetJSONP(PG_GETARG_DATUM(n)) -#define PG_RETURN_JSON_P(x) PG_RETURN_POINTER(x) +#define PG_GETARG_JSON_P(n) DatumGetJSONP(PG_GETARG_DATUM(n)) +#define PG_RETURN_JSON_P(x) PG_RETURN_POINTER(x) /* Keep the order of these enum entries in sync with * enum_type_names[] in json_ops.c . */ -typedef enum { +typedef enum +{ JSON_NULL, JSON_STRING, JSON_NUMBER, @@ -55,82 +56,95 @@ typedef enum { JSON_OBJECT, JSON_ARRAY, JSON_TYPE_COUNT = JSON_ARRAY + 1, - + JSON_INVALID -} json_type; +} json_type; #define json_type_is_valid(type) ((type) >= 0 && (type) < JSON_TYPE_COUNT) typedef struct json_node json_node; -struct json_node { - json_type type; - - union { +struct json_node +{ + json_type type; + + union + { /* JSON_BOOL */ - bool v_bool; - + bool v_bool; + /* JSON_STRING */ - struct { - char *str; - size_t length; - } string; - + struct + { + char *str; + size_t length; + } string; + /* JSON_NUMBER */ - char *number; - + char *number; + /* JSON_ARRAY or JSON_OBJECT (children) */ - struct { - json_node *head, *tail; - size_t count; - } children; - } v; - - json_node *parent; - json_node *prev, *next; - - char *key; - size_t key_length; - /* If node is a member of an object, key will be set. - Otherwise, key will be null. */ - - struct json_node_orig { + struct + { + json_node *head; + json_node *tail; + size_t count; + } children; + } v; + + json_node *parent; + json_node *prev; + json_node *next; + + /* + * If node is a member of an object, key will be set. Otherwise, key will + * be null. + */ + char *key; + size_t key_length; + + struct json_node_orig + { /* These only apply if this node is a member of an object. */ - struct { - const char *start, *end; - } key_left_space, key, key_right_space; - - struct { - const char *start, *end; - } left_space, value, right_space; - } orig; + struct + { + const char *start; + const char *end; + } key_left_space, key, key_right_space; + + struct + { + const char *start; + const char *end; + } left_space, value, right_space; + } orig; /* Used by jp_set to indicate we should not visit this node again. */ - bool jp_changed; + bool jp_changed; }; -bool json_validate(const char *str); -bool json_validate_liberal(const char *str); -json_node *json_decode(const char *str); +bool json_validate(const char *str); +bool json_validate_liberal(const char *str); +json_node *json_decode(const char *str); #define JSONOPT_USE_ORIG 1 #define JSONOPT_ESCAPE_UNICODE 2 #define JSONOPT_NO_TRIM 4 -char *json_encode(json_node *node, int options); +char *json_encode(json_node * node, int options); /* Determines the type of a JSON string without fully decoding it. * Expects the given string to be valid JSON string. * Might return JSON_INVALID if something is wrong with the input. */ -json_type json_text_type(const char *str, size_t nbytes); +json_type json_text_type(const char *str, size_t nbytes); -/* Filter almost-JSON text to try to make it JSON. On failure, +/* Filter almost-JSON text to try to make it JSON. On failure, * returns NULL. On success, the text may or may not be valid JSON; * you still have to run it through json_validate or json_decode * to see. * * Free the result with free() when you're done with it. */ -char *json_cleanup(const char *str); +char *json_cleanup(const char *str); /* * Free a JSON node and all its descendants. @@ -139,14 +153,16 @@ char *json_cleanup(const char *str); * a descendant, as this function relies on each node's ->parent field * being trustworthy. */ -void json_delete(json_node *node); +void json_delete(json_node * node); #define json_foreach(child, parent) \ for ((child) = json_head(parent); (child) != NULL; (child) = (child)->next) -static inline json_node *json_head(json_node *parent) +static inline json_node * +json_head(json_node * parent) { - switch (parent->type) { + switch (parent->type) + { case JSON_ARRAY: case JSON_OBJECT: return parent->v.children.head; @@ -158,7 +174,7 @@ static inline json_node *json_head(json_node *parent) /* * Decodes a JSON-encoded string literal - * (If you're interested in the decoding JSON in general, see json_decode). + * (If you're interested in the decoding JSON in general, see json_decode). * If strict is true, string must be double-quoted, * as is required by the JSON RFC. * Otherwise, the string may be single- or double-quoted. @@ -169,64 +185,71 @@ static inline json_node *json_head(json_node *parent) * through *length (which must not be NULL). On failure (parse error), * returns NULL and leaves *length untouched. */ -char *json_decode_string(const char **sp, size_t *length, bool strict); +char *json_decode_string(const char **sp, size_t *length, bool strict); /* * Encodes a string literal JSON-style using the given quote character, * only escaping characters when necessary - * (If you're interested in encoding JSON in general, see json_encode). + * (If you're interested in encoding JSON in general, see json_encode). * Note that using anything but '"' as the quote character will result in * invalid JSON. * * Returns NULL if input is invalid UTF-8 or if an invalid quote character * (such as backslash) is given. */ -char *json_encode_string(const char *str, size_t length, char quote, bool escape_unicode); +char *json_encode_string(const char *str, size_t length, char quote, bool escape_unicode); /* Add child to parent, putting it at the end. */ -void json_append(json_node *parent, json_node *child); +void json_append(json_node * parent, json_node * child); /* Remove node from its parent. */ -void json_remove(json_node *node); +void json_remove(json_node * node); /* Update the value of a node, preserving position and key information. */ -void json_replace_value(json_node *node, json_node *replacement); +void json_replace_value(json_node * node, json_node * replacement); /* Note that the factory functions and get/set functions do not validate input. * However, json_encode validates node contents to avoid producing * invalid JSON. */ /* Node factory functions */ -json_node *json_mknode(json_type type); -json_node *json_mkbool(bool v_bool); -json_node *json_mkstring(const char *str, size_t length); -json_node *json_mknumber(const char *number, size_t length); -static inline json_node *json_mkarray(void) { +json_node *json_mknode(json_type type); +json_node *json_mkbool(bool v_bool); +json_node *json_mkstring(const char *str, size_t length); +json_node *json_mknumber(const char *number, size_t length); +static inline json_node * +json_mkarray(void) +{ return json_mknode(JSON_ARRAY); } -static inline json_node *json_mkobject(void) { +static inline json_node * +json_mkobject(void) +{ return json_mknode(JSON_OBJECT); } -void json_touch_value(json_node *node); +void json_touch_value(json_node * node); /* Node value get/set functions. */ -static inline bool json_get_bool(json_node *node) { +static inline bool +json_get_bool(json_node * node) +{ Assert(node->type == JSON_BOOL); return node->v.v_bool; } -static inline void json_set_bool(json_node *node, bool v_bool) { +static inline void +json_set_bool(json_node * node, bool v_bool) +{ Assert(node->type == JSON_BOOL); node->v.v_bool = v_bool; json_touch_value(node); } -const char *json_get_string(json_node *node, size_t *length_out); -void json_set_string(json_node *node, const char *str, size_t length); -const char *json_get_number(json_node *node); -void json_set_number(json_node *node, const char *number, size_t length); +const char *json_get_string(json_node * node, size_t *length_out); +void json_set_string(json_node * node, const char *str, size_t length); +const char *json_get_number(json_node * node); +void json_set_number(json_node * node, const char *number, size_t length); /* Utility function used by json_get to automatically apply from_json to its result. */ const char *from_json_cstring(const char *input, const char *funcname); #endif - |
