]> mj.ucw.cz Git - libucw.git/blobdiff - ucw-json/json.h
Released as 6.5.16.
[libucw.git] / ucw-json / json.h
index 74620498387ba588bf822ce80bc1badda066fe5c..369598b705f9ab255eaeed90c2c715aa8103559c 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef _UCW_JSON_JSON_H
 #define _UCW_JSON_JSON_H
 
-#include <ucw/clists.h>
-#include <ucw/slists.h>
 #include <ucw/mempool.h>
 #include <ucw/fastbuf.h>
 
 #define json_new ucw_json_new
 #define json_new_array ucw_json_new_array
 #define json_new_node ucw_json_new_node
+#define json_new_number ucw_json_new_number
 #define json_new_object ucw_json_new_object
 #define json_next_token ucw_json_next_token
 #define json_next_value ucw_json_next_value
+#define json_number_to_int ucw_json_number_to_int
+#define json_number_to_s64 ucw_json_number_to_s64
+#define json_number_to_u64 ucw_json_number_to_u64
+#define json_number_to_uint ucw_json_number_to_uint
 #define json_object_get ucw_json_object_get
 #define json_object_set ucw_json_object_set
 #define json_parse ucw_json_parse
@@ -101,6 +104,17 @@ void json_reset(struct json_context *js);
  **/
 void json_push(struct json_context *js);
 
+/**
+ * Create a copy of a string in JSON memory.
+ *
+ * For example, this is useful when you want to use a string of unknown
+ * lifetime as a key in json_object_set().
+ **/
+static inline const char *json_strdup(struct json_context *js, const char *str)
+{
+  return mp_strdup(js->pool, str);
+}
+
 /**
  * Pop state of the context off state stack. All JSON values created
  * since the state was saved by json_push() are released.
@@ -167,28 +181,47 @@ struct json_pair {
 struct json_node *json_new_node(struct json_context *js, enum json_node_type type);
 
 /** Creates a new null value. **/
-static inline struct json_node *json_new_null(struct json_context *js)
+static inline struct json_node *json_new_null(struct json_context *js UNUSED)
 {
-  return json_new_node(js, JSON_NULL);
+  static const struct json_node static_null = { .type = JSON_NULL };
+  return (struct json_node *) &static_null;
 }
 
 /** Creates a new boolean value. **/
-static inline struct json_node *json_new_bool(struct json_context *js, bool value)
+static inline struct json_node *json_new_bool(struct json_context *js UNUSED, bool value)
 {
-  struct json_node *n = json_new_node(js, JSON_BOOLEAN);
-  n->boolean = value;
-  return n;
+  static const struct json_node static_bool[2] = {
+    [0] = { .type = JSON_BOOLEAN, { .boolean = 0 } },
+    [1] = { .type = JSON_BOOLEAN, { .boolean = 1 } },
+  };
+  return (struct json_node *) &static_bool[value];
 }
 
-/** Creates a new numeric value. **/
-static inline struct json_node *json_new_number(struct json_context *js, double value)
-{
-  struct json_node *n = json_new_node(js, JSON_NUMBER);
-  n->number = value;
-  return n;
-}
+/** Creates a new numeric value. The @value must be a finite number. **/
+struct json_node *json_new_number(struct json_context *js, double value);
 
-/** Creates a new string value. The @value is kept only as a reference. **/
+/**
+ * Convert a numeric value to an `int`. Returns false if the value
+ * is not numeric or if it is too large for an int.
+ **/
+bool json_number_to_int(struct json_node *num, int *dest);
+
+/** Same as above, but for `uint`. **/
+bool json_number_to_uint(struct json_node *num, uint *dest);
+
+/** Same as above, but for `s64`. **/
+bool json_number_to_s64(struct json_node *num, s64 *dest);
+
+/** Same as above, but for `u64`. **/
+bool json_number_to_u64(struct json_node *num, u64 *dest);
+
+/**
+ * Creates a new string value. The @value is kept only as a reference.
+ *
+ * String values can contain an arbitrary UTF-8 string with no null
+ * characters. However, it is not recommended to use UTF-8 values outside
+ * the range of UniCode codepoints (0 to 0x10ffff).
+ **/
 static inline struct json_node *json_new_string_ref(struct json_context *js, const char *value)
 {
   struct json_node *n = json_new_node(js, JSON_STRING);
@@ -217,9 +250,7 @@ struct json_node *json_new_object(struct json_context *js);
  * and a pre-existing pair is deleted.
  *
  * The @key is referenced by the object, you must not free it during
- * the lifetime of the JSON context.
- *
- * FIXME: Add json_copy_key().
+ * the lifetime of the object. When in doubt, use json_strdup().
  **/
 void json_object_set(struct json_node *n, const char *key, struct json_node *value);
 
@@ -236,6 +267,10 @@ struct json_node *json_object_get(struct json_node *n, const char *key);
  * and then repeat json_next_token(). If you are parsing huge JSON files,
  * you probably want to do json_push() first, then scan and process some
  * tokens, and then json_pop().
+ *
+ * All parsing functions throw LibUCW exceptions of class `ucw.json.parse`
+ * upon errors. If you want to catch them, call the parser inside
+ * a transaction.
  ***/
 
 /** Parses a JSON file from the given fastbuf stream. **/