]> git.sesse.net Git - vlc/blobdiff - modules/misc/xml/libxml.c
XML reader: use VLC object and plugin infrastructures
[vlc] / modules / misc / xml / libxml.c
index c098f6824e1cc2ff0e3a2b16b1977af2172aa446..c2c74c7edfbc4a824daf4ac24426630ee536f05e 100644 (file)
@@ -28,9 +28,9 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 
-#include "vlc_block.h"
-#include "vlc_stream.h"
-#include "vlc_xml.h"
+#include <vlc_block.h>
+#include <vlc_stream.h>
+#include <vlc_xml.h>
 
 #include <libxml/xmlreader.h>
 #include <libxml/catalog.h>
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
 
-vlc_module_begin();
-    set_description( N_("XML Parser (using libxml2)") );
-    set_capability( "xml", 10 );
-    set_callbacks( Open, Close );
-vlc_module_end();
+static int ReaderOpen( vlc_object_t * );
+static void ReaderClose( vlc_object_t * );
 
-struct xml_reader_sys_t
-{
-    /* libxml2 reader context */
-    xmlTextReaderPtr p_reader;
-};
 
-static xml_reader_t *ReaderCreate( xml_t *, stream_t * );
-static void ReaderDelete( xml_reader_t * );
+vlc_module_begin ()
+    set_description( N_("XML Parser (using libxml2)") )
+    set_capability( "xml", 10 )
+    set_callbacks( Open, Close )
+
+#ifdef WIN32
+    cannot_unload_broken_library()
+#endif
+
+    add_submodule()
+    set_capability( "xml reader", 10 )
+    set_callbacks( ReaderOpen, ReaderClose )
+
+vlc_module_end ()
+
 static int ReaderRead( xml_reader_t * );
 static int ReaderNodeType( xml_reader_t * );
 static char *ReaderName( xml_reader_t * );
@@ -67,6 +72,8 @@ static void CatalogLoad( xml_t *, const char * );
 static void CatalogAdd( xml_t *, const char *, const char *, const char * );
 static int StreamRead( void *p_context, char *p_buffer, int i_buffer );
 
+static vlc_mutex_t lock = VLC_STATIC_MUTEX;
+
 /*****************************************************************************
  * Module initialization
  *****************************************************************************/
@@ -74,8 +81,12 @@ static int Open( vlc_object_t *p_this )
 {
     xml_t *p_xml = (xml_t *)p_this;
 
-    p_xml->pf_reader_create = ReaderCreate;
-    p_xml->pf_reader_delete = ReaderDelete;
+    if( !xmlHasFeature( XML_WITH_THREAD ) )
+        return VLC_EGENERIC;
+
+    vlc_mutex_lock( &lock );
+    xmlInitParser();
+    vlc_mutex_unlock( &lock );
 
     p_xml->pf_catalog_load = CatalogLoad;
     p_xml->pf_catalog_add  = CatalogAdd;
@@ -88,6 +99,11 @@ static int Open( vlc_object_t *p_this )
  *****************************************************************************/
 static void Close( vlc_object_t *p_this )
 {
+#ifdef LIBXML_GETS_A_CLUE_ABOUT_REENTRANCY_AND_MEMORY_LEAKS
+    vlc_mutex_lock( &lock );
+    xmlCleanupParser();
+    vlc_mutex_unlock( &lock );
+#endif
     VLC_UNUSED(p_this);
     return;
 }
@@ -120,33 +136,35 @@ static void ReaderErrorHandler( void *p_arg, const char *p_msg,
     VLC_UNUSED(severity);
     xml_reader_t *p_reader = (xml_reader_t *)p_arg;
     int line = xmlTextReaderLocatorLineNumber( locator );
-    msg_Err( p_reader->p_xml, "XML parser error (line %d) : %s", line, p_msg );
+    msg_Err( p_reader, "XML parser error (line %d) : %s", line, p_msg );
 }
 
-static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *p_stream )
+static int ReaderOpen( vlc_object_t *p_this )
 {
-    xml_reader_t *p_reader;
-    xml_reader_sys_t *p_sys;
+    xml_reader_t *p_reader = (xml_reader_t *)p_this;
     xmlTextReaderPtr p_libxml_reader;
 
-    p_libxml_reader = xmlReaderForIO( StreamRead, NULL, p_stream,
+    if( !xmlHasFeature( XML_WITH_THREAD ) )
+        return VLC_EGENERIC;
+
+    vlc_mutex_lock( &lock );
+    xmlInitParser();
+    vlc_mutex_unlock( &lock );
+
+    p_libxml_reader = xmlReaderForIO( StreamRead, NULL, p_reader->p_stream,
                                       NULL, NULL, 0 );
     if( !p_libxml_reader )
     {
-        msg_Err( p_xml, "failed to create XML parser" );
-        return 0;
+        msg_Err( p_this, "failed to create XML parser" );
+        return VLC_ENOMEM;
     }
 
-    p_reader = malloc( sizeof(xml_reader_t) );
-    p_reader->p_sys = p_sys = malloc( sizeof(xml_reader_sys_t) );
-    p_reader->p_sys->p_reader = p_libxml_reader;
-    p_reader->p_xml = p_xml;
+    p_reader->p_sys = (void *)p_libxml_reader;
 
     /* Set the error handler */
     xmlTextReaderSetErrorHandler( p_libxml_reader,
                                   ReaderErrorHandler, p_reader );
 
-
     p_reader->pf_read = ReaderRead;
     p_reader->pf_node_type = ReaderNodeType;
     p_reader->pf_name = ReaderName;
@@ -154,22 +172,27 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *p_stream )
     p_reader->pf_next_attr = ReaderNextAttr;
     p_reader->pf_use_dtd = ReaderUseDTD;
 
-    return p_reader;
+    return VLC_SUCCESS;
 }
 
