00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "xmlparser.hpp"
00025 #include "../src/os_factory.hpp"
00026
00027 #ifdef HAVE_SYS_STAT_H
00028 # include <sys/stat.h>
00029 #endif
00030
00031
00032 static bool m_initialized = false;
00033
00034 XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName ):
00035 SkinObject( pIntf )
00036 {
00037 m_pReader = NULL;
00038 m_pStream = NULL;
00039
00040 m_pXML = xml_Create( pIntf );
00041 if( !m_pXML )
00042 {
00043 msg_Err( getIntf(), "Failed to open XML parser" );
00044 return;
00045 }
00046
00047
00048 if( !m_initialized )
00049 {
00050 LoadCatalog();
00051 m_initialized = true;
00052 }
00053
00054 m_pStream = stream_UrlNew( pIntf, rFileName.c_str() );
00055 if( !m_pStream )
00056 {
00057 msg_Err( getIntf(), "Failed to open %s for reading",
00058 rFileName.c_str() );
00059 return;
00060 }
00061 m_pReader = xml_ReaderCreate( m_pXML, m_pStream );
00062 if( !m_pReader )
00063 {
00064 msg_Err( getIntf(), "Failed to open %s for parsing",
00065 rFileName.c_str() );
00066 return;
00067 }
00068
00069 xml_ReaderUseDTD( m_pReader, VLC_TRUE );
00070
00071 }
00072
00073
00074 XMLParser::~XMLParser()
00075 {
00076 if( m_pReader && m_pXML ) xml_ReaderDelete( m_pXML, m_pReader );
00077 if( m_pXML ) xml_Delete( m_pXML );
00078 if( m_pStream ) stream_Delete( m_pStream );
00079 }
00080
00081
00082 void XMLParser::LoadCatalog()
00083 {
00084
00085 OSFactory *pOSFactory = OSFactory::instance( getIntf() );
00086 const list<string> &resPath = pOSFactory->getResourcePath();
00087 const string &sep = pOSFactory->getDirSeparator();
00088 list<string>::const_iterator it;
00089
00090 #ifdef HAVE_SYS_STAT_H
00091 struct stat statBuf;
00092
00093
00094
00095 for( it = resPath.begin(); it != resPath.end(); it++ )
00096 {
00097 string catalog_path = (*it) + sep + "skin.catalog";
00098 if( !stat( catalog_path.c_str(), &statBuf ) )
00099 {
00100 msg_Dbg( getIntf(), "Using catalog %s", catalog_path.c_str() );
00101 xml_CatalogLoad( m_pXML, catalog_path.c_str() );
00102 break;
00103 }
00104 }
00105 if( it == resPath.end() )
00106 {
00107
00108 xml_CatalogLoad( m_pXML, 0 );
00109 }
00110
00111 for( it = resPath.begin(); it != resPath.end(); it++ )
00112 {
00113 string path = (*it) + sep + "skin.dtd";
00114 if( !stat( path.c_str(), &statBuf ) )
00115 {
00116
00117 msg_Dbg( getIntf(), "Using DTD %s", path.c_str() );
00118
00119
00120 xml_CatalogAdd( m_pXML, "public",
00121 "-//VideoLAN//DTD VLC Skins V"
00122 SKINS_DTD_VERSION "//EN", path.c_str() );
00123 break;
00124 }
00125 }
00126 if( it == resPath.end() )
00127 {
00128 msg_Err( getIntf(), "Cannot find the skins DTD !");
00129 }
00130 #endif
00131 }
00132
00133 bool XMLParser::parse()
00134 {
00135 if( !m_pReader ) return false;
00136
00137 m_errors = false;
00138
00139 int ret = xml_ReaderRead( m_pReader );
00140 while( ret == 1 )
00141 {
00142 if( m_errors ) return false;
00143
00144
00145 int type = xml_ReaderNodeType( m_pReader );
00146 switch( type )
00147 {
00148
00149 case -1:
00150 return false;
00151 break;
00152
00153 case XML_READER_STARTELEM:
00154 {
00155
00156 char *eltName = xml_ReaderName( m_pReader );
00157 if( !eltName ) return false;
00158
00159
00160 AttrList_t attributes;
00161 while( xml_ReaderNextAttr( m_pReader ) == VLC_SUCCESS )
00162 {
00163 char *name = xml_ReaderName( m_pReader );
00164 char *value = xml_ReaderValue( m_pReader );
00165 if( !name || !value ) return false;
00166 attributes[name] = value;
00167 }
00168
00169 handleBeginElement( eltName, attributes );
00170 free( eltName );
00171
00172 map<const char*, const char*, ltstr> ::iterator it =
00173 attributes.begin();
00174 while( it != attributes.end() )
00175 {
00176 free( (char *)it->first );
00177 free( (char *)it->second );
00178 it++;
00179 }
00180 break;
00181 }
00182
00183
00184 case XML_READER_ENDELEM:
00185 {
00186
00187 char *eltName = xml_ReaderName( m_pReader );
00188 if( !eltName ) return false;
00189
00190 handleEndElement( eltName );
00191 free( eltName );
00192 break;
00193 }
00194 }
00195 ret = xml_ReaderRead( m_pReader );
00196 }
00197 return (ret == 0 && !m_errors );
00198 }