/*****************************************************************************
- * 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" {
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 * );
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 )
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 )
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 * );
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;
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;
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;
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 )
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 )
{
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;
}
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;
}
*****************************************************************************/
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
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 * );
{
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;
/*****************************************************************************
* 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;
/* 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 )
{
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;
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 )
text_style_Duplicate
text_style_New
xml_Delete
+xml_ReaderCreate
+xml_ReaderDelete
KeyToString
StringToKey
/*****************************************************************************
* 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>
*
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);
+}