-static void ReaderDelete( xml_reader_t *p_reader )
+static void ReaderClose( vlc_object_t *p_this )
 {
-    xmlFreeTextReader( p_reader->p_sys->p_reader );
-    free( p_reader->p_sys );
-    free( p_reader );
+    xml_reader_t *p_reader = (xml_reader_t *)p_this;
+
+#ifdef LIBXML_GETS_A_CLUE_ABOUT_REENTRANCY_AND_MEMORY_LEAKS
+    vlc_mutex_lock( &lock );
+    xmlCleanupParser();
+    vlc_mutex_unlock( &lock );
+#endif
+    xmlFreeTextReader( (void *)p_reader->p_sys );
 }
 
 static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use )
 {
     /* Activate DTD validation */
-    xmlTextReaderSetParserProp( p_reader->p_sys->p_reader,
+    xmlTextReaderSetParserProp( (void *)p_reader->p_sys,
                                 XML_PARSER_DEFAULTATTRS, b_use );
-    xmlTextReaderSetParserProp( p_reader->p_sys->p_reader,
+    xmlTextReaderSetParserProp( (void *)p_reader->p_sys,
                                 XML_PARSER_VALIDATE, b_use );
 
     return VLC_SUCCESS;
@@ -177,7 +200,7 @@ static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use )
 
 static int ReaderRead( xml_reader_t *p_reader )
 {
-    int i_ret = xmlTextReaderRead( p_reader->p_sys->p_reader );
+    int i_ret = xmlTextReaderRead( (void *)p_reader->p_sys );
 
 #if 0
     switch( i_ret )
@@ -191,7 +214,7 @@ static int ReaderRead( xml_reader_t *p_reader )
 
 static int ReaderNodeType( xml_reader_t *p_reader )
 {
-    int i_ret = xmlTextReaderNodeType( p_reader->p_sys->p_reader );
+    int i_ret = xmlTextReaderNodeType( (void *)p_reader->p_sys );
 
     switch( i_ret )
     {
@@ -219,24 +242,22 @@ static int ReaderNodeType( xml_reader_t *p_reader )
 static char *ReaderName( xml_reader_t *p_reader )
 {
     const xmlChar *psz_name =
-        xmlTextReaderConstName( p_reader->p_sys->p_reader );
+        xmlTextReaderConstName( (void *)p_reader->p_sys );
 
-    if( psz_name ) return strdup( (const char *)psz_name );
-    else return 0;
+    return psz_name ? strdup( (const char *)psz_name ) : NULL;
 }
 
 static char *ReaderValue( xml_reader_t *p_reader )
 {
     const xmlChar *psz_value =
-        xmlTextReaderConstValue( p_reader->p_sys->p_reader );
+        xmlTextReaderConstValue( (void *)p_reader->p_sys );
 
-    if( psz_value ) return strdup( (const char *)psz_value );
-    else return 0;
+    return psz_value ? strdup( (const char *)psz_value ) : NULL;
 }
 
 static int ReaderNextAttr( xml_reader_t *p_reader )
 {
-    return ( xmlTextReaderMoveToNextAttribute( p_reader->p_sys->p_reader )
+    return ( xmlTextReaderMoveToNextAttribute( (void *)p_reader->p_sys )
              == 1 ) ? VLC_SUCCESS : VLC_EGENERIC;
 }