99afd257029f698daf8ae1bdb36b0a0e5c820074
[platform/upstream/gstreamer.git] / gst / gstxml.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstxml.c: XML save/restore of pipelines
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include "gst_private.h"
24
25 #include "gstxml.h"
26
27
28 static void     gst_xml_class_init              (GstXMLClass *klass);
29 static void     gst_xml_init                    (GstXML *xml);
30
31 static GstObjectClass *parent_class = NULL;
32
33 GtkType 
34 gst_xml_get_type(void) 
35 {
36   static GtkType xml_type = 0;
37
38   if (!xml_type) {
39     static const GtkTypeInfo xml_info = {
40       "GstXML",
41       sizeof(GstElement),
42       sizeof(GstElementClass),
43       (GtkClassInitFunc)gst_xml_class_init,
44       (GtkObjectInitFunc)gst_xml_init,
45       (GtkArgSetFunc)NULL,
46       (GtkArgGetFunc)NULL,
47       (GtkClassInitFunc)NULL,
48     };
49     xml_type = gtk_type_unique (GST_TYPE_XML, &xml_info);
50   }
51   return xml_type;
52 }
53
54 static void
55 gst_xml_class_init (GstXMLClass *klass) 
56 {
57   parent_class = gtk_type_class (GST_TYPE_OBJECT);
58 }
59
60 static void 
61 gst_xml_init(GstXML *xml) 
62 {
63 }
64
65 /**
66  * gst_xml_write:
67  * @element: The element to write out
68  *
69  * converts the given element into an XML presentation
70  *
71  * Returns: a pointer to an XML document
72  */
73 xmlDocPtr 
74 gst_xml_write (GstElement *element) 
75 {
76   xmlDocPtr doc;
77
78   doc = xmlNewDoc ("1.0");
79   doc->root = xmlNewDocNode (doc, NULL, "GST-Pipeline", NULL);
80
81   gst_element_save_thyself (element, doc->root);
82
83   return doc;
84 }
85
86 /**
87  * gst_xml_new:
88  * @fname: The filename with the xml description
89  * @root: The name of the root object to build
90  *
91  * Creates a new GstXML object (and the corresponding elements) from 
92  * the XML file fname. Optionally it will only build the element from 
93  * the element node root (if it is not NULL). This feature is useful 
94  * if you only want to build a specific element from an XML file
95  * but not the pipeline it is embedded in. Note also that the XML parse 
96  * tree is cached to speed up creating another GstXML object for 
97  * the same file
98  *
99  * Returns: a pointer to a new GstElement
100  */
101 GstXML*
102 gst_xml_new (const guchar *fname, const guchar *root) 
103 {
104   xmlDocPtr doc;
105   xmlNodePtr field;
106   GstXML *xml;
107
108   g_return_val_if_fail(fname != NULL, NULL);
109         
110   doc = xmlParseFile(fname);
111
112   if (!doc) {
113     g_print("gstxml: XML file \"%s\" could not be read\n", fname);
114     return NULL;
115   }
116   if (strcmp(doc->root->name, "GST-Pipeline")) {
117     g_print("gstxml: XML file \"%s\" is in wrong format\n", fname);
118     return NULL;
119   }
120
121   xml = GST_XML(gtk_type_new(GST_TYPE_XML));
122
123   xml->topelements = NULL;
124
125   field = doc->root->childs;
126   
127   while (field) {
128     if (!strcmp(field->name, "element")) {
129       GstElement *element;
130       
131       xml->elements = g_hash_table_new(g_str_hash, g_str_equal);
132
133       element = gst_element_load_thyself(field, xml->elements);
134       
135       g_hash_table_destroy (xml->elements);
136
137       xml->topelements = g_list_prepend (xml->topelements, element);
138     }
139     field = field->next;
140   }
141
142   xml->topelements = g_list_reverse (xml->topelements);
143
144   return xml;
145 }
146
147 /**
148  * gst_xml_get_topelements:
149  * @xml: The GstXML to get the elements from
150  *
151  * retrive a list of toplevel elements
152  *
153  * Returns: a GList of elements
154  */
155 GList*
156 gst_xml_get_topelements (GstXML *xml) 
157 {
158   g_return_val_if_fail (xml != NULL, NULL);
159
160   return xml->topelements;
161 }
162
163 /**
164  * gst_xml_get_element:
165  * @xml: The GstXML to get the element from
166  * @name: The name of element to retreive
167  *
168  * This function is used to get a pointer to the GstElement corresponding 
169  * to name in the pipeline description. You would use this if you have 
170  * to do anything to the element after loading.
171  *
172  * Returns: a pointer to a new GstElement
173  */
174 GstElement*
175 gst_xml_get_element (GstXML *xml, const guchar *name) 
176 {
177   GstElement *element;
178
179   g_return_val_if_fail(xml != NULL, NULL);
180   g_return_val_if_fail(name != NULL, NULL);
181
182   GST_DEBUG (0,"gstxml: getting element \"%s\"\n", name);
183
184   element = g_hash_table_lookup(xml->elements, name);
185
186   return element;
187 }