root/trunk/libfreebob/src/xmlparser.c

Revision 125, 12.6 kB (checked in by wagi, 18 years ago)

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* xmlparser.cpp
2  * Copyright (C) 2005 Pieter Palmers, Daniel Wagner
3  *
4  * This file is part of FreeBoB
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  */
21
22 #include "libfreebob/xmlparser.h"
23 #include "libfreebob/freebob.h"
24
25 #include <libxml/xmlmemory.h>
26 #include <libxml/parser.h>
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32
33 #undef DEBUG
34 #ifdef DEBUG
35     #define debugPrint( format, args... ) printf( format, ##args )
36 #else
37     #define debugPrint( format, args... )
38 #endif
39
40 /* XML parsing functions
41  */
42 freebob_stream_spec_t*
43 freebob_xmlparse_stream( xmlDocPtr doc, xmlNodePtr cur )
44 {
45     freebob_stream_spec_t *stream_spec;
46
47     // allocate memory
48     stream_spec = malloc( sizeof(freebob_stream_spec_t) );
49     if ( !stream_spec ) {
50         fprintf( stderr, "Could not allocate memory for stream_spec" );
51         return 0;
52     }
53
54     #define StreamSpecParseNode( NodeName, Member )                     \
55         if ( !xmlStrcmp( cur->name, (const xmlChar*) NodeName ) ) {     \
56             xmlChar* key =                                              \
57                 xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );   \
58             debugPrint( "\t\t"#NodeName": %s\n", key );                 \
59             stream_spec->Member = strtol( (const char*) key,            \
60                                           (char**) 0, 10 );             \
61             xmlFree( key );                                             \
62         }
63
64     cur = cur->xmlChildrenNode;
65     while ( cur ) {
66         StreamSpecParseNode( "Position", position );
67         StreamSpecParseNode( "Location", location );
68         StreamSpecParseNode( "Format", format );
69         StreamSpecParseNode( "Type", type );
70         StreamSpecParseNode( "DestinationPort", destination_port );
71
72         if ( !xmlStrcmp( cur->name, (const xmlChar *) "Name" ) ) {
73             xmlChar* key =
74                 xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );
75             debugPrint( "\t\tname: %s\n", key );
76             strncpy( stream_spec->name, (const char*) key,
77                      FREEBOB_MAX_NAME_LEN );
78             xmlFree( key );
79         }
80         cur = cur->next;
81     }
82     #undef StreamSpecParseNode
83
84     return stream_spec;
85 }
86
87 freebob_stream_info_t *
88 freebob_xmlparse_streams( xmlDocPtr doc, xmlNodePtr node )
89 {
90     freebob_stream_info_t* stream_info;
91
92     // allocate memory
93     stream_info = malloc( sizeof(freebob_stream_info_t) );
94     if ( !stream_info ) {
95         fprintf( stderr, "Could not allocate memory for stream_info" );
96         return 0;
97     }
98
99     // count number of child streams
100     stream_info->nb_streams=0;
101     xmlNodePtr cur = node->xmlChildrenNode;
102     while (cur != NULL) {
103         if ( !xmlStrcmp( cur->name, (const xmlChar*) "Stream" ) ) {
104             stream_info->nb_streams++;
105         }
106         cur = cur->next;
107     }
108
109     if ( stream_info->nb_streams ) {
110         // allocate memory for the stream_spec pointer array
111         stream_info->streams =
112             (freebob_stream_spec_t**) calloc( stream_info->nb_streams,
113                                               sizeof(freebob_stream_spec_t*) );
114
115         if ( !stream_info->streams ) {
116             fprintf( stderr, "Could not allocate memory for stream specs" );
117             free( stream_info );
118             return 0;
119         }
120
121         // parse the child stream_specs
122         cur = node->xmlChildrenNode;
123         int i = 0;
124         while ( cur ) {
125             if ( !xmlStrcmp( cur->name, (const xmlChar*) "Stream" ) ) {
126                 stream_info->streams[i] =
127                     freebob_xmlparse_stream( doc, cur );
128
129                 if ( !stream_info->streams[i] ) {
130                     // invalid XML or memory problem, clean up.
131                     while ( --i ) {
132                         free( stream_info->streams[i] );
133                     }
134                     free( stream_info->streams );
135                     stream_info->streams = 0;
136                     free( stream_info );
137                     return 0;
138                 }
139                 i++;
140             }
141             cur = cur->next;
142         }
143     }
144     return stream_info;
145 }
146
147
148
149
150 freebob_connection_spec_t*
151 freebob_xmlparse_connection( xmlDocPtr doc, xmlNodePtr cur )
152 {
153     #define ConnectionSpecParseNode( NodeName, Member )                  \
154          if ( !xmlStrcmp( cur->name, (const xmlChar*) NodeName ) ) {     \
155              xmlChar* key =                                              \
156                  xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );   \
157              debugPrint( "\t"#NodeName": %s\n",  key );                  \
158              connection_spec->Member = strtol( (const char*) key,        \
159                                                (char**) 0, 10 );         \
160              xmlFree( key );                                             \
161          }
162
163     // allocate memory
164     freebob_connection_spec_t* connection_spec =
165         calloc( 1, sizeof(freebob_connection_spec_t) );
166     if ( !connection_spec ) {
167         fprintf( stderr, "Could not allocate memory for connection_spec" );
168         return 0;
169     }
170
171     cur = cur->xmlChildrenNode;
172     while ( cur ) {
173         ConnectionSpecParseNode( "Id", id );
174         ConnectionSpecParseNode( "Node", node );
175         ConnectionSpecParseNode( "Port", port );
176         ConnectionSpecParseNode( "Plug", plug );
177         ConnectionSpecParseNode( "Dimension", dimension );
178         ConnectionSpecParseNode( "Samplerate", samplerate );
179
180         if ( !xmlStrcmp( cur->name, (const xmlChar*) "Streams" ) ) {
181             connection_spec->stream_info
182                 = freebob_xmlparse_streams( doc, cur );
183             if ( !connection_spec->stream_info ) {
184                 free( connection_spec );
185                 return 0;
186             }
187         }
188         cur = cur->next;
189     }
190     #undef ConnectionSpecParseNode
191
192     return connection_spec;
193 }
194
195 freebob_connection_info_t*
196 freebob_xmlparse_connectionset( xmlDocPtr doc, xmlNodePtr node )
197 {
198     assert( node );
199
200     // allocate memory
201     freebob_connection_info_t* connection_info =
202         malloc( sizeof(freebob_connection_info_t) );
203     if ( !connection_info ) {
204         fprintf( stderr, "Could not allocate memory for connection_info" );
205         return 0;
206     }
207
208     // count number of child streams
209     connection_info->nb_connections = 0;
210     xmlNodePtr cur = node->xmlChildrenNode;
211     while ( cur ) {
212         if ( !xmlStrcmp( cur->name, (const xmlChar*) "Connection" ) ) {
213             connection_info->nb_connections =
214                 connection_info->nb_connections + 1;
215             debugPrint( "nb_connections: %d\n",
216                         connection_info->nb_connections );
217         }
218
219         if ( !xmlStrcmp( cur->name, (const xmlChar*) "Direction" ) ) {
220             xmlChar* key =
221                 xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );
222             debugPrint( "\tdirection: %s\n", key );
223             connection_info->direction = strtol( (const char*) key,
224                                                  (char**) 0, 10);
225             xmlFree( key );
226         }
227         cur = cur->next;
228     }
229
230     debugPrint( "ConnectionInfo contains %d connection_specs\n",
231                 connection_info->nb_connections );
232
233     if ( connection_info->nb_connections ) {
234         // allocate memory for the connection_spec pointer array
235         connection_info->connections =
236             (freebob_connection_spec_t**)
237             calloc( connection_info->nb_connections,
238                     sizeof(freebob_connection_spec_t*) );
239
240         if ( !connection_info->connections ) {
241             fprintf( stderr,
242                      "Could not allocate memory for connection specs" );
243             free( connection_info );
244             return 0;
245         }
246
247         // parse the child stream_specs
248         cur = node->xmlChildrenNode;
249         int i = 0;
250         while ( cur ) {
251             if ( !xmlStrcmp( cur->name, (const xmlChar*) "Connection" ) ) {
252                 connection_info->connections[i] =
253                     freebob_xmlparse_connection( doc, cur );
254
255                 if ( !connection_info->connections[i] ) {
256                     // invalid XML or memory problem, clean up.
257                     while ( --i ) {
258                         freebob_free_connection_spec( connection_info->connections[i] );
259                     }
260                     free( connection_info->connections );
261                     connection_info->connections = 0;
262                     free( connection_info );
263                     return 0;
264                 }
265                 i++;
266             }
267             cur = cur->next;
268         }
269     }
270
271     return connection_info;
272 }
273
274 xmlNodePtr
275 freebob_xmlparse_get_connectionset_node( xmlDocPtr doc,
276                                          xmlNodePtr cur,
277                                          int direction )
278 {
279     while ( cur ) {
280         if ( !xmlStrcmp( cur->name, (const xmlChar*) "ConnectionSet" ) ) {
281             xmlNodePtr cur2 = cur->xmlChildrenNode;
282             while ( cur2 ) {
283                 if ( !xmlStrcmp( cur2->name, (const xmlChar*) "Direction" ) ) {
284                     xmlChar* key = xmlNodeListGetString( doc,
285                                                          cur2->xmlChildrenNode,
286                                                          1 );
287                     int tmp_direction = strtol( (const char*) key,
288                                                 (char**) 0, 10 );
289                     xmlFree( key );
290                     if( tmp_direction == direction) {
291                         return cur;
292                     }
293                 }
294                 cur2 = cur2->next;
295             }
296         }
297         cur = cur->next;
298     }
299     return 0;
300 }
301
302 xmlNodePtr
303 freebob_xmlparse_get_connection_set_by_node_id( xmlDocPtr doc,
304                                                 xmlNodePtr cur,
305                                                 int nodeId )
306 {
307     while ( cur ) {
308         if ( !xmlStrcmp( cur->name, (const xmlChar*) "Device" ) ) {
309             xmlNodePtr cur2 = cur->xmlChildrenNode;
310             while ( cur2 ) {
311                 if ( !xmlStrcmp( cur2->name,
312                                  (const xmlChar*) "NodeId" ) )
313                 {
314                     xmlChar* key = xmlNodeListGetString( doc,
315                                                          cur2->xmlChildrenNode,
316                                                          1 );
317                     int tmp_node_id = strtol( (const char*) key,
318                                               (char**) 0, 10 );
319                     xmlFree( key );
320
321                     if ( tmp_node_id == nodeId ) {
322                         xmlNodePtr cur3 = cur->xmlChildrenNode;
323                         while ( cur3 ) {
324                             if ( !xmlStrcmp( cur3->name,
325                                              (const xmlChar*) "ConnectionSet" ) )
326                             {
327                                 return cur3;
328                             }
329                             cur3 = cur3->next;
330                         }
331                     }
332                 }
333                 cur2 = cur2->next;
334             }
335         }
336         cur = cur->next;
337     }
338
339     return 0;
340 }
341
342 freebob_connection_info_t*
343 freebob_xmlparse_get_connection_info( xmlDocPtr doc,
344                                       int node_id,
345                                       int direction )
346 {
347     xmlNodePtr cur = xmlDocGetRootElement(doc);
348     if ( !cur ) {
349         fprintf( stderr, "empty document\n");
350         return 0;
351     }
352
353     if ( xmlStrcmp( cur->name, (const xmlChar*) "FreeBobConnectionInfo") ) {
354         fprintf( stderr,
355                  "document of the wrong type, root node "
356                  "!= FreeBobConnectionInfo\n" );
357         return 0;
358     }
359
360     cur = cur->xmlChildrenNode;
361     if ( !cur ) {
362         fprintf( stderr, "Root node has no children!\n" );
363         return 0;
364     }
365
366     cur = freebob_xmlparse_get_connection_set_by_node_id( doc, cur, node_id );
367     if ( !cur ) {
368         fprintf( stderr,
369                  "Could not get find description for node id %d\n", node_id );
370         return 0;
371     }
372     cur = freebob_xmlparse_get_connectionset_node( doc, cur, direction );
373     if ( !cur ) {
374         fprintf( stderr,
375                  "Could not get a connection set for direction %d\n",
376                  direction );
377         return 0;
378     }
379
380     freebob_connection_info_t* connection_info =
381         freebob_xmlparse_connectionset( doc, cur );
382
383     return connection_info;
384 }
Note: See TracBrowser for help on using the browser.