]> git.sesse.net Git - vlc/blob - modules/gui/skins2/parser/xmlparser.cpp
Segregate access-specific V4L2 code
[vlc] / modules / gui / skins2 / parser / xmlparser.cpp
1 /*****************************************************************************
2  * xmlparser.cpp
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "xmlparser.hpp"
25 #include "../src/os_factory.hpp"
26 #include <vlc_url.h>
27
28 #ifdef HAVE_SYS_STAT_H
29 #   include <sys/stat.h>
30 #endif
31
32 XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName )
33     : SkinObject( pIntf ), m_pXML( NULL ), m_pReader( NULL ), m_pStream( NULL )
34 {
35     m_pXML = xml_Create( pIntf );
36     if( !m_pXML )
37     {
38         msg_Err( getIntf(), "cannot initialize xml" );
39         return;
40     }
41
42     LoadCatalog();
43
44     char* psz_uri = make_URI( rFileName.c_str(), NULL );
45     m_pStream = stream_UrlNew( pIntf, psz_uri );
46     free( psz_uri );
47     if( !m_pStream )
48     {
49         msg_Err( getIntf(), "failed to open %s for reading",
50                  rFileName.c_str() );
51         return;
52     }
53
54     m_pReader = xml_ReaderCreate( m_pXML, m_pStream );
55     if( !m_pReader )
56     {
57         msg_Err( getIntf(), "failed to open %s for parsing",
58                  rFileName.c_str() );
59         return;
60     }
61
62     xml_ReaderUseDTD( m_pReader );
63 }
64
65
66 XMLParser::~XMLParser()
67 {
68     if( m_pReader ) xml_ReaderDelete( m_pReader );
69     if( m_pXML ) xml_Delete( m_pXML );
70     if( m_pStream ) stream_Delete( m_pStream );
71 }
72
73
74 void XMLParser::LoadCatalog()
75 {
76     // Get the resource path and look for the DTD
77     OSFactory *pOSFactory = OSFactory::instance( getIntf() );
78     const list<string> &resPath = pOSFactory->getResourcePath();
79     const string &sep = pOSFactory->getDirSeparator();
80     list<string>::const_iterator it;
81
82 #ifdef HAVE_SYS_STAT_H
83     struct stat statBuf;
84
85     // Try to load the catalog first (needed at least on win32 where
86     // we don't have a default catalog)
87     for( it = resPath.begin(); it != resPath.end(); ++it )
88     {
89         string catalog_path = (*it) + sep + "skin.catalog";
90         if( !stat( catalog_path.c_str(), &statBuf ) )
91         {
92             msg_Dbg( getIntf(), "Using catalog %s", catalog_path.c_str() );
93             xml_CatalogLoad( m_pXML, catalog_path.c_str() );
94             break;
95         }
96     }
97     if( it == resPath.end() )
98     {
99         // Ok, try the default one
100         xml_CatalogLoad( m_pXML, NULL );
101     }
102
103     for( it = resPath.begin(); it != resPath.end(); ++it )
104     {
105         string path = (*it) + sep + "skin.dtd";
106         if( !stat( path.c_str(), &statBuf ) )
107         {
108             // DTD found
109             msg_Dbg( getIntf(), "using DTD %s", path.c_str() );
110
111             // Add an entry in the default catalog
112             xml_CatalogAdd( m_pXML, "public",
113                             "-//VideoLAN//DTD VLC Skins V"
114                             SKINS_DTD_VERSION "//EN", path.c_str() );
115             break;
116         }
117     }
118     if( it == resPath.end() )
119     {
120         msg_Err( getIntf(), "cannot find the skins DTD");
121     }
122 #endif
123 }
124
125 bool XMLParser::parse()
126 {
127     const char *node;
128     int type;
129
130     if( !m_pReader ) return false;
131
132     m_errors = false;
133
134     while( (type = xml_ReaderNextNode( m_pReader, &node )) > 0 )
135     {
136         if( m_errors ) return false;
137
138         switch( type )
139         {
140             case XML_READER_STARTELEM:
141             {
142                 // Read the attributes
143                 AttrList_t attributes;
144                 const char *name, *value;
145                 while( (name = xml_ReaderNextAttr( m_pReader, &value )) != NULL )
146                     attributes[strdup(name)] = strdup(value);
147
148                 handleBeginElement( node, attributes );
149
150                 map<const char*, const char*, ltstr> ::iterator it =
151                     attributes.begin();
152                 while( it != attributes.end() )
153                 {
154                     free( (char *)it->first );
155                     free( (char *)it->second );
156                     ++it;
157                 }
158                 break;
159             }
160
161             // End element
162             case XML_READER_ENDELEM:
163             {
164                 handleEndElement( node );
165                 break;
166             }
167         }
168     }
169     return (type == 0 && !m_errors );
170 }