int tt_nodes_Read( xml_reader_t *p_reader, tt_node_t *p_root_node ) { size_t i_depth = 0; tt_node_t *p_node = p_root_node; do { const char* psz_node_name; int i_type = xml_ReaderNextNode( p_reader, &psz_node_name ); /* !warn read empty state now as attributes reading will **** it up */ bool b_empty = xml_ReaderIsEmptyElement( p_reader ); if( i_type <= XML_READER_NONE ) break; switch( i_type ) { default: break; case XML_READER_STARTELEM: { tt_node_t *p_newnode = tt_node_New( p_reader, p_node, psz_node_name ); if( !p_newnode ) return VLC_EGENERIC; if( !b_empty ) { p_node = p_newnode; i_depth++; } break; } case XML_READER_TEXT: { tt_textnode_t *p_textnode = tt_textnode_New( p_node, psz_node_name ); VLC_UNUSED(p_textnode); } break; case XML_READER_ENDELEM: { if( strcmp( psz_node_name, p_node->psz_node_name ) ) return VLC_EGENERIC; if( i_depth == 0 ) { if( p_node != p_root_node ) return VLC_EGENERIC; break; /* END */ } i_depth--; p_node = p_node->p_parent; break; } } } while( 1 ); return VLC_SUCCESS; }
static int ReadTTML( demux_t* p_demux ) { demux_sys_t* p_sys = p_demux->p_sys; const char* psz_node_name; do { int i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_node_name ); bool b_empty = xml_ReaderIsEmptyElement( p_sys->p_reader ); if( i_type <= XML_READER_NONE ) break; switch(i_type) { default: break; case XML_READER_STARTELEM: if( tt_node_NameCompare( psz_node_name, "tt" ) || p_sys->p_rootnode != NULL ) return VLC_EGENERIC; p_sys->p_rootnode = tt_node_New( p_sys->p_reader, NULL, psz_node_name ); if( b_empty ) break; if( !p_sys->p_rootnode || tt_nodes_Read( p_sys->p_reader, p_sys->p_rootnode ) != VLC_SUCCESS ) return VLC_EGENERIC; break; case XML_READER_ENDELEM: if( !p_sys->p_rootnode || tt_node_NameCompare( psz_node_name, p_sys->p_rootnode->psz_node_name ) ) return VLC_EGENERIC; break; } } while( 1 ); if( p_sys->p_rootnode == NULL ) return VLC_EGENERIC; return VLC_SUCCESS; }