]> git.sesse.net Git - vlc/commitdiff
XML reader: use VLC object and plugin infrastructures
authorRémi Denis-Courmont <remi@remlab.net>
Tue, 27 Jul 2010 16:43:32 +0000 (19:43 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Tue, 27 Jul 2010 19:33:37 +0000 (22:33 +0300)
include/vlc_xml.h
modules/misc/xml/libxml.c
modules/misc/xml/xtag.c
src/libvlccore.sym
src/misc/xml.c

index 378ef55ce5a323466fe640af0e8f2f75a360e853..740bc6d08652af5b330c08f543b75b6d68157bca 100644 (file)
@@ -1,34 +1,33 @@
 /*****************************************************************************
- * xml.h: XML abstraction layer
- *****************************************************************************
- * Copyright (C) 2004 the VideoLAN team
- * $Id$
- *
- * Author: Gildas Bazin <gbazin@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
+* xml.h: XML abstraction layer
+*****************************************************************************
+* Copyright (C) 2004-2010 the VideoLAN team
+*
+* Author: Gildas Bazin <gbazin@videolan.org>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+*****************************************************************************/
 
 #ifndef VLC_XML_H
 #define VLC_XML_H
 
 /**
- * \file
- * This file defines functions and structures to handle xml tags in vlc
- *
- */
+* \file
+* This file defines functions and structures to handle xml tags in vlc
+*
+*/
 
 # ifdef __cplusplus
 extern "C" {
@@ -36,33 +35,31 @@ extern "C" {
 
 struct xml_t
 {
-    VLC_COMMON_MEMBERS
-
-    /* Module properties */
-    module_t  *p_module;
-    xml_sys_t *p_sys;
+VLC_COMMON_MEMBERS
 
-    xml_reader_t * (*pf_reader_create) ( xml_t *, stream_t * );
-    void (*pf_reader_delete) ( xml_reader_t * );
+/* Module properties */
+module_t  *p_module;
+xml_sys_t *p_sys;
 
-    void (*pf_catalog_load) ( xml_t *, const char * );
-    void (*pf_catalog_add) ( xml_t *, const char *, const char *,
-                               const char * );
+void (*pf_catalog_load) ( xml_t *, const char * );
+void (*pf_catalog_add) ( xml_t *, const char *, const char *,
+                      const char * );
 };
 
 VLC_EXPORT( xml_t *, xml_Create, ( vlc_object_t * ) LIBVLC_USED );
 #define xml_Create( a ) xml_Create( VLC_OBJECT(a) )
 VLC_EXPORT( void, xml_Delete, ( xml_t * ) );
 
-#define xml_ReaderCreate( a, b ) a->pf_reader_create( a, b )
-#define xml_ReaderDelete( a ) a->p_xml->pf_reader_delete( a )
 #define xml_CatalogLoad( a, b ) a->pf_catalog_load( a, b )
 #define xml_CatalogAdd( a, b, c, d ) a->pf_catalog_add( a, b, c, d )
 
 struct xml_reader_t
 {
-    xml_t *p_xml;
+    VLC_COMMON_MEMBERS
+
     xml_reader_sys_t *p_sys;
+    stream_t *p_stream;
+    module_t *p_module;
 
     int (*pf_read) ( xml_reader_t * );
     int (*pf_node_type) ( xml_reader_t * );
@@ -73,6 +70,10 @@ struct xml_reader_t
     int (*pf_use_dtd) ( xml_reader_t *, bool );
 };
 
+VLC_EXPORT( xml_reader_t *, xml_ReaderCreate, (vlc_object_t *, stream_t *) LIBVLC_USED );
+#define xml_ReaderCreate( a, s ) xml_ReaderCreate(VLC_OBJECT(a), s)
+VLC_EXPORT( void, xml_ReaderDelete, (xml_reader_t *) );
+
 #define xml_ReaderRead( a ) a->pf_read( a )
 #define xml_ReaderNodeType( a ) a->pf_node_type( a )
 #define xml_ReaderName( a ) a->pf_name( a )
index 540579318fddb932b6ff8c2d43765f7867135bd2..c2c74c7edfbc4a824daf4ac24426630ee536f05e 100644 (file)
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
 
+static int ReaderOpen( vlc_object_t * );
+static void ReaderClose( vlc_object_t * );
+
+
 vlc_module_begin ()
     set_description( N_("XML Parser (using libxml2)") )
     set_capability( "xml", 10 )
@@ -50,16 +54,12 @@ vlc_module_begin ()
     cannot_unload_broken_library()
 #endif
 
-vlc_module_end ()
+    add_submodule()
+    set_capability( "xml reader", 10 )
+    set_callbacks( ReaderOpen, ReaderClose )
 
-struct xml_reader_sys_t
-{
-    /* libxml2 reader context */
-    xmlTextReaderPtr p_reader;
-};
+vlc_module_end ()
 
-static xml_reader_t *ReaderCreate( xml_t *, stream_t * );
-static void ReaderDelete( xml_reader_t * );
 static int ReaderRead( xml_reader_t * );
 static int ReaderNodeType( xml_reader_t * );
 static char *ReaderName( xml_reader_t * );
@@ -88,9 +88,6 @@ static int Open( vlc_object_t *p_this )
     xmlInitParser();
     vlc_mutex_unlock( &lock );
 
-    p_xml->pf_reader_create = ReaderCreate;
-    p_xml->pf_reader_delete = ReaderDelete;
-
     p_xml->pf_catalog_load = CatalogLoad;
     p_xml->pf_catalog_add  = CatalogAdd;
 
@@ -139,44 +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 NULL;
+        msg_Err( p_this, "failed to create XML parser" );
+        return VLC_ENOMEM;
     }
 
-    p_reader = malloc( sizeof(xml_reader_t) );
-    if( !p_reader )
-    {
-        xmlFreeTextReader( p_libxml_reader );
-        return NULL;
-    }
-    p_reader->p_sys = p_sys = malloc( sizeof(xml_reader_sys_t) );
-    if( !p_sys )
-    {
-        xmlFreeTextReader( p_libxml_reader );
-        free( p_reader );
-        return NULL;
-    }
-    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;
@@ -184,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;
@@ -207,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 )
@@ -221,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 )
     {
@@ -249,7 +242,7 @@ 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 );
 
     return psz_name ? strdup( (const char *)psz_name ) : NULL;
 }
