[json-glib] Add JsonValue



commit 7bd24bd628df97d216436e03237fc27f85a6aa8b
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Sat Jun 30 13:22:47 2012 +0100

    Add JsonValue
    
    Given its ECMAScript inheritance, JSON allows only four types of values:
    
      - integer numbers
      - floating point numbers
      - booleans
      - strings
    
    We can efficiently represent a JSON value using a simple, reference
    counted structure, that behaves similarly to GValue but without the
    baggage of the whole type system.
    
    For the time being, we should keep the whole JsonValue internal: we
    already specify typed public accessors, so there's no need to complicate
    the API any further.

 json-glib/Makefile.am          |    5 +-
 json-glib/json-types-private.h |   78 ++++++++++++++-
 json-glib/json-value.c         |  216 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+), 3 deletions(-)
---
diff --git a/json-glib/Makefile.am b/json-glib/Makefile.am
index ee658ee..f2ee4ef 100644
--- a/json-glib/Makefile.am
+++ b/json-glib/Makefile.am
@@ -31,11 +31,11 @@ source_h = \
 	$(top_srcdir)/json-glib/json-builder.h		\
 	$(top_srcdir)/json-glib/json-generator.h 	\
 	$(top_srcdir)/json-glib/json-gobject.h 		\
+	$(top_srcdir)/json-glib/json-gvariant.h		\
 	$(top_srcdir)/json-glib/json-parser.h 		\
 	$(top_srcdir)/json-glib/json-path.h		\
 	$(top_srcdir)/json-glib/json-reader.h		\
 	$(top_srcdir)/json-glib/json-types.h 		\
-	$(top_srcdir)/json-glib/json-gvariant.h		\
 	$(NULL)
 
 source_h_private = \
@@ -52,6 +52,7 @@ source_c = \
 	$(srcdir)/json-gboxed.c		\
 	$(srcdir)/json-generator.c 	\
 	$(srcdir)/json-gobject.c 	\
+	$(srcdir)/json-gvariant.c	\
 	$(srcdir)/json-node.c 		\
 	$(srcdir)/json-object.c 	\
 	$(srcdir)/json-parser.c 	\
@@ -59,7 +60,7 @@ source_c = \
 	$(srcdir)/json-reader.c		\
 	$(srcdir)/json-scanner.c 	\
 	$(srcdir)/json-serializable.c	\
-	$(srcdir)/json-gvariant.c	\
+	$(srcdir)/json-value.c		\
 	$(NULL)
 
 # glib-mkenums rules
diff --git a/json-glib/json-types-private.h b/json-glib/json-types-private.h
index e7f73f2..8a572bc 100644
--- a/json-glib/json-types-private.h
+++ b/json-glib/json-types-private.h
@@ -28,6 +28,17 @@
 
 G_BEGIN_DECLS
 
+typedef struct _JsonValue JsonValue;
+
+typedef enum {
+  JSON_VALUE_INVALID = 0,
+  JSON_VALUE_INT,
+  JSON_VALUE_DOUBLE,
+  JSON_VALUE_BOOLEAN,
+  JSON_VALUE_STRING,
+  JSON_VALUE_NULL
+} JsonValueType;
+
 struct _JsonNode
 {
   /*< private >*/
@@ -42,6 +53,31 @@ struct _JsonNode
   JsonNode *parent;
 };
 
+#define JSON_VALUE_INIT                 { JSON_VALUE_INVALID, 1, { 0 } }
+#define JSON_VALUE_INIT_TYPE(t)         { (t), 1, { 0 } }
+#define JSON_VALUE_IS_VALID(v)          ((v) != NULL && (v)->type != JSON_VALUE_INVALID)
+#define JSON_VALUE_HOLDS(v,t)           ((v) != NULL && (v)->type == (t))
+#define JSON_VALUE_HOLDS_INT(v)         (JSON_VALUE_HOLDS((v), JSON_VALUE_INT))
+#define JSON_VALUE_HOLDS_DOUBLE(v)      (JSON_VALUE_HOLDS((v), JSON_VALUE_DOUBLE))
+#define JSON_VALUE_HOLDS_BOOLEAN(v)     (JSON_VALUE_HOLDS((v), JSON_VALUE_BOOLEAN))
+#define JSON_VALUE_HOLDS_STRING(v)      (JSON_VALUE_HOLDS((v), JSON_VALUE_STRING))
+#define JSON_VALUE_HOLDS_NULL(v)        (JSON_VALUE_HOLDS((v), JSON_VALUE_NULL))
+#define JSON_VALUE_TYPE(v)              (json_value_type((v)))
+
+struct _JsonValue
+{
+  JsonValueType type;
+
+  volatile gint ref_count;
+
+  union {
+    gint64 v_int;
+    gdouble v_double;
+    gboolean v_bool;
+    gchar *v_str;
+  } data;
+};
+
 struct _JsonArray
 {
   GPtrArray *elements;
@@ -59,7 +95,47 @@ struct _JsonObject
   volatile gint ref_count;
 };
 
