Commit 354f70c5 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

XML reader: use VLC object and plugin infrastructures

parent 9d016759
/***************************************************************************** /*****************************************************************************
* xml.h: XML abstraction layer * xml.h: XML abstraction layer
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 the VideoLAN team * Copyright (C) 2004-2010 the VideoLAN team
* $Id$ *
* * Author: Gildas Bazin <gbazin@videolan.org>
* Author: Gildas Bazin <gbazin@videolan.org> *
* * This program is free software; you can redistribute it and/or modify
* 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
* it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or * (at your option) any later version.
* (at your option) any later version. *
* * This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
* GNU General Public License for more details. *
* * You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/
*****************************************************************************/
#ifndef VLC_XML_H #ifndef VLC_XML_H
#define VLC_XML_H #define VLC_XML_H
/** /**
* \file * \file
* This file defines functions and structures to handle xml tags in vlc * This file defines functions and structures to handle xml tags in vlc
* *
*/ */
# ifdef __cplusplus # ifdef __cplusplus
extern "C" { extern "C" {
...@@ -36,33 +35,31 @@ extern "C" { ...@@ -36,33 +35,31 @@ extern "C" {
struct xml_t struct xml_t
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
/* Module properties */
module_t *p_module;
xml_sys_t *p_sys;
xml_reader_t * (*pf_reader_create) ( xml_t *, stream_t * ); /* Module properties */
void (*pf_reader_delete) ( xml_reader_t * ); module_t *p_module;
xml_sys_t *p_sys;
void (*pf_catalog_load) ( xml_t *, const char * ); void (*pf_catalog_load) ( xml_t *, const char * );
void (*pf_catalog_add) ( xml_t *, const char *, const char *, void (*pf_catalog_add) ( xml_t *, const char *, const char *,
const char * ); const char * );
}; };
VLC_EXPORT( xml_t *, xml_Create, ( vlc_object_t * ) LIBVLC_USED ); VLC_EXPORT( xml_t *, xml_Create, ( vlc_object_t * ) LIBVLC_USED );
#define xml_Create( a ) xml_Create( VLC_OBJECT(a) ) #define xml_Create( a ) xml_Create( VLC_OBJECT(a) )
VLC_EXPORT( void, xml_Delete, ( xml_t * ) ); 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_CatalogLoad( a, b ) a->pf_catalog_load( a, b )
#define xml_CatalogAdd( a, b, c, d ) a->pf_catalog_add( a, b, c, d ) #define xml_CatalogAdd( a, b, c, d ) a->pf_catalog_add( a, b, c, d )
struct xml_reader_t struct xml_reader_t
{ {
xml_t *p_xml; VLC_COMMON_MEMBERS
xml_reader_sys_t *p_sys; xml_reader_sys_t *p_sys;
stream_t *p_stream;
module_t *p_module;
int (*pf_read) ( xml_reader_t * ); int (*pf_read) ( xml_reader_t * );
int (*pf_node_type) ( xml_reader_t * ); int (*pf_node_type) ( xml_reader_t * );
...@@ -73,6 +70,10 @@ struct xml_reader_t ...@@ -73,6 +70,10 @@ struct xml_reader_t
int (*pf_use_dtd) ( xml_reader_t *, bool ); 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_ReaderRead( a ) a->pf_read( a )
#define xml_ReaderNodeType( a ) a->pf_node_type( a ) #define xml_ReaderNodeType( a ) a->pf_node_type( a )
#define xml_ReaderName( a ) a->pf_name( a ) #define xml_ReaderName( a ) a->pf_name( a )
......
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close( vlc_object_t * ); static void Close( vlc_object_t * );
static int ReaderOpen( vlc_object_t * );
static void ReaderClose( vlc_object_t * );
vlc_module_begin () vlc_module_begin ()
set_description( N_("XML Parser (using libxml2)") ) set_description( N_("XML Parser (using libxml2)") )
set_capability( "xml", 10 ) set_capability( "xml", 10 )
...@@ -50,16 +54,12 @@ vlc_module_begin () ...@@ -50,16 +54,12 @@ vlc_module_begin ()
cannot_unload_broken_library() cannot_unload_broken_library()
#endif #endif
vlc_module_end () add_submodule()
set_capability( "xml reader", 10 )
set_callbacks( ReaderOpen, ReaderClose )
struct xml_reader_sys_t vlc_module_end ()
{
/* libxml2 reader context */
xmlTextReaderPtr p_reader;
};
static xml_reader_t *ReaderCreate( xml_t *, stream_t * );
static void ReaderDelete( xml_reader_t * );
static int ReaderRead( xml_reader_t * ); static int ReaderRead( xml_reader_t * );
static int ReaderNodeType( xml_reader_t * ); static int ReaderNodeType( xml_reader_t * );
static char *ReaderName( xml_reader_t * ); static char *ReaderName( xml_reader_t * );
...@@ -88,9 +88,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -88,9 +88,6 @@ static int Open( vlc_object_t *p_this )
xmlInitParser(); xmlInitParser();
vlc_mutex_unlock( &lock ); 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_load = CatalogLoad;
p_xml->pf_catalog_add = CatalogAdd; p_xml->pf_catalog_add = CatalogAdd;
...@@ -139,44 +136,35 @@ static void ReaderErrorHandler( void *p_arg, const char *p_msg, ...@@ -139,44 +136,35 @@ static void ReaderErrorHandler( void *p_arg, const char *p_msg,
VLC_UNUSED(severity); VLC_UNUSED(severity);
xml_reader_t *p_reader = (xml_reader_t *)p_arg; xml_reader_t *p_reader = (xml_reader_t *)p_arg;
int line = xmlTextReaderLocatorLineNumber( locator ); 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_t *p_reader = (xml_reader_t *)p_this;
xml_reader_sys_t *p_sys;
xmlTextReaderPtr p_libxml_reader; 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 ); NULL, NULL, 0 );
if( !p_libxml_reader ) if( !p_libxml_reader )
{ {
msg_Err( p_xml, "failed to create XML parser" ); msg_Err( p_this, "failed to create XML parser" );
return NULL; return VLC_ENOMEM;
} }
p_reader = malloc( sizeof(xml_reader_t) ); p_reader->p_sys = (void *)p_libxml_reader;
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;
/* Set the error handler */ /* Set the error handler */
xmlTextReaderSetErrorHandler( p_libxml_reader, xmlTextReaderSetErrorHandler( p_libxml_reader,
ReaderErrorHandler, p_reader ); ReaderErrorHandler, p_reader );
p_reader->pf_read = ReaderRead; p_reader->pf_read = ReaderRead;
p_reader->pf_node_type = ReaderNodeType; p_reader->pf_node_type = ReaderNodeType;
p_reader->pf_name = ReaderName; p_reader->pf_name = ReaderName;
...@@ -184,22 +172,27 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *p_stream ) ...@@ -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_next_attr = ReaderNextAttr;
p_reader->pf_use_dtd = ReaderUseDTD; 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 ); xml_reader_t *p_reader = (xml_reader_t *)p_this;
free( p_reader->p_sys );
free( p_reader ); #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 ) static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use )
{ {
/* Activate DTD validation */ /* Activate DTD validation */
xmlTextReaderSetParserProp( p_reader->p_sys->p_reader, xmlTextReaderSetParserProp( (void *)p_reader->p_sys,
XML_PARSER_DEFAULTATTRS, b_use ); XML_PARSER_DEFAULTATTRS, b_use );
xmlTextReaderSetParserProp( p_reader->p_sys->p_reader, xmlTextReaderSetParserProp( (void *)p_reader->p_sys,
XML_PARSER_VALIDATE, b_use ); XML_PARSER_VALIDATE, b_use );
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -207,7 +200,7 @@ static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use ) ...@@ -207,7 +200,7 @@ static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use )
static int ReaderRead( xml_reader_t *p_reader ) 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 #if 0
switch( i_ret ) switch( i_ret )
...@@ -221,7 +214,7 @@ static int ReaderRead( xml_reader_t *p_reader ) ...@@ -221,7 +214,7 @@ static int ReaderRead( xml_reader_t *p_reader )
static int ReaderNodeType( 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 ) switch( i_ret )
{ {
...@@ -249,7 +242,7 @@ static int ReaderNodeType( xml_reader_t *p_reader ) ...@@ -249,7 +242,7 @@ static int ReaderNodeType( xml_reader_t *p_reader )
static char *ReaderName( xml_reader_t *p_reader ) static char *ReaderName( xml_reader_t *p_reader )
{ {
const xmlChar *psz_name = 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; return psz_name ? strdup( (const char *)psz_name ) : NULL;
} }
...@@ -257,14 +250,14 @@ static char *ReaderName( xml_reader_t *p_reader ) ...@@ -257,14 +250,14 @@ static char *ReaderName( xml_reader_t *p_reader )
static char *ReaderValue( xml_reader_t *p_reader ) static char *ReaderValue( xml_reader_t *p_reader )
{ {
const xmlChar *psz_value = 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; return psz_value ? strdup( (const char *)psz_value ) : NULL;
} }
static int ReaderNextAttr( xml_reader_t *p_reader ) 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; == 1 ) ? VLC_SUCCESS : VLC_EGENERIC;
} }
......
...@@ -85,11 +85,17 @@ typedef struct _XTagParser ...@@ -85,11 +85,17 @@ typedef struct _XTagParser
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close( vlc_object_t * ); static void Close( vlc_object_t * );
static int ReaderOpen( vlc_object_t * );
static void ReaderClose( vlc_object_t * );
vlc_module_begin () vlc_module_begin ()
set_description( N_("Simple XML Parser") ) set_description( N_("Simple XML Parser") )
set_capability( "xml", 5 ) set_capability( "xml", 5 )
set_callbacks( Open, Close ) set_callbacks( Open, Close )
add_submodule()
set_capability( "xml reader", 5 )
set_callbacks( ReaderOpen, ReaderClose )
vlc_module_end () vlc_module_end ()
struct xml_reader_sys_t struct xml_reader_sys_t
...@@ -100,8 +106,6 @@ struct xml_reader_sys_t ...@@ -100,8 +106,6 @@ struct xml_reader_sys_t
bool b_endtag; 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 ReaderRead( xml_reader_t * );
static int ReaderNodeType( xml_reader_t * ); static int ReaderNodeType( xml_reader_t * );
static char *ReaderName( xml_reader_t * ); static char *ReaderName( xml_reader_t * );
...@@ -133,9 +137,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -133,9 +137,6 @@ static int Open( vlc_object_t *p_this )
{ {
xml_t *p_xml = (xml_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_load = CatalogLoad;
p_xml->pf_catalog_add = CatalogAdd; p_xml->pf_catalog_add = CatalogAdd;
...@@ -170,9 +171,10 @@ static void CatalogAdd( xml_t *p_xml, const char *psz_arg1, ...@@ -170,9 +171,10 @@ static void CatalogAdd( xml_t *p_xml, const char *psz_arg1,
/***************************************************************************** /*****************************************************************************
* Reader functions * 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; char *p_buffer;
int i_size, i_pos = 0, i_buffer = 2048; int i_size, i_pos = 0, i_buffer = 2048;
XTag *p_root; XTag *p_root;
...@@ -180,7 +182,7 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s ) ...@@ -180,7 +182,7 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s )
/* Open and read file */ /* Open and read file */
p_buffer = malloc( i_buffer ); p_buffer = malloc( i_buffer );
if( p_buffer == NULL ) if( p_buffer == NULL )
return NULL; return VLC_ENOMEM;
while( ( i_size = stream_Read( s, &p_buffer[i_pos], 2048 ) ) == 2048 ) 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 ) ...@@ -188,39 +190,34 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s )
i_buffer += i_size; i_buffer += i_size;
p_buffer = realloc_or_free( p_buffer, i_buffer ); p_buffer = realloc_or_free( p_buffer, i_buffer );
if( !p_buffer ) if( !p_buffer )
return NULL; return VLC_ENOMEM;
} }
if( i_pos + i_size == 0 ) if( i_pos + i_size == 0 )
{ {
msg_Dbg( p_xml, "empty XML" ); msg_Dbg( p_this, "empty XML" );
free( p_buffer ); free( p_buffer );
return NULL; return VLC_ENOMEM;
} }
p_buffer[ i_pos + i_size ] = '\0'; /* 0 terminated string */ p_buffer[ i_pos + i_size ] = '\0'; /* 0 terminated string */
p_root = xtag_new_parse( p_buffer, i_buffer ); p_root = xtag_new_parse( p_buffer, i_buffer );
free( p_buffer );
if( !p_root ) if( !p_root )
{ {
msg_Warn( p_xml, "couldn't parse XML" ); msg_Warn( p_this, "couldn't parse XML" );
free( p_buffer ); return VLC_ENOMEM;
return NULL;
} }
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) ); p_reader->p_sys = malloc( sizeof(xml_reader_sys_t) );
if( !p_reader->p_sys ) if( !p_reader->p_sys )
{ {
free( p_reader ); xtag_free( p_root );
return NULL; return VLC_ENOMEM;
} }
p_reader->p_sys->p_root = p_root; p_reader->p_sys->p_root = p_root;
p_reader->p_sys->p_curtag = NULL; p_reader->p_sys->p_curtag = NULL;
p_reader->p_sys->p_curattr = NULL; p_reader->p_sys->p_curattr = NULL;
p_reader->p_sys->b_endtag = false; p_reader->p_sys->b_endtag = false;
p_reader->p_xml = p_xml;
p_reader->pf_read = ReaderRead; p_reader->pf_read = ReaderRead;
p_reader->pf_node_type = ReaderNodeType; p_reader->pf_node_type = ReaderNodeType;
...@@ -229,14 +226,15 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s ) ...@@ -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_next_attr = ReaderNextAttr;
p_reader->pf_use_dtd = ReaderUseDTD; 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 ); xtag_free( p_reader->p_sys->p_root );
free( p_reader->p_sys ); free( p_reader->p_sys );
free( p_reader );
} }
static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use ) static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use )
......
...@@ -671,5 +671,7 @@ text_style_Delete ...@@ -671,5 +671,7 @@ text_style_Delete
text_style_Duplicate text_style_Duplicate
text_style_New text_style_New
xml_Delete xml_Delete
xml_ReaderCreate
xml_ReaderDelete
KeyToString KeyToString
StringToKey StringToKey
/***************************************************************************** /*****************************************************************************
* xml.c: XML parser wrapper for XML modules * xml.c: XML parser wrapper for XML modules
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 the VideoLAN team * Copyright (C) 2004-2010 the VideoLAN team
* $Id$
* *
* Authors: Gildas Bazin <gbazin@videolan.org> * Authors: Gildas Bazin <gbazin@videolan.org>
* *
...@@ -64,3 +63,41 @@ void xml_Delete( xml_t *p_xml ) ...@@ -64,3 +63,41 @@ void xml_Delete( xml_t *p_xml )
module_unneed( p_xml, p_xml->p_module ); module_unneed( p_xml, p_xml->p_module );
vlc_object_release( p_xml ); 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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment