From: David Schleef Date: Thu, 15 Sep 2005 03:20:49 +0000 (+0000) Subject: configure.ac: Remove gst/registries, since it's no longer used. X-Git-Tag: RELEASE-0_9_3~147 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9a150e83f8434c5bd51a6170e24ff5caea35f5b;p=platform%2Fupstream%2Fgstreamer.git configure.ac: Remove gst/registries, since it's no longer used. Original commit message from CVS: * configure.ac: Remove gst/registries, since it's no longer used. * gst/registries/Makefile.am: * gst/registries/gstlibxmlregistry.c: * gst/registries/gstlibxmlregistry.h: * gst/registries/gstxmlregistry.c: * gst/registries/gstxmlregistry.h: * gst/registries/registrytest.c: --- diff --git a/ChangeLog b/ChangeLog index 2e70713..d6bc6ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2005-09-14 David Schleef + * configure.ac: Remove gst/registries, since it's no longer used. + * gst/registries/Makefile.am: + * gst/registries/gstlibxmlregistry.c: + * gst/registries/gstlibxmlregistry.h: + * gst/registries/gstxmlregistry.c: + * gst/registries/gstxmlregistry.h: + * gst/registries/registrytest.c: + +2005-09-14 David Schleef + * gst/glib-compat.h: * gst/gstregistryxml.c: Convergence is near. Seriously. diff --git a/configure.ac b/configure.ac index d09df60..174ef61 100644 --- a/configure.ac +++ b/configure.ac @@ -639,7 +639,6 @@ gst/check/Makefile gst/indexers/Makefile gst/elements/Makefile gst/parse/Makefile -gst/registries/Makefile libs/Makefile libs/gst/Makefile libs/gst/controller/Makefile diff --git a/gst/registries/Makefile.am b/gst/registries/Makefile.am deleted file mode 100644 index a015dcf..0000000 --- a/gst/registries/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -noinst_LTLIBRARIES = libgstxmlregistry.la - -if GST_DISABLE_LOADSAVE -xmlregistry_sources = gstxmlregistry.c -else -xmlregistry_sources = gstlibxmlregistry.c -endif - -libgstxmlregistry_la_SOURCES = $(xmlregistry_sources) - -libgstxmlregistry_la_CFLAGS = $(GST_LIB_CFLAGS) -libgstxmlregistry_la_LIBADD = $(GST_LIB_LIBS) - -noinst_HEADERS = gstxmlregistry.h gstlibxmlregistry.h -check_PROGRAMS = registrytest - -registrytest_SOURCES = registrytest.c -registrytest_CFLAGS = $(GST_OBJ_CFLAGS) -registrytest_LDADD = $(GST_OBJ_LIBS) libgstxmlregistry.la diff --git a/gst/registries/gstlibxmlregistry.c b/gst/registries/gstlibxmlregistry.c deleted file mode 100644 index 3f57f9d..0000000 --- a/gst/registries/gstlibxmlregistry.c +++ /dev/null @@ -1,1315 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstxml_registry.c: GstXMLRegistry object, support routines - * - * This library is free software; you can redistribute it and/or - * modify it ulnder 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#ifdef _MSC_VER -#include -#include -#ifndef F_OK -#define F_OK 0 -#define W_OK 2 -#define R_OK 4 -#endif -#ifndef S_ISREG -#define S_ISREG(mode) ((mode)&_S_IFREG) -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) ((mode)&_S_IFDIR) -#endif -#else /* _MSC_VER */ -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "gstlibxmlregistry.h" -#include - -#define BLOCK_SIZE 1024*10 - -#define CLASS(registry) GST_XML_REGISTRY_CLASS (G_OBJECT_GET_CLASS (registry)) - - -enum -{ - PROP_0, - PROP_LOCATION -}; - - -static void gst_xml_registry_class_init (GstXMLRegistryClass * klass); -static void gst_xml_registry_init (GstXMLRegistry * registry); - -static void gst_xml_registry_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_xml_registry_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static gboolean gst_xml_registry_load (GstRegistry * registry); -static gboolean gst_xml_registry_save (GstRegistry * registry); -static gboolean gst_xml_registry_rebuild (GstRegistry * registry); - -static void gst_xml_registry_get_perms_func (GstXMLRegistry * registry); -static gboolean gst_xml_registry_open_func (GstXMLRegistry * registry, - GstXMLRegistryMode mode); -static gboolean gst_xml_registry_load_func (GstXMLRegistry * registry, - gchar * data, gssize * size); -static gboolean gst_xml_registry_save_func (GstXMLRegistry * registry, - gchar * format, ...); -static gboolean gst_xml_registry_close_func (GstXMLRegistry * registry); - -static GstRegistryReturn gst_xml_registry_load_plugin (GstRegistry * registry, - GstPlugin * plugin); - -static GstRegistryClass *parent_class = NULL; - -/* static guint gst_xml_registry_signals[LAST_SIGNAL] = { 0 }; */ - - -GType -gst_xml_registry_get_type (void) -{ - static GType xml_registry_type = 0; - - if (!xml_registry_type) { - static const GTypeInfo xml_registry_info = { - sizeof (GstXMLRegistryClass), - NULL, - NULL, - (GClassInitFunc) gst_xml_registry_class_init, - NULL, - NULL, - sizeof (GstXMLRegistry), - 0, - (GInstanceInitFunc) gst_xml_registry_init, - NULL - }; - - xml_registry_type = g_type_register_static (GST_TYPE_REGISTRY, - "GstXMLRegistry", &xml_registry_info, 0); - } - return xml_registry_type; -} - -static void -gst_xml_registry_class_init (GstXMLRegistryClass * klass) -{ - GObjectClass *gobject_class; - GstRegistryClass *gstregistry_class; - GstXMLRegistryClass *gstxmlregistry_class; - - gobject_class = (GObjectClass *) klass; - gstregistry_class = (GstRegistryClass *) klass; - gstxmlregistry_class = (GstXMLRegistryClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_REGISTRY); - - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_xml_registry_get_property); - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_xml_registry_set_property); - - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LOCATION, - g_param_spec_string ("location", "Location", - "Location of the registry file", NULL, G_PARAM_READWRITE)); - - gstregistry_class->load = GST_DEBUG_FUNCPTR (gst_xml_registry_load); - gstregistry_class->save = GST_DEBUG_FUNCPTR (gst_xml_registry_save); - gstregistry_class->rebuild = GST_DEBUG_FUNCPTR (gst_xml_registry_rebuild); - - gstregistry_class->load_plugin = - GST_DEBUG_FUNCPTR (gst_xml_registry_load_plugin); - - gstxmlregistry_class->get_perms_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_get_perms_func); - gstxmlregistry_class->open_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_open_func); - gstxmlregistry_class->load_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_load_func); - gstxmlregistry_class->save_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_save_func); - gstxmlregistry_class->close_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_close_func); -} - -static void -gst_xml_registry_init (GstXMLRegistry * registry) -{ - registry->location = NULL; -} - -/** - * gst_xml_registry_new: - * @name: the name of the registry - * @location: the location of the registry file - * - * Create a new xml registry with the given name and location. - * - * Returns: a new GstXMLRegistry with the given name an location. - */ -GstRegistry * -gst_xml_registry_new (const gchar * name, const gchar * location) -{ - GstXMLRegistry *xmlregistry; - - xmlregistry = GST_XML_REGISTRY (g_object_new (GST_TYPE_XML_REGISTRY, NULL)); - - g_object_set (G_OBJECT (xmlregistry), "location", location, NULL); - - GST_REGISTRY (xmlregistry)->name = g_strdup (name); - - return GST_REGISTRY (xmlregistry); -} - -static void -gst_xml_registry_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstXMLRegistry *registry; - - registry = GST_XML_REGISTRY (object); - - switch (prop_id) { - case PROP_LOCATION: - if (registry->open) { - CLASS (object)->close_func (registry); - g_return_if_fail (registry->open == FALSE); - } - - if (registry->location) - g_free (registry->location); - - registry->location = g_strdup (g_value_get_string (value)); - GST_REGISTRY (registry)->flags = 0x0; - - if (CLASS (object)->get_perms_func) - CLASS (object)->get_perms_func (registry); - - /* FIXME? (can't enable, because it's called before initialization is done) */ - /* gst_xml_registry_load (GST_REGISTRY (registry)); */ - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_xml_registry_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstXMLRegistry *registry; - - registry = GST_XML_REGISTRY (object); - - switch (prop_id) { - case PROP_LOCATION: - g_value_set_string (value, registry->location); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* this function returns the biggest of the path's mtime and ctime - * mtime is updated through an actual write (data) - * ctime is updated through changing inode information - * so this function returns the last time *anything* changed to this path - * it also sets the given boolean to TRUE if the given path is a directory - */ -static time_t -get_time (const char *path, gboolean * is_dir) -{ - struct stat statbuf; - - if (stat (path, &statbuf)) { - *is_dir = FALSE; - return 0; - } - - if (is_dir) - *is_dir = S_ISDIR (statbuf.st_mode); - - if (statbuf.st_mtime > statbuf.st_ctime) - return statbuf.st_mtime; - return statbuf.st_ctime; -} - -#if defined(_MSC_VER) || defined(__MINGW32__) -#define xmkdir(dirname) _mkdir (dirname) -#else -#define xmkdir(dirname) mkdir (dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) -#endif - -static gboolean -make_dir (gchar * filename) -{ - struct stat dirstat; - gchar *dirname; - - if (strrchr (filename, '/') == NULL) - return FALSE; - - dirname = g_strndup (filename, strrchr (filename, '/') - filename); - - if (stat (dirname, &dirstat) == -1 && errno == ENOENT) { - if (xmkdir (dirname) != 0) { - if (make_dir (dirname) != TRUE) { - g_free (dirname); - return FALSE; - } else { - if (xmkdir (dirname) != 0) { - return FALSE; - } - } - } - } - - g_free (dirname); - return TRUE; -} - -static void -gst_xml_registry_get_perms_func (GstXMLRegistry * registry) -{ - gchar *dirname; - - /* if the dir does not exist, make it. if that can't be done, flags = 0x0. - if the file can be appended to, it's writable. if it can then be read, - it's readable. - After that check if it exists. */ - - if (make_dir (registry->location) != TRUE) { - /* we can't do anything with it, leave flags as 0x0 */ - return; - } - - dirname = g_path_get_dirname (registry->location); - - if (g_file_test (registry->location, G_FILE_TEST_EXISTS)) { - GST_REGISTRY (registry)->flags |= GST_REGISTRY_EXISTS; - } - - if (!access (dirname, W_OK)) { - GST_REGISTRY (registry)->flags |= GST_REGISTRY_WRITABLE; - } - - if (!access (dirname, R_OK)) { - GST_REGISTRY (registry)->flags |= GST_REGISTRY_READABLE; - } - - g_free (dirname); -} - -/* return TRUE iff regtime is more recent than the times of all the .so files - * in the plugin dirs; ie return TRUE if this path does not need to trigger - * a rebuild of registry - * - * - if it's a directory, recurse on subdirs - * - if it's a file - * - if entry is not newer, return TRUE. - * - if it's newer - * - and it's a plugin, return FALSE - * - otherwise return TRUE - */ -static gboolean -plugin_times_older_than_recurse (gchar * path, time_t regtime) -{ - DIR *dir; - struct dirent *dirent; - gboolean is_dir; - gchar *new_path; - - time_t pathtime = get_time (path, &is_dir); - - if (is_dir) { - dir = opendir (path); - if (dir) { - while ((dirent = readdir (dir))) { - /* don't want to recurse in place or backwards */ - if (strcmp (dirent->d_name, ".") && strcmp (dirent->d_name, "..")) { - new_path = g_build_filename (path, dirent->d_name, NULL); - if (!plugin_times_older_than_recurse (new_path, regtime)) { - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, - "path %s is more recent than registry time of %ld", - new_path, (long) regtime); - g_free (new_path); - closedir (dir); - return FALSE; - } - g_free (new_path); - } - } - closedir (dir); - } - return TRUE; - } - - /* it's a file */ - if (pathtime <= regtime) { - return TRUE; - } - - /* it's a file, and it's more recent */ - if (g_str_has_suffix (path, ".so") || g_str_has_suffix (path, ".dll")) { - if (!gst_plugin_check_file (path, NULL)) - return TRUE; - - /* it's a newer GStreamer plugin */ - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, - "%s looks like a plugin and is more recent than registry time of %ld", - path, (long) regtime); - return FALSE; - } - return TRUE; -} - -/* return TRUE iff regtime is more recent than the times of all the .so files - * in the plugin dirs; ie return TRUE if registry is up to date. - */ -static gboolean -plugin_times_older_than (GList * paths, time_t regtime) -{ - while (paths) { - GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, - "comparing plugin times from %s with %ld", - (gchar *) paths->data, (long) regtime); - if (!plugin_times_older_than_recurse (paths->data, regtime)) - return FALSE; - paths = g_list_next (paths); - } - GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, - "everything's fine, no registry rebuild needed."); - return TRUE; -} - -static gboolean -gst_xml_registry_open_func (GstXMLRegistry * registry, GstXMLRegistryMode mode) -{ - GstRegistry *gst_registry; - GList *paths; - - gst_registry = GST_REGISTRY (registry); - paths = gst_registry->paths; - GST_CAT_DEBUG (GST_CAT_GST_INIT, "opening registry %s", registry->location); - - g_return_val_if_fail (registry->open == FALSE, FALSE); - - /* if it doesn't exist, first try to build it, and check if it worked - * if it's not readable, return false - * if it's out of date, rebuild it */ - if (mode == GST_XML_REGISTRY_READ) { - if (!(gst_registry->flags & GST_REGISTRY_EXISTS)) { - /* if it's not writable, then don't bother */ - if (!(gst_registry->flags & GST_REGISTRY_WRITABLE)) { - GST_CAT_INFO (GST_CAT_GST_INIT, "Registry isn't writable"); - return FALSE; - } - GST_CAT_INFO (GST_CAT_GST_INIT, - "Registry doesn't exist, trying to build..."); - gst_registry_rebuild (gst_registry); - gst_registry_save (gst_registry); - /* FIXME: verify that the flags actually get updated ! */ - if (!(gst_registry->flags & GST_REGISTRY_EXISTS)) { - return FALSE; - } - } - /* at this point we know it exists */ - g_return_val_if_fail (gst_registry->flags & GST_REGISTRY_READABLE, FALSE); - - if (!plugin_times_older_than (paths, get_time (registry->location, NULL))) { - if (gst_registry->flags & GST_REGISTRY_WRITABLE) { - GST_CAT_INFO (GST_CAT_GST_INIT, "Registry out of date, rebuilding..."); - - gst_registry_rebuild (gst_registry); - - gst_registry_save (gst_registry); - - if (!plugin_times_older_than (paths, get_time (registry->location, - NULL))) { - GST_CAT_INFO (GST_CAT_GST_INIT, - "Registry still out of date, something is wrong..."); - return FALSE; - } - } else { - GST_CAT_INFO (GST_CAT_GST_INIT, - "Can't write to this registry and it's out of date, ignoring it"); - return FALSE; - } - } - - GST_CAT_DEBUG (GST_CAT_GST_INIT, "opening registry %s for reading", - registry->location); - registry->regfile = fopen (registry->location, "r"); - } else if (mode == GST_XML_REGISTRY_WRITE) { - char *tmploc; - int fd; - - g_return_val_if_fail (gst_registry->flags & GST_REGISTRY_WRITABLE, FALSE); - - tmploc = g_strconcat (registry->location, ".tmp", NULL); - - GST_CAT_DEBUG (GST_CAT_GST_INIT, "opening registry %s for writing", tmploc); - - if ((fd = open (tmploc, O_WRONLY | O_CREAT, 0644)) < 0) { - g_free (tmploc); - return FALSE; - } - g_free (tmploc); - - registry->regfile = fdopen (fd, "w"); - } - - if (!registry->regfile) - return FALSE; - - registry->open = TRUE; - - return TRUE; -} - -static gboolean -gst_xml_registry_load_func (GstXMLRegistry * registry, gchar * data, - gssize * size) -{ - *size = fread (data, 1, *size, registry->regfile); - - return TRUE; -} - -static gboolean -gst_xml_registry_save_func (GstXMLRegistry * registry, gchar * format, ...) -{ - va_list var_args; - - va_start (var_args, format); - - vfprintf (registry->regfile, format, var_args); - - va_end (var_args); - - return TRUE; -} - -static gboolean -gst_xml_registry_close_func (GstXMLRegistry * registry) -{ - char *tmploc; - - GST_CAT_DEBUG (GST_CAT_GST_INIT, "closing registry %s", registry->location); - fclose (registry->regfile); - - /* If we opened for writing, rename our temporary file. */ - tmploc = g_strconcat (registry->location, ".tmp", NULL); - if (g_file_test (tmploc, G_FILE_TEST_EXISTS)) { -#ifdef WIN32 - remove (registry->location); -#endif - rename (tmploc, registry->location); - } - g_free (tmploc); - - registry->open = FALSE; - - return TRUE; -} - -/* takes ownership of given value */ -static void -add_to_char_array (gchar *** array, gchar * value) -{ - gchar **new; - gchar **old = *array; - gint i = 0; - - /* expensive, but cycles are cheap... */ - if (old) - while (old[i]) - i++; - new = g_new0 (gchar *, i + 2); - new[i] = value; - while (i > 0) { - i--; - new[i] = old[i]; - } - g_free (old); - *array = new; -} - -/* read a string and store the result in *write_to. - * return whether or not *write_to was set to a newly allocated string - * FIXME: return values aren't actually checked, and in those failure cases - * (that currently aren't triggered) cleanup is not done correctly - */ -static gboolean -read_string (xmlTextReaderPtr reader, gchar ** write_to) -{ - int depth = xmlTextReaderDepth (reader); - gboolean found = FALSE; - - if (*write_to) - return FALSE; - while (xmlTextReaderRead (reader) == 1) { - if (xmlTextReaderDepth (reader) == depth) - return found; - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_TEXT) { - if (found) { - return FALSE; - } - *write_to = g_strdup ((gchar *) xmlTextReaderConstValue (reader)); - found = TRUE; - } - } - - return FALSE; -} - -static gboolean -read_uint (xmlTextReaderPtr reader, guint * write_to) -{ - int depth = xmlTextReaderDepth (reader); - gboolean found = FALSE; - - if (*write_to) - return FALSE; - while (xmlTextReaderRead (reader) == 1) { - if (xmlTextReaderDepth (reader) == depth) - return found; - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_TEXT) { - gchar *ret; - - if (found) - return FALSE; - *write_to = strtol ((char *) xmlTextReaderConstValue (reader), &ret, 0); - if (ret != NULL) - return FALSE; - found = TRUE; - } - } - return FALSE; -} - -static gboolean -read_enum (xmlTextReaderPtr reader, GType enum_type, guint * write_to) -{ - int depth = xmlTextReaderDepth (reader); - gboolean found = FALSE; - - if (*write_to) - return FALSE; - while (xmlTextReaderRead (reader) == 1) { - if (xmlTextReaderDepth (reader) == depth) - return found; - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_TEXT) { - GEnumClass *enum_class; - GEnumValue *value; - - if (found) - return FALSE; - enum_class = g_type_class_ref (enum_type); - if (!enum_class) - return FALSE; - value = - g_enum_get_value_by_nick (enum_class, - (gchar *) xmlTextReaderConstValue (reader)); - if (value) { - *write_to = value->value; - found = TRUE; - } - g_type_class_unref (enum_class); - } - } - return FALSE; -} - -static GstStaticPadTemplate * -load_pad_template (xmlTextReaderPtr reader) -{ - int ret; - int depth = xmlTextReaderDepth (reader); - gchar *name = NULL, *caps_str = NULL; - guint direction = 0, presence = 0; - - while ((ret = xmlTextReaderRead (reader)) == 1) { - /* if we're back at our depth, we have all info, and can return - * the completely parsed template */ - if (xmlTextReaderDepth (reader) == depth) { - GstStaticPadTemplate *template; - - template = g_new0 (GstStaticPadTemplate, 1); - template->name_template = name; - template->presence = presence; - template->direction = direction; - template->static_caps.string = caps_str; - - return template; - } - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_ELEMENT && - xmlTextReaderDepth (reader) == depth + 1) { - const gchar *tag = (gchar *) xmlTextReaderConstName (reader); - - if (g_str_equal (tag, "nametemplate")) { - read_string (reader, &name); - } else if (g_str_equal (tag, "direction")) { - read_enum (reader, GST_TYPE_PAD_DIRECTION, &direction); - } else if (g_str_equal (tag, "presence")) { - read_enum (reader, GST_TYPE_PAD_PRESENCE, &presence); - } else if (!strncmp (tag, "caps", 4)) { - read_string (reader, &caps_str); - } - } - } - g_free (name); - g_free (caps_str); - - return NULL; -} - -static GstPluginFeature * -load_feature (xmlTextReaderPtr reader) -{ - int ret; - int depth = xmlTextReaderDepth (reader); - xmlChar *feature_name = - xmlTextReaderGetAttribute (reader, BAD_CAST "typename"); - GstPluginFeature *feature; - GType type; - - if (!feature_name) - return NULL; - type = g_type_from_name ((gchar *) feature_name); - xmlFree (feature_name); - if (!type) - return NULL; - feature = g_object_new (type, NULL); - if (!feature) - return NULL; - if (!GST_IS_PLUGIN_FEATURE (feature)) { - g_object_unref (feature); - return NULL; - } - while ((ret = xmlTextReaderRead (reader)) == 1) { - if (xmlTextReaderDepth (reader) == depth) - return feature; - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_ELEMENT && - xmlTextReaderDepth (reader) == depth + 1) { - const gchar *tag = (gchar *) xmlTextReaderConstName (reader); - - if (g_str_equal (tag, "name")) - read_string (reader, &feature->name); - if (g_str_equal (tag, "rank")) - read_uint (reader, &feature->rank); - if (GST_IS_ELEMENT_FACTORY (feature)) { - GstElementFactory *factory = GST_ELEMENT_FACTORY (feature); - - if (g_str_equal (tag, "longname")) { - read_string (reader, &factory->details.longname); - } else if (g_str_equal (tag, "class")) { - read_string (reader, &factory->details.klass); - } else if (g_str_equal (tag, "description")) { - read_string (reader, &factory->details.description); - } else if (g_str_equal (tag, "author")) { - read_string (reader, &factory->details.author); - } else if (g_str_equal (tag, "uri_type")) { - gchar *s = NULL; - - if (read_string (reader, &s)) { - if (g_ascii_strncasecmp (s, "sink", 4) == 0) { - factory->uri_type = GST_URI_SINK; - } else if (g_ascii_strncasecmp (s, "source", 5) == 0) { - factory->uri_type = GST_URI_SRC; - } - g_free (s); - } - } else if (g_str_equal (tag, "uri_protocol")) { - gchar *s = NULL; - - if (read_string (reader, &s)) { - add_to_char_array (&factory->uri_protocols, s); - } - } else if (g_str_equal (tag, "interface")) { - gchar *s = NULL; - - if (read_string (reader, &s)) { - __gst_element_factory_add_interface (factory, s); - g_free (s); - } - } else if (g_str_equal (tag, "padtemplate")) { - GstStaticPadTemplate *template = load_pad_template (reader); - - if (template) { - GST_LOG ("adding template %s to factory %s", - template->name_template, GST_PLUGIN_FEATURE_NAME (feature)); - __gst_element_factory_add_static_pad_template (factory, template); - } - } - } else if (GST_IS_TYPE_FIND_FACTORY (feature)) { - GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature); - - if (g_str_equal (tag, "extension")) { - gchar *s = NULL; - - if (read_string (reader, &s)) { - add_to_char_array (&factory->extensions, s); - } - } else if (g_str_equal (tag, "caps")) { - gchar *s = NULL; - - if (read_string (reader, &s)) { - factory->caps = gst_caps_from_string (s); - g_free (s); - } - } - } else if (GST_IS_INDEX_FACTORY (feature)) { - GstIndexFactory *factory = GST_INDEX_FACTORY (feature); - - if (g_str_equal (tag, "longdesc")) - read_string (reader, &factory->longdesc); - } - } - } - - return NULL; -} - -static GstPlugin * -load_plugin (xmlTextReaderPtr reader) -{ - int ret; - GstPlugin *plugin = g_new0 (GstPlugin, 1); - - while ((ret = xmlTextReaderRead (reader)) == 1) { - if (xmlTextReaderDepth (reader) == 1) { - return plugin; - } - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_ELEMENT && - xmlTextReaderDepth (reader) == 2) { - const gchar *tag = (gchar *) xmlTextReaderConstName (reader); - - if (g_str_equal (tag, "name")) { - if (!read_string (reader, &plugin->desc.name)) - break; - } else if (g_str_equal (tag, "description")) { - if (!read_string (reader, &plugin->desc.description)) - break; - } else if (g_str_equal (tag, "filename")) { - if (!read_string (reader, &plugin->filename)) - break; - } else if (g_str_equal (tag, "version")) { - if (!read_string (reader, &plugin->desc.version)) - break; - } else if (g_str_equal (tag, "license")) { - if (!read_string (reader, &plugin->desc.license)) - break; - } else if (g_str_equal (tag, "source")) { - if (!read_string (reader, &plugin->desc.source)) - break; - } else if (g_str_equal (tag, "package")) { - if (!read_string (reader, &plugin->desc.package)) - break; - } else if (g_str_equal (tag, "origin")) { - if (!read_string (reader, &plugin->desc.origin)) - break; - } else if (g_str_equal (tag, "feature")) { - GstPluginFeature *feature = load_feature (reader); - - if (feature) - gst_plugin_add_feature (plugin, feature); - } - } - } - g_free (plugin); - - return NULL; -} - -static void -load_paths (xmlTextReaderPtr reader, GstXMLRegistry * registry) -{ - int ret; - - while ((ret = xmlTextReaderRead (reader)) == 1) { - if (xmlTextReaderDepth (reader) == 1) { - return; - } - if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_ELEMENT && - xmlTextReaderDepth (reader) == 2) { - const gchar *tag = (gchar *) xmlTextReaderConstName (reader); - - if (g_str_equal (tag, "path")) { - gchar *s = NULL; - - if (read_string (reader, &s) && - !g_list_find_custom (GST_REGISTRY (registry)->paths, s, - (GCompareFunc) strcmp)) - gst_registry_add_path (GST_REGISTRY (registry), s); - g_free (s); - } - } - } - - return; -} - -static gboolean -gst_xml_registry_load (GstRegistry * registry) -{ - GstXMLRegistry *xmlregistry; - GTimer *timer; - gdouble seconds; - xmlTextReaderPtr reader; - int ret; - gboolean in_registry = FALSE; - - xmlregistry = GST_XML_REGISTRY (registry); - - /* make sure these types exist */ - GST_TYPE_ELEMENT_FACTORY; - GST_TYPE_TYPE_FIND_FACTORY; - GST_TYPE_INDEX_FACTORY; - - timer = g_timer_new (); - - if (!CLASS (xmlregistry)->open_func (xmlregistry, GST_XML_REGISTRY_READ)) { - g_timer_destroy (timer); - return FALSE; - } - - reader = xmlReaderForFd (fileno (xmlregistry->regfile), NULL, NULL, 0); - if (!reader) { - CLASS (xmlregistry)->close_func (xmlregistry); - g_timer_destroy (timer); - return FALSE; - } - - while ((ret = xmlTextReaderRead (reader)) == 1) { - if (xmlTextReaderDepth (reader) == 0) { - in_registry = xmlTextReaderNodeType (reader) == XML_READER_TYPE_ELEMENT && - g_str_equal ("GST-PluginRegistry", xmlTextReaderConstName (reader)); - } else if (in_registry) { - if (xmlTextReaderDepth (reader) == 1 && - xmlTextReaderNodeType (reader) == XML_READER_TYPE_ELEMENT) { - const gchar *tag = (const gchar *) xmlTextReaderConstName (reader); - - if (g_str_equal (tag, "plugin")) { - GstPlugin *plugin = load_plugin (reader); - - if (plugin) { - GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, - "adding plugin %s with %d features", plugin->desc.name, - plugin->numfeatures); - gst_registry_add_plugin (GST_REGISTRY (xmlregistry), plugin); - } - } else if (g_str_equal (tag, "gst-plugin-paths")) { - load_paths (reader, xmlregistry); - } - } - } - } - xmlFreeTextReader (reader); - if (ret != 0) { - GST_ERROR ("parsing registry: %s (at %s)", registry->name, - xmlregistry->location); - CLASS (xmlregistry)->close_func (xmlregistry); - g_timer_destroy (timer); - return FALSE; - } - - g_timer_stop (timer); - seconds = g_timer_elapsed (timer, NULL); - g_timer_destroy (timer); - - GST_INFO ("loaded %s in %f seconds (%s)", - registry->name, seconds, xmlregistry->location); - - CLASS (xmlregistry)->close_func (xmlregistry); - - return TRUE; -} - -static GstRegistryReturn -gst_xml_registry_load_plugin (GstRegistry * registry, GstPlugin * plugin) -{ - GError *error = NULL; - GstPlugin *loaded_plugin; - - /* FIXME: add gerror support */ - loaded_plugin = gst_plugin_load_file (plugin->filename, &error); - if (!plugin) { - if (error) { - g_warning ("could not load plugin %s: %s", plugin->desc.name, - error->message); - g_error_free (error); - } - return GST_REGISTRY_PLUGIN_LOAD_ERROR; - } else if (loaded_plugin != plugin) { - g_critical ("how to remove plugins?"); - } - - return GST_REGISTRY_OK; -} - -/* - * Save - */ -#define PUT_ESCAPED(tag,value) \ -G_STMT_START{ \ - const gchar *toconv = value; \ - if (toconv) { \ - gchar *v = g_markup_escape_text (toconv, strlen (toconv)); \ - CLASS (xmlregistry)->save_func (xmlregistry, "<%s>%s\n", tag, v, tag); \ - g_free (v); \ - } \ -}G_STMT_END -#define PUT_ESCAPED_INT(tag,value) \ -G_STMT_START{ \ - gchar *save = g_strdup_printf ("%ld", (glong) value); \ - CLASS (xmlregistry)->save_func (xmlregistry, "<%s>%s\n", tag, save, tag); \ - g_free (save); \ -}G_STMT_END - - -static gboolean -gst_xml_registry_save_caps (GstXMLRegistry * xmlregistry, const GstCaps * caps) -{ - /* we copy the caps here so we can simplify them before saving. This is a lot - * faster when loading them later on */ - char *s; - GstCaps *copy = gst_caps_copy (caps); - - gst_caps_do_simplify (copy); - s = gst_caps_to_string (copy); - gst_caps_unref (copy); - - PUT_ESCAPED ("caps", s); - g_free (s); - return TRUE; -} - -static gboolean -gst_xml_registry_save_pad_template (GstXMLRegistry * xmlregistry, - GstStaticPadTemplate * template) -{ - gchar *presence; - - PUT_ESCAPED ("nametemplate", template->name_template); - CLASS (xmlregistry)->save_func (xmlregistry, "%s\n", - (template->direction == GST_PAD_SINK ? "sink" : "src")); - - switch (template->presence) { - case GST_PAD_ALWAYS: - presence = "always"; - break; - case GST_PAD_SOMETIMES: - presence = "sometimes"; - break; - case GST_PAD_REQUEST: - presence = "request"; - break; - default: - presence = "unknown"; - break; - } - CLASS (xmlregistry)->save_func (xmlregistry, "%s\n", - presence); - - if (template->static_caps.string) { - CLASS (xmlregistry)->save_func (xmlregistry, "%s\n", - template->static_caps.string); - } - return TRUE; -} - -static gboolean -gst_xml_registry_save_feature (GstXMLRegistry * xmlregistry, - GstPluginFeature * feature) -{ - PUT_ESCAPED ("name", feature->name); - - if (feature->rank > 0) { - gint rank = feature->rank; - - CLASS (xmlregistry)->save_func (xmlregistry, "%d\n", rank); - } - - if (GST_IS_ELEMENT_FACTORY (feature)) { - GstElementFactory *factory = GST_ELEMENT_FACTORY (feature); - GList *walk; - - PUT_ESCAPED ("longname", factory->details.longname); - PUT_ESCAPED ("class", factory->details.klass); - PUT_ESCAPED ("description", factory->details.description); - PUT_ESCAPED ("author", factory->details.author); - - walk = factory->staticpadtemplates; - - while (walk) { - GstStaticPadTemplate *template = walk->data; - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - gst_xml_registry_save_pad_template (xmlregistry, template); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = g_list_next (walk); - } - - walk = factory->interfaces; - while (walk) { - PUT_ESCAPED ("interface", (gchar *) walk->data); - walk = g_list_next (walk); - } - - if (GST_URI_TYPE_IS_VALID (factory->uri_type)) { - gchar **protocol; - - PUT_ESCAPED ("uri_type", - factory->uri_type == GST_URI_SINK ? "sink" : "source"); - g_assert (factory->uri_protocols); - protocol = factory->uri_protocols; - while (*protocol) { - PUT_ESCAPED ("uri_protocol", *protocol); - protocol++; - } - } - } else if (GST_IS_TYPE_FIND_FACTORY (feature)) { - GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature); - gint i = 0; - - if (factory->caps) { - gst_xml_registry_save_caps (xmlregistry, factory->caps); - } - if (factory->extensions) { - while (factory->extensions[i]) { - PUT_ESCAPED ("extension", factory->extensions[i]); - i++; - } - } - } else if (GST_IS_INDEX_FACTORY (feature)) { - PUT_ESCAPED ("longdesc", GST_INDEX_FACTORY (feature)->longdesc); - } - return TRUE; -} - -static gboolean -gst_xml_registry_save_plugin (GstXMLRegistry * xmlregistry, GstPlugin * plugin) -{ - GList *walk; - - PUT_ESCAPED ("name", plugin->desc.name); - PUT_ESCAPED ("description", plugin->desc.description); - PUT_ESCAPED ("filename", plugin->filename); - PUT_ESCAPED ("version", plugin->desc.version); - PUT_ESCAPED ("license", plugin->desc.license); - PUT_ESCAPED ("source", plugin->desc.source); - PUT_ESCAPED ("package", plugin->desc.package); - PUT_ESCAPED ("origin", plugin->desc.origin); - - walk = plugin->features; - - while (walk) { - GstPluginFeature *feature = GST_PLUGIN_FEATURE (walk->data); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n", - g_type_name (G_OBJECT_TYPE (feature))); - gst_xml_registry_save_feature (xmlregistry, feature); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = g_list_next (walk); - } - return TRUE; -} - - -static gboolean -gst_xml_registry_save (GstRegistry * registry) -{ - GList *walk; - GstXMLRegistry *xmlregistry; - - g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE); - g_return_val_if_fail (registry->flags & GST_REGISTRY_WRITABLE, FALSE); - - xmlregistry = GST_XML_REGISTRY (registry); - - if (!CLASS (xmlregistry)->open_func (xmlregistry, GST_XML_REGISTRY_WRITE)) { - return FALSE; - } - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = gst_registry_get_path_list (GST_REGISTRY (registry)); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - while (walk) { - CLASS (xmlregistry)->save_func (xmlregistry, ""); - CLASS (xmlregistry)->save_func (xmlregistry, (gchar *) walk->data); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - walk = g_list_next (walk); - } - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = registry->plugins; - - while (walk) { - GstPlugin *plugin = GST_PLUGIN (walk->data); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - gst_xml_registry_save_plugin (xmlregistry, plugin); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = g_list_next (walk); - } - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - CLASS (xmlregistry)->close_func (xmlregistry); - - return TRUE; -} - -static GList * -gst_xml_registry_rebuild_recurse (GstXMLRegistry * registry, - const gchar * directory) -{ - GList *ret = NULL; - gint dr_len, sf_len; - - if (g_file_test (directory, G_FILE_TEST_IS_DIR)) { - GDir *dir = g_dir_open (directory, 0, NULL); - - if (dir) { - const gchar *dirent; - - while ((dirent = g_dir_read_name (dir))) { - gchar *dirname; - - if (*dirent == '=') { - /* =build, =inst, etc. -- automake distcheck directories */ - continue; - } - - dirname = g_strjoin ("/", directory, dirent, NULL); - ret = - g_list_concat (ret, gst_xml_registry_rebuild_recurse (registry, - dirname)); - g_free (dirname); - } - g_dir_close (dir); - } - } else { - dr_len = strlen (directory); - sf_len = strlen (G_MODULE_SUFFIX); - if (dr_len >= sf_len && - strcmp (directory + dr_len - sf_len, G_MODULE_SUFFIX) == 0) { - ret = g_list_prepend (ret, g_strdup (directory)); - } - } - - return ret; -} - -static gboolean -gst_xml_registry_rebuild (GstRegistry * registry) -{ - GList *walk = NULL, *plugins = NULL, *prune = NULL; - GError *error = NULL; - guint length; - GstPlugin *plugin; - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (registry); - - walk = registry->paths; - - while (walk) { - gchar *path = (gchar *) walk->data; - - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, - "Rebuilding registry %p in directory %s...", registry, path); - - plugins = g_list_concat (plugins, - gst_xml_registry_rebuild_recurse (xmlregistry, path)); - - walk = g_list_next (walk); - } - - do { - length = g_list_length (plugins); - - walk = plugins; - while (walk) { - g_assert (walk->data); - plugin = gst_plugin_load_file ((gchar *) walk->data, NULL); - if (plugin) { - prune = g_list_append (prune, walk->data); - gst_registry_add_plugin (registry, plugin); - } - - walk = g_list_next (walk); - } - - walk = prune; - while (walk) { - plugins = g_list_remove (plugins, walk->data); - g_free (walk->data); - walk = g_list_next (walk); - } - g_list_free (prune); - prune = NULL; - } while (g_list_length (plugins) != length); - - walk = plugins; - while (walk) { - if ((plugin = gst_plugin_load_file ((gchar *) walk->data, &error))) { - g_warning ("Bizarre behavior: plugin %s actually loaded", - (gchar *) walk->data); - gst_registry_add_plugin (registry, plugin); - } else { - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, "Plugin %s failed to load: %s", - (gchar *) walk->data, error->message); - - g_free (walk->data); - g_error_free (error); - error = NULL; - } - - walk = g_list_next (walk); - } - return TRUE; -} diff --git a/gst/registries/gstlibxmlregistry.h b/gst/registries/gstlibxmlregistry.h deleted file mode 100644 index 72661e8..0000000 --- a/gst/registries/gstlibxmlregistry.h +++ /dev/null @@ -1,112 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstpluginfeature.h: Header for base GstXMLRegistry - * - * 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. - */ - - -#ifndef __GST_XML_REGISTRY_H__ -#define __GST_XML_REGISTRY_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_XML_REGISTRY \ - (gst_xml_registry_get_type()) -#define GST_XML_REGISTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XML_REGISTRY,GstXMLRegistry)) -#define GST_XML_REGISTRY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XML_REGISTRY,GstXMLRegistryClass)) -#define GST_XML_REGISTRY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XML_REGISTRY, GstXMLRegistryClass)) -#define GST_IS_XML_REGISTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XML_REGISTRY)) -#define GST_IS_XML_REGISTRY_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XML_REGISTRY)) - -typedef struct _GstXMLRegistry GstXMLRegistry; -typedef struct _GstXMLRegistryClass GstXMLRegistryClass; - -typedef enum { - GST_XML_REGISTRY_NONE, - GST_XML_REGISTRY_TOP, - GST_XML_REGISTRY_PATHS, - GST_XML_REGISTRY_PATH, - GST_XML_REGISTRY_PATHS_DONE, - GST_XML_REGISTRY_PLUGIN, - GST_XML_REGISTRY_FEATURE, - GST_XML_REGISTRY_PADTEMPLATE, - GST_XML_REGISTRY_CAPS, - GST_XML_REGISTRY_STRUCTURE, - GST_XML_REGISTRY_PROPERTIES -} GstXMLRegistryState; - -typedef enum { - GST_XML_REGISTRY_READ, - GST_XML_REGISTRY_WRITE -} GstXMLRegistryMode; - -typedef void (*GstXMLRegistryGetPerms) (GstXMLRegistry *registry); -typedef gboolean (*GstXMLRegistryParser) (GMarkupParseContext *context, - const gchar *tag, - const gchar *text, - gsize text_len, - GstXMLRegistry *registry, - GError **error); - -typedef gboolean (*GstXMLRegistryOpen) (GstXMLRegistry *registry, - GstXMLRegistryMode mode); -typedef gboolean (*GstXMLRegistryLoad) (GstXMLRegistry *registry, - gchar *dest, - gssize *size); -typedef gboolean (*GstXMLRegistrySave) (GstXMLRegistry *registry, - gchar *format, - ...); -typedef gboolean (*GstXMLRegistryClose) (GstXMLRegistry *registry); - -struct _GstXMLRegistry { - GstRegistry object; - - gchar *location; - gboolean open; - - FILE *regfile; -}; - -struct _GstXMLRegistryClass { - GstRegistryClass parent_class; - - GstXMLRegistryGetPerms get_perms_func; - GstXMLRegistryOpen open_func; - GstXMLRegistryLoad load_func; - GstXMLRegistrySave save_func; - GstXMLRegistryClose close_func; -}; - - -/* normal GObject stuff */ -GType gst_xml_registry_get_type (void); - -GstRegistry* gst_xml_registry_new (const gchar *name, const gchar *location); - -G_END_DECLS - -#endif /* __GST_XML_REGISTRY_H__ */ - diff --git a/gst/registries/gstxmlregistry.c b/gst/registries/gstxmlregistry.c deleted file mode 100644 index e99f788..0000000 --- a/gst/registries/gstxmlregistry.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstxml_registry.c: GstXMLRegistry object, support routines - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#ifdef _MSC_VER -#include -#include -#ifndef F_OK -#define F_OK 0 -#define W_OK 2 -#define R_OK 4 -#endif -#ifndef S_ISREG -#define S_ISREG(mode) ((mode)&_S_IFREG) -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) ((mode)&_S_IFDIR) -#endif -#else /* _MSC_VER */ -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "gstxmlregistry.h" - -#define BLOCK_SIZE 1024*10 - -#define CLASS(registry) GST_XML_REGISTRY_CLASS (G_OBJECT_GET_CLASS (registry)) - - -enum -{ - PROP_0, - PROP_LOCATION -}; - - -static void gst_xml_registry_class_init (GstXMLRegistryClass * klass); -static void gst_xml_registry_init (GstXMLRegistry * registry); - -static void gst_xml_registry_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_xml_registry_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static gboolean gst_xml_registry_load (GstRegistry * registry); -static gboolean gst_xml_registry_save (GstRegistry * registry); -static gboolean gst_xml_registry_rebuild (GstRegistry * registry); - -static void gst_xml_registry_get_perms_func (GstXMLRegistry * registry); -static void gst_xml_registry_add_path_list_func (GstXMLRegistry * registry); -static gboolean gst_xml_registry_open_func (GstXMLRegistry * registry, - GstXMLRegistryMode mode); -static gboolean gst_xml_registry_load_func (GstXMLRegistry * registry, - gchar * data, gssize * size); -static gboolean gst_xml_registry_save_func (GstXMLRegistry * registry, - gchar * format, ...); -static gboolean gst_xml_registry_close_func (GstXMLRegistry * registry); - -static GstRegistryReturn gst_xml_registry_load_plugin (GstRegistry * registry, - GstPlugin * plugin); - -static void gst_xml_registry_start_element (GMarkupParseContext * context, - const gchar * element_name, - const gchar ** attribute_names, - const gchar ** attribute_values, gpointer user_data, GError ** error); -static void gst_xml_registry_end_element (GMarkupParseContext * context, - const gchar * element_name, gpointer user_data, GError ** error); -static void gst_xml_registry_text (GMarkupParseContext * context, - const gchar * text, gsize text_len, gpointer user_data, GError ** error); -static void gst_xml_registry_passthrough (GMarkupParseContext * context, - const gchar * passthrough_text, - gsize text_len, gpointer user_data, GError ** error); -static void gst_xml_registry_error (GMarkupParseContext * context, - GError * error, gpointer user_data); - - -static void gst_xml_registry_paths_start_element (GMarkupParseContext * context, - const gchar * element_name, - const gchar ** attribute_names, - const gchar ** attribute_values, gpointer user_data, GError ** error); -static void gst_xml_registry_paths_end_element (GMarkupParseContext * context, - const gchar * element_name, gpointer user_data, GError ** error); -static void gst_xml_registry_paths_text (GMarkupParseContext * context, - const gchar * text, gsize text_len, gpointer user_data, GError ** error); - -static GstRegistryClass *parent_class = NULL; - -/* static guint gst_xml_registry_signals[LAST_SIGNAL] = { 0 }; */ - -static const GMarkupParser gst_xml_registry_parser = { - gst_xml_registry_start_element, - gst_xml_registry_end_element, - gst_xml_registry_text, - gst_xml_registry_passthrough, - gst_xml_registry_error, -}; - -static const GMarkupParser gst_xml_registry_paths_parser = { - gst_xml_registry_paths_start_element, - gst_xml_registry_paths_end_element, - gst_xml_registry_paths_text, - NULL, - NULL -}; - - -GType -gst_xml_registry_get_type (void) -{ - static GType xml_registry_type = 0; - - if (!xml_registry_type) { - static const GTypeInfo xml_registry_info = { - sizeof (GstXMLRegistryClass), - NULL, - NULL, - (GClassInitFunc) gst_xml_registry_class_init, - NULL, - NULL, - sizeof (GstXMLRegistry), - 0, - (GInstanceInitFunc) gst_xml_registry_init, - NULL - }; - - xml_registry_type = g_type_register_static (GST_TYPE_REGISTRY, - "GstXMLRegistry", &xml_registry_info, 0); - } - return xml_registry_type; -} - -static void -gst_xml_registry_class_init (GstXMLRegistryClass * klass) -{ - GObjectClass *gobject_class; - GstRegistryClass *gstregistry_class; - GstXMLRegistryClass *gstxmlregistry_class; - - gobject_class = (GObjectClass *) klass; - gstregistry_class = (GstRegistryClass *) klass; - gstxmlregistry_class = (GstXMLRegistryClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_REGISTRY); - - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_xml_registry_get_property); - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_xml_registry_set_property); - - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LOCATION, - g_param_spec_string ("location", "Location", - "Location of the registry file", NULL, G_PARAM_READWRITE)); - - gstregistry_class->load = GST_DEBUG_FUNCPTR (gst_xml_registry_load); - gstregistry_class->save = GST_DEBUG_FUNCPTR (gst_xml_registry_save); - gstregistry_class->rebuild = GST_DEBUG_FUNCPTR (gst_xml_registry_rebuild); - - gstregistry_class->load_plugin = - GST_DEBUG_FUNCPTR (gst_xml_registry_load_plugin); - - gstxmlregistry_class->get_perms_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_get_perms_func); - gstxmlregistry_class->add_path_list_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_add_path_list_func); - gstxmlregistry_class->open_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_open_func); - gstxmlregistry_class->load_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_load_func); - gstxmlregistry_class->save_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_save_func); - gstxmlregistry_class->close_func = - GST_DEBUG_FUNCPTR (gst_xml_registry_close_func); -} - -static void -gst_xml_registry_init (GstXMLRegistry * registry) -{ - registry->location = NULL; - registry->context = NULL; - registry->state = GST_XML_REGISTRY_NONE; - registry->current_plugin = NULL; - registry->current_feature = NULL; - registry->open_tags = NULL; -} - -/** - * gst_xml_registry_new: - * @name: the name of the registry - * @location: the location of the registry file - * - * Create a new xml registry with the given name and location. - * - * Returns: a new GstXMLRegistry with the given name an location. - */ -GstRegistry * -gst_xml_registry_new (const gchar * name, const gchar * location) -{ - GstXMLRegistry *xmlregistry; - - xmlregistry = GST_XML_REGISTRY (g_object_new (GST_TYPE_XML_REGISTRY, NULL)); - - g_object_set (G_OBJECT (xmlregistry), "location", location, NULL); - - GST_REGISTRY (xmlregistry)->name = g_strdup (name); - - return GST_REGISTRY (xmlregistry); -} - -static void -gst_xml_registry_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstXMLRegistry *registry; - - registry = GST_XML_REGISTRY (object); - - switch (prop_id) { - case PROP_LOCATION: - if (registry->open) { - CLASS (object)->close_func (registry); - g_return_if_fail (registry->open == FALSE); - } - - if (registry->location) - g_free (registry->location); - - registry->location = g_strdup (g_value_get_string (value)); - GST_REGISTRY (registry)->flags = 0x0; - - if (CLASS (object)->get_perms_func) - CLASS (object)->get_perms_func (registry); - - if (CLASS (object)->add_path_list_func) - CLASS (object)->add_path_list_func (registry); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_xml_registry_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstXMLRegistry *registry; - - registry = GST_XML_REGISTRY (object); - - switch (prop_id) { - case PROP_LOCATION: - g_value_set_string (value, g_strdup (registry->location)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* this function returns the biggest of the path's mtime and ctime - * mtime is updated through an actual write (data) - * ctime is updated through changing inode information - * so this function returns the last time *anything* changed to this path - * it also sets the given boolean to TRUE if the given path is a directory - */ -static time_t -get_time (const char *path, gboolean * is_dir) -{ - struct stat statbuf; - - if (stat (path, &statbuf)) { - *is_dir = FALSE; - return 0; - } - - if (is_dir) - *is_dir = S_ISDIR (statbuf.st_mode); - - if (statbuf.st_mtime > statbuf.st_ctime) - return statbuf.st_mtime; - return statbuf.st_ctime; -} - -#if defined(_MSC_VER) || defined(__MINGW32__) -#define xmkdir(dirname) _mkdir (dirname) -#else -#define xmkdir(dirname) mkdir (dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) -#endif - -static gboolean -make_dir (gchar * filename) -{ - struct stat dirstat; - gchar *dirname; - - if (strrchr (filename, '/') == NULL) - return FALSE; - - dirname = g_strndup (filename, strrchr (filename, '/') - filename); - - if (stat (dirname, &dirstat) == -1 && errno == ENOENT) { - if (xmkdir (dirname) != 0) { - if (make_dir (dirname) != TRUE) { - g_free (dirname); - return FALSE; - } else { - if (xmkdir (dirname) != 0) { - return FALSE; - } - } - } - } - - g_free (dirname); - return TRUE; -} - -static void -gst_xml_registry_get_perms_func (GstXMLRegistry * registry) -{ - gchar *dirname; - - /* if the dir does not exist, make it. if that can't be done, flags = 0x0. - if the file can be appended to, it's writable. if it can then be read, - it's readable. - After that check if it exists. */ - - if (make_dir (registry->location) != TRUE) { - /* we can't do anything with it, leave flags as 0x0 */ - return; - } - - dirname = g_path_get_dirname (registry->location); - - if (g_file_test (registry->location, G_FILE_TEST_EXISTS)) { - GST_REGISTRY (registry)->flags |= GST_REGISTRY_EXISTS; - } - - if (!access (dirname, W_OK)) { - GST_REGISTRY (registry)->flags |= GST_REGISTRY_WRITABLE; - } - - if (!access (dirname, R_OK)) { - GST_REGISTRY (registry)->flags |= GST_REGISTRY_READABLE; - } - - g_free (dirname); -} - -static void -gst_xml_registry_add_path_list_func (GstXMLRegistry * registry) -{ - FILE *reg = NULL; - GMarkupParseContext *context; - gchar *text = NULL; - gssize size; - GError *error = NULL; - - context = g_markup_parse_context_new (&gst_xml_registry_paths_parser, 0, - registry, NULL); - - if (!(reg = fopen (registry->location, "r"))) { - goto finished; - } - - /* slightly allocate more as gmarkup reads too much */ - text = g_malloc0 (BLOCK_SIZE + 32); - - size = fread (text, 1, BLOCK_SIZE, reg); - - while (size) { - g_markup_parse_context_parse (context, text, size, &error); - - if (error) { - GST_ERROR ("parsing registry %s: %s\n", - registry->location, error->message); - goto finished; - } - - if (registry->state == GST_XML_REGISTRY_PATHS_DONE) - break; - - size = fread (text, 1, BLOCK_SIZE, reg); - } - -finished: - - g_markup_parse_context_free (context); - - if (reg) - fclose (reg); - - g_free (text); -} - -/* return TRUE iff regtime is more recent than the times of all the .so files - * in the plugin dirs; ie return TRUE if this path does not need to trigger - * a rebuild of registry - * - * - if it's a directory, recurse on subdirs - * - if it's a file - * - if entry is not newer, return TRUE. - * - if it's newer - * - and it's a plugin, return FALSE - * - otherwise return TRUE - */ -static gboolean -plugin_times_older_than_recurse (gchar * path, time_t regtime) -{ - DIR *dir; - struct dirent *dirent; - gboolean is_dir; - gchar *new_path; - - time_t pathtime = get_time (path, &is_dir); - - if (is_dir) { - dir = opendir (path); - if (dir) { - while ((dirent = readdir (dir))) { - /* don't want to recurse in place or backwards */ - if (strcmp (dirent->d_name, ".") && strcmp (dirent->d_name, "..")) { - new_path = g_build_filename (path, dirent->d_name, NULL); - if (!plugin_times_older_than_recurse (new_path, regtime)) { - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, - "path %s is more recent than registry time of %ld", - new_path, (long) regtime); - g_free (new_path); - closedir (dir); - return FALSE; - } - g_free (new_path); - } - } - closedir (dir); - } - return TRUE; - } - - /* it's a file */ - if (pathtime <= regtime) { - return TRUE; - } - - /* it's a file, and it's more recent */ - if (g_str_has_suffix (path, ".so") || g_str_has_suffix (path, ".dll")) { - if (!gst_plugin_check_file (path, NULL)) - return TRUE; - - /* it's a newer GStreamer plugin */ - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, - "%s looks like a plugin and is more recent than registry time of %ld", - path, (long) regtime); - return FALSE; - } - return TRUE; -} - -/* return TRUE iff regtime is more recent than the times of all the .so files - * in the plugin dirs; ie return TRUE if registry is up to date. - */ -static gboolean -plugin_times_older_than (GList * paths, time_t regtime) -{ - while (paths) { - GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, - "comparing plugin times from %s with %ld", - (gchar *) paths->data, (long) regtime); - if (!plugin_times_older_than_recurse (paths->data, regtime)) - return FALSE; - paths = g_list_next (paths); - } - GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, - "everything's fine, no registry rebuild needed."); - return TRUE; -} - -static gboolean -gst_xml_registry_open_func (GstXMLRegistry * registry, GstXMLRegistryMode mode) -{ - GstRegistry *gst_registry; - GList *paths; - - gst_registry = GST_REGISTRY (registry); - paths = gst_registry->paths; - GST_CAT_DEBUG (GST_CAT_GST_INIT, "opening registry %s", registry->location); - - g_return_val_if_fail (registry->open == FALSE, FALSE); - - /* if it doesn't exist, first try to build it, and check if it worked - * if it's not readable, return false - * if it's out of date, rebuild it */ - if (mode == GST_XML_REGISTRY_READ) { - if (!(gst_registry->flags & GST_REGISTRY_EXISTS)) { - /* if it's not writable, then don't bother */ - if (!(gst_registry->flags & GST_REGISTRY_WRITABLE)) { - GST_CAT_INFO (GST_CAT_GST_INIT, "Registry isn't writable"); - return FALSE; - } - GST_CAT_INFO (GST_CAT_GST_INIT, - "Registry doesn't exist, trying to build..."); - gst_registry_rebuild (gst_registry); - gst_registry_save (gst_registry); - /* FIXME: verify that the flags actually get updated ! */ - if (!(gst_registry->flags & GST_REGISTRY_EXISTS)) { - return FALSE; - } - } - /* at this point we know it exists */ - g_return_val_if_fail (gst_registry->flags & GST_REGISTRY_READABLE, FALSE); - - if (!plugin_times_older_than (paths, get_time (registry->location, NULL))) { - if (gst_registry->flags & GST_REGISTRY_WRITABLE) { - GST_CAT_INFO (GST_CAT_GST_INIT, "Registry out of date, rebuilding..."); - - gst_registry_rebuild (gst_registry); - - gst_registry_save (gst_registry); - - if (!plugin_times_older_than (paths, get_time (registry->location, - NULL))) { - GST_CAT_INFO (GST_CAT_GST_INIT, - "Registry still out of date, something is wrong..."); - return FALSE; - } - } else { - GST_CAT_INFO (GST_CAT_GST_INIT, - "Can't write to this registry and it's out of date, ignoring it"); - return FALSE; - } - } - - GST_CAT_DEBUG (GST_CAT_GST_INIT, "opening registry %s for reading", - registry->location); - registry->regfile = fopen (registry->location, "r"); - } else if (mode == GST_XML_REGISTRY_WRITE) { - char *tmploc; - int fd; - - g_return_val_if_fail (gst_registry->flags & GST_REGISTRY_WRITABLE, FALSE); - - tmploc = g_strconcat (registry->location, ".tmp", NULL); - - GST_CAT_DEBUG (GST_CAT_GST_INIT, "opening registry %s for writing", tmploc); - - if ((fd = open (tmploc, O_WRONLY | O_CREAT, 0644)) < 0) { - g_free (tmploc); - return FALSE; - } - g_free (tmploc); - - registry->regfile = fdopen (fd, "w"); - } - - if (!registry->regfile) - return FALSE; - - registry->open = TRUE; - - return TRUE; -} - -static gboolean -gst_xml_registry_load_func (GstXMLRegistry * registry, gchar * data, - gssize * size) -{ - *size = fread (data, 1, *size, registry->regfile); - - return TRUE; -} - -static gboolean -gst_xml_registry_save_func (GstXMLRegistry * registry, gchar * format, ...) -{ - va_list var_args; - - va_start (var_args, format); - - vfprintf (registry->regfile, format, var_args); - - va_end (var_args); - - return TRUE; -} - -static gboolean -gst_xml_registry_close_func (GstXMLRegistry * registry) -{ - char *tmploc; - - GST_CAT_DEBUG (GST_CAT_GST_INIT, "closing registry %s", registry->location); - fclose (registry->regfile); - - /* If we opened for writing, rename our temporary file. */ - tmploc = g_strconcat (registry->location, ".tmp", NULL); - if (g_file_test (tmploc, G_FILE_TEST_EXISTS)) { -#ifdef WIN32 - remove (registry->location); -#endif - rename (tmploc, registry->location); - } - g_free (tmploc); - - registry->open = FALSE; - - return TRUE; -} - -static gboolean -gst_xml_registry_load (GstRegistry * registry) -{ - GstXMLRegistry *xmlregistry; - gchar *text; - gssize size; - GError *error = NULL; - GTimer *timer; - gdouble seconds; - - xmlregistry = GST_XML_REGISTRY (registry); - - timer = g_timer_new (); - - xmlregistry->context = - g_markup_parse_context_new (&gst_xml_registry_parser, 0, registry, NULL); - - if (!CLASS (xmlregistry)->open_func (xmlregistry, GST_XML_REGISTRY_READ)) { - g_timer_destroy (timer); - return FALSE; - } - - text = g_malloc0 (BLOCK_SIZE + 32); - - size = BLOCK_SIZE; - CLASS (xmlregistry)->load_func (xmlregistry, text, &size); - - while (size) { - g_markup_parse_context_parse (xmlregistry->context, text, size, &error); - - if (error) { - GST_ERROR ("parsing registry: %s\n", error->message); - g_free (text); - CLASS (xmlregistry)->close_func (xmlregistry); - g_timer_destroy (timer); - return FALSE; - } - - size = BLOCK_SIZE; - CLASS (xmlregistry)->load_func (xmlregistry, text, &size); - } - - g_free (text); - - g_timer_stop (timer); - - seconds = g_timer_elapsed (timer, NULL); - g_timer_destroy (timer); - - GST_INFO ("loaded %s in %f seconds (%s)", - registry->name, seconds, xmlregistry->location); - - CLASS (xmlregistry)->close_func (xmlregistry); - - g_markup_parse_context_free (xmlregistry->context); - - return TRUE; -} - -static GstRegistryReturn -gst_xml_registry_load_plugin (GstRegistry * registry, GstPlugin * plugin) -{ - GError *error = NULL; - GstPlugin *loaded_plugin; - - /* FIXME: add gerror support */ - loaded_plugin = gst_plugin_load_file (plugin->filename, &error); - if (!plugin) { - if (error) { - g_warning ("could not load plugin %s: %s", plugin->desc.name, - error->message); - g_error_free (error); - } - return GST_REGISTRY_PLUGIN_LOAD_ERROR; - } else if (loaded_plugin != plugin) { - g_critical ("how to remove plugins?"); - } - - return GST_REGISTRY_OK; -} - -static gboolean -gst_xml_registry_parse_plugin (GMarkupParseContext * context, const gchar * tag, - const gchar * text, gsize text_len, GstXMLRegistry * registry, - GError ** error) -{ - GstPlugin *plugin = registry->current_plugin; - - if (!strcmp (tag, "name")) { - plugin->desc.name = g_strndup (text, text_len); - } else if (!strcmp (tag, "description")) { - plugin->desc.description = g_strndup (text, text_len); - } else if (!strcmp (tag, "filename")) { - plugin->filename = g_strndup (text, text_len); - } else if (!strcmp (tag, "version")) { - plugin->desc.version = g_strndup (text, text_len); - } else if (!strcmp (tag, "license")) { - plugin->desc.license = g_strndup (text, text_len); - } else if (!strcmp (tag, "source")) { - plugin->desc.source = g_strndup (text, text_len); - } else if (!strcmp (tag, "package")) { - plugin->desc.package = g_strndup (text, text_len); - } else if (!strcmp (tag, "origin")) { - plugin->desc.origin = g_strndup (text, text_len); - } - - return TRUE; -} - -static void -add_to_char_array (gchar *** array, gchar * value) -{ - gchar **new; - gchar **old = *array; - gint i = 0; - - /* expensive, but cycles are cheap... */ - if (old) - while (old[i]) - i++; - new = g_new0 (gchar *, i + 2); - new[i] = value; - while (i > 0) { - i--; - new[i] = old[i]; - } - g_free (old); - *array = new; -} - -static gboolean -gst_xml_registry_parse_element_factory (GMarkupParseContext * context, - const gchar * tag, const gchar * text, gsize text_len, - GstXMLRegistry * registry, GError ** error) -{ - GstElementFactory *factory = GST_ELEMENT_FACTORY (registry->current_feature); - - if (!strcmp (tag, "name")) { - gchar *name = g_strndup (text, text_len); - - gst_plugin_feature_set_name (registry->current_feature, name); - g_free (name); - } else if (!strcmp (tag, "longname")) { - g_free (factory->details.longname); - factory->details.longname = g_strndup (text, text_len); - } else if (!strcmp (tag, "class")) { - g_free (factory->details.klass); - factory->details.klass = g_strndup (text, text_len); - } else if (!strcmp (tag, "description")) { - g_free (factory->details.description); - factory->details.description = g_strndup (text, text_len); - } else if (!strcmp (tag, "author")) { - g_free (factory->details.author); - factory->details.author = g_strndup (text, text_len); - } else if (!strcmp (tag, "rank")) { - gint rank; - gchar *ret; - - rank = strtol (text, &ret, 0); - if (ret == text + text_len) { - gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank); - } - } else if (!strcmp (tag, "uri_type")) { - if (g_ascii_strncasecmp (text, "sink", 4) == 0) { - factory->uri_type = GST_URI_SINK; - } else if (g_ascii_strncasecmp (text, "source", 5) == 0) { - factory->uri_type = GST_URI_SRC; - } - } else if (!strcmp (tag, "uri_protocol")) { - add_to_char_array (&factory->uri_protocols, g_strndup (text, text_len)); - } else if (!strcmp (tag, "interface")) { - gchar *tmp = g_strndup (text, text_len); - - __gst_element_factory_add_interface (factory, tmp); - g_free (tmp); - } - - return TRUE; -} - -static gboolean -gst_xml_registry_parse_type_find_factory (GMarkupParseContext * context, - const gchar * tag, const gchar * text, gsize text_len, - GstXMLRegistry * registry, GError ** error) -{ - GstTypeFindFactory *factory = - GST_TYPE_FIND_FACTORY (registry->current_feature); - - if (!strcmp (tag, "name")) { - registry->current_feature->name = g_strndup (text, text_len); - } else if (!strcmp (tag, "rank")) { - glong rank; - gchar *ret; - - rank = strtol (text, &ret, 0); - if (ret == text + text_len) { - gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank); - } - } - /* FIXME!! - else if (!strcmp (tag, "caps")) { - factory->caps = g_strndup (text, text_len); - } */ - else if (!strcmp (tag, "extension")) { - add_to_char_array (&factory->extensions, g_strndup (text, text_len)); - } - - return TRUE; -} - -static gboolean -gst_xml_registry_parse_index_factory (GMarkupParseContext * context, - const gchar * tag, const gchar * text, gsize text_len, - GstXMLRegistry * registry, GError ** error) -{ - GstIndexFactory *factory = GST_INDEX_FACTORY (registry->current_feature); - - if (!strcmp (tag, "name")) { - registry->current_feature->name = g_strndup (text, text_len); - } else if (!strcmp (tag, "longdesc")) { - factory->longdesc = g_strndup (text, text_len); - } - return TRUE; -} - -static gboolean -gst_xml_registry_parse_padtemplate (GMarkupParseContext * context, - const gchar * tag, const gchar * text, gsize text_len, - GstXMLRegistry * registry, GError ** error) -{ - if (!strcmp (tag, "nametemplate")) { - registry->name_template = g_strndup (text, text_len); - } else if (!strcmp (tag, "direction")) { - if (!strncmp (text, "sink", text_len)) { - registry->direction = GST_PAD_SINK; - } else if (!strncmp (text, "src", text_len)) { - registry->direction = GST_PAD_SRC; - } - } else if (!strcmp (tag, "presence")) { - if (!strncmp (text, "always", text_len)) { - registry->presence = GST_PAD_ALWAYS; - } else if (!strncmp (text, "sometimes", text_len)) { - registry->presence = GST_PAD_SOMETIMES; - } else if (!strncmp (text, "request", text_len)) { - registry->presence = GST_PAD_REQUEST; - } - } else if (!strncmp (tag, "caps", 4)) { - char *s; - - s = g_strndup (text, text_len); - g_assert (registry->caps_string == NULL); - registry->caps_string = s; - return TRUE; - } - return TRUE; -} - -static void -gst_xml_registry_start_element (GMarkupParseContext * context, - const gchar * element_name, - const gchar ** attribute_names, - const gchar ** attribute_values, gpointer user_data, GError ** error) -{ - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data); - - xmlregistry->open_tags = g_list_prepend (xmlregistry->open_tags, - g_strdup (element_name)); - - switch (xmlregistry->state) { - case GST_XML_REGISTRY_NONE: - if (!strcmp (element_name, "GST-PluginRegistry")) { - xmlregistry->state = GST_XML_REGISTRY_TOP; - } - break; - case GST_XML_REGISTRY_TOP: - if (!strncmp (element_name, "plugin", 6)) { - xmlregistry->state = GST_XML_REGISTRY_PLUGIN; - xmlregistry->parser = gst_xml_registry_parse_plugin; - xmlregistry->current_plugin = (GstPlugin *) g_new0 (GstPlugin, 1); - } - break; - case GST_XML_REGISTRY_PLUGIN: - if (!strncmp (element_name, "feature", 7)) { - gint i = 0; - GstPluginFeature *feature = NULL; - - xmlregistry->state = GST_XML_REGISTRY_FEATURE; - - while (attribute_names[i]) { - if (!strncmp (attribute_names[i], "typename", 8)) { - feature = - GST_PLUGIN_FEATURE (g_object_new (g_type_from_name - (attribute_values[i]), NULL)); - break; - } - i++; - } - if (feature) { - xmlregistry->current_feature = feature; - - if (GST_IS_ELEMENT_FACTORY (feature)) { - GstElementFactory *factory = GST_ELEMENT_FACTORY (feature); - - factory->staticpadtemplates = NULL; - xmlregistry->parser = gst_xml_registry_parse_element_factory; - break; - } else if (GST_IS_TYPE_FIND_FACTORY (feature)) { - xmlregistry->parser = gst_xml_registry_parse_type_find_factory; - } else if (GST_IS_INDEX_FACTORY (feature)) { - xmlregistry->parser = gst_xml_registry_parse_index_factory; - } else { - g_warning ("unknown feature type"); - } - } - } - break; - case GST_XML_REGISTRY_FEATURE: - if (!strncmp (element_name, "padtemplate", 11)) { - xmlregistry->state = GST_XML_REGISTRY_PADTEMPLATE; - xmlregistry->parser = gst_xml_registry_parse_padtemplate; - xmlregistry->name_template = NULL; - xmlregistry->direction = 0; - xmlregistry->presence = 0; - xmlregistry->caps_string = NULL; - } - break; - default: - break; - } -} - -static void -gst_xml_registry_end_element (GMarkupParseContext * context, - const gchar * element_name, gpointer user_data, GError ** error) -{ - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data); - gchar *open_tag = (gchar *) xmlregistry->open_tags->data; - - xmlregistry->open_tags = g_list_remove (xmlregistry->open_tags, open_tag); - g_free (open_tag); - - switch (xmlregistry->state) { - case GST_XML_REGISTRY_TOP: - if (!strcmp (element_name, "GST-PluginRegistry")) { - xmlregistry->state = GST_XML_REGISTRY_NONE; - } - break; - case GST_XML_REGISTRY_PLUGIN: - if (!strcmp (element_name, "plugin")) { - xmlregistry->state = GST_XML_REGISTRY_TOP; - xmlregistry->parser = NULL; - gst_registry_add_plugin (GST_REGISTRY (xmlregistry), - xmlregistry->current_plugin); - } - break; - case GST_XML_REGISTRY_FEATURE: - if (!strcmp (element_name, "feature")) { - xmlregistry->state = GST_XML_REGISTRY_PLUGIN; - xmlregistry->parser = gst_xml_registry_parse_plugin; - gst_plugin_add_feature (xmlregistry->current_plugin, - xmlregistry->current_feature); - xmlregistry->current_feature = NULL; - } - break; - case GST_XML_REGISTRY_PADTEMPLATE: - if (!strcmp (element_name, "padtemplate")) { - GstStaticPadTemplate *template; - - template = g_new0 (GstStaticPadTemplate, 1); - template->name_template = xmlregistry->name_template; - template->presence = xmlregistry->presence; - template->direction = xmlregistry->direction; - template->static_caps.string = xmlregistry->caps_string; - - xmlregistry->name_template = NULL; - xmlregistry->caps_string = NULL; - - __gst_element_factory_add_static_pad_template (GST_ELEMENT_FACTORY - (xmlregistry->current_feature), template); - - xmlregistry->state = GST_XML_REGISTRY_FEATURE; - xmlregistry->parser = gst_xml_registry_parse_element_factory; - } - break; - default: - break; - } -} - -static void -gst_xml_registry_text (GMarkupParseContext * context, const gchar * text, - gsize text_len, gpointer user_data, GError ** error) -{ - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data); - gchar *open_tag; - - if (xmlregistry->open_tags) { - open_tag = (gchar *) xmlregistry->open_tags->data; - - if (!strcmp (open_tag, "plugin-path")) { - //gst_plugin_add_path (g_strndup (text, text_len)); - } else if (xmlregistry->parser) { - xmlregistry->parser (context, open_tag, text, text_len, xmlregistry, - error); - } - } -} - -static void -gst_xml_registry_passthrough (GMarkupParseContext * context, - const gchar * passthrough_text, gsize text_len, gpointer user_data, - GError ** error) -{ -} - -static void -gst_xml_registry_error (GMarkupParseContext * context, GError * error, - gpointer user_data) -{ - GST_ERROR ("%s\n", error->message); -} - -static void -gst_xml_registry_paths_start_element (GMarkupParseContext * context, - const gchar * element_name, - const gchar ** attribute_names, - const gchar ** attribute_values, gpointer user_data, GError ** error) -{ - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data); - - switch (xmlregistry->state) { - case GST_XML_REGISTRY_NONE: - if (!strcmp (element_name, "GST-PluginRegistry")) { - xmlregistry->state = GST_XML_REGISTRY_TOP; - } - break; - case GST_XML_REGISTRY_TOP: - if (!strcmp (element_name, "gst-registry-paths")) { - xmlregistry->state = GST_XML_REGISTRY_PATHS; - } - break; - case GST_XML_REGISTRY_PATHS: - if (!strcmp (element_name, "path")) { - xmlregistry->state = GST_XML_REGISTRY_PATH; - } - break; - default: - break; - } -} - -static void -gst_xml_registry_paths_end_element (GMarkupParseContext * context, - const gchar * element_name, gpointer user_data, GError ** error) -{ - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data); - - switch (xmlregistry->state) { - case GST_XML_REGISTRY_PATH: - if (!strcmp (element_name, "path")) { - xmlregistry->state = GST_XML_REGISTRY_PATHS; - } - break; - case GST_XML_REGISTRY_PATHS: - if (!strcmp (element_name, "gst-plugin-paths")) { - xmlregistry->state = GST_XML_REGISTRY_PATHS_DONE; - } - break; - default: - break; - } -} - -static void -gst_xml_registry_paths_text (GMarkupParseContext * context, const gchar * text, - gsize text_len, gpointer user_data, GError ** error) -{ - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data); - - if (xmlregistry->state == GST_XML_REGISTRY_PATH) - gst_registry_add_path (GST_REGISTRY (xmlregistry), g_strndup (text, - text_len)); -} - -/* - * Save - */ -#define PUT_ESCAPED(tag,value) \ -G_STMT_START{ \ - const gchar *toconv = value; \ - if (toconv) { \ - gchar *v = g_markup_escape_text (toconv, strlen (toconv)); \ - CLASS (xmlregistry)->save_func (xmlregistry, "<%s>%s\n", tag, v, tag); \ - g_free (v); \ - } \ -}G_STMT_END -#define PUT_ESCAPED_INT(tag,value) \ -G_STMT_START{ \ - gchar *save = g_strdup_printf ("%ld", (glong) value); \ - CLASS (xmlregistry)->save_func (xmlregistry, "<%s>%s\n", tag, save, tag); \ - g_free (save); \ -}G_STMT_END - - -static gboolean -gst_xml_registry_save_caps (GstXMLRegistry * xmlregistry, const GstCaps * caps) -{ - char *s = gst_caps_to_string (caps); - - PUT_ESCAPED ("caps", s); - g_free (s); - return TRUE; -} - -static gboolean -gst_xml_registry_save_pad_template (GstXMLRegistry * xmlregistry, - GstPadTemplate * template) -{ - gchar *presence; - - PUT_ESCAPED ("nametemplate", template->name_template); - CLASS (xmlregistry)->save_func (xmlregistry, "%s\n", - (template->direction == GST_PAD_SINK ? "sink" : "src")); - - switch (template->presence) { - case GST_PAD_ALWAYS: - presence = "always"; - break; - case GST_PAD_SOMETIMES: - presence = "sometimes"; - break; - case GST_PAD_REQUEST: - presence = "request"; - break; - default: - presence = "unknown"; - break; - } - CLASS (xmlregistry)->save_func (xmlregistry, "%s\n", - presence); - - if (GST_PAD_TEMPLATE_CAPS (template)) { - gst_xml_registry_save_caps (xmlregistry, GST_PAD_TEMPLATE_CAPS (template)); - } - return TRUE; -} - -static gboolean -gst_xml_registry_save_feature (GstXMLRegistry * xmlregistry, - GstPluginFeature * feature) -{ - PUT_ESCAPED ("name", feature->name); - - if (feature->rank > 0) { - gint rank = feature->rank; - - CLASS (xmlregistry)->save_func (xmlregistry, "%d\n", rank); - } - - if (GST_IS_ELEMENT_FACTORY (feature)) { - GstElementFactory *factory = GST_ELEMENT_FACTORY (feature); - GList *walk; - - PUT_ESCAPED ("longname", factory->details.longname); - PUT_ESCAPED ("class", factory->details.klass); - PUT_ESCAPED ("description", factory->details.description); - PUT_ESCAPED ("author", factory->details.author); - - walk = factory->staticpadtemplates; - - while (walk) { - GstPadTemplate *template = GST_PAD_TEMPLATE (walk->data); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - gst_xml_registry_save_pad_template (xmlregistry, template); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = g_list_next (walk); - } - - walk = factory->interfaces; - while (walk) { - PUT_ESCAPED ("interface", (gchar *) walk->data); - walk = g_list_next (walk); - } - - if (GST_URI_TYPE_IS_VALID (factory->uri_type)) { - gchar **protocol; - - PUT_ESCAPED ("uri_type", - factory->uri_type == GST_URI_SINK ? "sink" : "source"); - g_assert (factory->uri_protocols); - protocol = factory->uri_protocols; - while (*protocol) { - PUT_ESCAPED ("uri_protocol", *protocol); - protocol++; - } - } - } else if (GST_IS_TYPE_FIND_FACTORY (feature)) { - GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature); - gint i = 0; - - if (factory->caps) { - gst_xml_registry_save_caps (xmlregistry, factory->caps); - } - if (factory->extensions) { - while (factory->extensions[i]) { - PUT_ESCAPED ("extension", factory->extensions[i]); - i++; - } - } - } else if (GST_IS_INDEX_FACTORY (feature)) { - PUT_ESCAPED ("longdesc", GST_INDEX_FACTORY (feature)->longdesc); - } - return TRUE; -} - -static gboolean -gst_xml_registry_save_plugin (GstXMLRegistry * xmlregistry, GstPlugin * plugin) -{ - GList *walk; - - PUT_ESCAPED ("name", plugin->desc.name); - PUT_ESCAPED ("description", plugin->desc.description); - PUT_ESCAPED ("filename", plugin->filename); - PUT_ESCAPED ("version", plugin->desc.version); - PUT_ESCAPED ("license", plugin->desc.license); - PUT_ESCAPED ("source", plugin->desc.source); - PUT_ESCAPED ("package", plugin->desc.package); - PUT_ESCAPED ("origin", plugin->desc.origin); - - walk = plugin->features; - - while (walk) { - GstPluginFeature *feature = GST_PLUGIN_FEATURE (walk->data); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n", - g_type_name (G_OBJECT_TYPE (feature))); - gst_xml_registry_save_feature (xmlregistry, feature); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = g_list_next (walk); - } - return TRUE; -} - - -static gboolean -gst_xml_registry_save (GstRegistry * registry) -{ - GList *walk; - GstXMLRegistry *xmlregistry; - - g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE); - g_return_val_if_fail (registry->flags & GST_REGISTRY_WRITABLE, FALSE); - - xmlregistry = GST_XML_REGISTRY (registry); - - if (!CLASS (xmlregistry)->open_func (xmlregistry, GST_XML_REGISTRY_WRITE)) { - return FALSE; - } - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = gst_registry_get_path_list (GST_REGISTRY (registry)); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - while (walk) { - CLASS (xmlregistry)->save_func (xmlregistry, ""); - CLASS (xmlregistry)->save_func (xmlregistry, (gchar *) walk->data); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - walk = g_list_next (walk); - } - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = registry->plugins; - - while (walk) { - GstPlugin *plugin = GST_PLUGIN (walk->data); - - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - gst_xml_registry_save_plugin (xmlregistry, plugin); - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - walk = g_list_next (walk); - } - CLASS (xmlregistry)->save_func (xmlregistry, "\n"); - - CLASS (xmlregistry)->close_func (xmlregistry); - - return TRUE; -} - -static GList * -gst_xml_registry_rebuild_recurse (GstXMLRegistry * registry, - const gchar * directory) -{ - GList *ret = NULL; - gint dr_len, sf_len; - - if (g_file_test (directory, G_FILE_TEST_IS_DIR)) { - GDir *dir = g_dir_open (directory, 0, NULL); - - if (dir) { - const gchar *dirent; - - while ((dirent = g_dir_read_name (dir))) { - gchar *dirname; - - if (*dirent == '=') { - /* =build, =inst, etc. -- automake distcheck directories */ - continue; - } - - dirname = g_strjoin ("/", directory, dirent, NULL); - ret = - g_list_concat (ret, gst_xml_registry_rebuild_recurse (registry, - dirname)); - g_free (dirname); - } - g_dir_close (dir); - } - } else { - dr_len = strlen (directory); - sf_len = strlen (G_MODULE_SUFFIX); - if (dr_len >= sf_len && - strcmp (directory + dr_len - sf_len, G_MODULE_SUFFIX) == 0) { - ret = g_list_prepend (ret, g_strdup (directory)); - } - } - - return ret; -} - -static gboolean -gst_xml_registry_rebuild (GstRegistry * registry) -{ - GList *walk = NULL, *plugins = NULL, *prune = NULL; - GError *error = NULL; - guint length; - GstPlugin *plugin; - GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (registry); - - walk = registry->paths; - - while (walk) { - gchar *path = (gchar *) walk->data; - - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, - "Rebuilding registry %p in directory %s...", registry, path); - - plugins = g_list_concat (plugins, - gst_xml_registry_rebuild_recurse (xmlregistry, path)); - - walk = g_list_next (walk); - } - - do { - length = g_list_length (plugins); - - walk = plugins; - while (walk) { - g_assert (walk->data); - plugin = gst_plugin_load_file ((gchar *) walk->data, NULL); - if (plugin) { - prune = g_list_append (prune, walk->data); - gst_registry_add_plugin (registry, plugin); - } - - walk = g_list_next (walk); - } - - walk = prune; - while (walk) { - plugins = g_list_remove (plugins, walk->data); - g_free (walk->data); - walk = g_list_next (walk); - } - g_list_free (prune); - prune = NULL; - } while (g_list_length (plugins) != length); - - walk = plugins; - while (walk) { - if ((plugin = gst_plugin_load_file ((gchar *) walk->data, &error))) { - g_warning ("Bizarre behavior: plugin %s actually loaded", - (gchar *) walk->data); - gst_registry_add_plugin (registry, plugin); - } else { - GST_CAT_INFO (GST_CAT_PLUGIN_LOADING, "Plugin %s failed to load: %s", - (gchar *) walk->data, error->message); - - g_free (walk->data); - g_error_free (error); - error = NULL; - } - - walk = g_list_next (walk); - } - return TRUE; -} diff --git a/gst/registries/gstxmlregistry.h b/gst/registries/gstxmlregistry.h deleted file mode 100644 index daff15a..0000000 --- a/gst/registries/gstxmlregistry.h +++ /dev/null @@ -1,135 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstpluginfeature.h: Header for base GstXMLRegistry - * - * 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. - */ - - -#ifndef __GST_XML_REGISTRY_H__ -#define __GST_XML_REGISTRY_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_XML_REGISTRY \ - (gst_xml_registry_get_type()) -#define GST_XML_REGISTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XML_REGISTRY,GstXMLRegistry)) -#define GST_XML_REGISTRY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XML_REGISTRY,GstXMLRegistryClass)) -#define GST_XML_REGISTRY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XML_REGISTRY, GstXMLRegistryClass)) -#define GST_IS_XML_REGISTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XML_REGISTRY)) -#define GST_IS_XML_REGISTRY_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XML_REGISTRY)) - -typedef struct _GstXMLRegistry GstXMLRegistry; -typedef struct _GstXMLRegistryClass GstXMLRegistryClass; - -typedef enum { - GST_XML_REGISTRY_NONE, - GST_XML_REGISTRY_TOP, - GST_XML_REGISTRY_PATHS, - GST_XML_REGISTRY_PATH, - GST_XML_REGISTRY_PATHS_DONE, - GST_XML_REGISTRY_PLUGIN, - GST_XML_REGISTRY_FEATURE, - GST_XML_REGISTRY_PADTEMPLATE, - GST_XML_REGISTRY_CAPS, - GST_XML_REGISTRY_STRUCTURE, - GST_XML_REGISTRY_PROPERTIES -} GstXMLRegistryState; - -typedef enum { - GST_XML_REGISTRY_READ, - GST_XML_REGISTRY_WRITE -} GstXMLRegistryMode; - -typedef void (*GstXMLRegistryGetPerms) (GstXMLRegistry *registry); -typedef void (*GstXMLRegistryAddPathList) (GstXMLRegistry *registry); -typedef gboolean (*GstXMLRegistryParser) (GMarkupParseContext *context, - const gchar *tag, - const gchar *text, - gsize text_len, - GstXMLRegistry *registry, - GError **error); - -typedef gboolean (*GstXMLRegistryOpen) (GstXMLRegistry *registry, - GstXMLRegistryMode mode); -typedef gboolean (*GstXMLRegistryLoad) (GstXMLRegistry *registry, - gchar *dest, - gssize *size); -typedef gboolean (*GstXMLRegistrySave) (GstXMLRegistry *registry, - gchar *format, - ...); -typedef gboolean (*GstXMLRegistryClose) (GstXMLRegistry *registry); - -struct _GstXMLRegistry { - GstRegistry object; - - gchar *location; - gboolean open; - - FILE *regfile; - gchar *buffer; - - GMarkupParseContext *context; - GList *open_tags; - GstXMLRegistryState state; - GstXMLRegistryParser parser; - - GstPlugin *current_plugin; - GstPluginFeature *current_feature; - - gchar *name_template; - GstPadDirection direction; - GstPadPresence presence; - gchar *caps_string; - - gchar *caps_name; - gchar *structure_name; - - gboolean in_list; - GList *entry_list; - gchar *list_name; -}; - -struct _GstXMLRegistryClass { - GstRegistryClass parent_class; - - GstXMLRegistryGetPerms get_perms_func; - GstXMLRegistryAddPathList add_path_list_func; - GstXMLRegistryOpen open_func; - GstXMLRegistryLoad load_func; - GstXMLRegistrySave save_func; - GstXMLRegistryClose close_func; -}; - - -/* normal GObject stuff */ -GType gst_xml_registry_get_type (void); - -GstRegistry* gst_xml_registry_new (const gchar *name, const gchar *location); - -G_END_DECLS - -#endif /* __GST_XML_REGISTRY_H__ */ - diff --git a/gst/registries/registrytest.c b/gst/registries/registrytest.c deleted file mode 100644 index 27b11d0..0000000 --- a/gst/registries/registrytest.c +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#include "gstxmlregistry.h" - -gint -main (gint argc, gchar * argv[]) -{ - GstRegistry *registry; - - gst_init (&argc, &argv); - - registry = gst_xml_registry_new ("test", "reg.xml"); - - gst_registry_load (registry); - - - return 0; - -}