@@ -257,14 +250,14 @@ static char *ReaderName( xml_reader_t *p_reader )
 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 );
 
     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;
 }
 
index 779fd40ae7da2efa47af60ccc74c36c084d87126..cb2936b4f1bbeec493b2190159a90b23e4341c7b 100644 (file)
@@ -85,11 +85,17 @@ typedef struct _XTagParser
  *****************************************************************************/
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
+static int ReaderOpen( vlc_object_t * );
+static void ReaderClose( vlc_object_t * );
 
 vlc_module_begin ()
     set_description( N_("Simple XML Parser") )
     set_capability( "xml", 5 )
     set_callbacks( Open, Close )
+
+    add_submodule()
+    set_capability( "xml reader", 5 )
+    set_callbacks( ReaderOpen, ReaderClose )
 vlc_module_end ()
 
 struct xml_reader_sys_t
@@ -100,8 +106,6 @@ struct xml_reader_sys_t
     bool b_endtag;
 };
 
-static xml_reader_t *ReaderCreate( xml_t *, stream_t * );
-static void ReaderDelete( xml_reader_t * );
 static int ReaderRead( xml_reader_t * );
 static int ReaderNodeType( xml_reader_t * );
 static char *ReaderName( xml_reader_t * );
@@ -133,9 +137,6 @@ 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;
-
     p_xml->pf_catalog_load = CatalogLoad;
     p_xml->pf_catalog_add  = CatalogAdd;
 
@@ -170,9 +171,10 @@ static void CatalogAdd( xml_t *p_xml, const char *psz_arg1,
 /*****************************************************************************
  * Reader functions
  *****************************************************************************/
-static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s )
+static int ReaderOpen( vlc_object_t *p_this )
 {
-    xml_reader_t *p_reader;
+    xml_reader_t *p_reader = (xml_reader_t *)p_this;
+    stream_t *s = p_reader->p_stream;
     char *p_buffer;
     int i_size, i_pos = 0, i_buffer = 2048;
     XTag *p_root;
@@ -180,7 +182,7 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s )
     /* Open and read file */
     p_buffer = malloc( i_buffer );
     if( p_buffer == NULL )