-const gchar *json_node_type_get_name (JsonNodeType node_type);
+G_GNUC_INTERNAL
+const gchar *   json_node_type_get_name         (JsonNodeType     node_type);
+G_GNUC_INTERNAL
+const gchar *   json_value_type_get_name        (JsonValueType    value_type);
+
+G_GNUC_INTERNAL
+GType           json_value_type                 (const JsonValue *value);
+
+G_GNUC_INTERNAL
+JsonValue *     json_value_alloc                (void);
+G_GNUC_INTERNAL
+JsonValue *     json_value_init                 (JsonValue       *value,
+                                                 JsonValueType    value_type);
+G_GNUC_INTERNAL
+JsonValue *     json_value_ref                  (JsonValue       *value);
+G_GNUC_INTERNAL
+void            json_value_unref                (JsonValue       *value);
+G_GNUC_INTERNAL
+void            json_value_unset                (JsonValue       *value);
+G_GNUC_INTERNAL
+void            json_value_free                 (JsonValue       *value);
+G_GNUC_INTERNAL
+void            json_value_set_int              (JsonValue       *value,
+                                                 gint64           v_int);
+G_GNUC_INTERNAL
+gint64          json_value_get_int              (const JsonValue *value);
+G_GNUC_INTERNAL
+void            json_value_set_double           (JsonValue       *value,
+                                                 gdouble          v_double);
+G_GNUC_INTERNAL
+gdouble         json_value_get_double           (const JsonValue *value);
+G_GNUC_INTERNAL
+void            json_value_set_boolean          (JsonValue       *value,
+                                                 gboolean         v_bool);
+G_GNUC_INTERNAL
+gboolean        json_value_get_boolean          (const JsonValue *value);
+G_GNUC_INTERNAL
+void            json_value_set_string           (JsonValue       *value,
+                                                 const gchar     *v_str);
+G_GNUC_INTERNAL
+const gchar *   json_value_get_string           (const JsonValue *value);
 
 G_END_DECLS
 
