[gjs/cairo] [gi] Add arg overrides



commit 3eeb98da29d2a0a7586b1f69a3a8abe7c37177ab
Author: Johan Dahlin <johan gnome org>
Date:   Thu Feb 18 00:21:42 2010 -0200

    [gi] Add arg overrides
    
    Adds arg overrides, which is a way to specificy that certain gi types
    should use custom create/get and release functions. This is useful
    to be able to integrate types from third-party libraries.

 Makefile-gi.am |    2 +
 gi/arg.c       |   12 ++++-
 gi/override.c  |  164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gi/override.h  |   55 +++++++++++++++++++
 4 files changed, 232 insertions(+), 1 deletions(-)
---
diff --git a/Makefile-gi.am b/Makefile-gi.am
index 108069c..5aad834 100644
--- a/Makefile-gi.am
+++ b/Makefile-gi.am
@@ -20,6 +20,7 @@ nobase_gjsgiinclude_HEADERS =	\
 	gi/keep-alive.h	\
 	gi/ns.h	        \
 	gi/object.h	\
+	gi/override.h	\
 	gi/param.h	\
 	gi/repo.h	\
 	gi/union.h	\
@@ -34,6 +35,7 @@ libgjs_gi_la_SOURCES =	\
 	gi/keep-alive.c	\
 	gi/ns.c	\
 	gi/object.c	\
+	gi/override.c	\
 	gi/param.c	\
         gi/repo.c	\
 	gi/union.c	\
diff --git a/gi/arg.c b/gi/arg.c
index 7772392..626f04e 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -25,6 +25,7 @@
 
 #include "arg.h"
 #include "object.h"
+#include "override.h"
 #include "boxed.h"
 #include "union.h"
 #include "value.h"
@@ -594,6 +595,9 @@ gjs_value_to_g_argument(JSContext      *context,
                       "Converting jsval to GArgument %s",
                       g_type_tag_to_string(type_tag));
 
+    if (gjs_arg_override_convert_to_g_argument(context, type_info, value, arg))
+        return JS_TRUE;
+
     nullable_type = FALSE;
     wrong = FALSE; /* return JS_FALSE */
     out_of_range = FALSE;
