gstreamer_core/gst/gstinterface.c
changeset 0 0e761a78d257
child 7 567bb019e3e3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gstreamer_core/gst/gstinterface.c	Thu Dec 17 08:53:32 2009 +0200
@@ -0,0 +1,209 @@
+/* GStreamer
+ *
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstinterface.c: Interface functions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gstimplementsinterface
+ * @short_description: Core interface implemented by #GstElement instances that
+ * allows runtime querying of interface availabillity
+ * @see_also: #GstElement
+ *
+ * Provides interface functionality on per instance basis and not per class
+ * basis, which is the case for gobject.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gst_private.h"
+#include "gstinterface.h"
+
+static void
+gst_implements_interface_class_init (GstImplementsInterfaceClass * ifklass);
+static gboolean
+gst_implements_interface_supported_default (GstImplementsInterface * iface,
+    GType iface_type);
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+
+GType
+gst_implements_interface_get_type (void)
+{
+  static GType gst_interface_type = 0;
+
+  if (!gst_interface_type) {
+    static const GTypeInfo gst_interface_info = {
+      sizeof (GstImplementsInterfaceClass),
+      (GBaseInitFunc) gst_implements_interface_class_init,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      0,
+      0,
+      NULL,
+      NULL
+    };
+
+    gst_interface_type = g_type_register_static (G_TYPE_INTERFACE,
+        "GstImplementsInterface", &gst_interface_info, 0);
+
+    g_type_interface_add_prerequisite (gst_interface_type, GST_TYPE_ELEMENT);
+  }
+
+  return gst_interface_type;
+}
+
+static void
+gst_implements_interface_class_init (GstImplementsInterfaceClass * klass)
+{
+  klass->supported = gst_implements_interface_supported_default;
+}
+
+static gboolean
+gst_implements_interface_supported_default (GstImplementsInterface * interface,
+    GType iface_type)
+{
+  /* Well, if someone didn't set the virtual function,
+   * then something is clearly wrong. So big no-no here */
+
+  return FALSE;
+}
+
+/**
+ * gst_element_implements_interface:
+ * @element: #GstElement to check for the implementation of the interface
+ * @iface_type: (final) type of the interface which we want to be implemented
+ *
+ * Test whether the given element implements a certain interface of type
+ * iface_type, and test whether it is supported for this specific instance.
+ *
+ * Returns: whether or not the element implements the interface.
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+
+gboolean
+gst_element_implements_interface (GstElement * element, GType iface_type)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
+
+  if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (element), iface_type)) {
+    GstImplementsInterface *iface;
+    GstImplementsInterfaceClass *ifclass;
+
+    iface = G_TYPE_CHECK_INSTANCE_CAST (G_OBJECT (element),
+        iface_type, GstImplementsInterface);
+    ifclass = GST_IMPLEMENTS_INTERFACE_GET_CLASS (iface);
+
+    /* element implements iface_type but not GstImplementsInterface, so
+     * just assume the other interface is implemented unconditionally */
+    if (ifclass == NULL)
+      return TRUE;
+
+    if (ifclass->supported != NULL &&
+        ifclass->supported (iface, iface_type) == TRUE) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * gst_implements_interface_cast:
+ * @from: the object (any sort) from which to cast to the interface
+ * @type: the interface type to cast to
+ *
+ * cast a given object to an interface type, and check whether this
+ * interface is supported for this specific instance.
+ *
+ * Returns: a gpointer to the interface type
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+
+gpointer
+gst_implements_interface_cast (gpointer from, GType iface_type)
+{
+  GstImplementsInterface *iface;
+
+  /* check cast, give warning+fail if it's invalid */
+  if (!(iface = G_TYPE_CHECK_INSTANCE_CAST (from, iface_type,
+              GstImplementsInterface))) {
+    return NULL;
+  }
+
+  /* if we're an element, take care that this interface
+   * is actually implemented */
+  if (GST_IS_ELEMENT (from)) {
+    g_return_val_if_fail (gst_element_implements_interface (GST_ELEMENT (from),
+            iface_type), NULL);
+  }
+
+  return iface;
+}
+
+/**
+ * gst_implements_interface_check:
+ * @from: the object (any sort) from which to check from for the interface
+ * @type: the interface type to check for
+ *
+ * check a given object for an interface implementation, and check
+ * whether this interface is supported for this specific instance.
+ *
+ * Returns: whether or not the object implements the given interface
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+
+gboolean
+gst_implements_interface_check (gpointer from, GType type)
+{
+  GstImplementsInterface *iface;
+
+  /* check cast, return FALSE if it fails, don't give a warning... */
+  if (!G_TYPE_CHECK_INSTANCE_TYPE (from, type)) {
+    return FALSE;
+  }
+
+  iface = G_TYPE_CHECK_INSTANCE_CAST (from, type, GstImplementsInterface);
+
+  /* now, if we're an element (or derivative), is this thing
+   * actually implemented for real? */
+  if (GST_IS_ELEMENT (from)) {
+    if (!gst_element_implements_interface (GST_ELEMENT (from), type)) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}