]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/parser/xmlparser.cpp
skins2: remove unused static variable
[vlc] / modules / gui / skins2 / parser / xmlparser.cpp
index a098fb50529e32da2d324b16d60f0dd444022776..fea743a56c6565fc6cfd3ca2bb2453c70923c44a 100644 (file)
@@ -1,11 +1,10 @@
 /*****************************************************************************
  * xmlparser.cpp
  *****************************************************************************
- * Copyright (C) 2004 VideoLAN
- * $Id: xmlparser.cpp,v 1.1 2004/01/24 13:08:12 asmax Exp $
+ * Copyright (C) 2004 the VideoLAN team
+ * $Id$
  *
  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
- *          Olivier Teulière <ipkiss@via.ecp.fr>
  *
  * 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
  *
  * 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 "xmlparser.hpp"
+#include "../src/os_factory.hpp"
+#include <vlc_url.h>
 
-XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName ):
+#ifdef HAVE_SYS_STAT_H
+#   include <sys/stat.h>
+#endif
+
+XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName,
+                      bool useDTD ):
     SkinObject( pIntf )
 {
-    m_pReader = xmlNewTextReaderFilename( rFileName.c_str() );
+    m_pReader = NULL;
+    m_pStream = NULL;
+
+    if( useDTD )
+    {
+        m_pXML = xml_Create( pIntf );
+        if( m_pXML )
+            LoadCatalog();
+        else
+        {
+            msg_Err( getIntf(), "DTD not supported" );
+            useDTD = false;
+        }
+    }
+    else
+        m_pXML = NULL;
+
+    char* psz_uri = make_URI( rFileName.c_str(), NULL );
+    m_pStream = stream_UrlNew( pIntf, psz_uri );
+    free( psz_uri );
+
+    if( !m_pStream )
+    {
+        msg_Err( getIntf(), "failed to open %s for reading",
+                 rFileName.c_str() );
+        return;
+    }
+    m_pReader = xml_ReaderCreate( m_pXML, m_pStream );
     if( !m_pReader )
     {
-        msg_Err( getIntf(), "Failed to open %s for parsing",
+        msg_Err( getIntf(), "failed to open %s for parsing",
                  rFileName.c_str() );
+        return;
     }
+
+    xml_ReaderUseDTD( m_pReader, useDTD );
 }
 
 
 XMLParser::~XMLParser()
 {
-    if( m_pReader )
-    {
-        xmlFreeTextReader( m_pReader );
-    }
+    if( m_pReader ) xml_ReaderDelete( m_pReader );
+    if( m_pXML ) xml_Delete( m_pXML );
+    if( m_pStream ) stream_Delete( m_pStream );
 }
 
 
-int XMLParser::parse()
+void XMLParser::LoadCatalog()
 {
-    if( !m_pReader )
+    // Get the resource path and look for the DTD
+    OSFactory *pOSFactory = OSFactory::instance( getIntf() );
+    const list<string> &resPath = pOSFactory->getResourcePath();
+    const string &sep = pOSFactory->getDirSeparator();
+    list<string>::const_iterator it;
+
+#ifdef HAVE_SYS_STAT_H
+    struct stat statBuf;
+
+    // Try to load the catalog first (needed at least on win32 where
+    // we don't have a default catalog)
+    for( it = resPath.begin(); it != resPath.end(); it++ )
+    {
+        string catalog_path = (*it) + sep + "skin.catalog";
+        if( !stat( catalog_path.c_str(), &statBuf ) )
+        {
+            msg_Dbg( getIntf(), "Using catalog %s", catalog_path.c_str() );
+            xml_CatalogLoad( m_pXML, catalog_path.c_str() );
+            break;
+        }
+    }
+    if( it == resPath.end() )
     {
-        return -1;
+        // Ok, try the default one
+        xml_CatalogLoad( m_pXML, 0 );
     }
 
-    int ret = xmlTextReaderRead( m_pReader );
-    while (ret == 1)
+    for( it = resPath.begin(); it != resPath.end(); it++ )
     {
+        string path = (*it) + sep + "skin.dtd";
+        if( !stat( path.c_str(), &statBuf ) )
+        {
+            // DTD found
+            msg_Dbg( getIntf(), "using DTD %s", path.c_str() );
+
+            // Add an entry in the default catalog
+            xml_CatalogAdd( m_pXML, "public",
+                            "-//VideoLAN//DTD VLC Skins V"
+                            SKINS_DTD_VERSION "//EN", path.c_str() );
+            break;
+        }
+    }
+    if( it == resPath.end() )
+    {
+        msg_Err( getIntf(), "cannot find the skins DTD");
+    }
+#endif
+}
+
+bool XMLParser::parse()
+{
+    if( !m_pReader ) return false;
+
+    m_errors = false;
+
+    int ret = xml_ReaderRead( m_pReader );
+    while( ret == 1 )
+    {
+        if( m_errors ) return false;
+
         // Get the node type
-        int type = xmlTextReaderNodeType( m_pReader );
-        switch (type )
+        int type = xml_ReaderNodeType( m_pReader );
+        switchtype )
         {
             // Error
             case -1:
-                return -1;
+                return false;
                 break;
 
-            // Begin element
-            case 1:
+            case XML_READER_STARTELEM:
+            {
                 // Read the element name
-                const xmlChar *eltName = xmlTextReaderConstName( m_pReader );
-                if( !eltName )
-                {
-                    return -1;
-                }
+                char *eltName = xml_ReaderName( m_pReader );
+                if( !eltName ) return false;
+
                 // Read the attributes
                 AttrList_t attributes;
-                while( xmlTextReaderMoveToNextAttribute( m_pReader ) == 1 )
+                while( xml_ReaderNextAttr( m_pReader ) == VLC_SUCCESS )
                 {
-                    const xmlChar *name = xmlTextReaderConstName( m_pReader );
-                    const xmlChar *value = xmlTextReaderConstValue( m_pReader );
+                    char *name = xml_ReaderName( m_pReader );
+                    char *value = xml_ReaderValue( m_pReader );
                     if( !name || !value )
                     {
-                        return -1;
+                        free( name );
+                        free( value );
+                        return false;
                     }
-                    attributes[(const char*)name] = (const char*)value;
+                    attributes[name] = value;
+                }
+
+                handleBeginElement( eltName, attributes );
+                free( eltName );
+
+                map<const char*, const char*, ltstr> ::iterator it =
+                    attributes.begin();
+                while( it != attributes.end() )
+                {
+                    free( (char *)it->first );
+                    free( (char *)it->second );
+                    it++;
                 }
-                handleBeginElement( (const char*)eltName, attributes);
                 break;
-        }
-        ret = xmlTextReaderRead( m_pReader );
-    }
-    return 0;
-}
+            }
 
+            // End element
+            case XML_READER_ENDELEM:
+            {
+                // Read the element name
+                char *eltName = xml_ReaderName( m_pReader );
+                if( !eltName ) return false;
 
-void XMLParser::handleBeginElement( const string &rName,
-                                    AttrList_t &attributes )
-{
-    fprintf(stderr,"%s\n", rName.c_str());
-    AttrList_t::const_iterator it;
-    for (it = attributes.begin(); it != attributes.end(); it++)
-    {
-        fprintf(stderr,"  %s = %s\n", (*it).first, (*it).second);
+                handleEndElement( eltName );
+                free( eltName );
+                break;
+            }
+        }
+        ret = xml_ReaderRead( m_pReader );
     }
+    return (ret == 0 && !m_errors );
 }