From 354f70c527ff183d34f0432b3611ef762fbc84b9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Tue, 27 Jul 2010 19:43:32 +0300 Subject: [PATCH] XML reader: use VLC object and plugin infrastructures --- include/vlc_xml.h | 77 ++++++++++++++++++----------------- modules/misc/xml/libxml.c | 85 ++++++++++++++++++--------------------- modules/misc/xml/xtag.c | 46 ++++++++++----------- src/libvlccore.sym | 2 + src/misc/xml.c | 41 ++++++++++++++++++- 5 files changed, 141 insertions(+), 110 deletions(-) diff --git a/include/vlc_xml.h b/include/vlc_xml.h index 378ef55ce5..740bc6d086 100644 --- a/include/vlc_xml.h +++ b/include/vlc_xml.h @@ -1,34 +1,33 @@ /***************************************************************************** - * xml.h: XML abstraction layer - ***************************************************************************** - * Copyright (C) 2004 the VideoLAN team - * $Id$ - * - * Author: Gildas Bazin - * - * 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 +* +* 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 ) diff --git a/modules/misc/xml/libxml.c b/modules/misc/xml/libxml.c index 540579318f..c2c74c7edf 100644 --- a/modules/misc/xml/libxml.c +++ b/modules/misc/xml/libxml.c @@ -41,6 +41,10 @@ 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; } diff --git a/modules/misc/xml/xtag.c b/modules/misc/xml/xtag.c index 779fd40ae7..cb2936b4f1 100644 --- a/modules/misc/xml/xtag.c +++ b/modules/misc/xml/xtag.c @@ -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 ) diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 5e4ad0ced6..dbbb2b416a 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -671,5 +671,7 @@ text_style_Delete text_style_Duplicate text_style_New xml_Delete +xml_ReaderCreate +xml_ReaderDelete KeyToString StringToKey diff --git a/src/misc/xml.c b/src/misc/xml.c index 6efe0c25c2..f5e2fec74b 100644 --- a/src/misc/xml.c +++ b/src/misc/xml.c @@ -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 * @@ -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); +} -- 2.39.2