2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstxml.c: XML save/restore of pipelines
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include "gst_private.h"
35 static void gst_xml_class_init (GstXMLClass *klass);
36 static void gst_xml_init (GstXML *xml);
38 static GstObjectClass *parent_class = NULL;
39 static guint gst_xml_signals[LAST_SIGNAL] = { 0 };
42 gst_xml_get_type(void)
44 static GtkType xml_type = 0;
47 static const GtkTypeInfo xml_info = {
51 (GtkClassInitFunc)gst_xml_class_init,
52 (GtkObjectInitFunc)gst_xml_init,
55 (GtkClassInitFunc)NULL,
57 xml_type = gtk_type_unique (GST_TYPE_OBJECT, &xml_info);
63 gst_xml_class_init (GstXMLClass *klass)
65 GtkObjectClass *gtkobject_class;
67 gtkobject_class = (GtkObjectClass *)klass;
69 parent_class = gtk_type_class (GST_TYPE_OBJECT);
71 gst_xml_signals[OBJECT_LOADED] =
72 gtk_signal_new ("object_loaded", GTK_RUN_LAST, gtkobject_class->type,
73 GTK_SIGNAL_OFFSET (GstXMLClass, object_loaded),
74 gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2,
75 GST_TYPE_OBJECT, GTK_TYPE_POINTER);
77 gst_xml_signals[OBJECT_SAVED] =
78 gtk_signal_new ("object_saved", GTK_RUN_LAST, gtkobject_class->type,
79 GTK_SIGNAL_OFFSET (GstXMLClass, object_saved),
80 gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2,
81 GST_TYPE_OBJECT, GTK_TYPE_POINTER);
83 gtk_object_class_add_signals (gtkobject_class, gst_xml_signals, LAST_SIGNAL);
87 gst_xml_init(GstXML *xml)
89 xml->topelements = NULL;
95 * Create a new GstXML parser object.
97 * Returns: a pointer to a new GstXML object.
102 return GST_XML (gtk_type_new (GST_TYPE_XML));
107 * @element: The element to write out
109 * Converts the given element into an XML presentation.
111 * Returns: a pointer to an XML document
114 gst_xml_write (GstElement *element)
117 xmlNodePtr elementnode;
120 doc = xmlNewDoc ("1.0");
121 xmlNewGlobalNs (doc, "http://gstreamer.net/gst-core/1.0/", "gst");
122 ns = xmlNewNs (doc->xmlRootNode, "http://gstreamer.net/gst-core/1.0/", "gst");
124 doc->xmlRootNode = xmlNewDocNode (doc, ns, "GST-Pipeline", NULL);
126 elementnode = xmlNewChild (doc->xmlRootNode, NULL, "element", NULL);
128 gst_object_save_thyself (GST_OBJECT (element), elementnode);
134 gst_xml_real_parse (GstXML *xml, xmlDocPtr doc, const guchar *root)
136 xmlNodePtr field, cur;
139 cur = xmlDocGetRootElement(doc);
141 g_warning("gstxml: empty document\n");
144 ns = xmlSearchNsByHref(doc, cur, "http://gstreamer.net/gst-core/1.0/");
146 g_warning("gstxml: document of wrong type, core namespace not found\n");
149 if (strcmp(cur->name, "GST-Pipeline")) {
150 g_warning("gstxml: XML file is in wrong format\n");
156 field = cur->xmlChildrenNode;
159 if (!strcmp(field->name, "element") && (field->ns == xml->ns)) {
162 element = gst_element_load_thyself(field, NULL);
164 xml->topelements = g_list_prepend (xml->topelements, element);
169 xml->topelements = g_list_reverse (xml->topelements);
175 * gst_xml_parse_file:
176 * @fname: The filename with the xml description
177 * @root: The name of the root object to build
179 * Creates a new GstXML object (and the corresponding elements) from
180 * the XML file fname. Optionally it will only build the element from
181 * the element node root (if it is not NULL). This feature is useful
182 * if you only want to build a specific element from an XML file
183 * but not the pipeline it is embedded in. Note also that the XML parse
184 * tree is cached to speed up creating another GstXML object for
187 * Returns: TRUE on success, FALSE otherwise
190 gst_xml_parse_file (GstXML *xml, const guchar *fname, const guchar *root)
194 g_return_val_if_fail(fname != NULL, FALSE);
196 doc = xmlParseFile(fname);
199 g_warning("gstxml: XML file \"%s\" could not be read\n", fname);
203 return gst_xml_real_parse (xml, doc, root);
207 * gst_xml_parse_memory:
208 * @buffer: a pointer to the in memory XML buffer
209 * @size: the size of the buffer
210 * @root: the name of the root objects to build
212 * Creates a new GstXML object (and the corresponding elements) from
213 * an in memory XML buffer.
215 * Returns: a pointer to a new GstXML object
218 gst_xml_parse_memory (GstXML *xml, guchar *buffer, guint size, const gchar *root)
222 g_return_val_if_fail(buffer != NULL, FALSE);
224 doc = xmlParseMemory (buffer, size);
226 return gst_xml_real_parse (xml, doc, root);
230 gst_xml_object_loaded (GstXML *xml, GstObject *object, xmlNodePtr self)
232 gtk_signal_emit (GTK_OBJECT (xml), gst_xml_signals[OBJECT_LOADED], object, self);
236 gst_xml_object_saved (GstXML *xml, GstObject *object, xmlNodePtr self)
238 gtk_signal_emit (GTK_OBJECT (xml), gst_xml_signals[OBJECT_SAVED], object, self);
241 * gst_xml_get_topelements:
242 * @xml: The GstXML to get the elements from
244 * Retrive a list of toplevel elements.
246 * Returns: a GList of elements
249 gst_xml_get_topelements (GstXML *xml)
251 g_return_val_if_fail (xml != NULL, NULL);
253 return xml->topelements;
257 * gst_xml_get_element:
258 * @xml: The GstXML to get the element from
259 * @name: The name of element to retreive
261 * This function is used to get a pointer to the GstElement corresponding
262 * to name in the pipeline description. You would use this if you have
263 * to do anything to the element after loading.
265 * Returns: a pointer to a new GstElement
268 gst_xml_get_element (GstXML *xml, const guchar *name)
273 g_return_val_if_fail(xml != NULL, NULL);
274 g_return_val_if_fail(name != NULL, NULL);
276 GST_DEBUG (0,"gstxml: getting element \"%s\"\n", name);
278 topelements = gst_xml_get_topelements (xml);
280 while (topelements) {
281 GstElement *top = GST_ELEMENT (topelements->data);
283 GST_DEBUG (0,"gstxml: getting element \"%s\"\n", name);
284 if (!strcmp (GST_ELEMENT_NAME (top), name)) {
288 if (GST_IS_BIN (top)) {
289 element = gst_bin_get_by_name (GST_BIN (top), name);
295 topelements = g_list_next (topelements);