diff --git a/json-glib/json-value.c b/json-glib/json-value.c
new file mode 100644
index 0000000..7e9babd
--- /dev/null
+++ b/json-glib/json-value.c
@@ -0,0 +1,216 @@
+/* json-value.c - JSON value container
+ * 
+ * This file is part of JSON-GLib
+ * Copyright (C) 2012  Emmanuele Bassi <ebassi gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Emmanuele Bassi  <ebassi linux intel com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+
+#include "json-types-private.h"
+
+const gchar *
+json_value_type_get_name (JsonValueType value_type)
+{
+  switch (value_type)
+    {
+    case JSON_VALUE_INVALID:
+      return "Unset";
+
+    case JSON_VALUE_INT:
+      return "Integer";
+
+    case JSON_VALUE_DOUBLE:
+      return "Floating Point";
+
+    case JSON_VALUE_BOOLEAN:
+      return "Boolean";
+
+    case JSON_VALUE_STRING:
+      return "String";
+
+    case JSON_VALUE_NULL:
+      return "Null";
+    }
+
+  return "Undefined";
+}
+
+GType
+json_value_type (const JsonValue *value)
+{
+  switch (value->type)
+    {
+    case JSON_VALUE_INVALID:
+      return G_TYPE_INVALID;
+
+    case JSON_VALUE_INT:
+      return G_TYPE_INT64;
+
+    case JSON_VALUE_DOUBLE:
+      return G_TYPE_DOUBLE;
+
+    case JSON_VALUE_BOOLEAN:
+      return G_TYPE_BOOLEAN;
+
+    case JSON_VALUE_STRING:
+      return G_TYPE_STRING;
+
+    case JSON_VALUE_NULL:
+      return G_TYPE_INVALID;
+    }
+
+  return G_TYPE_INVALID;
+}
+
+JsonValue *
+json_value_alloc (void)
+{
+  JsonValue *res = g_slice_new0 (JsonValue);
+
+  res->ref_count = 1;
+
+  return res;
+}
+
+JsonValue *
+json_value_init (JsonValue     *value,
+                 JsonValueType  value_type)
+{
+  g_return_val_if_fail (value != NULL, NULL);
+
+  if (value->type != JSON_VALUE_INVALID)
+    json_value_unset (value);
+
+  value->type = value_type;
+
+  return value;
+}
+
+JsonValue *
+json_value_ref (JsonValue *value)
+{
+  g_return_val_if_fail (value != NULL, NULL);
+
+  g_atomic_int_add (&value->ref_count, 1);
+
+  return value;
+}
+
+void
+json_value_unref (JsonValue *value)
+{
+  g_return_if_fail (value != NULL);
+
+  if (g_atomic_int_dec_and_test (&value->ref_count))
+    json_value_free (value);
+}
+
+void
+json_value_unset (JsonValue *value)
+{
+  g_return_if_fail (value != NULL);
+
+  switch (value->type)
+    {
+    case JSON_VALUE_INVALID:
+      break;
+
+    case JSON_VALUE_INT:
+      value->data.v_int = 0;
+      break;
+
+    case JSON_VALUE_DOUBLE:
+      value->data.v_double = 0.0;
+      break;
+
+    case JSON_VALUE_BOOLEAN:
+      value->data.v_bool = FALSE;
+      break;
+
+    case JSON_VALUE_STRING:
+      g_free (value->data.v_str);
+      value->data.v_str = NULL;
+      break;
+
+    case JSON_VALUE_NULL:
+      break;
+    }
+}
+
+void
+json_value_free (JsonValue *value)
+{
+  if (G_LIKELY (value != NULL))
+    {
+      json_value_unset (value);
+      g_slice_free (JsonValue, value);
+    }
+}
+
+#define _JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \
+void \
+json_value_set_##Type (JsonValue *value, CType VField) \
+{ \
+  g_return_if_fail (JSON_VALUE_IS_VALID (value)); \
+  g_return_if_fail (JSON_VALUE_HOLDS (value, JSON_VALUE_##EType)); \
+\
+  value->data.VField = VField; \
+\
+}
+
+#define _JSON_VALUE_DEFINE_GET(Type,EType,CType,VField) \
+CType \
+json_value_get_##Type (const JsonValue *value) \
+{ \
+  g_return_val_if_fail (JSON_VALUE_IS_VALID (value), 0); \
+  g_return_val_if_fail (JSON_VALUE_HOLDS (value, JSON_VALUE_##EType), 0); \
+\
+  return value->data.VField; \
+}
+
+#define _JSON_VALUE_DEFINE_SET_GET(Type,EType,CType,VField) \
+_JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \
+_JSON_VALUE_DEFINE_GET(Type,EType,CType,VField)
+
+_JSON_VALUE_DEFINE_SET_GET(int, INT, gint64, v_int)
+
+_JSON_VALUE_DEFINE_SET_GET(double, DOUBLE, gdouble, v_double)
+
+_JSON_VALUE_DEFINE_SET_GET(boolean, BOOLEAN, gboolean, v_bool)
+
+void
+json_value_set_string (JsonValue *value,
+                       const gchar *v_str)
+{
+  g_return_if_fail (JSON_VALUE_IS_VALID (value));
+  g_return_if_fail (JSON_VALUE_HOLDS_STRING (value));
+
+  g_free (value->data.v_str);
+  value->data.v_str = g_strdup (v_str);
+}
+
+_JSON_VALUE_DEFINE_GET(string, STRING, const gchar *, v_str)
+
+#undef _JSON_VALUE_DEFINE_SET_GET
+#undef _JSON_VALUE_DEFINE_GET
+#undef _JSON_VALUE_DEFINE_SET



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]