Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

xmlparser.cpp

00001 /*****************************************************************************
00002  * xmlparser.cpp
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: xmlparser.cpp 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Cyril Deguet     <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
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 // Static variable to avoid initializing catalogs twice
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     // Avoid duplicate initialization (mutex needed ?)
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     // Get the resource path and look for the DTD
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     // Try to load the catalog first (needed at least on win32 where
00094     // we don't have a default catalog)
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         // Ok, try the default one
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             // DTD found
00117             msg_Dbg( getIntf(), "Using DTD %s", path.c_str() );
00118 
00119             // Add an entry in the default catalog
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         // Get the node type
00145         int type = xml_ReaderNodeType( m_pReader );
00146         switch( type )
00147         {
00148             // Error
00149             case -1:
00150                 return false;
00151                 break;
00152 
00153             case XML_READER_STARTELEM:
00154             {
00155                 // Read the element name
00156                 char *eltName = xml_ReaderName( m_pReader );
00157                 if( !eltName ) return false;
00158 
00159                 // Read the attributes
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             // End element
00184             case XML_READER_ENDELEM:
00185             {
00186                 // Read the element name
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 }

Generated on Tue Dec 20 10:14:42 2005 for vlc-0.8.4a by  doxygen 1.4.2