summaryrefslogtreecommitdiff
path: root/json.h
diff options
context:
space:
mode:
Diffstat (limited to 'json.h')
-rw-r--r--json.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/json.h b/json.h
new file mode 100644
index 0000000..a767e35
--- /dev/null
+++ b/json.h
@@ -0,0 +1,166 @@
+/*
+ Copyright (C) 2010 Joseph A. Adams (joeyadams3.14159@gmail.com)
+ All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef JSON_H
+#define JSON_H
+
+#include "postgres.h"
+
+#include "access/heapam.h"
+#include "access/htup.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_type.h"
+#include "funcapi.h"
+#include "libpq/pqformat.h"
+#include "utils/builtins.h"
+#include "utils/lsyscache.h"
+#include "utils/syscache.h"
+#include "utils/typcache.h"
+
+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)
+
+/* Keep the order of these enum entries in sync with
+ * enum_type_names[] in json_ops.c . */
+typedef enum {
+ JSON_NULL,
+ JSON_STRING,
+ JSON_NUMBER,
+ JSON_BOOL,
+ JSON_OBJECT,
+ JSON_ARRAY,
+ JSON_TYPE_COUNT = JSON_ARRAY + 1,
+
+ JSON_INVALID
+} 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 {
+ /* JSON_BOOL */
+ bool v_bool;
+
+ /* JSON_STRING */
+ struct {
+ char *str;
+ size_t length;
+ } string;
+
+ /* JSON_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. */
+};
+
+
+bool json_validate(const char *str);
+bool json_validate_liberal(const char *str);
+json_node *json_decode(const char *str);
+json_node *json_decode_liberal(const char *str);
+char *json_encode(json_node *node);
+
+/* 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);
+
+/* 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);
+
+/* Free a JSON node (recursively). */
+void json_delete(json_node *node);
+
+/*
+ * Default: false
+ *
+ * If json_escape_unicode is set, json_encode will escape all Unicode
+ * characters, resulting in pure ASCII output.
+ */
+extern bool json_escape_unicode;
+
+/* Add child to parent, putting it at the end. */
+void json_append(json_node *parent, json_node *child);
+
+/* Remove node from its parent. */
+void json_remove(json_node *node);
+
+/* 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) {
+ return json_mknode(JSON_ARRAY);
+}
+static inline json_node *json_mkobject(void) {
+ return json_mknode(JSON_OBJECT);
+}
+
+/* Node value get/set functions. */
+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) {
+ Assert(node->type == JSON_BOOL);
+ node->v.v_bool = v_bool;
+}
+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);
+
+#endif
+