@@ -1300,6 +1304,9 @@ gjs_value_from_g_argument (JSContext  *context,
 
     *value_p = JSVAL_NULL;
 
+    if (gjs_arg_override_convert_from_g_argument(context, type_info, value_p, arg))
+        return JS_TRUE;
+
     switch (type_tag) {
     case GI_TYPE_TAG_VOID:
         *value_p = JSVAL_VOID; /* or JSVAL_NULL ? */
@@ -1637,11 +1644,14 @@ gjs_g_arg_release_internal(JSContext  *context,
                            GArgument  *arg)
 {
     JSBool failed;
-    
+
     g_assert(transfer != GI_TRANSFER_NOTHING);
 
     failed = JS_FALSE;
 
+    if (gjs_arg_override_release_g_argument(context, type_info, arg))
+        return JS_TRUE;
+
     switch (type_tag) {
     case GI_TYPE_TAG_VOID:
     case GI_TYPE_TAG_BOOLEAN:
diff --git a/gi/override.c b/gi/override.c
new file mode 100644
index 0000000..653e9dd
--- /dev/null
+++ b/gi/override.c
@@ -0,0 +1,164 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2010  litl, LLC
+ *
+ * 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.
+ */
+
+#include <config.h>
+
+#include <gjs/gjs.h>
+#include <girepository.h>
+
+#include "arg.h"
+#include "override.h"
+
+static GHashTable *arg_overrides_table = NULL;
+
+typedef struct {
+    char *namespace;
+    char *type_name;
+    GjsArgOverrideToGArgumentFunc to_func;
+    GjsArgOverrideFromGArgumentFunc from_func;
+} GjsArgOverride;
+
+
+static void
+gjs_arg_override_value_free(GjsArgOverride *override)
+{
+    g_free(override->namespace);
+    g_free(override->type_name);
+    g_slice_free(GjsArgOverride, override);
+}
+
+JSBool
+gjs_arg_override_register(const char *namespace,
+                          const char *type_name,
+                          GjsArgOverrideToGArgumentFunc to_func,
+                          GjsArgOverrideFromGArgumentFunc from_func)
+{
+    char *canonical_name;
+    GjsArgOverride *override;
+
+    g_return_val_if_fail(to_func != NULL, JS_FALSE);
+    g_return_val_if_fail(from_func != NULL, JS_FALSE);
+
+    override = g_slice_new(GjsArgOverride);
+    override->namespace = g_strdup(namespace);
+    override->type_name = g_strdup(type_name);
+    override->to_func = to_func;
+    override->from_func = from_func;
+
+    canonical_name = g_strdup_printf("%s.%s", namespace, type_name);
+    if (!arg_overrides_table) {
+        arg_overrides_table = g_hash_table_new_full(
+            g_str_hash, g_str_equal,
+            (GDestroyNotify)g_free,
+            (GDestroyNotify)gjs_arg_override_value_free);
+    }
+    g_hash_table_insert(arg_overrides_table, canonical_name, override);
+    return JS_TRUE;
+}
+
+#include <string.h>
+
+static GjsArgOverride *
+gjs_arg_override_lookup(GITypeInfo *type_info)
+{
+    const char *type_name;
+    const char *namespace;
+    char *canonical;
+    GIBaseInfo *base_info;
+
+    base_info = g_type_info_get_interface(type_info);
+    if (!base_info)
+        return NULL;
+    namespace = g_base_info_get_namespace(base_info);
+    type_name = g_base_info_get_name(base_info);
+    g_base_info_unref(base_info);
+
+    /* silly optimiazation, since this is rather frequent */
+    canonical = g_alloca(sizeof(char) * strlen(namespace) + 1 + strlen(type_name) + 1);
+    g_memmove(canonical, namespace, strlen(namespace));
+    canonical[strlen(namespace)] = '.';
+    g_memmove(canonical+strlen(namespace)+1, type_name, strlen(type_name));
+    canonical[strlen(namespace)+1+strlen(type_name)] = '\0';
+
+    return (GjsArgOverride*)g_hash_table_lookup(arg_overrides_table, canonical);
+}
+
+JSBool
+gjs_arg_override_convert_to_g_argument(JSContext      *context,
+                                       GITypeInfo     *type_info,
+                                       jsval           value,
+                                       GArgument      *arg)
+{
+    GjsArgOverride *override;
+
+    if (!arg_overrides_table)
+        return JS_FALSE;
+
+    override = gjs_arg_override_lookup(type_info);
+    if (!override)
+        return JS_FALSE;
+
+    if (!override->to_func(context, value, arg))
+        return JS_FALSE;
+
+    return JS_TRUE;
+}
+
+JSBool
+gjs_arg_override_convert_from_g_argument(JSContext  *context,
+                                         GITypeInfo *type_info,
+                                         jsval      *value_p,
+                                         GArgument  *arg)
+{
+    GjsArgOverride *override;
+
+    if (!arg_overrides_table)
+        return JS_FALSE;
+
+    override = gjs_arg_override_lookup(type_info);
+    if (!override)
+        return JS_FALSE;
+
+    if (!override->from_func(context, value_p, arg))
+        return JS_FALSE;
+
+    return JS_TRUE;
+}
+
+JSBool
+gjs_arg_override_release_g_argument(JSContext  *context,
+                                    GITypeInfo *type_info,
+                                    GArgument  *arg)
+{
+    GjsArgOverride *override;
+
+    if (!arg_overrides_table)
+        return JS_FALSE;
+
+    override = gjs_arg_override_lookup(type_info);
+    if (!override)
+        return JS_FALSE;
+
+    return JS_TRUE;
+}
+
diff --git a/gi/override.h b/gi/override.h
new file mode 100644
index 0000000..bde92d2
--- /dev/null
+++ b/gi/override.h
@@ -0,0 +1,55 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2010  litl, LLC
+ *
+ * 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 __GJS_OVERRIDE_H__
+#define __GJS_OVERRIDE_H__
+
+#include <girepository.h>
+#include <gjs/gjs.h>
+
+typedef JSBool (*GjsArgOverrideToGArgumentFunc) (JSContext      *context,
+                                                jsval           value,
+                                                GArgument      *arg);
+
+typedef JSBool (*GjsArgOverrideFromGArgumentFunc) (JSContext  *context,
+                                                   jsval      *value_p,
+                                                   GArgument  *arg);
+
+JSBool gjs_arg_override_register(const char                     *namespace,
+                                 const char                     *type_name,
+                                 GjsArgOverrideToGArgumentFunc   to_func,
+                                 GjsArgOverrideFromGArgumentFunc from_func);
+
+JSBool gjs_arg_override_convert_to_g_argument  (JSContext  *context,
+                                                GITypeInfo *type_info,
+                                                jsval       value,
+                                                GArgument  *arg);
+JSBool gjs_arg_override_convert_from_g_argument(JSContext  *context,
+                                                GITypeInfo *type_info,
+                                                jsval      *value_p,
+                                                GArgument  *arg);
+JSBool gjs_arg_override_release_g_argument(JSContext  *context,
+                                           GITypeInfo *type_info,
+                                           GArgument  *arg);
+
+#endif /* __GJS_OVERRIDE_H__ */



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