-        return NULL;
+        return VLC_ENOMEM;
 
     while( ( i_size = stream_Read( s, &p_buffer[i_pos], 2048 ) ) == 2048 )
     {
@@ -188,39 +190,34 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s )
         i_buffer += i_size;
         p_buffer = realloc_or_free( p_buffer, i_buffer );
         if( !p_buffer )
-            return NULL;
+            return VLC_ENOMEM;
     }
     if( i_pos + i_size == 0 )
     {
-        msg_Dbg( p_xml, "empty XML" );
+        msg_Dbg( p_this, "empty XML" );
         free( p_buffer );
-        return NULL;
+        return VLC_ENOMEM;
     }
     p_buffer[ i_pos + i_size ] = '\0'; /* 0 terminated string */
 
     p_root = xtag_new_parse( p_buffer, i_buffer );
+    free( p_buffer );
     if( !p_root )
     {
-        msg_Warn( p_xml, "couldn't parse XML" );
-        free( p_buffer );
-        return NULL;
+        msg_Warn( p_this, "couldn't parse XML" );
+        return VLC_ENOMEM;
     }
 
-    free( p_buffer );
-    p_reader = malloc( sizeof(xml_reader_t) );
-    if( !p_reader )
-        return NULL;
     p_reader->p_sys = malloc( sizeof(xml_reader_sys_t) );
     if( !p_reader->p_sys )
     {
-        free( p_reader );
-        return NULL;
+        xtag_free( p_root );
+        return VLC_ENOMEM;
     }
     p_reader->p_sys->p_root = p_root;
     p_reader->p_sys->p_curtag = NULL;
     p_reader->p_sys->p_curattr = NULL;
     p_reader->p_sys->b_endtag = false;
-    p_reader->p_xml = p_xml;
 
     p_reader->pf_read = ReaderRead;
     p_reader->pf_node_type = ReaderNodeType;
@@ -229,14 +226,15 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s )
     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 )
 {
+    xml_reader_t *p_reader = (vlc_object_t *)p_this;
+
     xtag_free( p_reader->p_sys->p_root );
     free( p_reader->p_sys );
-    free( p_reader );
 }
 
 static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use )
index 5e4ad0ced67c4db471ba02001a144a8e6f66df78..dbbb2b416a772aa839e64186856e1f4a7de3e5ed 100644 (file)
@@ -671,5 +671,7 @@ text_style_Delete
 text_style_Duplicate
 text_style_New
 xml_Delete
+xml_ReaderCreate
+xml_ReaderDelete
 KeyToString
 StringToKey
index 6efe0c25c21d08562cbbb17570cde648899776ab..f5e2fec74b51d427cf39706e6f7c6ea9ad63b1b6 100644 (file)
@@ -1,8 +1,7 @@
 /*****************************************************************************
  * xml.c: XML parser wrapper for XML modules
  *****************************************************************************
- * Copyright (C) 2004 the VideoLAN team
- * $Id$
+ * Copyright (C) 2004-2010 the VideoLAN team
  *
  * Authors: Gildas Bazin <gbazin@videolan.org>
  *
@@ -64,3 +63,41 @@ void xml_Delete( xml_t *p_xml )
     module_unneed( p_xml, p_xml->p_module );
     vlc_object_release( p_xml );
 }
+
+
+#undef xml_ReaderCreate
+/**
+ * Creates an XML reader.
+ * @param obj parent VLC object
+ * @param stream stream to read XML from
+ * @return NULL on error.
+ */
+xml_reader_t *xml_ReaderCreate(vlc_object_t *obj, stream_t *stream)
+{
+    xml_reader_t *reader;
+
+    reader = vlc_custom_create(obj, sizeof(*reader), VLC_OBJECT_GENERIC,
+                               "xml reader");
+    vlc_object_attach(reader, obj);
+
+    reader->p_stream = stream;
+    reader->p_module = module_need(reader, "xml reader", NULL, false);
+    if (unlikely(reader->p_module == NULL))
+    {
+        msg_Err(reader, "XML reader not found");
+        vlc_object_release(reader);
+        return NULL;
+    }
+    return reader;
+}
+
+
+/**
+ * Deletes an XML reader.
+ * @param reader XML reader created with xml_RaederCreate().
+ */
+void xml_ReaderDelete(xml_reader_t *reader)
+{
+    module_unneed(reader, reader->p_module);
+    vlc_object_release(reader);
+}