X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Fxml%2Fxtag.c;h=b5eb64bcc7c404bb4ff4dedf02894d04e35d9224;hb=5d313c65e44d8963262fdbc5d5d52f5169f3f787;hp=bd0696d1daa9653178f5db55d4f1b378b31af89c;hpb=715ef9ae71310bec0088109e85e919b3a30e37c6;p=vlc diff --git a/modules/misc/xml/xtag.c b/modules/misc/xml/xtag.c index bd0696d1da..b5eb64bcc7 100644 --- a/modules/misc/xml/xtag.c +++ b/modules/misc/xml/xtag.c @@ -3,7 +3,7 @@ ***************************************************************************** * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research * Organisation (CSIRO) Australia - * Copyright (C) 2000-2004 VideoLAN + * Copyright (C) 2000-2004 the VideoLAN team * * $Id$ * @@ -23,21 +23,24 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include #include "vlc_xml.h" #include "vlc_block.h" #include "vlc_stream.h" #include -#include #include -#include -#include + +#include #undef XTAG_DEBUG @@ -85,9 +88,7 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); vlc_module_begin(); - set_category( CAT_ADVANCED ); - set_subcategory( SUBCAT_ADVANCED_XML ); - set_description( _("Simple XML Parser") ); + set_description( N_("Simple XML Parser") ); set_capability( "xml", 5 ); set_callbacks( Open, Close ); vlc_module_end(); @@ -97,7 +98,7 @@ struct xml_reader_sys_t XTag *p_root; /* Root tag */ XTag *p_curtag; /* Current tag */ XList *p_curattr; /* Current attribute */ - vlc_bool_t b_endtag; + bool b_endtag; }; static xml_reader_t *ReaderCreate( xml_t *, stream_t * ); @@ -108,15 +109,17 @@ static char *ReaderName( xml_reader_t * ); static char *ReaderValue( xml_reader_t * ); static int ReaderNextAttr( xml_reader_t * ); -static int ReaderUseDTD ( xml_reader_t *, vlc_bool_t ); +static int ReaderUseDTD ( xml_reader_t *, bool ); static void CatalogLoad( xml_t *, const char * ); static void CatalogAdd( xml_t *, const char *, const char *, const char * ); static XTag *xtag_new_parse( const char *, int ); static char *xtag_get_name( XTag * ); +#if 0 static char *xtag_get_pcdata( XTag * ); static char *xtag_get_attribute( XTag *, char * ); +#endif static XTag *xtag_first_child( XTag *, char * ); static XTag *xtag_next_child( XTag *, char * ); static XTag *xtag_free( XTag * ); @@ -143,6 +146,7 @@ static int Open( vlc_object_t *p_this ) *****************************************************************************/ static void Close( vlc_object_t *p_this ) { + VLC_UNUSED(p_this); return; } @@ -151,12 +155,15 @@ static void Close( vlc_object_t *p_this ) *****************************************************************************/ static void CatalogLoad( xml_t *p_xml, const char *psz_filename ) { + VLC_UNUSED(psz_filename); msg_Dbg( p_xml, "catalog support not implemented" ); } static void CatalogAdd( xml_t *p_xml, const char *psz_arg1, const char *psz_arg2, const char *psz_filename ) { + VLC_UNUSED(p_xml); VLC_UNUSED(psz_arg1); VLC_UNUSED(psz_arg2); + VLC_UNUSED(psz_filename); } /***************************************************************************** @@ -165,34 +172,32 @@ static void CatalogAdd( xml_t *p_xml, const char *psz_arg1, static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s ) { xml_reader_t *p_reader; - char *p_buffer; - int i_pos,i_size,i_buffer = 5000; + char *p_buffer, *p_new; + int i_size, i_pos = 0, i_buffer = 2048; XTag *p_root; /* Open and read file */ - p_buffer = malloc( i_buffer + 1 ); + p_buffer = malloc( i_buffer ); if( p_buffer == NULL ) return NULL; - i_pos = 0; - i_size = 0; - while( i_pos < i_buffer ) + while( ( i_size = stream_Read( s, &p_buffer[i_pos], 2048 ) ) == 2048 ) { - i_size = stream_Read( s, &p_buffer[i_pos], 5000 ); i_pos += i_size; - if( i_size < 5000 ) - break; /* we're done */ - else + i_buffer += i_size; + p_new = realloc( p_buffer, i_buffer ); + if( !p_new ) { - i_buffer += 5000; - p_buffer = realloc( p_buffer, i_buffer * sizeof( char *) ); + free( p_buffer ); + return NULL; } + p_buffer = p_new; } - p_buffer[ i_pos ] = 0; + p_buffer[ i_pos + i_size ] = 0; /* 0 terminated string */ - if( !i_buffer ) + if( i_pos + i_size == 0 ) { - msg_Dbg( p_xml, "empty xml" ); + msg_Dbg( p_xml, "empty XML" ); free( p_buffer ); return 0; } @@ -200,17 +205,18 @@ static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *s ) p_root = xtag_new_parse( p_buffer, i_buffer ); if( !p_root ) { - msg_Warn( p_xml, "couldn't parse xml" ); + msg_Warn( p_xml, "couldn't parse XML" ); free( p_buffer ); return 0; } + free( p_buffer ); p_reader = malloc( sizeof(xml_reader_t) ); p_reader->p_sys = malloc( sizeof(xml_reader_sys_t) ); 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 = VLC_FALSE; + p_reader->p_sys->b_endtag = false; p_reader->p_xml = p_xml; p_reader->pf_read = ReaderRead; @@ -230,8 +236,9 @@ static void ReaderDelete( xml_reader_t *p_reader ) free( p_reader ); } -static int ReaderUseDTD ( xml_reader_t *p_reader, vlc_bool_t b_use ) +static int ReaderUseDTD ( xml_reader_t *p_reader, bool b_use ) { + VLC_UNUSED(p_reader); VLC_UNUSED(b_use); return VLC_EGENERIC; } @@ -251,18 +258,18 @@ static int ReaderRead( xml_reader_t *p_reader ) { p_reader->p_sys->p_curtag = p_child; p_reader->p_sys->p_curattr = 0; - p_reader->p_sys->b_endtag = VLC_FALSE; + p_reader->p_sys->b_endtag = false; return 1; } if( p_reader->p_sys->p_curtag->name && /* no end tag for pcdata */ !p_reader->p_sys->b_endtag ) { - p_reader->p_sys->b_endtag = VLC_TRUE; + p_reader->p_sys->b_endtag = true; return 1; } - p_reader->p_sys->b_endtag = VLC_FALSE; + p_reader->p_sys->b_endtag = false; if( !p_reader->p_sys->p_curtag->parent ) return 0; p_reader->p_sys->p_curtag = p_reader->p_sys->p_curtag->parent; } @@ -350,7 +357,7 @@ static XList *xlist_append( XList *list, void *data ) if( last->next == NULL ) break; if( last ) last->next = l; - l->prev = last; + l->prev = last; return list; } @@ -376,20 +383,22 @@ static void xlist_free( XList *list ) #define X_SLASH 1<<6 #define X_QMARK 1<<7 #define X_DASH 1<<8 +#define X_EMARK 1<<9 static int xtag_cin( char c, int char_class ) { - if( char_class & X_WHITESPACE ) if( isspace(c) ) return VLC_TRUE; - if( char_class & X_OPENTAG ) if( c == '<' ) return VLC_TRUE; - if( char_class & X_CLOSETAG ) if( c == '>' ) return VLC_TRUE; - if( char_class & X_DQUOTE ) if( c == '"' ) return VLC_TRUE; - if( char_class & X_SQUOTE ) if( c == '\'' ) return VLC_TRUE; - if( char_class & X_EQUAL ) if( c == '=' ) return VLC_TRUE; - if( char_class & X_SLASH ) if( c == '/' ) return VLC_TRUE; - if( char_class & X_QMARK ) if( c == '!' ) return VLC_TRUE; - if( char_class & X_DASH ) if( c == '-' ) return VLC_TRUE; - - return VLC_FALSE; + if( char_class & X_WHITESPACE ) if( isspace(c) ) return true; + if( char_class & X_OPENTAG ) if( c == '<' ) return true; + if( char_class & X_CLOSETAG ) if( c == '>' ) return true; + if( char_class & X_DQUOTE ) if( c == '"' ) return true; + if( char_class & X_SQUOTE ) if( c == '\'' ) return true; + if( char_class & X_EQUAL ) if( c == '=' ) return true; + if( char_class & X_SLASH ) if( c == '/' ) return true; + if( char_class & X_QMARK ) if( c == '?' ) return true; + if( char_class & X_DASH ) if( c == '-' ) return true; + if( char_class & X_EMARK ) if( c == '!' ) return true; + + return false; } static int xtag_index( XTagParser *parser, int char_class ) @@ -454,17 +463,17 @@ static int xtag_assert_and_pass( XTagParser *parser, int char_class ) { char *s = parser->start; - if( !parser->valid ) return VLC_FALSE; + if( !parser->valid ) return false; if( !xtag_cin( s[0], char_class ) ) { - parser->valid = VLC_FALSE; - return VLC_FALSE; + parser->valid = false; + return false; } parser->start = &s[1]; - return VLC_TRUE; + return true; } static char *xtag_slurp_quoted( XTagParser *parser ) @@ -546,7 +555,7 @@ static XAttribute *xtag_parse_attribute( XTagParser *parser ) err_free_name: free (name); - parser->valid = VLC_FALSE; + parser->valid = false; return NULL; } @@ -557,44 +566,21 @@ static XTag *xtag_parse_tag( XTagParser *parser ) char *name; char *pcdata; char *s; + int xi; if( !parser->valid ) return NULL; -#if 0 /* Do we really want all the whitespace pcdata ? */ - xtag_skip_whitespace( parser ); -#endif - - if( (pcdata = xtag_slurp_to( parser, X_OPENTAG, X_NONE )) != NULL ) - { - tag = malloc( sizeof(*tag) ); - tag->name = NULL; - tag->pcdata = pcdata; - tag->parent = parser->current_tag; - tag->attributes = NULL; - tag->children = NULL; - tag->current_child = NULL; - - return tag; - } - s = parser->start; - /* if this starts a close tag, return NULL and let the parent take it */ - if( xtag_cin( s[0], X_OPENTAG ) && xtag_cin( s[1], X_SLASH ) ) - return NULL; - /* if this starts a comment tag, skip until end */ - if( xtag_cin( s[0], X_OPENTAG ) && xtag_cin( s[1], X_QMARK ) && + if( (parser->end - parser->start) > 7 && + xtag_cin( s[0], X_OPENTAG ) && xtag_cin( s[1], X_EMARK ) && xtag_cin( s[2], X_DASH ) && xtag_cin( s[3], X_DASH ) ) { - int xi; - parser->start = s = &s[4]; - while( (xi = xtag_index( parser, X_DASH )) >= 0 ) { parser->start = s = &s[xi+1]; - if( xtag_cin( s[0], X_DASH ) && xtag_cin( s[1], X_CLOSETAG ) ) { parser->start = &s[2]; @@ -602,19 +588,79 @@ static XTag *xtag_parse_tag( XTagParser *parser ) return xtag_parse_tag( parser ); } } + return NULL; + } + /* ignore processing instructions '' */ + if( (parser->end - parser->start) > 4 && + xtag_cin( s[0], X_OPENTAG ) && xtag_cin( s[1], X_QMARK ) ) + { + parser->start = s = &s[2]; + while ((xi = xtag_index( parser, X_QMARK )) >= 0) { + if (xtag_cin( s[xi+1], X_CLOSETAG )) { + parser->start = &s[xi+2]; + xtag_skip_whitespace( parser ); + return xtag_parse_tag( parser ); + } + } return NULL; } - /* FIXME: if this starts a DOCTYPE tag, skip until end */ - if( xtag_cin( s[0], X_OPENTAG ) && xtag_cin( s[1], X_QMARK ) ) + /* ignore doctype '' */ + if ( (parser->end - parser->start) > 8 && + !strncmp( s, " 0 ) { + parser->start = s = &s[xi+1]; + xtag_skip_whitespace( parser ); + return xtag_parse_tag( parser ); + } + else { + return NULL; + } + } + + if( (pcdata = xtag_slurp_to( parser, X_OPENTAG, X_NONE )) != NULL ) { - int xi = xtag_index( parser, X_CLOSETAG ); - if( xi <= 0 ) return NULL; + tag = malloc( sizeof(*tag) ); + tag->name = NULL; + tag->pcdata = pcdata; + tag->parent = parser->current_tag; + tag->attributes = NULL; + tag->children = NULL; + tag->current_child = NULL; - parser->start = &s[xi+1]; - xtag_skip_whitespace( parser ); - return xtag_parse_tag( parser ); + return tag; + } + + /* if this starts a close tag, return NULL and let the parent take it */ + if( xtag_cin( s[0], X_OPENTAG ) && xtag_cin( s[1], X_SLASH ) ) + return NULL; + + /* parse CDATA content */ + if ( (parser->end - parser->start) > 8 && + !strncmp( s, "start = s = &s[9]; + while (parser->end - s > 2) { + if (strncmp( s, "]]>", 3 ) == 0) { + if ( !(tag = malloc( sizeof(*tag))) ) return NULL; + if ( !(pcdata = malloc( sizeof(char)*(s - parser->start + 1))) ) return NULL; + strncpy( pcdata, parser->start, s - parser->start ); + pcdata[s - parser->start]='\0'; + parser->start = s = &s[3]; + tag->name = NULL; + tag->pcdata = pcdata; + tag->parent = parser->current_tag; + tag->attributes = NULL; + tag->children = NULL; + tag->current_child = NULL; + return tag; + } + else { + s++; + } + } + return NULL; } if( !xtag_assert_and_pass( parser, X_OPENTAG ) ) return NULL; @@ -672,19 +718,20 @@ static XTag *xtag_parse_tag( XTagParser *parser ) #ifdef XTAG_DEBUG printf ("got %s expected %s\n", name, tag->name); #endif - parser->valid = VLC_FALSE; + parser->valid = false; } free( name ); } xtag_skip_whitespace( parser ); xtag_assert_and_pass( parser, X_CLOSETAG ); - + xtag_skip_whitespace( parser ); } else { xtag_assert_and_pass( parser, X_SLASH ); xtag_assert_and_pass( parser, X_CLOSETAG ); + xtag_skip_whitespace( parser ); } return tag; @@ -698,15 +745,15 @@ static XTag *xtag_free( XTag *xtag ) if( xtag == NULL ) return NULL; - if( xtag->name ) free( xtag->name ); - if( xtag->pcdata ) free( xtag->pcdata ); + free( xtag->name ); + free( xtag->pcdata ); for( l = xtag->attributes; l; l = l->next ) { if( (attr = (XAttribute *)l->data) != NULL ) { - if( attr->name ) free( attr->name ); - if( attr->value ) free( attr->value ); + free( attr->name ); + free( attr->value ); free( attr ); } } @@ -729,7 +776,7 @@ static XTag *xtag_new_parse( const char *s, int n ) XTagParser parser; XTag *tag, *ttag, *wrapper; - parser.valid = VLC_TRUE; + parser.valid = true; parser.current_tag = NULL; parser.start = (char *)s; @@ -738,7 +785,7 @@ static XTag *xtag_new_parse( const char *s, int n ) { #ifdef XTAG_DEBUG printf ("empty buffer"); -#endif +#endif return NULL; } else parser.end = (char *)&s[n]; @@ -797,6 +844,7 @@ static char *xtag_get_name( XTag *xtag ) return xtag ? xtag->name : NULL; } +#if 0 static char *xtag_get_pcdata( XTag *xtag ) { XList *l; @@ -833,6 +881,7 @@ static char *xtag_get_attribute( XTag *xtag, char *attribute ) return NULL; } +#endif static XTag *xtag_first_child( XTag *xtag, char *name ) { @@ -911,7 +960,7 @@ static int xtag_snprints( char *buf, int n, ... ) int len, to_copy, total = 0; va_start( ap, n ); - + for( s = va_arg( ap, char * ); s; s = va_arg( ap, char *) ) { len = strlen (s); @@ -965,7 +1014,7 @@ static int xtag_snprint( char *buf, int n, XTag *xtag ) for( l = xtag->attributes; l; l = l->next ) { attr = (XAttribute *)l->data; - + nn = xtag_snprints( buf, n, " ", attr->name, "=\"", attr->value, "\"", NULL); FORWARD( nn );