/libfreebob-1.0.11/src/xmlparser.c

# · C · 787 lines · 638 code · 103 blank · 46 comment · 109 complexity · 55d5a6cb0e67f0e601277ab7be782189 MD5 · raw file

  1. /* xmlparser.cpp
  2. * Copyright (C) 2005,06 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. #include "libfreebob/xmlparser.h"
  22. #include "libfreebob/freebob.h"
  23. #include <libxml/xmlmemory.h>
  24. #include <libxml/parser.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #undef DEBUG
  30. #ifdef DEBUG
  31. #define debugPrint( format, args... ) printf( format, ##args )
  32. #else
  33. #define debugPrint( format, args... )
  34. #endif
  35. /* XML parsing functions
  36. */
  37. freebob_stream_spec_t*
  38. freebob_xmlparse_stream( xmlDocPtr doc, xmlNodePtr cur )
  39. {
  40. freebob_stream_spec_t *stream_spec;
  41. // allocate memory
  42. stream_spec = malloc( sizeof(freebob_stream_spec_t) );
  43. if ( !stream_spec ) {
  44. fprintf( stderr, "Could not allocate memory for stream_spec" );
  45. return 0;
  46. }
  47. #define StreamSpecParseNode( NodeName, Member ) \
  48. if ( !xmlStrcmp( cur->name, (const xmlChar*) NodeName ) ) { \
  49. xmlChar* key = \
  50. xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); \
  51. debugPrint( "\t\t"#NodeName": %s\n", key ); \
  52. stream_spec->Member = strtol( (const char*) key, \
  53. (char**) 0, 10 ); \
  54. xmlFree( key ); \
  55. }
  56. cur = cur->xmlChildrenNode;
  57. while ( cur ) {
  58. StreamSpecParseNode( "Position", position );
  59. StreamSpecParseNode( "Location", location );
  60. StreamSpecParseNode( "Format", format );
  61. StreamSpecParseNode( "Type", type );
  62. StreamSpecParseNode( "DestinationPort", destination_port );
  63. if ( !xmlStrcmp( cur->name, (const xmlChar *) "Name" ) ) {
  64. xmlChar* key =
  65. xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );
  66. debugPrint( "\t\tname: %s\n", key );
  67. strncpy( stream_spec->name, (const char*) key,
  68. FREEBOB_MAX_NAME_LEN );
  69. xmlFree( key );
  70. }
  71. cur = cur->next;
  72. }
  73. #undef StreamSpecParseNode
  74. return stream_spec;
  75. }
  76. freebob_stream_info_t *
  77. freebob_xmlparse_streams( xmlDocPtr doc, xmlNodePtr node )
  78. {
  79. freebob_stream_info_t* stream_info;
  80. // allocate memory
  81. stream_info = malloc( sizeof(freebob_stream_info_t) );
  82. if ( !stream_info ) {
  83. fprintf( stderr, "Could not allocate memory for stream_info" );
  84. return 0;
  85. }
  86. // count number of child streams
  87. stream_info->nb_streams=0;
  88. xmlNodePtr cur = node->xmlChildrenNode;
  89. while (cur != NULL) {
  90. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Stream" ) ) {
  91. stream_info->nb_streams++;
  92. }
  93. cur = cur->next;
  94. }
  95. if ( stream_info->nb_streams ) {
  96. // allocate memory for the stream_spec pointer array
  97. stream_info->streams =
  98. (freebob_stream_spec_t**) calloc( stream_info->nb_streams,
  99. sizeof(freebob_stream_spec_t*) );
  100. if ( !stream_info->streams ) {
  101. fprintf( stderr, "Could not allocate memory for stream specs" );
  102. free( stream_info );
  103. return 0;
  104. }
  105. // parse the child stream_specs
  106. cur = node->xmlChildrenNode;
  107. int i = 0;
  108. while ( cur ) {
  109. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Stream" ) ) {
  110. stream_info->streams[i] =
  111. freebob_xmlparse_stream( doc, cur );
  112. if ( !stream_info->streams[i] ) {
  113. // invalid XML or memory problem, clean up.
  114. while ( --i ) {
  115. free( stream_info->streams[i] );
  116. }
  117. free( stream_info->streams );
  118. stream_info->streams = 0;
  119. free( stream_info );
  120. return 0;
  121. }
  122. i++;
  123. }
  124. cur = cur->next;
  125. }
  126. }
  127. return stream_info;
  128. }
  129. freebob_connection_spec_t*
  130. freebob_xmlparse_connection( xmlDocPtr doc, xmlNodePtr cur )
  131. {
  132. #define ConnectionSpecParseNode( NodeName, Member ) \
  133. if ( !xmlStrcmp( cur->name, (const xmlChar*) NodeName ) ) { \
  134. xmlChar* key = \
  135. xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); \
  136. debugPrint( "\t"#NodeName": %s\n", key ); \
  137. connection_spec->Member = strtol( (const char*) key, \
  138. (char**) 0, 10 ); \
  139. xmlFree( key ); \
  140. }
  141. // allocate memory
  142. freebob_connection_spec_t* connection_spec =
  143. calloc( 1, sizeof(freebob_connection_spec_t) );
  144. if ( !connection_spec ) {
  145. fprintf( stderr, "Could not allocate memory for connection_spec" );
  146. return 0;
  147. }
  148. cur = cur->xmlChildrenNode;
  149. while ( cur ) {
  150. ConnectionSpecParseNode( "Id", id );
  151. ConnectionSpecParseNode( "Node", node );
  152. ConnectionSpecParseNode( "Port", port );
  153. ConnectionSpecParseNode( "Plug", plug );
  154. ConnectionSpecParseNode( "Dimension", dimension );
  155. ConnectionSpecParseNode( "Samplerate", samplerate );
  156. ConnectionSpecParseNode( "IsoChannel", iso_channel );
  157. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Streams" ) ) {
  158. connection_spec->stream_info
  159. = freebob_xmlparse_streams( doc, cur );
  160. if ( !connection_spec->stream_info ) {
  161. free( connection_spec );
  162. return 0;
  163. }
  164. }
  165. cur = cur->next;
  166. }
  167. #undef ConnectionSpecParseNode
  168. return connection_spec;
  169. }
  170. freebob_supported_stream_format_spec_t*
  171. freebob_xmlparse_supported_stream_format_node( xmlDocPtr doc, xmlNodePtr cur )
  172. {
  173. #define FormatSpecParseNode( NodeName, Member ) \
  174. if ( !xmlStrcmp( cur->name, (const xmlChar*) NodeName ) ) { \
  175. xmlChar* key = \
  176. xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); \
  177. debugPrint( "\t"#NodeName": %s\n", key ); \
  178. format_spec->Member = strtol( (const char*) key, \
  179. (char**) 0, 10 ); \
  180. xmlFree( key ); \
  181. }
  182. // allocate memory
  183. freebob_supported_stream_format_spec_t* format_spec =
  184. calloc( 1, sizeof(freebob_supported_stream_format_spec_t) );
  185. if ( !format_spec ) {
  186. fprintf( stderr, "Could not allocate memory for format_spec" );
  187. return 0;
  188. }
  189. cur = cur->xmlChildrenNode;
  190. while ( cur ) {
  191. FormatSpecParseNode( "Samplerate", samplerate );
  192. FormatSpecParseNode( "AudioChannels", nb_audio_channels );
  193. FormatSpecParseNode( "MidiChannels", nb_midi_channels );
  194. cur = cur->next;
  195. }
  196. #undef FormatSpecParseNode
  197. return format_spec;
  198. }
  199. freebob_connection_info_t*
  200. freebob_xmlparse_connectionset( xmlDocPtr doc, xmlNodePtr node )
  201. {
  202. assert( node );
  203. // allocate memory
  204. freebob_connection_info_t* connection_info =
  205. malloc( sizeof(freebob_connection_info_t) );
  206. if ( !connection_info ) {
  207. fprintf( stderr, "Could not allocate memory for connection_info" );
  208. return 0;
  209. }
  210. // count number of child streams
  211. connection_info->nb_connections = 0;
  212. xmlNodePtr cur = node->xmlChildrenNode;
  213. while ( cur ) {
  214. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Connection" ) ) {
  215. connection_info->nb_connections =
  216. connection_info->nb_connections + 1;
  217. debugPrint( "nb_connections: %d\n",
  218. connection_info->nb_connections );
  219. }
  220. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Direction" ) ) {
  221. xmlChar* key =
  222. xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );
  223. debugPrint( "\tdirection: %s\n", key );
  224. connection_info->direction = strtol( (const char*) key,
  225. (char**) 0, 10);
  226. xmlFree( key );
  227. }
  228. cur = cur->next;
  229. }
  230. debugPrint( "ConnectionInfo contains %d connection_specs\n",
  231. connection_info->nb_connections );
  232. if ( connection_info->nb_connections ) {
  233. // allocate memory for the connection_spec pointer array
  234. connection_info->connections =
  235. (freebob_connection_spec_t**)
  236. calloc( connection_info->nb_connections,
  237. sizeof(freebob_connection_spec_t*) );
  238. if ( !connection_info->connections ) {
  239. fprintf( stderr,
  240. "Could not allocate memory for connection specs" );
  241. free( connection_info );
  242. return 0;
  243. }
  244. // parse the child stream_specs
  245. cur = node->xmlChildrenNode;
  246. int i = 0;
  247. while ( cur ) {
  248. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Connection" ) ) {
  249. connection_info->connections[i] =
  250. freebob_xmlparse_connection( doc, cur );
  251. if ( !connection_info->connections[i] ) {
  252. // invalid XML or memory problem, clean up.
  253. while ( --i ) {
  254. freebob_free_connection_spec( connection_info->connections[i] );
  255. }
  256. free( connection_info->connections );
  257. connection_info->connections = 0;
  258. free( connection_info );
  259. return 0;
  260. }
  261. i++;
  262. }
  263. cur = cur->next;
  264. }
  265. }
  266. return connection_info;
  267. }
  268. freebob_supported_stream_format_info_t*
  269. freebob_xmlparse_supported_stream_format( xmlDocPtr doc, xmlNodePtr node )
  270. {
  271. assert( node );
  272. // allocate memory
  273. freebob_supported_stream_format_info_t* stream_info =
  274. malloc( sizeof(freebob_supported_stream_format_info_t) );
  275. if ( !stream_info ) {
  276. fprintf( stderr, "Could not allocate memory for stream_info" );
  277. return 0;
  278. }
  279. // count number of child streams
  280. stream_info->nb_formats = 0;
  281. xmlNodePtr cur = node->xmlChildrenNode;
  282. while ( cur ) {
  283. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Format" ) ) {
  284. stream_info->nb_formats += 1;
  285. debugPrint( "\tnb_formats: %d\n",
  286. stream_info->nb_formats );
  287. }
  288. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Direction" ) ) {
  289. xmlChar* key =
  290. xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 );
  291. debugPrint( "\tdirection: %s\n", key );
  292. stream_info->direction = strtol( (const char*) key,
  293. (char**) 0, 10);
  294. xmlFree( key );
  295. }
  296. cur = cur->next;
  297. }
  298. debugPrint( "StreamFormatInfo contains %d stream_format_specs\n",
  299. stream_info->nb_formats );
  300. if ( stream_info->nb_formats ) {
  301. // allocate memory for the connection_spec pointer array
  302. stream_info->formats =
  303. (freebob_supported_stream_format_spec_t**)
  304. calloc( stream_info->nb_formats,
  305. sizeof(freebob_supported_stream_format_spec_t*) );
  306. if ( !stream_info->formats ) {
  307. fprintf( stderr,
  308. "Could not allocate memory for stream format specs" );
  309. free( stream_info );
  310. return 0;
  311. }
  312. // parse the child stream_specs
  313. cur = node->xmlChildrenNode;
  314. int i = 0;
  315. while ( cur ) {
  316. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Format" ) ) {
  317. stream_info->formats[i] =
  318. freebob_xmlparse_supported_stream_format_node( doc, cur );
  319. if ( !stream_info->formats[i] ) {
  320. // invalid XML or memory problem, clean up.
  321. while ( --i ) {
  322. freebob_free_supported_stream_format_spec( stream_info->formats[i] );
  323. }
  324. free( stream_info->formats );
  325. stream_info->formats = 0;
  326. free( stream_info );
  327. return 0;
  328. }
  329. i++;
  330. }
  331. cur = cur->next;
  332. }
  333. }
  334. return stream_info;
  335. }
  336. xmlNodePtr
  337. freebob_xmlparse_get_connectionset_node( xmlDocPtr doc,
  338. xmlNodePtr cur,
  339. int direction )
  340. {
  341. while ( cur ) {
  342. if ( !xmlStrcmp( cur->name, (const xmlChar*) "ConnectionSet" ) ) {
  343. xmlNodePtr cur2 = cur->xmlChildrenNode;
  344. while ( cur2 ) {
  345. if ( !xmlStrcmp( cur2->name, (const xmlChar*) "Direction" ) ) {
  346. xmlChar* key = xmlNodeListGetString( doc,
  347. cur2->xmlChildrenNode,
  348. 1 );
  349. int tmp_direction = strtol( (const char*) key,
  350. (char**) 0, 10 );
  351. xmlFree( key );
  352. if( tmp_direction == direction) {
  353. return cur;
  354. }
  355. }
  356. cur2 = cur2->next;
  357. }
  358. }
  359. cur = cur->next;
  360. }
  361. return 0;
  362. }
  363. xmlNodePtr
  364. freebob_xmlparse_get_supported_stream_format_node( xmlDocPtr doc,
  365. xmlNodePtr cur,
  366. int direction )
  367. {
  368. while ( cur ) {
  369. if ( !xmlStrcmp( cur->name, (const xmlChar*) "StreamFormats" ) ) {
  370. xmlNodePtr cur2 = cur->xmlChildrenNode;
  371. while ( cur2 ) {
  372. if ( !xmlStrcmp( cur2->name, (const xmlChar*) "Direction" ) ) {
  373. xmlChar* key = xmlNodeListGetString( doc,
  374. cur2->xmlChildrenNode,
  375. 1 );
  376. int tmp_direction = strtol( (const char*) key,
  377. (char**) 0, 10 );
  378. xmlFree( key );
  379. if( tmp_direction == direction) {
  380. return cur;
  381. }
  382. }
  383. cur2 = cur2->next;
  384. }
  385. }
  386. cur = cur->next;
  387. }
  388. return 0;
  389. }
  390. xmlNodePtr
  391. freebob_xmlparse_get_connection_set_by_node_id( xmlDocPtr doc,
  392. xmlNodePtr cur,
  393. int nodeId )
  394. {
  395. while ( cur ) {
  396. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Device" ) ) {
  397. xmlNodePtr cur2 = cur->xmlChildrenNode;
  398. while ( cur2 ) {
  399. if ( !xmlStrcmp( cur2->name,
  400. (const xmlChar*) "NodeId" ) )
  401. {
  402. xmlChar* key = xmlNodeListGetString( doc,
  403. cur2->xmlChildrenNode,
  404. 1 );
  405. int tmp_node_id = strtol( (const char*) key,
  406. (char**) 0, 10 );
  407. xmlFree( key );
  408. if ( tmp_node_id == nodeId ) {
  409. xmlNodePtr cur3 = cur->xmlChildrenNode;
  410. while ( cur3 ) {
  411. if ( !xmlStrcmp( cur3->name,
  412. (const xmlChar*) "ConnectionSet" ) )
  413. {
  414. return cur3;
  415. }
  416. cur3 = cur3->next;
  417. }
  418. }
  419. }
  420. cur2 = cur2->next;
  421. }
  422. }
  423. cur = cur->next;
  424. }
  425. return 0;
  426. }
  427. xmlNodePtr
  428. freebob_xmlparse_get_supported_stream_format_set_by_node_id( xmlDocPtr doc,
  429. xmlNodePtr cur,
  430. int nodeId )
  431. {
  432. while ( cur ) {
  433. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Device" ) ) {
  434. xmlNodePtr cur2 = cur->xmlChildrenNode;
  435. while ( cur2 ) {
  436. if ( !xmlStrcmp( cur2->name,
  437. (const xmlChar*) "NodeId" ) )
  438. {
  439. xmlChar* key = xmlNodeListGetString( doc,
  440. cur2->xmlChildrenNode,
  441. 1 );
  442. int tmp_node_id = strtol( (const char*) key,
  443. (char**) 0, 10 );
  444. xmlFree( key );
  445. if ( tmp_node_id == nodeId ) {
  446. xmlNodePtr cur3 = cur->xmlChildrenNode;
  447. while ( cur3 ) {
  448. if ( !xmlStrcmp( cur3->name,
  449. (const xmlChar*) "StreamFormats" ) )
  450. {
  451. return cur3;
  452. }
  453. cur3 = cur3->next;
  454. }
  455. }
  456. }
  457. cur2 = cur2->next;
  458. }
  459. }
  460. cur = cur->next;
  461. }
  462. return 0;
  463. }
  464. xmlNodePtr
  465. freebob_xmlparse_get_connection_set_by_device( xmlDocPtr doc,
  466. xmlNodePtr cur,
  467. int device )
  468. {
  469. int count=0;
  470. while ( count < device ) {
  471. if(!cur) {
  472. return NULL;
  473. }
  474. if(!xmlStrcmp( cur->name, (const xmlChar*) "Device" )) {
  475. count++;
  476. }
  477. cur=cur->next;
  478. }
  479. if ( !xmlStrcmp( cur->name, (const xmlChar*) "Device" ) ) {
  480. xmlNodePtr cur3 = cur->xmlChildrenNode;
  481. while ( cur3 ) {
  482. if ( !xmlStrcmp( cur3->name,
  483. (const xmlChar*) "ConnectionSet" ) )
  484. {
  485. return cur3;
  486. }
  487. cur3 = cur3->next;
  488. }
  489. } else {
  490. return NULL;
  491. }
  492. return NULL;
  493. }
  494. // a side effect is that both old connection info's are freed, unless NULL is returned!
  495. freebob_connection_info_t*
  496. freebob_xmlparse_append_connectionset(freebob_connection_info_t* connection_info, freebob_connection_info_t* cinfo)
  497. {
  498. if(connection_info==NULL) return cinfo;
  499. if(cinfo==NULL) return connection_info;
  500. if (connection_info->direction != cinfo->direction) {
  501. // direction mismatch
  502. return NULL;
  503. }
  504. freebob_connection_info_t *tmpci=calloc(1,sizeof(freebob_connection_info_t));
  505. if (!tmpci) {
  506. return NULL;
  507. }
  508. tmpci->nb_connections=connection_info->nb_connections+cinfo->nb_connections;
  509. tmpci->connections = calloc( tmpci->nb_connections, sizeof(freebob_connection_spec_t*));
  510. int i=0;
  511. int c=0;
  512. for(i=0;i<connection_info->nb_connections;i++) {
  513. tmpci->connections[c]=connection_info->connections[i]; // these are pointers
  514. c++;
  515. }
  516. for(i=0;i<cinfo->nb_connections;i++) {
  517. tmpci->connections[c]=cinfo->connections[i]; // these are pointers
  518. c++;
  519. }
  520. free(connection_info->connections);
  521. free(cinfo->connections);
  522. free(connection_info);
  523. free(cinfo);
  524. connection_info=NULL;
  525. cinfo=NULL;
  526. return tmpci;
  527. }
  528. // a side effect is that both old connection info's are freed, unless NULL is returned!
  529. freebob_supported_stream_format_info_t*
  530. freebob_xmlparse_append_stream_format(freebob_supported_stream_format_info_t* stream_info,
  531. freebob_supported_stream_format_info_t* cinfo)
  532. {
  533. if ( !stream_info ) {
  534. return cinfo;
  535. }
  536. if ( !cinfo ) {
  537. return stream_info;
  538. }
  539. if ( stream_info->direction != cinfo->direction ) {
  540. return 0;
  541. }
  542. freebob_supported_stream_format_info_t* tmpci =
  543. calloc( 1, sizeof( freebob_supported_stream_format_info_t ) );
  544. if ( !tmpci ) {
  545. return 0;
  546. }
  547. tmpci->nb_formats =
  548. stream_info->nb_formats + cinfo->nb_formats;
  549. tmpci->formats =
  550. calloc( tmpci->nb_formats,
  551. sizeof( freebob_supported_stream_format_spec_t* ) );
  552. int c = 0;
  553. for( int i = 0; i < stream_info->nb_formats; i++, c++ ) {
  554. tmpci->formats[c] = stream_info->formats[i];
  555. }
  556. for ( int i = 0; i < cinfo->nb_formats; i++, c++ ) {
  557. tmpci->formats[c] = cinfo->formats[i];
  558. }
  559. free( stream_info->formats );
  560. free( cinfo->formats );
  561. free( stream_info );
  562. free( cinfo );
  563. stream_info = 0;
  564. cinfo = 0;
  565. return tmpci;
  566. }
  567. int
  568. freebob_xmlparse_get_nb_devices( xmlDocPtr doc,
  569. xmlNodePtr cur)
  570. {
  571. int count=0;
  572. while (cur != NULL) {
  573. if ((!xmlStrcmp(cur->name, (const xmlChar *)"Device"))) {
  574. count++;
  575. }
  576. cur = cur->next;
  577. }
  578. return count;
  579. }
  580. freebob_connection_info_t*
  581. freebob_xmlparse_get_connection_info( xmlDocPtr doc,
  582. int node_id,
  583. int direction )
  584. {
  585. xmlNodePtr base = xmlDocGetRootElement(doc);
  586. xmlNodePtr cur;
  587. if ( !base ) {
  588. fprintf( stderr, "empty document\n");
  589. return 0;
  590. }
  591. if ( xmlStrcmp( base->name, (const xmlChar*) "FreeBoBConnectionInfo") ) {
  592. fprintf( stderr,
  593. "document of the wrong type, root node "
  594. "!= FreeBoBConnectionInfo\n" );
  595. return 0;
  596. }
  597. base = base->xmlChildrenNode;
  598. if ( !base ) {
  599. fprintf( stderr, "Root node has no children!\n" );
  600. return 0;
  601. }
  602. if( node_id > -1) {
  603. cur = freebob_xmlparse_get_connection_set_by_node_id( doc, base, node_id );
  604. if ( !cur ) {
  605. fprintf( stderr,
  606. "Could not get description for node id %d\n", node_id );
  607. return 0;
  608. }
  609. cur = freebob_xmlparse_get_connectionset_node( doc, cur, direction );
  610. if ( !cur ) {
  611. fprintf( stderr,
  612. "Could not get a connection set for direction %d\n",
  613. direction );
  614. return 0;
  615. }
  616. freebob_connection_info_t* connection_info =
  617. freebob_xmlparse_connectionset( doc, cur );
  618. return connection_info;
  619. } else {
  620. freebob_connection_info_t* connection_info=NULL;
  621. int device_nr=0;
  622. int nb_devices=freebob_xmlparse_get_nb_devices(doc, base);
  623. /* fprintf( stderr,
  624. "Nb devices %d\n",
  625. nb_devices );*/
  626. for(device_nr=0;device_nr<nb_devices;device_nr++) {
  627. cur = freebob_xmlparse_get_connection_set_by_device( doc, base, device_nr );
  628. if ( !cur ) {
  629. fprintf( stderr,
  630. "Could not get description for device %d\n", device_nr );
  631. return 0;
  632. }
  633. cur = freebob_xmlparse_get_connectionset_node( doc, cur, direction );
  634. if ( !cur ) {
  635. fprintf( stderr,
  636. "Could not get a connection set for direction %d\n",
  637. direction );
  638. return 0;
  639. }
  640. freebob_connection_info_t* cinfo = freebob_xmlparse_connectionset( doc, cur );
  641. connection_info=freebob_xmlparse_append_connectionset(connection_info,cinfo);
  642. }
  643. return connection_info;
  644. }
  645. }
  646. freebob_supported_stream_format_info_t*
  647. freebob_xmlparse_get_stream_formats( xmlDocPtr doc,
  648. int node_id,
  649. int direction )
  650. {
  651. xmlNodePtr base = xmlDocGetRootElement(doc);
  652. xmlNodePtr cur;
  653. if ( !base ) {
  654. fprintf( stderr, "empty document\n");
  655. return 0;
  656. }
  657. if ( xmlStrcmp( base->name, (const xmlChar*) "FreeBoBConnectionInfo") ) {
  658. fprintf( stderr,
  659. "document of the wrong type, root node "
  660. "!= FreeBoBConnectionInfo\n" );
  661. return 0;
  662. }
  663. base = base->xmlChildrenNode;
  664. if ( !base ) {
  665. fprintf( stderr, "Root node has no children!\n" );
  666. return 0;
  667. }
  668. cur = freebob_xmlparse_get_supported_stream_format_set_by_node_id( doc, base, node_id );
  669. if ( !cur ) {
  670. fprintf( stderr,
  671. "Could not get description for node id %d\n", node_id );
  672. return 0;
  673. }
  674. cur = freebob_xmlparse_get_supported_stream_format_node( doc, cur, direction );
  675. if ( !cur ) {
  676. fprintf( stderr,
  677. "Could not get a connection set for direction %d\n",
  678. direction );
  679. return 0;
  680. }
  681. freebob_supported_stream_format_info_t* stream_info =
  682. freebob_xmlparse_supported_stream_format( doc, cur );
  683. return stream_info; return 0;
  684. }