xref: /reactos/dll/win32/msxml3/saxreader.c (revision eb44c20c)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  *    SAX Reader implementation
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2008 Alistair Leslie-Hughes
5c2c66affSColin Finck  * Copyright 2008 Piotr Caban
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21bab6b90fSAmine Khaldi #define COBJMACROS
22c2c66affSColin Finck 
23bab6b90fSAmine Khaldi #include "config.h"
24c2c66affSColin Finck 
25bab6b90fSAmine Khaldi #include <stdarg.h>
26c2c66affSColin Finck #ifdef HAVE_LIBXML2
27bab6b90fSAmine Khaldi # include <libxml/parser.h>
28bab6b90fSAmine Khaldi # include <libxml/xmlerror.h>
29bab6b90fSAmine Khaldi # include <libxml/SAX2.h>
30c2c66affSColin Finck # include <libxml/parserInternals.h>
31c2c66affSColin Finck #endif
32c2c66affSColin Finck 
33bab6b90fSAmine Khaldi #include "windef.h"
34bab6b90fSAmine Khaldi #include "winbase.h"
35bab6b90fSAmine Khaldi #include "winuser.h"
36bab6b90fSAmine Khaldi #include "winnls.h"
37bab6b90fSAmine Khaldi #include "ole2.h"
38bab6b90fSAmine Khaldi #include "msxml6.h"
39bab6b90fSAmine Khaldi #include "wininet.h"
40bab6b90fSAmine Khaldi #include "urlmon.h"
41bab6b90fSAmine Khaldi #include "winreg.h"
42bab6b90fSAmine Khaldi #include "shlwapi.h"
43bab6b90fSAmine Khaldi 
44bab6b90fSAmine Khaldi #include "wine/debug.h"
45bab6b90fSAmine Khaldi 
46bab6b90fSAmine Khaldi #include "msxml_private.h"
47bab6b90fSAmine Khaldi 
48c2c66affSColin Finck #ifdef HAVE_LIBXML2
49c2c66affSColin Finck 
50bab6b90fSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(msxml);
51bab6b90fSAmine Khaldi 
52c2c66affSColin Finck typedef enum
53c2c66affSColin Finck {
54c2c66affSColin Finck     FeatureUnknown               = 0,
55c2c66affSColin Finck     ExhaustiveErrors             = 1 << 1,
56c2c66affSColin Finck     ExternalGeneralEntities      = 1 << 2,
57c2c66affSColin Finck     ExternalParameterEntities    = 1 << 3,
58c2c66affSColin Finck     ForcedResync                 = 1 << 4,
59c2c66affSColin Finck     NamespacePrefixes            = 1 << 5,
60c2c66affSColin Finck     Namespaces                   = 1 << 6,
61c2c66affSColin Finck     ParameterEntities            = 1 << 7,
62c2c66affSColin Finck     PreserveSystemIndentifiers   = 1 << 8,
63c2c66affSColin Finck     ProhibitDTD                  = 1 << 9,
64c2c66affSColin Finck     SchemaValidation             = 1 << 10,
65c2c66affSColin Finck     ServerHttpRequest            = 1 << 11,
66c2c66affSColin Finck     SuppressValidationfatalError = 1 << 12,
67c2c66affSColin Finck     UseInlineSchema              = 1 << 13,
68c2c66affSColin Finck     UseSchemaLocation            = 1 << 14,
69c2c66affSColin Finck     LexicalHandlerParEntities    = 1 << 15
70c2c66affSColin Finck } saxreader_feature;
71c2c66affSColin Finck 
72c2c66affSColin Finck /* feature names */
73c2c66affSColin Finck static const WCHAR FeatureExternalGeneralEntitiesW[] = {
74c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
75c2c66affSColin Finck     'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
76c2c66affSColin Finck     '-','e','n','t','i','t','i','e','s',0
77c2c66affSColin Finck };
78c2c66affSColin Finck 
79c2c66affSColin Finck static const WCHAR FeatureExternalParameterEntitiesW[] = {
80c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
81c2c66affSColin Finck     '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
82c2c66affSColin Finck };
83c2c66affSColin Finck 
84c2c66affSColin Finck static const WCHAR FeatureLexicalHandlerParEntitiesW[] = {
85c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
86c2c66affSColin Finck     '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
87c2c66affSColin Finck };
88c2c66affSColin Finck 
89c2c66affSColin Finck static const WCHAR FeatureProhibitDTDW[] = {
90c2c66affSColin Finck     'p','r','o','h','i','b','i','t','-','d','t','d',0
91c2c66affSColin Finck };
92c2c66affSColin Finck 
93c2c66affSColin Finck static const WCHAR FeatureNamespacesW[] = {
94c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
95c2c66affSColin Finck     '/','n','a','m','e','s','p','a','c','e','s',0
96c2c66affSColin Finck };
97c2c66affSColin Finck 
98c2c66affSColin Finck static const WCHAR FeatureNamespacePrefixesW[] = {
99c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
100c2c66affSColin Finck     '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
101c2c66affSColin Finck };
102c2c66affSColin Finck 
103bab6b90fSAmine Khaldi static const WCHAR ExhaustiveErrorsW[] = {
104bab6b90fSAmine Khaldi     'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
105bab6b90fSAmine Khaldi };
106bab6b90fSAmine Khaldi 
107bab6b90fSAmine Khaldi static const WCHAR SchemaValidationW[] = {
108bab6b90fSAmine Khaldi     's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0
109bab6b90fSAmine Khaldi };
110bab6b90fSAmine Khaldi 
111c2c66affSColin Finck struct saxreader_feature_pair
112c2c66affSColin Finck {
113c2c66affSColin Finck     saxreader_feature feature;
114c2c66affSColin Finck     const WCHAR *name;
115c2c66affSColin Finck };
116c2c66affSColin Finck 
117c2c66affSColin Finck static const struct saxreader_feature_pair saxreader_feature_map[] = {
118bab6b90fSAmine Khaldi     { ExhaustiveErrors, ExhaustiveErrorsW },
119c2c66affSColin Finck     { ExternalGeneralEntities, FeatureExternalGeneralEntitiesW },
120c2c66affSColin Finck     { ExternalParameterEntities, FeatureExternalParameterEntitiesW },
121c2c66affSColin Finck     { LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW },
122c2c66affSColin Finck     { NamespacePrefixes, FeatureNamespacePrefixesW },
123c2c66affSColin Finck     { Namespaces, FeatureNamespacesW },
124bab6b90fSAmine Khaldi     { ProhibitDTD, FeatureProhibitDTDW },
125bab6b90fSAmine Khaldi     { SchemaValidation, SchemaValidationW },
126c2c66affSColin Finck };
127c2c66affSColin Finck 
get_saxreader_feature(const WCHAR * name)128c2c66affSColin Finck static saxreader_feature get_saxreader_feature(const WCHAR *name)
129c2c66affSColin Finck {
130c2c66affSColin Finck     int min, max, n, c;
131c2c66affSColin Finck 
132c2c66affSColin Finck     min = 0;
133bab6b90fSAmine Khaldi     max = ARRAY_SIZE(saxreader_feature_map) - 1;
134c2c66affSColin Finck 
135c2c66affSColin Finck     while (min <= max)
136c2c66affSColin Finck     {
137c2c66affSColin Finck         n = (min+max)/2;
138c2c66affSColin Finck 
139c2c66affSColin Finck         c = strcmpW(saxreader_feature_map[n].name, name);
140c2c66affSColin Finck         if (!c)
141c2c66affSColin Finck             return saxreader_feature_map[n].feature;
142c2c66affSColin Finck 
143c2c66affSColin Finck         if (c > 0)
144c2c66affSColin Finck             max = n-1;
145c2c66affSColin Finck         else
146c2c66affSColin Finck             min = n+1;
147c2c66affSColin Finck     }
148c2c66affSColin Finck 
149c2c66affSColin Finck     return FeatureUnknown;
150c2c66affSColin Finck }
151c2c66affSColin Finck 
152*eb44c20cSAmine Khaldi static const WCHAR empty_str;
153*eb44c20cSAmine Khaldi 
154c2c66affSColin Finck struct bstrpool
155c2c66affSColin Finck {
156c2c66affSColin Finck     BSTR *pool;
157c2c66affSColin Finck     unsigned int index;
158c2c66affSColin Finck     unsigned int len;
159c2c66affSColin Finck };
160c2c66affSColin Finck 
161c2c66affSColin Finck typedef struct
162c2c66affSColin Finck {
163c2c66affSColin Finck     BSTR prefix;
164c2c66affSColin Finck     BSTR uri;
165c2c66affSColin Finck } ns;
166c2c66affSColin Finck 
167c2c66affSColin Finck typedef struct
168c2c66affSColin Finck {
169c2c66affSColin Finck     struct list entry;
170c2c66affSColin Finck     BSTR prefix;
171c2c66affSColin Finck     BSTR local;
172c2c66affSColin Finck     BSTR qname;
173c2c66affSColin Finck     ns *ns; /* namespaces defined in this particular element */
174c2c66affSColin Finck     int ns_count;
175c2c66affSColin Finck } element_entry;
176c2c66affSColin Finck 
177c2c66affSColin Finck enum saxhandler_type
178c2c66affSColin Finck {
179c2c66affSColin Finck     SAXContentHandler = 0,
180c2c66affSColin Finck     SAXDeclHandler,
181c2c66affSColin Finck     SAXDTDHandler,
182c2c66affSColin Finck     SAXEntityResolver,
183c2c66affSColin Finck     SAXErrorHandler,
184c2c66affSColin Finck     SAXLexicalHandler,
185c2c66affSColin Finck     SAXHandler_Last
186c2c66affSColin Finck };
187c2c66affSColin Finck 
188c2c66affSColin Finck struct saxanyhandler_iface
189c2c66affSColin Finck {
190c2c66affSColin Finck     IUnknown *handler;
191c2c66affSColin Finck     IUnknown *vbhandler;
192c2c66affSColin Finck };
193c2c66affSColin Finck 
194c2c66affSColin Finck struct saxcontenthandler_iface
195c2c66affSColin Finck {
196c2c66affSColin Finck     ISAXContentHandler *handler;
197c2c66affSColin Finck     IVBSAXContentHandler *vbhandler;
198c2c66affSColin Finck };
199c2c66affSColin Finck 
200c2c66affSColin Finck struct saxerrorhandler_iface
201c2c66affSColin Finck {
202c2c66affSColin Finck     ISAXErrorHandler *handler;
203c2c66affSColin Finck     IVBSAXErrorHandler *vbhandler;
204c2c66affSColin Finck };
205c2c66affSColin Finck 
206c2c66affSColin Finck struct saxlexicalhandler_iface
207c2c66affSColin Finck {
208c2c66affSColin Finck     ISAXLexicalHandler *handler;
209c2c66affSColin Finck     IVBSAXLexicalHandler *vbhandler;
210c2c66affSColin Finck };
211c2c66affSColin Finck 
212c2c66affSColin Finck struct saxentityresolver_iface
213c2c66affSColin Finck {
214c2c66affSColin Finck     ISAXEntityResolver *handler;
215c2c66affSColin Finck     IVBSAXEntityResolver *vbhandler;
216c2c66affSColin Finck };
217c2c66affSColin Finck 
218c2c66affSColin Finck struct saxhandler_iface
219c2c66affSColin Finck {
220c2c66affSColin Finck     union {
221c2c66affSColin Finck         struct saxcontenthandler_iface content;
222c2c66affSColin Finck         struct saxentityresolver_iface entityresolver;
223c2c66affSColin Finck         struct saxerrorhandler_iface error;
224c2c66affSColin Finck         struct saxlexicalhandler_iface lexical;
225c2c66affSColin Finck         struct saxanyhandler_iface anyhandler;
226c2c66affSColin Finck     } u;
227c2c66affSColin Finck };
228c2c66affSColin Finck 
229c2c66affSColin Finck typedef struct
230c2c66affSColin Finck {
231c2c66affSColin Finck     DispatchEx dispex;
232c2c66affSColin Finck     IVBSAXXMLReader IVBSAXXMLReader_iface;
233c2c66affSColin Finck     ISAXXMLReader ISAXXMLReader_iface;
234c2c66affSColin Finck     LONG ref;
235c2c66affSColin Finck 
236c2c66affSColin Finck     struct saxhandler_iface saxhandlers[SAXHandler_Last];
237c2c66affSColin Finck     xmlSAXHandler sax;
238c2c66affSColin Finck     BOOL isParsing;
239c2c66affSColin Finck     struct bstrpool pool;
240c2c66affSColin Finck     saxreader_feature features;
241c2c66affSColin Finck     BSTR xmldecl_version;
242c2c66affSColin Finck     MSXML_VERSION version;
243c2c66affSColin Finck } saxreader;
244c2c66affSColin Finck 
saxreader_put_handler(saxreader * reader,enum saxhandler_type type,void * ptr,BOOL vb)245c2c66affSColin Finck static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
246c2c66affSColin Finck {
247c2c66affSColin Finck     struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
248c2c66affSColin Finck     IUnknown *unk = (IUnknown*)ptr;
249c2c66affSColin Finck 
250c2c66affSColin Finck     if (unk)
251c2c66affSColin Finck         IUnknown_AddRef(unk);
252c2c66affSColin Finck 
253c2c66affSColin Finck     if ((vb && iface->vbhandler) || (!vb && iface->handler))
254c2c66affSColin Finck         IUnknown_Release(vb ? iface->vbhandler : iface->handler);
255c2c66affSColin Finck 
256c2c66affSColin Finck     if (vb)
257c2c66affSColin Finck         iface->vbhandler = unk;
258c2c66affSColin Finck     else
259c2c66affSColin Finck         iface->handler = unk;
260c2c66affSColin Finck 
261c2c66affSColin Finck     return S_OK;
262c2c66affSColin Finck }
263c2c66affSColin Finck 
saxreader_get_handler(const saxreader * reader,enum saxhandler_type type,BOOL vb,void ** ret)264c2c66affSColin Finck static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
265c2c66affSColin Finck {
266c2c66affSColin Finck     const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
267c2c66affSColin Finck 
268c2c66affSColin Finck     if (!ret) return E_POINTER;
269c2c66affSColin Finck 
270c2c66affSColin Finck     if ((vb && iface->vbhandler) || (!vb && iface->handler))
271c2c66affSColin Finck     {
272c2c66affSColin Finck         if (vb)
273c2c66affSColin Finck             IUnknown_AddRef(iface->vbhandler);
274c2c66affSColin Finck         else
275c2c66affSColin Finck             IUnknown_AddRef(iface->handler);
276c2c66affSColin Finck     }
277c2c66affSColin Finck 
278c2c66affSColin Finck     *ret = vb ? iface->vbhandler : iface->handler;
279c2c66affSColin Finck 
280c2c66affSColin Finck     return S_OK;
281c2c66affSColin Finck }
282c2c66affSColin Finck 
saxreader_get_contenthandler(saxreader * reader)283c2c66affSColin Finck static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
284c2c66affSColin Finck {
285c2c66affSColin Finck     return &reader->saxhandlers[SAXContentHandler].u.content;
286c2c66affSColin Finck }
287c2c66affSColin Finck 
saxreader_get_errorhandler(saxreader * reader)288c2c66affSColin Finck static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
289c2c66affSColin Finck {
290c2c66affSColin Finck     return &reader->saxhandlers[SAXErrorHandler].u.error;
291c2c66affSColin Finck }
292c2c66affSColin Finck 
saxreader_get_lexicalhandler(saxreader * reader)293c2c66affSColin Finck static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
294c2c66affSColin Finck {
295c2c66affSColin Finck     return &reader->saxhandlers[SAXLexicalHandler].u.lexical;
296c2c66affSColin Finck }
297c2c66affSColin Finck 
298c2c66affSColin Finck typedef struct
299c2c66affSColin Finck {
300c2c66affSColin Finck     IVBSAXLocator IVBSAXLocator_iface;
301c2c66affSColin Finck     ISAXLocator ISAXLocator_iface;
302c2c66affSColin Finck     IVBSAXAttributes IVBSAXAttributes_iface;
303c2c66affSColin Finck     ISAXAttributes ISAXAttributes_iface;
304c2c66affSColin Finck     LONG ref;
305c2c66affSColin Finck     saxreader *saxreader;
306c2c66affSColin Finck     HRESULT ret;
307c2c66affSColin Finck     xmlParserCtxtPtr pParserCtxt;
308c2c66affSColin Finck     BSTR publicId;
309c2c66affSColin Finck     BSTR systemId;
310c2c66affSColin Finck     int line;
311c2c66affSColin Finck     int column;
312c2c66affSColin Finck     BOOL vbInterface;
313c2c66affSColin Finck     struct list elements;
314c2c66affSColin Finck 
315c2c66affSColin Finck     BSTR namespaceUri;
316c2c66affSColin Finck     int attr_alloc_count;
317c2c66affSColin Finck     int attr_count;
318c2c66affSColin Finck     struct _attributes
319c2c66affSColin Finck     {
320c2c66affSColin Finck         BSTR szLocalname;
321c2c66affSColin Finck         BSTR szURI;
322c2c66affSColin Finck         BSTR szValue;
323c2c66affSColin Finck         BSTR szQName;
324c2c66affSColin Finck     } *attributes;
325c2c66affSColin Finck } saxlocator;
326c2c66affSColin Finck 
impl_from_IVBSAXXMLReader(IVBSAXXMLReader * iface)327c2c66affSColin Finck static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
328c2c66affSColin Finck {
329c2c66affSColin Finck     return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface);
330c2c66affSColin Finck }
331c2c66affSColin Finck 
impl_from_ISAXXMLReader(ISAXXMLReader * iface)332c2c66affSColin Finck static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
333c2c66affSColin Finck {
334c2c66affSColin Finck     return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface);
335c2c66affSColin Finck }
336c2c66affSColin Finck 
impl_from_IVBSAXLocator(IVBSAXLocator * iface)337c2c66affSColin Finck static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
338c2c66affSColin Finck {
339c2c66affSColin Finck     return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface);
340c2c66affSColin Finck }
341c2c66affSColin Finck 
impl_from_ISAXLocator(ISAXLocator * iface)342c2c66affSColin Finck static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
343c2c66affSColin Finck {
344c2c66affSColin Finck     return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface);
345c2c66affSColin Finck }
346c2c66affSColin Finck 
impl_from_IVBSAXAttributes(IVBSAXAttributes * iface)347c2c66affSColin Finck static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
348c2c66affSColin Finck {
349c2c66affSColin Finck     return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface);
350c2c66affSColin Finck }
351c2c66affSColin Finck 
impl_from_ISAXAttributes(ISAXAttributes * iface)352c2c66affSColin Finck static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface )
353c2c66affSColin Finck {
354c2c66affSColin Finck     return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
355c2c66affSColin Finck }
356c2c66affSColin Finck 
saxreader_has_handler(const saxlocator * locator,enum saxhandler_type type)357c2c66affSColin Finck static inline BOOL saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type)
358c2c66affSColin Finck {
359c2c66affSColin Finck     struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler;
360c2c66affSColin Finck     return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler);
361c2c66affSColin Finck }
362c2c66affSColin Finck 
saxreader_saxcharacters(saxlocator * locator,BSTR chars)363c2c66affSColin Finck static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars)
364c2c66affSColin Finck {
365c2c66affSColin Finck     struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader);
366c2c66affSColin Finck     HRESULT hr;
367c2c66affSColin Finck 
368c2c66affSColin Finck     if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK;
369c2c66affSColin Finck 
370c2c66affSColin Finck     if (locator->vbInterface)
371c2c66affSColin Finck         hr = IVBSAXContentHandler_characters(content->vbhandler, &chars);
372c2c66affSColin Finck     else
373c2c66affSColin Finck         hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars));
374c2c66affSColin Finck 
375c2c66affSColin Finck     return hr;
376c2c66affSColin Finck }
377c2c66affSColin Finck 
378c2c66affSColin Finck /* property names */
379c2c66affSColin Finck static const WCHAR PropertyCharsetW[] = {
380c2c66affSColin Finck     'c','h','a','r','s','e','t',0
381c2c66affSColin Finck };
382c2c66affSColin Finck static const WCHAR PropertyXmlDeclVersionW[] = {
383c2c66affSColin Finck     'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
384c2c66affSColin Finck };
385c2c66affSColin Finck static const WCHAR PropertyDeclHandlerW[] = {
386c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
387c2c66affSColin Finck     's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
388c2c66affSColin Finck     'd','e','c','l','a','r','a','t','i','o','n',
389c2c66affSColin Finck     '-','h','a','n','d','l','e','r',0
390c2c66affSColin Finck };
391c2c66affSColin Finck static const WCHAR PropertyDomNodeW[] = {
392c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
393c2c66affSColin Finck     's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
394c2c66affSColin Finck     'd','o','m','-','n','o','d','e',0
395c2c66affSColin Finck };
396c2c66affSColin Finck static const WCHAR PropertyInputSourceW[] = {
397c2c66affSColin Finck     'i','n','p','u','t','-','s','o','u','r','c','e',0
398c2c66affSColin Finck };
399c2c66affSColin Finck static const WCHAR PropertyLexicalHandlerW[] = {
400c2c66affSColin Finck     'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
401c2c66affSColin Finck     's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
402c2c66affSColin Finck     'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
403c2c66affSColin Finck };
404c2c66affSColin Finck static const WCHAR PropertyMaxElementDepthW[] = {
405c2c66affSColin Finck     'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
406c2c66affSColin Finck };
407c2c66affSColin Finck static const WCHAR PropertyMaxXMLSizeW[] = {
408c2c66affSColin Finck     'm','a','x','-','x','m','l','-','s','i','z','e',0
409c2c66affSColin Finck };
410c2c66affSColin Finck static const WCHAR PropertySchemaDeclHandlerW[] = {
411c2c66affSColin Finck     's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
412c2c66affSColin Finck     'h','a','n','d','l','e','r',0
413c2c66affSColin Finck };
414c2c66affSColin Finck static const WCHAR PropertyXMLDeclEncodingW[] = {
415c2c66affSColin Finck     'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
416c2c66affSColin Finck };
417c2c66affSColin Finck static const WCHAR PropertyXMLDeclStandaloneW[] = {
418c2c66affSColin Finck     'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
419c2c66affSColin Finck };
420c2c66affSColin Finck static const WCHAR PropertyXMLDeclVersionW[] = {
421c2c66affSColin Finck     'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
422c2c66affSColin Finck };
423c2c66affSColin Finck 
set_feature_value(saxreader * reader,saxreader_feature feature,VARIANT_BOOL value)424c2c66affSColin Finck static inline HRESULT set_feature_value(saxreader *reader, saxreader_feature feature, VARIANT_BOOL value)
425c2c66affSColin Finck {
426c2c66affSColin Finck     /* handling of non-VARIANT_* values is version dependent */
427c2c66affSColin Finck     if ((reader->version <  MSXML4) && (value != VARIANT_TRUE))
428c2c66affSColin Finck         value = VARIANT_FALSE;
429c2c66affSColin Finck     if ((reader->version >= MSXML4) && (value != VARIANT_FALSE))
430c2c66affSColin Finck         value = VARIANT_TRUE;
431c2c66affSColin Finck 
432c2c66affSColin Finck     if (value == VARIANT_TRUE)
433c2c66affSColin Finck         reader->features |=  feature;
434c2c66affSColin Finck     else
435c2c66affSColin Finck         reader->features &= ~feature;
436c2c66affSColin Finck 
437c2c66affSColin Finck     return S_OK;
438c2c66affSColin Finck }
439c2c66affSColin Finck 
get_feature_value(const saxreader * reader,saxreader_feature feature,VARIANT_BOOL * value)440c2c66affSColin Finck static inline HRESULT get_feature_value(const saxreader *reader, saxreader_feature feature, VARIANT_BOOL *value)
441c2c66affSColin Finck {
442c2c66affSColin Finck     *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE;
443c2c66affSColin Finck     return S_OK;
444c2c66affSColin Finck }
445c2c66affSColin Finck 
is_namespaces_enabled(const saxreader * reader)446c2c66affSColin Finck static BOOL is_namespaces_enabled(const saxreader *reader)
447c2c66affSColin Finck {
448c2c66affSColin Finck     return (reader->version < MSXML4) || (reader->features & Namespaces);
449c2c66affSColin Finck }
450c2c66affSColin Finck 
build_qname(BSTR prefix,BSTR local)451c2c66affSColin Finck static BSTR build_qname(BSTR prefix, BSTR local)
452c2c66affSColin Finck {
453c2c66affSColin Finck     if (prefix && *prefix)
454c2c66affSColin Finck     {
455c2c66affSColin Finck         BSTR qname = SysAllocStringLen(NULL, SysStringLen(prefix) + SysStringLen(local) + 1);
456c2c66affSColin Finck         WCHAR *ptr;
457c2c66affSColin Finck 
458c2c66affSColin Finck         ptr = qname;
459c2c66affSColin Finck         strcpyW(ptr, prefix);
460c2c66affSColin Finck         ptr += SysStringLen(prefix);
461c2c66affSColin Finck         *ptr++ = ':';
462c2c66affSColin Finck         strcpyW(ptr, local);
463c2c66affSColin Finck         return qname;
464c2c66affSColin Finck     }
465c2c66affSColin Finck     else
466c2c66affSColin Finck         return SysAllocString(local);
467c2c66affSColin Finck }
468c2c66affSColin Finck 
alloc_element_entry(const xmlChar * local,const xmlChar * prefix,int nb_ns,const xmlChar ** namespaces)469c2c66affSColin Finck static element_entry* alloc_element_entry(const xmlChar *local, const xmlChar *prefix, int nb_ns,
470c2c66affSColin Finck     const xmlChar **namespaces)
471c2c66affSColin Finck {
472c2c66affSColin Finck     element_entry *ret;
473c2c66affSColin Finck     int i;
474c2c66affSColin Finck 
475c2c66affSColin Finck     ret = heap_alloc(sizeof(*ret));
476c2c66affSColin Finck     if (!ret) return ret;
477c2c66affSColin Finck 
478c2c66affSColin Finck     ret->local  = bstr_from_xmlChar(local);
479c2c66affSColin Finck     ret->prefix = bstr_from_xmlChar(prefix);
480c2c66affSColin Finck     ret->qname  = build_qname(ret->prefix, ret->local);
481c2c66affSColin Finck     ret->ns = nb_ns ? heap_alloc(nb_ns*sizeof(ns)) : NULL;
482c2c66affSColin Finck     ret->ns_count = nb_ns;
483c2c66affSColin Finck 
484c2c66affSColin Finck     for (i=0; i < nb_ns; i++)
485c2c66affSColin Finck     {
486c2c66affSColin Finck         ret->ns[i].prefix = bstr_from_xmlChar(namespaces[2*i]);
487c2c66affSColin Finck         ret->ns[i].uri = bstr_from_xmlChar(namespaces[2*i+1]);
488c2c66affSColin Finck     }
489c2c66affSColin Finck 
490c2c66affSColin Finck     return ret;
491c2c66affSColin Finck }
492c2c66affSColin Finck 
free_element_entry(element_entry * element)493c2c66affSColin Finck static void free_element_entry(element_entry *element)
494c2c66affSColin Finck {
495c2c66affSColin Finck     int i;
496c2c66affSColin Finck 
497c2c66affSColin Finck     for (i=0; i<element->ns_count;i++)
498c2c66affSColin Finck     {
499c2c66affSColin Finck         SysFreeString(element->ns[i].prefix);
500c2c66affSColin Finck         SysFreeString(element->ns[i].uri);
501c2c66affSColin Finck     }
502c2c66affSColin Finck 
503c2c66affSColin Finck     SysFreeString(element->prefix);
504c2c66affSColin Finck     SysFreeString(element->local);
505c2c66affSColin Finck     SysFreeString(element->qname);
506c2c66affSColin Finck 
507c2c66affSColin Finck     heap_free(element->ns);
508c2c66affSColin Finck     heap_free(element);
509c2c66affSColin Finck }
510c2c66affSColin Finck 
push_element_ns(saxlocator * locator,element_entry * element)511c2c66affSColin Finck static void push_element_ns(saxlocator *locator, element_entry *element)
512c2c66affSColin Finck {
513c2c66affSColin Finck     list_add_head(&locator->elements, &element->entry);
514c2c66affSColin Finck }
515c2c66affSColin Finck 
pop_element_ns(saxlocator * locator)516c2c66affSColin Finck static element_entry * pop_element_ns(saxlocator *locator)
517c2c66affSColin Finck {
518c2c66affSColin Finck     element_entry *element = LIST_ENTRY(list_head(&locator->elements), element_entry, entry);
519c2c66affSColin Finck 
520c2c66affSColin Finck     if (element)
521c2c66affSColin Finck         list_remove(&element->entry);
522c2c66affSColin Finck 
523c2c66affSColin Finck     return element;
524c2c66affSColin Finck }
525c2c66affSColin Finck 
find_element_uri(saxlocator * locator,const xmlChar * uri)526c2c66affSColin Finck static BSTR find_element_uri(saxlocator *locator, const xmlChar *uri)
527c2c66affSColin Finck {
528c2c66affSColin Finck     element_entry *element;
529c2c66affSColin Finck     BSTR uriW;
530c2c66affSColin Finck     int i;
531c2c66affSColin Finck 
532c2c66affSColin Finck     if (!uri) return NULL;
533c2c66affSColin Finck 
534c2c66affSColin Finck     uriW = bstr_from_xmlChar(uri);
535c2c66affSColin Finck 
536c2c66affSColin Finck     LIST_FOR_EACH_ENTRY(element, &locator->elements, element_entry, entry)
537c2c66affSColin Finck     {
538c2c66affSColin Finck         for (i=0; i < element->ns_count; i++)
539c2c66affSColin Finck             if (!strcmpW(uriW, element->ns[i].uri))
540c2c66affSColin Finck             {
541c2c66affSColin Finck                 SysFreeString(uriW);
542c2c66affSColin Finck                 return element->ns[i].uri;
543c2c66affSColin Finck             }
544c2c66affSColin Finck     }
545c2c66affSColin Finck 
546c2c66affSColin Finck     SysFreeString(uriW);
547c2c66affSColin Finck     ERR("namespace uri not found, %s\n", debugstr_a((char*)uri));
548c2c66affSColin Finck     return NULL;
549c2c66affSColin Finck }
550c2c66affSColin Finck 
551c2c66affSColin Finck /* used to localize version dependent error check behaviour */
sax_callback_failed(saxlocator * This,HRESULT hr)552c2c66affSColin Finck static inline BOOL sax_callback_failed(saxlocator *This, HRESULT hr)
553c2c66affSColin Finck {
554c2c66affSColin Finck     return This->saxreader->version >= MSXML4 ? FAILED(hr) : hr != S_OK;
555c2c66affSColin Finck }
556c2c66affSColin Finck 
557c2c66affSColin Finck /* index value -1 means it tries to loop for a first time */
iterate_endprefix_index(saxlocator * This,const element_entry * element,int * i)558c2c66affSColin Finck static inline BOOL iterate_endprefix_index(saxlocator *This, const element_entry *element, int *i)
559c2c66affSColin Finck {
560c2c66affSColin Finck     if (This->saxreader->version >= MSXML4)
561c2c66affSColin Finck     {
562c2c66affSColin Finck         if (*i == -1) *i = 0; else ++*i;
563c2c66affSColin Finck         return *i < element->ns_count;
564c2c66affSColin Finck     }
565c2c66affSColin Finck     else
566c2c66affSColin Finck     {
567c2c66affSColin Finck         if (*i == -1) *i = element->ns_count-1; else --*i;
568c2c66affSColin Finck         return *i >= 0;
569c2c66affSColin Finck     }
570c2c66affSColin Finck }
571c2c66affSColin Finck 
bstr_pool_insert(struct bstrpool * pool,BSTR pool_entry)572c2c66affSColin Finck static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
573c2c66affSColin Finck {
574c2c66affSColin Finck     if (!pool->pool)
575c2c66affSColin Finck     {
576bab6b90fSAmine Khaldi         pool->pool = heap_alloc(16 * sizeof(*pool->pool));
577c2c66affSColin Finck         if (!pool->pool)
578c2c66affSColin Finck             return FALSE;
579c2c66affSColin Finck 
580c2c66affSColin Finck         pool->index = 0;
581c2c66affSColin Finck         pool->len = 16;
582c2c66affSColin Finck     }
583c2c66affSColin Finck     else if (pool->index == pool->len)
584c2c66affSColin Finck     {
585bab6b90fSAmine Khaldi         BSTR *realloc = heap_realloc(pool->pool, pool->len * 2 * sizeof(*realloc));
586c2c66affSColin Finck 
587c2c66affSColin Finck         if (!realloc)
588c2c66affSColin Finck             return FALSE;
589c2c66affSColin Finck 
590c2c66affSColin Finck         pool->pool = realloc;
591c2c66affSColin Finck         pool->len *= 2;
592c2c66affSColin Finck     }
593c2c66affSColin Finck 
594c2c66affSColin Finck     pool->pool[pool->index++] = pool_entry;
595c2c66affSColin Finck     return TRUE;
596c2c66affSColin Finck }
597c2c66affSColin Finck 
free_bstr_pool(struct bstrpool * pool)598c2c66affSColin Finck static void free_bstr_pool(struct bstrpool *pool)
599c2c66affSColin Finck {
600c2c66affSColin Finck     unsigned int i;
601c2c66affSColin Finck 
602c2c66affSColin Finck     for (i = 0; i < pool->index; i++)
603c2c66affSColin Finck         SysFreeString(pool->pool[i]);
604c2c66affSColin Finck 
605bab6b90fSAmine Khaldi     heap_free(pool->pool);
606c2c66affSColin Finck 
607c2c66affSColin Finck     pool->pool = NULL;
608c2c66affSColin Finck     pool->index = pool->len = 0;
609c2c66affSColin Finck }
610c2c66affSColin Finck 
bstr_from_xmlCharN(const xmlChar * buf,int len)611c2c66affSColin Finck static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
612c2c66affSColin Finck {
613c2c66affSColin Finck     DWORD dLen;
614c2c66affSColin Finck     BSTR bstr;
615c2c66affSColin Finck 
616c2c66affSColin Finck     if (!buf)
617c2c66affSColin Finck         return NULL;
618c2c66affSColin Finck 
619c2c66affSColin Finck     dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
620c2c66affSColin Finck     if(len != -1) dLen++;
621c2c66affSColin Finck     bstr = SysAllocStringLen(NULL, dLen-1);
622c2c66affSColin Finck     if (!bstr)
623c2c66affSColin Finck         return NULL;
624c2c66affSColin Finck     MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen);
625c2c66affSColin Finck     if(len != -1) bstr[dLen-1] = '\0';
626c2c66affSColin Finck 
627c2c66affSColin Finck     return bstr;
628c2c66affSColin Finck }
629c2c66affSColin Finck 
QName_from_xmlChar(const xmlChar * prefix,const xmlChar * name)630c2c66affSColin Finck static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
631c2c66affSColin Finck {
632c2c66affSColin Finck     xmlChar *qname;
633c2c66affSColin Finck     BSTR bstr;
634c2c66affSColin Finck 
635c2c66affSColin Finck     if(!name) return NULL;
636c2c66affSColin Finck 
637c2c66affSColin Finck     if(!prefix || !*prefix)
638c2c66affSColin Finck         return bstr_from_xmlChar(name);
639c2c66affSColin Finck 
640c2c66affSColin Finck     qname = xmlBuildQName(name, prefix, NULL, 0);
641c2c66affSColin Finck     bstr = bstr_from_xmlChar(qname);
642c2c66affSColin Finck     xmlFree(qname);
643c2c66affSColin Finck 
644c2c66affSColin Finck     return bstr;
645c2c66affSColin Finck }
646c2c66affSColin Finck 
pooled_bstr_from_xmlChar(struct bstrpool * pool,const xmlChar * buf)647c2c66affSColin Finck static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf)
648c2c66affSColin Finck {
649c2c66affSColin Finck     BSTR pool_entry = bstr_from_xmlChar(buf);
650c2c66affSColin Finck 
651c2c66affSColin Finck     if (pool_entry && !bstr_pool_insert(pool, pool_entry))
652c2c66affSColin Finck     {
653c2c66affSColin Finck         SysFreeString(pool_entry);
654c2c66affSColin Finck         return NULL;
655c2c66affSColin Finck     }
656c2c66affSColin Finck 
657c2c66affSColin Finck     return pool_entry;
658c2c66affSColin Finck }
659c2c66affSColin Finck 
pooled_bstr_from_xmlCharN(struct bstrpool * pool,const xmlChar * buf,int len)660c2c66affSColin Finck static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len)
661c2c66affSColin Finck {
662c2c66affSColin Finck     BSTR pool_entry = bstr_from_xmlCharN(buf, len);
663c2c66affSColin Finck 
664c2c66affSColin Finck     if (pool_entry && !bstr_pool_insert(pool, pool_entry))
665c2c66affSColin Finck     {
666c2c66affSColin Finck         SysFreeString(pool_entry);
667c2c66affSColin Finck         return NULL;
668c2c66affSColin Finck     }
669c2c66affSColin Finck 
670c2c66affSColin Finck     return pool_entry;
671c2c66affSColin Finck }
672c2c66affSColin Finck 
format_error_message_from_id(saxlocator * This,HRESULT hr)673c2c66affSColin Finck static void format_error_message_from_id(saxlocator *This, HRESULT hr)
674c2c66affSColin Finck {
675c2c66affSColin Finck     struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
676c2c66affSColin Finck     xmlStopParser(This->pParserCtxt);
677c2c66affSColin Finck     This->ret = hr;
678c2c66affSColin Finck 
679c2c66affSColin Finck     if (saxreader_has_handler(This, SAXErrorHandler))
680c2c66affSColin Finck     {
681c2c66affSColin Finck         WCHAR msg[1024];
682c2c66affSColin Finck         if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
683bab6b90fSAmine Khaldi                     NULL, hr, 0, msg, ARRAY_SIZE(msg), NULL))
684c2c66affSColin Finck         {
685c2c66affSColin Finck             FIXME("MSXML errors not yet supported.\n");
686c2c66affSColin Finck             msg[0] = '\0';
687c2c66affSColin Finck         }
688c2c66affSColin Finck 
689c2c66affSColin Finck         if(This->vbInterface)
690c2c66affSColin Finck         {
691c2c66affSColin Finck             BSTR bstrMsg = SysAllocString(msg);
692c2c66affSColin Finck             IVBSAXErrorHandler_fatalError(handler->vbhandler,
693c2c66affSColin Finck                     &This->IVBSAXLocator_iface, &bstrMsg, hr);
694c2c66affSColin Finck             SysFreeString(bstrMsg);
695c2c66affSColin Finck         }
696c2c66affSColin Finck         else
697c2c66affSColin Finck             ISAXErrorHandler_fatalError(handler->handler,
698c2c66affSColin Finck                     &This->ISAXLocator_iface, msg, hr);
699c2c66affSColin Finck     }
700c2c66affSColin Finck }
701c2c66affSColin Finck 
update_position(saxlocator * This,BOOL fix_column)702c2c66affSColin Finck static void update_position(saxlocator *This, BOOL fix_column)
703c2c66affSColin Finck {
704c2c66affSColin Finck     const xmlChar *p = This->pParserCtxt->input->cur-1;
705c2c66affSColin Finck     const xmlChar *baseP = This->pParserCtxt->input->base;
706c2c66affSColin Finck 
707c2c66affSColin Finck     This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
708c2c66affSColin Finck     if(fix_column)
709c2c66affSColin Finck     {
710c2c66affSColin Finck         This->column = 1;
711c2c66affSColin Finck         for(;p>=baseP && *p!='\n' && *p!='\r'; p--)
712c2c66affSColin Finck             This->column++;
713c2c66affSColin Finck     }
714c2c66affSColin Finck     else
715c2c66affSColin Finck     {
716c2c66affSColin Finck         This->column = xmlSAX2GetColumnNumber(This->pParserCtxt);
717c2c66affSColin Finck     }
718c2c66affSColin Finck }
719c2c66affSColin Finck 
720c2c66affSColin Finck /*** IVBSAXAttributes interface ***/
ivbsaxattributes_QueryInterface(IVBSAXAttributes * iface,REFIID riid,void ** ppvObject)721c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_QueryInterface(
722c2c66affSColin Finck         IVBSAXAttributes* iface,
723c2c66affSColin Finck         REFIID riid,
724c2c66affSColin Finck         void **ppvObject)
725c2c66affSColin Finck {
726c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes(iface);
727c2c66affSColin Finck     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
728c2c66affSColin Finck     return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject);
729c2c66affSColin Finck }
730c2c66affSColin Finck 
ivbsaxattributes_AddRef(IVBSAXAttributes * iface)731c2c66affSColin Finck static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
732c2c66affSColin Finck {
733c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes(iface);
734c2c66affSColin Finck     return IVBSAXLocator_AddRef(&This->IVBSAXLocator_iface);
735c2c66affSColin Finck }
736c2c66affSColin Finck 
ivbsaxattributes_Release(IVBSAXAttributes * iface)737c2c66affSColin Finck static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
738c2c66affSColin Finck {
739c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes(iface);
740c2c66affSColin Finck     return IVBSAXLocator_Release(&This->IVBSAXLocator_iface);
741c2c66affSColin Finck }
742c2c66affSColin Finck 
ivbsaxattributes_GetTypeInfoCount(IVBSAXAttributes * iface,UINT * pctinfo)743c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
744c2c66affSColin Finck {
745c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
746c2c66affSColin Finck 
747c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, pctinfo);
748c2c66affSColin Finck 
749c2c66affSColin Finck     *pctinfo = 1;
750c2c66affSColin Finck 
751c2c66affSColin Finck     return S_OK;
752c2c66affSColin Finck }
753c2c66affSColin Finck 
ivbsaxattributes_GetTypeInfo(IVBSAXAttributes * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)754c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
755c2c66affSColin Finck     IVBSAXAttributes *iface,
756c2c66affSColin Finck     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
757c2c66affSColin Finck {
758c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
759c2c66affSColin Finck 
760c2c66affSColin Finck     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
761c2c66affSColin Finck 
762c2c66affSColin Finck     return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
763c2c66affSColin Finck }
764c2c66affSColin Finck 
ivbsaxattributes_GetIDsOfNames(IVBSAXAttributes * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)765c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
766c2c66affSColin Finck     IVBSAXAttributes *iface,
767c2c66affSColin Finck     REFIID riid,
768c2c66affSColin Finck     LPOLESTR* rgszNames,
769c2c66affSColin Finck     UINT cNames,
770c2c66affSColin Finck     LCID lcid,
771c2c66affSColin Finck     DISPID* rgDispId)
772c2c66affSColin Finck {
773c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
774c2c66affSColin Finck     ITypeInfo *typeinfo;
775c2c66affSColin Finck     HRESULT hr;
776c2c66affSColin Finck 
777c2c66affSColin Finck     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
778c2c66affSColin Finck           lcid, rgDispId);
779c2c66affSColin Finck 
780c2c66affSColin Finck     if(!rgszNames || cNames == 0 || !rgDispId)
781c2c66affSColin Finck         return E_INVALIDARG;
782c2c66affSColin Finck 
783c2c66affSColin Finck     hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
784c2c66affSColin Finck     if(SUCCEEDED(hr))
785c2c66affSColin Finck     {
786c2c66affSColin Finck         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
787c2c66affSColin Finck         ITypeInfo_Release(typeinfo);
788c2c66affSColin Finck     }
789c2c66affSColin Finck 
790c2c66affSColin Finck     return hr;
791c2c66affSColin Finck }
792c2c66affSColin Finck 
ivbsaxattributes_Invoke(IVBSAXAttributes * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)793c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_Invoke(
794c2c66affSColin Finck     IVBSAXAttributes *iface,
795c2c66affSColin Finck     DISPID dispIdMember,
796c2c66affSColin Finck     REFIID riid,
797c2c66affSColin Finck     LCID lcid,
798c2c66affSColin Finck     WORD wFlags,
799c2c66affSColin Finck     DISPPARAMS* pDispParams,
800c2c66affSColin Finck     VARIANT* pVarResult,
801c2c66affSColin Finck     EXCEPINFO* pExcepInfo,
802c2c66affSColin Finck     UINT* puArgErr)
803c2c66affSColin Finck {
804c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
805c2c66affSColin Finck     ITypeInfo *typeinfo;
806c2c66affSColin Finck     HRESULT hr;
807c2c66affSColin Finck 
808c2c66affSColin Finck     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
809c2c66affSColin Finck           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
810c2c66affSColin Finck 
811c2c66affSColin Finck     hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
812c2c66affSColin Finck     if(SUCCEEDED(hr))
813c2c66affSColin Finck     {
814c2c66affSColin Finck         hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
815c2c66affSColin Finck                 pDispParams, pVarResult, pExcepInfo, puArgErr);
816c2c66affSColin Finck         ITypeInfo_Release(typeinfo);
817c2c66affSColin Finck     }
818c2c66affSColin Finck 
819c2c66affSColin Finck     return hr;
820c2c66affSColin Finck }
821c2c66affSColin Finck 
822c2c66affSColin Finck /*** IVBSAXAttributes methods ***/
ivbsaxattributes_get_length(IVBSAXAttributes * iface,int * nLength)823c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_get_length(
824c2c66affSColin Finck         IVBSAXAttributes* iface,
825c2c66affSColin Finck         int *nLength)
826c2c66affSColin Finck {
827c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
828c2c66affSColin Finck     return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength);
829c2c66affSColin Finck }
830c2c66affSColin Finck 
ivbsaxattributes_getURI(IVBSAXAttributes * iface,int nIndex,BSTR * uri)831c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getURI(
832c2c66affSColin Finck         IVBSAXAttributes* iface,
833c2c66affSColin Finck         int nIndex,
834c2c66affSColin Finck         BSTR *uri)
835c2c66affSColin Finck {
836c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
837c2c66affSColin Finck     const WCHAR *uriW;
838c2c66affSColin Finck     HRESULT hr;
839c2c66affSColin Finck     int len;
840c2c66affSColin Finck 
841c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, nIndex, uri);
842c2c66affSColin Finck 
843c2c66affSColin Finck     if (!uri)
844c2c66affSColin Finck         return E_POINTER;
845c2c66affSColin Finck 
846c2c66affSColin Finck     *uri = NULL;
847c2c66affSColin Finck     hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, &uriW, &len);
848c2c66affSColin Finck     if (FAILED(hr))
849c2c66affSColin Finck         return hr;
850c2c66affSColin Finck 
851c2c66affSColin Finck     return return_bstrn(uriW, len, uri);
852c2c66affSColin Finck }
853c2c66affSColin Finck 
ivbsaxattributes_getLocalName(IVBSAXAttributes * iface,int nIndex,BSTR * name)854c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getLocalName(
855c2c66affSColin Finck         IVBSAXAttributes* iface,
856c2c66affSColin Finck         int nIndex,
857c2c66affSColin Finck         BSTR *name)
858c2c66affSColin Finck {
859c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
860c2c66affSColin Finck     const WCHAR *nameW;
861c2c66affSColin Finck     HRESULT hr;
862c2c66affSColin Finck     int len;
863c2c66affSColin Finck 
864c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, nIndex, name);
865c2c66affSColin Finck 
866c2c66affSColin Finck     if (!name)
867c2c66affSColin Finck         return E_POINTER;
868c2c66affSColin Finck 
869c2c66affSColin Finck     *name = NULL;
870c2c66affSColin Finck     hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex, &nameW, &len);
871c2c66affSColin Finck     if (FAILED(hr))
872c2c66affSColin Finck         return hr;
873c2c66affSColin Finck 
874c2c66affSColin Finck     return return_bstrn(nameW, len, name);
875c2c66affSColin Finck }
876c2c66affSColin Finck 
ivbsaxattributes_getQName(IVBSAXAttributes * iface,int nIndex,BSTR * QName)877c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getQName(
878c2c66affSColin Finck         IVBSAXAttributes* iface,
879c2c66affSColin Finck         int nIndex,
880c2c66affSColin Finck         BSTR *QName)
881c2c66affSColin Finck {
882c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
883c2c66affSColin Finck     const WCHAR *nameW;
884c2c66affSColin Finck     HRESULT hr;
885c2c66affSColin Finck     int len;
886c2c66affSColin Finck 
887c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, nIndex, QName);
888c2c66affSColin Finck 
889c2c66affSColin Finck     if (!QName)
890c2c66affSColin Finck         return E_POINTER;
891c2c66affSColin Finck 
892c2c66affSColin Finck     *QName = NULL;
893c2c66affSColin Finck     hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, &nameW, &len);
894c2c66affSColin Finck     if (FAILED(hr))
895c2c66affSColin Finck         return hr;
896c2c66affSColin Finck 
897c2c66affSColin Finck     return return_bstrn(nameW, len, QName);
898c2c66affSColin Finck }
899c2c66affSColin Finck 
ivbsaxattributes_getIndexFromName(IVBSAXAttributes * iface,BSTR uri,BSTR localName,int * index)900c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
901c2c66affSColin Finck         IVBSAXAttributes* iface,
902c2c66affSColin Finck         BSTR uri,
903c2c66affSColin Finck         BSTR localName,
904c2c66affSColin Finck         int *index)
905c2c66affSColin Finck {
906c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
907c2c66affSColin Finck     return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
908c2c66affSColin Finck             localName, SysStringLen(localName), index);
909c2c66affSColin Finck }
910c2c66affSColin Finck 
ivbsaxattributes_getIndexFromQName(IVBSAXAttributes * iface,BSTR QName,int * index)911c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
912c2c66affSColin Finck         IVBSAXAttributes* iface,
913c2c66affSColin Finck         BSTR QName,
914c2c66affSColin Finck         int *index)
915c2c66affSColin Finck {
916c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
917c2c66affSColin Finck     return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName,
918c2c66affSColin Finck             SysStringLen(QName), index);
919c2c66affSColin Finck }
920c2c66affSColin Finck 
ivbsaxattributes_getType(IVBSAXAttributes * iface,int nIndex,BSTR * type)921c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getType(
922c2c66affSColin Finck         IVBSAXAttributes* iface,
923c2c66affSColin Finck         int nIndex,
924c2c66affSColin Finck         BSTR *type)
925c2c66affSColin Finck {
926c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
927c2c66affSColin Finck     const WCHAR *typeW;
928c2c66affSColin Finck     HRESULT hr;
929c2c66affSColin Finck     int len;
930c2c66affSColin Finck 
931c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, nIndex, type);
932c2c66affSColin Finck 
933c2c66affSColin Finck     if (!type)
934c2c66affSColin Finck         return E_POINTER;
935c2c66affSColin Finck 
936c2c66affSColin Finck     *type = NULL;
937c2c66affSColin Finck     hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, &typeW, &len);
938c2c66affSColin Finck     if (FAILED(hr))
939c2c66affSColin Finck         return hr;
940c2c66affSColin Finck 
941c2c66affSColin Finck     return return_bstrn(typeW, len, type);
942c2c66affSColin Finck }
943c2c66affSColin Finck 
ivbsaxattributes_getTypeFromName(IVBSAXAttributes * iface,BSTR uri,BSTR localName,BSTR * type)944c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
945c2c66affSColin Finck         IVBSAXAttributes* iface,
946c2c66affSColin Finck         BSTR uri,
947c2c66affSColin Finck         BSTR localName,
948c2c66affSColin Finck         BSTR *type)
949c2c66affSColin Finck {
950c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
951c2c66affSColin Finck     const WCHAR *typeW;
952c2c66affSColin Finck     HRESULT hr;
953c2c66affSColin Finck     int len;
954c2c66affSColin Finck 
955c2c66affSColin Finck     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), type);
956c2c66affSColin Finck 
957c2c66affSColin Finck     if (!type)
958c2c66affSColin Finck         return E_POINTER;
959c2c66affSColin Finck 
960c2c66affSColin Finck     *type = NULL;
961c2c66affSColin Finck     hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
962c2c66affSColin Finck             localName, SysStringLen(localName), &typeW, &len);
963c2c66affSColin Finck     if (FAILED(hr))
964c2c66affSColin Finck         return hr;
965c2c66affSColin Finck 
966c2c66affSColin Finck     return return_bstrn(typeW, len, type);
967c2c66affSColin Finck }
968c2c66affSColin Finck 
ivbsaxattributes_getTypeFromQName(IVBSAXAttributes * iface,BSTR QName,BSTR * type)969c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
970c2c66affSColin Finck         IVBSAXAttributes* iface,
971c2c66affSColin Finck         BSTR QName,
972c2c66affSColin Finck         BSTR *type)
973c2c66affSColin Finck {
974c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
975c2c66affSColin Finck     const WCHAR *typeW;
976c2c66affSColin Finck     HRESULT hr;
977c2c66affSColin Finck     int len;
978c2c66affSColin Finck 
979c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), type);
980c2c66affSColin Finck 
981c2c66affSColin Finck     if (!type)
982c2c66affSColin Finck         return E_POINTER;
983c2c66affSColin Finck 
984c2c66affSColin Finck     *type = NULL;
985c2c66affSColin Finck     hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
986c2c66affSColin Finck             &typeW, &len);
987c2c66affSColin Finck     if (FAILED(hr))
988c2c66affSColin Finck         return hr;
989c2c66affSColin Finck 
990c2c66affSColin Finck     return return_bstrn(typeW, len, type);
991c2c66affSColin Finck }
992c2c66affSColin Finck 
ivbsaxattributes_getValue(IVBSAXAttributes * iface,int nIndex,BSTR * value)993c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getValue(
994c2c66affSColin Finck         IVBSAXAttributes* iface,
995c2c66affSColin Finck         int nIndex,
996c2c66affSColin Finck         BSTR *value)
997c2c66affSColin Finck {
998c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
999c2c66affSColin Finck     const WCHAR *valueW;
1000c2c66affSColin Finck     HRESULT hr;
1001c2c66affSColin Finck     int len;
1002c2c66affSColin Finck 
1003c2c66affSColin Finck     TRACE("(%p)->(%d %p)\n", This, nIndex, value);
1004c2c66affSColin Finck 
1005c2c66affSColin Finck     if (!value)
1006c2c66affSColin Finck         return E_POINTER;
1007c2c66affSColin Finck 
1008c2c66affSColin Finck     *value = NULL;
1009c2c66affSColin Finck     hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, &valueW, &len);
1010c2c66affSColin Finck     if (FAILED(hr))
1011c2c66affSColin Finck         return hr;
1012c2c66affSColin Finck 
1013c2c66affSColin Finck     return return_bstrn(valueW, len, value);
1014c2c66affSColin Finck }
1015c2c66affSColin Finck 
ivbsaxattributes_getValueFromName(IVBSAXAttributes * iface,BSTR uri,BSTR localName,BSTR * value)1016c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getValueFromName(
1017c2c66affSColin Finck         IVBSAXAttributes* iface,
1018c2c66affSColin Finck         BSTR uri,
1019c2c66affSColin Finck         BSTR localName,
1020c2c66affSColin Finck         BSTR *value)
1021c2c66affSColin Finck {
1022c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
1023c2c66affSColin Finck     const WCHAR *valueW;
1024c2c66affSColin Finck     HRESULT hr;
1025c2c66affSColin Finck     int len;
1026c2c66affSColin Finck 
1027c2c66affSColin Finck     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), value);
1028c2c66affSColin Finck 
1029c2c66affSColin Finck     if (!value)
1030c2c66affSColin Finck         return E_POINTER;
1031c2c66affSColin Finck 
1032c2c66affSColin Finck     *value = NULL;
1033c2c66affSColin Finck     hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
1034c2c66affSColin Finck             localName, SysStringLen(localName), &valueW, &len);
1035c2c66affSColin Finck     if (FAILED(hr))
1036c2c66affSColin Finck         return hr;
1037c2c66affSColin Finck 
1038c2c66affSColin Finck     return return_bstrn(valueW, len, value);
1039c2c66affSColin Finck }
1040c2c66affSColin Finck 
ivbsaxattributes_getValueFromQName(IVBSAXAttributes * iface,BSTR QName,BSTR * value)1041c2c66affSColin Finck static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
1042c2c66affSColin Finck         IVBSAXAttributes* iface,
1043c2c66affSColin Finck         BSTR QName,
1044c2c66affSColin Finck         BSTR *value)
1045c2c66affSColin Finck {
1046c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXAttributes( iface );
1047c2c66affSColin Finck     const WCHAR *valueW;
1048c2c66affSColin Finck     HRESULT hr;
1049c2c66affSColin Finck     int len;
1050c2c66affSColin Finck 
1051c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), value);
1052c2c66affSColin Finck 
1053c2c66affSColin Finck     if (!value)
1054c2c66affSColin Finck         return E_POINTER;
1055c2c66affSColin Finck 
1056c2c66affSColin Finck     *value = NULL;
1057c2c66affSColin Finck     hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
1058c2c66affSColin Finck             SysStringLen(QName), &valueW, &len);
1059c2c66affSColin Finck     if (FAILED(hr))
1060c2c66affSColin Finck         return hr;
1061c2c66affSColin Finck 
1062c2c66affSColin Finck     return return_bstrn(valueW, len, value);
1063c2c66affSColin Finck }
1064c2c66affSColin Finck 
1065c2c66affSColin Finck static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
1066c2c66affSColin Finck {
1067c2c66affSColin Finck     ivbsaxattributes_QueryInterface,
1068c2c66affSColin Finck     ivbsaxattributes_AddRef,
1069c2c66affSColin Finck     ivbsaxattributes_Release,
1070c2c66affSColin Finck     ivbsaxattributes_GetTypeInfoCount,
1071c2c66affSColin Finck     ivbsaxattributes_GetTypeInfo,
1072c2c66affSColin Finck     ivbsaxattributes_GetIDsOfNames,
1073c2c66affSColin Finck     ivbsaxattributes_Invoke,
1074c2c66affSColin Finck     ivbsaxattributes_get_length,
1075c2c66affSColin Finck     ivbsaxattributes_getURI,
1076c2c66affSColin Finck     ivbsaxattributes_getLocalName,
1077c2c66affSColin Finck     ivbsaxattributes_getQName,
1078c2c66affSColin Finck     ivbsaxattributes_getIndexFromName,
1079c2c66affSColin Finck     ivbsaxattributes_getIndexFromQName,
1080c2c66affSColin Finck     ivbsaxattributes_getType,
1081c2c66affSColin Finck     ivbsaxattributes_getTypeFromName,
1082c2c66affSColin Finck     ivbsaxattributes_getTypeFromQName,
1083c2c66affSColin Finck     ivbsaxattributes_getValue,
1084c2c66affSColin Finck     ivbsaxattributes_getValueFromName,
1085c2c66affSColin Finck     ivbsaxattributes_getValueFromQName
1086c2c66affSColin Finck };
1087c2c66affSColin Finck 
1088c2c66affSColin Finck /*** ISAXAttributes interface ***/
1089c2c66affSColin Finck /*** IUnknown methods ***/
isaxattributes_QueryInterface(ISAXAttributes * iface,REFIID riid,void ** ppvObject)1090c2c66affSColin Finck static HRESULT WINAPI isaxattributes_QueryInterface(
1091c2c66affSColin Finck         ISAXAttributes* iface,
1092c2c66affSColin Finck         REFIID riid,
1093c2c66affSColin Finck         void **ppvObject)
1094c2c66affSColin Finck {
1095c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes(iface);
1096c2c66affSColin Finck     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
1097c2c66affSColin Finck     return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject);
1098c2c66affSColin Finck }
1099c2c66affSColin Finck 
isaxattributes_AddRef(ISAXAttributes * iface)1100c2c66affSColin Finck static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
1101c2c66affSColin Finck {
1102c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes(iface);
1103c2c66affSColin Finck     TRACE("%p\n", This);
1104c2c66affSColin Finck     return ISAXLocator_AddRef(&This->ISAXLocator_iface);
1105c2c66affSColin Finck }
1106c2c66affSColin Finck 
isaxattributes_Release(ISAXAttributes * iface)1107c2c66affSColin Finck static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
1108c2c66affSColin Finck {
1109c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes(iface);
1110c2c66affSColin Finck 
1111c2c66affSColin Finck     TRACE("%p\n", This);
1112c2c66affSColin Finck     return ISAXLocator_Release(&This->ISAXLocator_iface);
1113c2c66affSColin Finck }
1114c2c66affSColin Finck 
1115c2c66affSColin Finck /*** ISAXAttributes methods ***/
isaxattributes_getLength(ISAXAttributes * iface,int * length)1116c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getLength(
1117c2c66affSColin Finck         ISAXAttributes* iface,
1118c2c66affSColin Finck         int *length)
1119c2c66affSColin Finck {
1120c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1121c2c66affSColin Finck 
1122c2c66affSColin Finck     *length = This->attr_count;
1123c2c66affSColin Finck     TRACE("Length set to %d\n", *length);
1124c2c66affSColin Finck     return S_OK;
1125c2c66affSColin Finck }
1126c2c66affSColin Finck 
is_valid_attr_index(const saxlocator * locator,int index)1127c2c66affSColin Finck static inline BOOL is_valid_attr_index(const saxlocator *locator, int index)
1128c2c66affSColin Finck {
1129c2c66affSColin Finck     return index < locator->attr_count && index >= 0;
1130c2c66affSColin Finck }
1131c2c66affSColin Finck 
isaxattributes_getURI(ISAXAttributes * iface,int index,const WCHAR ** url,int * size)1132c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getURI(
1133c2c66affSColin Finck         ISAXAttributes* iface,
1134c2c66affSColin Finck         int index,
1135c2c66affSColin Finck         const WCHAR **url,
1136c2c66affSColin Finck         int *size)
1137c2c66affSColin Finck {
1138c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1139c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, index);
1140c2c66affSColin Finck 
1141c2c66affSColin Finck     if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1142c2c66affSColin Finck     if(!url || !size) return E_POINTER;
1143c2c66affSColin Finck 
1144c2c66affSColin Finck     *size = SysStringLen(This->attributes[index].szURI);
1145c2c66affSColin Finck     *url = This->attributes[index].szURI;
1146c2c66affSColin Finck 
1147c2c66affSColin Finck     TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size);
1148c2c66affSColin Finck 
1149c2c66affSColin Finck     return S_OK;
1150c2c66affSColin Finck }
1151c2c66affSColin Finck 
isaxattributes_getLocalName(ISAXAttributes * iface,int index,const WCHAR ** pLocalName,int * pLocalNameLength)1152c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getLocalName(
1153c2c66affSColin Finck         ISAXAttributes* iface,
1154c2c66affSColin Finck         int index,
1155c2c66affSColin Finck         const WCHAR **pLocalName,
1156c2c66affSColin Finck         int *pLocalNameLength)
1157c2c66affSColin Finck {
1158c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1159c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, index);
1160c2c66affSColin Finck 
1161c2c66affSColin Finck     if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1162c2c66affSColin Finck     if(!pLocalName || !pLocalNameLength) return E_POINTER;
1163c2c66affSColin Finck 
1164c2c66affSColin Finck     *pLocalNameLength = SysStringLen(This->attributes[index].szLocalname);
1165c2c66affSColin Finck     *pLocalName = This->attributes[index].szLocalname;
1166c2c66affSColin Finck 
1167c2c66affSColin Finck     return S_OK;
1168c2c66affSColin Finck }
1169c2c66affSColin Finck 
isaxattributes_getQName(ISAXAttributes * iface,int index,const WCHAR ** pQName,int * pQNameLength)1170c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getQName(
1171c2c66affSColin Finck         ISAXAttributes* iface,
1172c2c66affSColin Finck         int index,
1173c2c66affSColin Finck         const WCHAR **pQName,
1174c2c66affSColin Finck         int *pQNameLength)
1175c2c66affSColin Finck {
1176c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1177c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, index);
1178c2c66affSColin Finck 
1179c2c66affSColin Finck     if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1180c2c66affSColin Finck     if(!pQName || !pQNameLength) return E_POINTER;
1181c2c66affSColin Finck 
1182c2c66affSColin Finck     *pQNameLength = SysStringLen(This->attributes[index].szQName);
1183c2c66affSColin Finck     *pQName = This->attributes[index].szQName;
1184c2c66affSColin Finck 
1185c2c66affSColin Finck     return S_OK;
1186c2c66affSColin Finck }
1187c2c66affSColin Finck 
isaxattributes_getName(ISAXAttributes * iface,int index,const WCHAR ** uri,int * pUriLength,const WCHAR ** localName,int * pLocalNameSize,const WCHAR ** QName,int * pQNameLength)1188c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getName(
1189c2c66affSColin Finck         ISAXAttributes* iface,
1190c2c66affSColin Finck         int index,
1191c2c66affSColin Finck         const WCHAR **uri,
1192c2c66affSColin Finck         int *pUriLength,
1193c2c66affSColin Finck         const WCHAR **localName,
1194c2c66affSColin Finck         int *pLocalNameSize,
1195c2c66affSColin Finck         const WCHAR **QName,
1196c2c66affSColin Finck         int *pQNameLength)
1197c2c66affSColin Finck {
1198c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1199c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, index);
1200c2c66affSColin Finck 
1201c2c66affSColin Finck     if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1202c2c66affSColin Finck     if(!uri || !pUriLength || !localName || !pLocalNameSize
1203c2c66affSColin Finck             || !QName || !pQNameLength) return E_POINTER;
1204c2c66affSColin Finck 
1205c2c66affSColin Finck     *pUriLength = SysStringLen(This->attributes[index].szURI);
1206c2c66affSColin Finck     *uri = This->attributes[index].szURI;
1207c2c66affSColin Finck     *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname);
1208c2c66affSColin Finck     *localName = This->attributes[index].szLocalname;
1209c2c66affSColin Finck     *pQNameLength = SysStringLen(This->attributes[index].szQName);
1210c2c66affSColin Finck     *QName = This->attributes[index].szQName;
1211c2c66affSColin Finck 
1212c2c66affSColin Finck     TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName));
1213c2c66affSColin Finck 
1214c2c66affSColin Finck     return S_OK;
1215c2c66affSColin Finck }
1216c2c66affSColin Finck 
isaxattributes_getIndexFromName(ISAXAttributes * iface,const WCHAR * pUri,int cUriLength,const WCHAR * pLocalName,int cocalNameLength,int * index)1217c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getIndexFromName(
1218c2c66affSColin Finck         ISAXAttributes* iface,
1219c2c66affSColin Finck         const WCHAR *pUri,
1220c2c66affSColin Finck         int cUriLength,
1221c2c66affSColin Finck         const WCHAR *pLocalName,
1222c2c66affSColin Finck         int cocalNameLength,
1223c2c66affSColin Finck         int *index)
1224c2c66affSColin Finck {
1225c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1226c2c66affSColin Finck     int i;
1227c2c66affSColin Finck     TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
1228c2c66affSColin Finck             debugstr_w(pLocalName), cocalNameLength);
1229c2c66affSColin Finck 
1230c2c66affSColin Finck     if(!pUri || !pLocalName || !index) return E_POINTER;
1231c2c66affSColin Finck 
1232c2c66affSColin Finck     for(i=0; i<This->attr_count; i++)
1233c2c66affSColin Finck     {
1234c2c66affSColin Finck         if(cUriLength!=SysStringLen(This->attributes[i].szURI)
1235c2c66affSColin Finck                 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
1236c2c66affSColin Finck             continue;
1237c2c66affSColin Finck         if(cUriLength && memcmp(pUri, This->attributes[i].szURI,
1238c2c66affSColin Finck                     sizeof(WCHAR)*cUriLength))
1239c2c66affSColin Finck             continue;
1240c2c66affSColin Finck         if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname,
1241c2c66affSColin Finck                     sizeof(WCHAR)*cocalNameLength))
1242c2c66affSColin Finck             continue;
1243c2c66affSColin Finck 
1244c2c66affSColin Finck         *index = i;
1245c2c66affSColin Finck         return S_OK;
1246c2c66affSColin Finck     }
1247c2c66affSColin Finck 
1248c2c66affSColin Finck     return E_INVALIDARG;
1249c2c66affSColin Finck }
1250c2c66affSColin Finck 
isaxattributes_getIndexFromQName(ISAXAttributes * iface,const WCHAR * pQName,int nQNameLength,int * index)1251c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getIndexFromQName(
1252c2c66affSColin Finck         ISAXAttributes* iface,
1253c2c66affSColin Finck         const WCHAR *pQName,
1254c2c66affSColin Finck         int nQNameLength,
1255c2c66affSColin Finck         int *index)
1256c2c66affSColin Finck {
1257c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1258c2c66affSColin Finck     int i;
1259c2c66affSColin Finck     TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
1260c2c66affSColin Finck 
1261c2c66affSColin Finck     if(!pQName || !index) return E_POINTER;
1262c2c66affSColin Finck     if(!nQNameLength) return E_INVALIDARG;
1263c2c66affSColin Finck 
1264c2c66affSColin Finck     for(i=0; i<This->attr_count; i++)
1265c2c66affSColin Finck     {
1266c2c66affSColin Finck         if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
1267c2c66affSColin Finck         if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
1268c2c66affSColin Finck 
1269c2c66affSColin Finck         *index = i;
1270c2c66affSColin Finck         return S_OK;
1271c2c66affSColin Finck     }
1272c2c66affSColin Finck 
1273c2c66affSColin Finck     return E_INVALIDARG;
1274c2c66affSColin Finck }
1275c2c66affSColin Finck 
isaxattributes_getType(ISAXAttributes * iface,int nIndex,const WCHAR ** pType,int * pTypeLength)1276c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getType(
1277c2c66affSColin Finck         ISAXAttributes* iface,
1278c2c66affSColin Finck         int nIndex,
1279c2c66affSColin Finck         const WCHAR **pType,
1280c2c66affSColin Finck         int *pTypeLength)
1281c2c66affSColin Finck {
1282c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1283c2c66affSColin Finck 
1284c2c66affSColin Finck     FIXME("(%p)->(%d) stub\n", This, nIndex);
1285c2c66affSColin Finck     return E_NOTIMPL;
1286c2c66affSColin Finck }
1287c2c66affSColin Finck 
isaxattributes_getTypeFromName(ISAXAttributes * iface,const WCHAR * pUri,int nUri,const WCHAR * pLocalName,int nLocalName,const WCHAR ** pType,int * nType)1288c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getTypeFromName(
1289c2c66affSColin Finck         ISAXAttributes* iface,
1290c2c66affSColin Finck         const WCHAR *pUri,
1291c2c66affSColin Finck         int nUri,
1292c2c66affSColin Finck         const WCHAR *pLocalName,
1293c2c66affSColin Finck         int nLocalName,
1294c2c66affSColin Finck         const WCHAR **pType,
1295c2c66affSColin Finck         int *nType)
1296c2c66affSColin Finck {
1297c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1298c2c66affSColin Finck 
1299c2c66affSColin Finck     FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
1300c2c66affSColin Finck             debugstr_w(pLocalName), nLocalName);
1301c2c66affSColin Finck     return E_NOTIMPL;
1302c2c66affSColin Finck }
1303c2c66affSColin Finck 
isaxattributes_getTypeFromQName(ISAXAttributes * iface,const WCHAR * pQName,int nQName,const WCHAR ** pType,int * nType)1304c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getTypeFromQName(
1305c2c66affSColin Finck         ISAXAttributes* iface,
1306c2c66affSColin Finck         const WCHAR *pQName,
1307c2c66affSColin Finck         int nQName,
1308c2c66affSColin Finck         const WCHAR **pType,
1309c2c66affSColin Finck         int *nType)
1310c2c66affSColin Finck {
1311c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1312c2c66affSColin Finck 
1313c2c66affSColin Finck     FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
1314c2c66affSColin Finck     return E_NOTIMPL;
1315c2c66affSColin Finck }
1316c2c66affSColin Finck 
isaxattributes_getValue(ISAXAttributes * iface,int index,const WCHAR ** value,int * nValue)1317c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getValue(
1318c2c66affSColin Finck         ISAXAttributes* iface,
1319c2c66affSColin Finck         int index,
1320c2c66affSColin Finck         const WCHAR **value,
1321c2c66affSColin Finck         int *nValue)
1322c2c66affSColin Finck {
1323c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1324c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, index);
1325c2c66affSColin Finck 
1326c2c66affSColin Finck     if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
1327c2c66affSColin Finck     if(!value || !nValue) return E_POINTER;
1328c2c66affSColin Finck 
1329c2c66affSColin Finck     *nValue = SysStringLen(This->attributes[index].szValue);
1330c2c66affSColin Finck     *value = This->attributes[index].szValue;
1331c2c66affSColin Finck 
1332c2c66affSColin Finck     TRACE("(%s:%d)\n", debugstr_w(*value), *nValue);
1333c2c66affSColin Finck 
1334c2c66affSColin Finck     return S_OK;
1335c2c66affSColin Finck }
1336c2c66affSColin Finck 
isaxattributes_getValueFromName(ISAXAttributes * iface,const WCHAR * pUri,int nUri,const WCHAR * pLocalName,int nLocalName,const WCHAR ** pValue,int * nValue)1337c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getValueFromName(
1338c2c66affSColin Finck         ISAXAttributes* iface,
1339c2c66affSColin Finck         const WCHAR *pUri,
1340c2c66affSColin Finck         int nUri,
1341c2c66affSColin Finck         const WCHAR *pLocalName,
1342c2c66affSColin Finck         int nLocalName,
1343c2c66affSColin Finck         const WCHAR **pValue,
1344c2c66affSColin Finck         int *nValue)
1345c2c66affSColin Finck {
1346c2c66affSColin Finck     HRESULT hr;
1347c2c66affSColin Finck     int index;
1348c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1349c2c66affSColin Finck     TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
1350c2c66affSColin Finck             debugstr_w(pLocalName), nLocalName);
1351c2c66affSColin Finck 
1352c2c66affSColin Finck     hr = ISAXAttributes_getIndexFromName(iface,
1353c2c66affSColin Finck             pUri, nUri, pLocalName, nLocalName, &index);
1354c2c66affSColin Finck     if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1355c2c66affSColin Finck 
1356c2c66affSColin Finck     return hr;
1357c2c66affSColin Finck }
1358c2c66affSColin Finck 
isaxattributes_getValueFromQName(ISAXAttributes * iface,const WCHAR * pQName,int nQName,const WCHAR ** pValue,int * nValue)1359c2c66affSColin Finck static HRESULT WINAPI isaxattributes_getValueFromQName(
1360c2c66affSColin Finck         ISAXAttributes* iface,
1361c2c66affSColin Finck         const WCHAR *pQName,
1362c2c66affSColin Finck         int nQName,
1363c2c66affSColin Finck         const WCHAR **pValue,
1364c2c66affSColin Finck         int *nValue)
1365c2c66affSColin Finck {
1366c2c66affSColin Finck     HRESULT hr;
1367c2c66affSColin Finck     int index;
1368c2c66affSColin Finck     saxlocator *This = impl_from_ISAXAttributes( iface );
1369c2c66affSColin Finck     TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
1370c2c66affSColin Finck 
1371c2c66affSColin Finck     hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
1372c2c66affSColin Finck     if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1373c2c66affSColin Finck 
1374c2c66affSColin Finck     return hr;
1375c2c66affSColin Finck }
1376c2c66affSColin Finck 
1377c2c66affSColin Finck static const struct ISAXAttributesVtbl isaxattributes_vtbl =
1378c2c66affSColin Finck {
1379c2c66affSColin Finck     isaxattributes_QueryInterface,
1380c2c66affSColin Finck     isaxattributes_AddRef,
1381c2c66affSColin Finck     isaxattributes_Release,
1382c2c66affSColin Finck     isaxattributes_getLength,
1383c2c66affSColin Finck     isaxattributes_getURI,
1384c2c66affSColin Finck     isaxattributes_getLocalName,
1385c2c66affSColin Finck     isaxattributes_getQName,
1386c2c66affSColin Finck     isaxattributes_getName,
1387c2c66affSColin Finck     isaxattributes_getIndexFromName,
1388c2c66affSColin Finck     isaxattributes_getIndexFromQName,
1389c2c66affSColin Finck     isaxattributes_getType,
1390c2c66affSColin Finck     isaxattributes_getTypeFromName,
1391c2c66affSColin Finck     isaxattributes_getTypeFromQName,
1392c2c66affSColin Finck     isaxattributes_getValue,
1393c2c66affSColin Finck     isaxattributes_getValueFromName,
1394c2c66affSColin Finck     isaxattributes_getValueFromQName
1395c2c66affSColin Finck };
1396c2c66affSColin Finck 
1397c2c66affSColin Finck /* Libxml2 escapes '&' back to char reference '&#38;' in attribute value,
1398c2c66affSColin Finck    so when document has escaped value with '&amp;' it's parsed to '&' and then
1399c2c66affSColin Finck    escaped to '&#38;'. This function takes care of ampersands only. */
saxreader_get_unescaped_value(const xmlChar * buf,int len)1400c2c66affSColin Finck static BSTR saxreader_get_unescaped_value(const xmlChar *buf, int len)
1401c2c66affSColin Finck {
1402c2c66affSColin Finck     static const WCHAR ampescW[] = {'&','#','3','8',';',0};
1403c2c66affSColin Finck     WCHAR *dest, *ptrW, *str;
1404c2c66affSColin Finck     DWORD str_len;
1405c2c66affSColin Finck     BSTR bstr;
1406c2c66affSColin Finck 
1407c2c66affSColin Finck     if (!buf)
1408c2c66affSColin Finck         return NULL;
1409c2c66affSColin Finck 
1410c2c66affSColin Finck     str_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
1411c2c66affSColin Finck     if (len != -1) str_len++;
1412c2c66affSColin Finck 
1413c2c66affSColin Finck     str = heap_alloc(str_len*sizeof(WCHAR));
1414c2c66affSColin Finck     if (!str) return NULL;
1415c2c66affSColin Finck 
1416c2c66affSColin Finck     MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, str_len);
1417c2c66affSColin Finck     if (len != -1) str[str_len-1] = 0;
1418c2c66affSColin Finck 
1419c2c66affSColin Finck     ptrW = str;
1420c2c66affSColin Finck     while ((dest = strstrW(ptrW, ampescW)))
1421c2c66affSColin Finck     {
1422c2c66affSColin Finck         WCHAR *src;
1423c2c66affSColin Finck 
1424c2c66affSColin Finck         /* leave first '&' from a reference as a value */
1425bab6b90fSAmine Khaldi         src = dest + ARRAY_SIZE(ampescW) - 1;
1426c2c66affSColin Finck         dest++;
1427c2c66affSColin Finck 
1428c2c66affSColin Finck         /* move together with null terminator */
1429c2c66affSColin Finck         memmove(dest, src, (strlenW(src) + 1)*sizeof(WCHAR));
1430c2c66affSColin Finck 
1431c2c66affSColin Finck         ptrW++;
1432c2c66affSColin Finck     }
1433c2c66affSColin Finck 
1434c2c66affSColin Finck     bstr = SysAllocString(str);
1435c2c66affSColin Finck     heap_free(str);
1436c2c66affSColin Finck 
1437c2c66affSColin Finck     return bstr;
1438c2c66affSColin Finck }
1439c2c66affSColin Finck 
free_attribute_values(saxlocator * locator)1440c2c66affSColin Finck static void free_attribute_values(saxlocator *locator)
1441c2c66affSColin Finck {
1442c2c66affSColin Finck     int i;
1443c2c66affSColin Finck 
1444c2c66affSColin Finck     for (i = 0; i < locator->attr_count; i++)
1445c2c66affSColin Finck     {
1446c2c66affSColin Finck         SysFreeString(locator->attributes[i].szLocalname);
1447c2c66affSColin Finck         locator->attributes[i].szLocalname = NULL;
1448c2c66affSColin Finck 
1449c2c66affSColin Finck         SysFreeString(locator->attributes[i].szValue);
1450c2c66affSColin Finck         locator->attributes[i].szValue = NULL;
1451c2c66affSColin Finck 
1452c2c66affSColin Finck         SysFreeString(locator->attributes[i].szQName);
1453c2c66affSColin Finck         locator->attributes[i].szQName = NULL;
1454c2c66affSColin Finck     }
1455c2c66affSColin Finck }
1456c2c66affSColin Finck 
SAXAttributes_populate(saxlocator * locator,int nb_namespaces,const xmlChar ** xmlNamespaces,int nb_attributes,const xmlChar ** xmlAttributes)1457c2c66affSColin Finck static HRESULT SAXAttributes_populate(saxlocator *locator,
1458c2c66affSColin Finck         int nb_namespaces, const xmlChar **xmlNamespaces,
1459c2c66affSColin Finck         int nb_attributes, const xmlChar **xmlAttributes)
1460c2c66affSColin Finck {
1461c2c66affSColin Finck     static const xmlChar xmlns[] = "xmlns";
1462c2c66affSColin Finck     static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 };
1463c2c66affSColin Finck 
1464c2c66affSColin Finck     struct _attributes *attrs;
1465c2c66affSColin Finck     int i;
1466c2c66affSColin Finck 
1467c2c66affSColin Finck     /* skip namespace definitions */
1468c2c66affSColin Finck     if ((locator->saxreader->features & NamespacePrefixes) == 0)
1469c2c66affSColin Finck         nb_namespaces = 0;
1470c2c66affSColin Finck 
1471c2c66affSColin Finck     locator->attr_count = nb_namespaces + nb_attributes;
1472c2c66affSColin Finck     if(locator->attr_count > locator->attr_alloc_count)
1473c2c66affSColin Finck     {
1474c2c66affSColin Finck         int new_size = locator->attr_count * 2;
1475c2c66affSColin Finck         attrs = heap_realloc_zero(locator->attributes, new_size * sizeof(struct _attributes));
1476c2c66affSColin Finck         if(!attrs)
1477c2c66affSColin Finck         {
1478c2c66affSColin Finck             free_attribute_values(locator);
1479c2c66affSColin Finck             locator->attr_count = 0;
1480c2c66affSColin Finck             return E_OUTOFMEMORY;
1481c2c66affSColin Finck         }
1482c2c66affSColin Finck         locator->attributes = attrs;
1483c2c66affSColin Finck         locator->attr_alloc_count = new_size;
1484c2c66affSColin Finck     }
1485c2c66affSColin Finck     else
1486c2c66affSColin Finck     {
1487c2c66affSColin Finck         attrs = locator->attributes;
1488c2c66affSColin Finck     }
1489c2c66affSColin Finck 
1490c2c66affSColin Finck     for (i = 0; i < nb_namespaces; i++)
1491c2c66affSColin Finck     {
1492c2c66affSColin Finck         SysFreeString(attrs[nb_attributes+i].szLocalname);
1493c2c66affSColin Finck         attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0);
1494c2c66affSColin Finck 
1495c2c66affSColin Finck         attrs[nb_attributes+i].szURI = locator->namespaceUri;
1496c2c66affSColin Finck 
1497c2c66affSColin Finck         SysFreeString(attrs[nb_attributes+i].szValue);
1498c2c66affSColin Finck         attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]);
1499c2c66affSColin Finck 
1500c2c66affSColin Finck         SysFreeString(attrs[nb_attributes+i].szQName);
1501c2c66affSColin Finck         if(!xmlNamespaces[2*i])
1502c2c66affSColin Finck             attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW);
1503c2c66affSColin Finck         else
1504c2c66affSColin Finck             attrs[nb_attributes+i].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*i]);
1505c2c66affSColin Finck     }
1506c2c66affSColin Finck 
1507c2c66affSColin Finck     for (i = 0; i < nb_attributes; i++)
1508c2c66affSColin Finck     {
1509c2c66affSColin Finck         static const xmlChar xmlA[] = "xml";
1510c2c66affSColin Finck 
1511c2c66affSColin Finck         if (xmlStrEqual(xmlAttributes[i*5+1], xmlA))
1512c2c66affSColin Finck             attrs[i].szURI = bstr_from_xmlChar(xmlAttributes[i*5+2]);
1513c2c66affSColin Finck         else
1514c2c66affSColin Finck             /* that's an important feature to keep same uri pointer for every reported attribute */
1515c2c66affSColin Finck             attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
1516c2c66affSColin Finck 
1517c2c66affSColin Finck         SysFreeString(attrs[i].szLocalname);
1518c2c66affSColin Finck         attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
1519c2c66affSColin Finck 
1520c2c66affSColin Finck         SysFreeString(attrs[i].szValue);
1521c2c66affSColin Finck         attrs[i].szValue = saxreader_get_unescaped_value(xmlAttributes[i*5+3], xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
1522c2c66affSColin Finck 
1523c2c66affSColin Finck         SysFreeString(attrs[i].szQName);
1524c2c66affSColin Finck         attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1], xmlAttributes[i*5]);
1525c2c66affSColin Finck     }
1526c2c66affSColin Finck 
1527c2c66affSColin Finck     return S_OK;
1528c2c66affSColin Finck }
1529c2c66affSColin Finck 
1530c2c66affSColin Finck /*** LibXML callbacks ***/
libxmlStartDocument(void * ctx)1531c2c66affSColin Finck static void libxmlStartDocument(void *ctx)
1532c2c66affSColin Finck {
1533c2c66affSColin Finck     saxlocator *This = ctx;
1534c2c66affSColin Finck     struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1535c2c66affSColin Finck     HRESULT hr;
1536c2c66affSColin Finck 
1537c2c66affSColin Finck     if (This->saxreader->version >= MSXML4)
1538c2c66affSColin Finck     {
1539c2c66affSColin Finck         const xmlChar *p = This->pParserCtxt->input->cur-1;
1540c2c66affSColin Finck         update_position(This, FALSE);
1541c2c66affSColin Finck         while(p>This->pParserCtxt->input->base && *p!='>')
1542c2c66affSColin Finck         {
1543c2c66affSColin Finck             if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1544c2c66affSColin Finck                 This->line--;
1545c2c66affSColin Finck             p--;
1546c2c66affSColin Finck         }
1547c2c66affSColin Finck         This->column = 0;
1548c2c66affSColin Finck         for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1549c2c66affSColin Finck             This->column++;
1550c2c66affSColin Finck     }
1551c2c66affSColin Finck 
1552c2c66affSColin Finck     /* store version value, declaration has to contain version attribute */
1553c2c66affSColin Finck     if (This->pParserCtxt->standalone != -1)
1554c2c66affSColin Finck     {
1555c2c66affSColin Finck         SysFreeString(This->saxreader->xmldecl_version);
1556c2c66affSColin Finck         This->saxreader->xmldecl_version = bstr_from_xmlChar(This->pParserCtxt->version);
1557c2c66affSColin Finck     }
1558c2c66affSColin Finck 
1559c2c66affSColin Finck     if (saxreader_has_handler(This, SAXContentHandler))
1560c2c66affSColin Finck     {
1561c2c66affSColin Finck         if(This->vbInterface)
1562c2c66affSColin Finck             hr = IVBSAXContentHandler_startDocument(handler->vbhandler);
1563c2c66affSColin Finck         else
1564c2c66affSColin Finck             hr = ISAXContentHandler_startDocument(handler->handler);
1565c2c66affSColin Finck 
1566c2c66affSColin Finck         if (sax_callback_failed(This, hr))
1567c2c66affSColin Finck             format_error_message_from_id(This, hr);
1568c2c66affSColin Finck     }
1569c2c66affSColin Finck }
1570c2c66affSColin Finck 
libxmlEndDocument(void * ctx)1571c2c66affSColin Finck static void libxmlEndDocument(void *ctx)
1572c2c66affSColin Finck {
1573c2c66affSColin Finck     saxlocator *This = ctx;
1574c2c66affSColin Finck     struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1575c2c66affSColin Finck     HRESULT hr;
1576c2c66affSColin Finck 
1577c2c66affSColin Finck     if (This->saxreader->version >= MSXML4) {
1578c2c66affSColin Finck         update_position(This, FALSE);
1579c2c66affSColin Finck         if(This->column > 1)
1580c2c66affSColin Finck             This->line++;
1581c2c66affSColin Finck         This->column = 0;
1582c2c66affSColin Finck     } else {
1583c2c66affSColin Finck         This->column = 0;
1584c2c66affSColin Finck         This->line = 0;
1585c2c66affSColin Finck     }
1586c2c66affSColin Finck 
1587c2c66affSColin Finck     if(This->ret != S_OK) return;
1588c2c66affSColin Finck 
1589c2c66affSColin Finck     if (saxreader_has_handler(This, SAXContentHandler))
1590c2c66affSColin Finck     {
1591c2c66affSColin Finck         if(This->vbInterface)
1592c2c66affSColin Finck             hr = IVBSAXContentHandler_endDocument(handler->vbhandler);
1593c2c66affSColin Finck         else
1594c2c66affSColin Finck             hr = ISAXContentHandler_endDocument(handler->handler);
1595c2c66affSColin Finck 
1596c2c66affSColin Finck         if (sax_callback_failed(This, hr))
1597c2c66affSColin Finck             format_error_message_from_id(This, hr);
1598c2c66affSColin Finck     }
1599c2c66affSColin Finck }
1600c2c66affSColin Finck 
libxmlStartElementNS(void * ctx,const xmlChar * localname,const xmlChar * prefix,const xmlChar * URI,int nb_namespaces,const xmlChar ** namespaces,int nb_attributes,int nb_defaulted,const xmlChar ** attributes)1601c2c66affSColin Finck static void libxmlStartElementNS(
1602c2c66affSColin Finck         void *ctx,
1603c2c66affSColin Finck         const xmlChar *localname,
1604c2c66affSColin Finck         const xmlChar *prefix,
1605c2c66affSColin Finck         const xmlChar *URI,
1606c2c66affSColin Finck         int nb_namespaces,
1607c2c66affSColin Finck         const xmlChar **namespaces,
1608c2c66affSColin Finck         int nb_attributes,
1609c2c66affSColin Finck         int nb_defaulted,
1610c2c66affSColin Finck         const xmlChar **attributes)
1611c2c66affSColin Finck {
1612c2c66affSColin Finck     saxlocator *This = ctx;
1613c2c66affSColin Finck     struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1614c2c66affSColin Finck     element_entry *element;
1615c2c66affSColin Finck     HRESULT hr = S_OK;
1616c2c66affSColin Finck     BSTR uri;
1617c2c66affSColin Finck 
1618c2c66affSColin Finck     update_position(This, TRUE);
1619c2c66affSColin Finck     if(*(This->pParserCtxt->input->cur) == '/')
1620c2c66affSColin Finck         This->column++;
1621c2c66affSColin Finck     if(This->saxreader->version < MSXML4)
1622c2c66affSColin Finck         This->column++;
1623c2c66affSColin Finck 
1624c2c66affSColin Finck     element = alloc_element_entry(localname, prefix, nb_namespaces, namespaces);
1625c2c66affSColin Finck     push_element_ns(This, element);
1626c2c66affSColin Finck 
1627c2c66affSColin Finck     if (is_namespaces_enabled(This->saxreader))
1628c2c66affSColin Finck     {
1629c2c66affSColin Finck         int i;
1630c2c66affSColin Finck 
1631c2c66affSColin Finck         for (i = 0; i < nb_namespaces && saxreader_has_handler(This, SAXContentHandler); i++)
1632c2c66affSColin Finck         {
1633c2c66affSColin Finck             if (This->vbInterface)
1634c2c66affSColin Finck                 hr = IVBSAXContentHandler_startPrefixMapping(
1635c2c66affSColin Finck                         handler->vbhandler,
1636c2c66affSColin Finck                         &element->ns[i].prefix,
1637c2c66affSColin Finck                         &element->ns[i].uri);
1638c2c66affSColin Finck             else
1639c2c66affSColin Finck                 hr = ISAXContentHandler_startPrefixMapping(
1640c2c66affSColin Finck                         handler->handler,
1641c2c66affSColin Finck                         element->ns[i].prefix,
1642c2c66affSColin Finck                         SysStringLen(element->ns[i].prefix),
1643c2c66affSColin Finck                         element->ns[i].uri,
1644c2c66affSColin Finck                         SysStringLen(element->ns[i].uri));
1645c2c66affSColin Finck 
1646c2c66affSColin Finck             if (sax_callback_failed(This, hr))
1647c2c66affSColin Finck             {
1648c2c66affSColin Finck                 format_error_message_from_id(This, hr);
1649c2c66affSColin Finck                 return;
1650c2c66affSColin Finck             }
1651c2c66affSColin Finck         }
1652c2c66affSColin Finck     }
1653c2c66affSColin Finck 
1654c2c66affSColin Finck     uri = find_element_uri(This, URI);
1655c2c66affSColin Finck     hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
1656c2c66affSColin Finck     if (hr == S_OK && saxreader_has_handler(This, SAXContentHandler))
1657c2c66affSColin Finck     {
1658c2c66affSColin Finck         BSTR local;
1659c2c66affSColin Finck 
1660c2c66affSColin Finck         if (is_namespaces_enabled(This->saxreader))
1661c2c66affSColin Finck             local = element->local;
1662c2c66affSColin Finck         else
1663c2c66affSColin Finck             uri = local = NULL;
1664c2c66affSColin Finck 
1665c2c66affSColin Finck         if (This->vbInterface)
1666c2c66affSColin Finck             hr = IVBSAXContentHandler_startElement(handler->vbhandler,
1667c2c66affSColin Finck                     &uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
1668c2c66affSColin Finck         else
1669c2c66affSColin Finck             hr = ISAXContentHandler_startElement(handler->handler,
1670*eb44c20cSAmine Khaldi                     uri ? uri : &empty_str, SysStringLen(uri),
1671*eb44c20cSAmine Khaldi                     local ? local : &empty_str, SysStringLen(local),
1672c2c66affSColin Finck                     element->qname, SysStringLen(element->qname),
1673c2c66affSColin Finck                     &This->ISAXAttributes_iface);
1674c2c66affSColin Finck 
1675c2c66affSColin Finck        if (sax_callback_failed(This, hr))
1676c2c66affSColin Finck            format_error_message_from_id(This, hr);
1677c2c66affSColin Finck     }
1678c2c66affSColin Finck }
1679c2c66affSColin Finck 
libxmlEndElementNS(void * ctx,const xmlChar * localname,const xmlChar * prefix,const xmlChar * URI)1680c2c66affSColin Finck static void libxmlEndElementNS(
1681c2c66affSColin Finck         void *ctx,
1682c2c66affSColin Finck         const xmlChar *localname,
1683c2c66affSColin Finck         const xmlChar *prefix,
1684c2c66affSColin Finck         const xmlChar *URI)
1685c2c66affSColin Finck {
1686c2c66affSColin Finck     saxlocator *This = ctx;
1687c2c66affSColin Finck     struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1688c2c66affSColin Finck     element_entry *element;
1689c2c66affSColin Finck     const xmlChar *p;
1690c2c66affSColin Finck     BSTR uri, local;
1691c2c66affSColin Finck     HRESULT hr;
1692c2c66affSColin Finck 
1693c2c66affSColin Finck     update_position(This, FALSE);
1694c2c66affSColin Finck     p = This->pParserCtxt->input->cur;
1695c2c66affSColin Finck 
1696c2c66affSColin Finck     if (This->saxreader->version >= MSXML4)
1697c2c66affSColin Finck     {
1698c2c66affSColin Finck         p--;
1699c2c66affSColin Finck         while(p>This->pParserCtxt->input->base && *p!='>')
1700c2c66affSColin Finck         {
1701c2c66affSColin Finck             if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1702c2c66affSColin Finck                 This->line--;
1703c2c66affSColin Finck             p--;
1704c2c66affSColin Finck         }
1705c2c66affSColin Finck     }
1706c2c66affSColin Finck     else if(*(p-1)!='>' || *(p-2)!='/')
1707c2c66affSColin Finck     {
1708c2c66affSColin Finck         p--;
1709c2c66affSColin Finck         while(p-2>=This->pParserCtxt->input->base
1710c2c66affSColin Finck                 && *(p-2)!='<' && *(p-1)!='/')
1711c2c66affSColin Finck         {
1712c2c66affSColin Finck             if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1713c2c66affSColin Finck                 This->line--;
1714c2c66affSColin Finck             p--;
1715c2c66affSColin Finck         }
1716c2c66affSColin Finck     }
1717c2c66affSColin Finck     This->column = 0;
1718c2c66affSColin Finck     for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1719c2c66affSColin Finck         This->column++;
1720c2c66affSColin Finck 
1721c2c66affSColin Finck     uri = find_element_uri(This, URI);
1722c2c66affSColin Finck     element = pop_element_ns(This);
1723c2c66affSColin Finck 
1724c2c66affSColin Finck     if (!saxreader_has_handler(This, SAXContentHandler))
1725c2c66affSColin Finck     {
1726c2c66affSColin Finck         free_attribute_values(This);
1727c2c66affSColin Finck         This->attr_count = 0;
1728c2c66affSColin Finck         free_element_entry(element);
1729c2c66affSColin Finck         return;
1730c2c66affSColin Finck     }
1731c2c66affSColin Finck 
1732c2c66affSColin Finck     if (is_namespaces_enabled(This->saxreader))
1733c2c66affSColin Finck         local = element->local;
1734c2c66affSColin Finck     else
1735c2c66affSColin Finck         uri = local = NULL;
1736c2c66affSColin Finck 
1737c2c66affSColin Finck     if (This->vbInterface)
1738c2c66affSColin Finck         hr = IVBSAXContentHandler_endElement(
1739c2c66affSColin Finck                 handler->vbhandler,
1740c2c66affSColin Finck                 &uri, &local, &element->qname);
1741c2c66affSColin Finck     else
1742c2c66affSColin Finck         hr = ISAXContentHandler_endElement(
1743c2c66affSColin Finck                 handler->handler,
1744*eb44c20cSAmine Khaldi                 uri ? uri : &empty_str, SysStringLen(uri),
1745*eb44c20cSAmine Khaldi                 local ? local : &empty_str, SysStringLen(local),
1746c2c66affSColin Finck                 element->qname, SysStringLen(element->qname));
1747c2c66affSColin Finck 
1748c2c66affSColin Finck     free_attribute_values(This);
1749c2c66affSColin Finck     This->attr_count = 0;
1750c2c66affSColin Finck 
1751c2c66affSColin Finck     if (sax_callback_failed(This, hr))
1752c2c66affSColin Finck     {
1753c2c66affSColin Finck         format_error_message_from_id(This, hr);
1754c2c66affSColin Finck         free_element_entry(element);
1755c2c66affSColin Finck         return;
1756c2c66affSColin Finck     }
1757c2c66affSColin Finck 
1758c2c66affSColin Finck     if (is_namespaces_enabled(This->saxreader))
1759c2c66affSColin Finck     {
1760c2c66affSColin Finck         int i = -1;
1761c2c66affSColin Finck         while (iterate_endprefix_index(This, element, &i) && saxreader_has_handler(This, SAXContentHandler))
1762c2c66affSColin Finck         {
1763c2c66affSColin Finck             if (This->vbInterface)
1764c2c66affSColin Finck                 hr = IVBSAXContentHandler_endPrefixMapping(
1765c2c66affSColin Finck                         handler->vbhandler, &element->ns[i].prefix);
1766c2c66affSColin Finck             else
1767c2c66affSColin Finck                 hr = ISAXContentHandler_endPrefixMapping(
1768c2c66affSColin Finck                         handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
1769c2c66affSColin Finck 
1770c2c66affSColin Finck             if (sax_callback_failed(This, hr)) break;
1771c2c66affSColin Finck        }
1772c2c66affSColin Finck 
1773c2c66affSColin Finck        if (sax_callback_failed(This, hr))
1774c2c66affSColin Finck            format_error_message_from_id(This, hr);
1775c2c66affSColin Finck     }
1776c2c66affSColin Finck 
1777c2c66affSColin Finck     free_element_entry(element);
1778c2c66affSColin Finck }
1779c2c66affSColin Finck 
libxmlCharacters(void * ctx,const xmlChar * ch,int len)1780c2c66affSColin Finck static void libxmlCharacters(
1781c2c66affSColin Finck         void *ctx,
1782c2c66affSColin Finck         const xmlChar *ch,
1783c2c66affSColin Finck         int len)
1784c2c66affSColin Finck {
1785c2c66affSColin Finck     saxlocator *This = ctx;
1786c2c66affSColin Finck     BSTR Chars;
1787c2c66affSColin Finck     HRESULT hr;
1788c2c66affSColin Finck     xmlChar *cur, *end;
1789c2c66affSColin Finck     BOOL lastEvent = FALSE;
1790c2c66affSColin Finck 
1791c2c66affSColin Finck     if (!saxreader_has_handler(This, SAXContentHandler)) return;
1792c2c66affSColin Finck 
1793c2c66affSColin Finck     update_position(This, FALSE);
1794c2c66affSColin Finck     cur = (xmlChar*)This->pParserCtxt->input->cur;
1795c2c66affSColin Finck     while(cur>=This->pParserCtxt->input->base && *cur!='>')
1796c2c66affSColin Finck     {
1797c2c66affSColin Finck         if(*cur=='\n' || (*cur=='\r' && *(cur+1)!='\n'))
1798c2c66affSColin Finck             This->line--;
1799c2c66affSColin Finck         cur--;
1800c2c66affSColin Finck     }
1801c2c66affSColin Finck     This->column = 1;
1802c2c66affSColin Finck     for(; cur>=This->pParserCtxt->input->base && *cur!='\n' && *cur!='\r'; cur--)
1803c2c66affSColin Finck         This->column++;
1804c2c66affSColin Finck 
1805c2c66affSColin Finck     cur = (xmlChar*)ch;
1806c2c66affSColin Finck     if(*(ch-1)=='\r') cur--;
1807c2c66affSColin Finck     end = cur;
1808c2c66affSColin Finck 
1809c2c66affSColin Finck     while(1)
1810c2c66affSColin Finck     {
1811c2c66affSColin Finck         while(end-ch<len && *end!='\r') end++;
1812c2c66affSColin Finck         if(end-ch==len)
1813c2c66affSColin Finck         {
1814c2c66affSColin Finck             lastEvent = TRUE;
1815c2c66affSColin Finck         }
1816c2c66affSColin Finck         else
1817c2c66affSColin Finck         {
1818c2c66affSColin Finck             *end = '\n';
1819c2c66affSColin Finck             end++;
1820c2c66affSColin Finck         }
1821c2c66affSColin Finck 
1822c2c66affSColin Finck         if (This->saxreader->version >= MSXML4)
1823c2c66affSColin Finck         {
1824c2c66affSColin Finck             xmlChar *p;
1825c2c66affSColin Finck 
1826c2c66affSColin Finck             for(p=cur; p!=end; p++)
1827c2c66affSColin Finck             {
1828c2c66affSColin Finck                 if(*p=='\n')
1829c2c66affSColin Finck                 {
1830c2c66affSColin Finck                     This->line++;
1831c2c66affSColin Finck                     This->column = 1;
1832c2c66affSColin Finck                 }
1833c2c66affSColin Finck                 else
1834c2c66affSColin Finck                 {
1835c2c66affSColin Finck                     This->column++;
1836c2c66affSColin Finck                 }
1837c2c66affSColin Finck             }
1838c2c66affSColin Finck 
1839c2c66affSColin Finck             if(!lastEvent)
1840c2c66affSColin Finck                 This->column = 0;
1841c2c66affSColin Finck         }
1842c2c66affSColin Finck 
1843c2c66affSColin Finck         Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
1844c2c66affSColin Finck         hr = saxreader_saxcharacters(This, Chars);
1845c2c66affSColin Finck 
1846c2c66affSColin Finck         if (sax_callback_failed(This, hr))
1847c2c66affSColin Finck         {
1848c2c66affSColin Finck             format_error_message_from_id(This, hr);
1849c2c66affSColin Finck             return;
1850c2c66affSColin Finck         }
1851c2c66affSColin Finck 
1852c2c66affSColin Finck         if (This->saxreader->version < MSXML4)
1853c2c66affSColin Finck             This->column += end-cur;
1854c2c66affSColin Finck 
1855c2c66affSColin Finck         if(lastEvent)
1856c2c66affSColin Finck             break;
1857c2c66affSColin Finck 
1858c2c66affSColin Finck         *(end-1) = '\r';
1859c2c66affSColin Finck         if(*end == '\n')
1860c2c66affSColin Finck         {
1861c2c66affSColin Finck             end++;
1862c2c66affSColin Finck             This->column++;
1863c2c66affSColin Finck         }
1864c2c66affSColin Finck         cur = end;
1865c2c66affSColin Finck 
1866c2c66affSColin Finck         if(end-ch == len) break;
1867c2c66affSColin Finck     }
1868c2c66affSColin Finck }
1869c2c66affSColin Finck 
libxmlSetDocumentLocator(void * ctx,xmlSAXLocatorPtr loc)1870c2c66affSColin Finck static void libxmlSetDocumentLocator(
1871c2c66affSColin Finck         void *ctx,
1872c2c66affSColin Finck         xmlSAXLocatorPtr loc)
1873c2c66affSColin Finck {
1874c2c66affSColin Finck     saxlocator *This = ctx;
1875c2c66affSColin Finck     struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
1876c2c66affSColin Finck     HRESULT hr = S_OK;
1877c2c66affSColin Finck 
1878c2c66affSColin Finck     if (saxreader_has_handler(This, SAXContentHandler))
1879c2c66affSColin Finck     {
1880c2c66affSColin Finck         if(This->vbInterface)
1881c2c66affSColin Finck             hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler,
1882c2c66affSColin Finck                     &This->IVBSAXLocator_iface);
1883c2c66affSColin Finck         else
1884c2c66affSColin Finck             hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface);
1885c2c66affSColin Finck     }
1886c2c66affSColin Finck 
1887c2c66affSColin Finck     if(FAILED(hr))
1888c2c66affSColin Finck         format_error_message_from_id(This, hr);
1889c2c66affSColin Finck }
1890c2c66affSColin Finck 
libxmlComment(void * ctx,const xmlChar * value)1891c2c66affSColin Finck static void libxmlComment(void *ctx, const xmlChar *value)
1892c2c66affSColin Finck {
1893c2c66affSColin Finck     saxlocator *This = ctx;
1894c2c66affSColin Finck     struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader);
1895c2c66affSColin Finck     BSTR bValue;
1896c2c66affSColin Finck     HRESULT hr;
1897c2c66affSColin Finck     const xmlChar *p = This->pParserCtxt->input->cur;
1898c2c66affSColin Finck 
1899c2c66affSColin Finck     update_position(This, FALSE);
1900c2c66affSColin Finck     while(p-4>=This->pParserCtxt->input->base
1901c2c66affSColin Finck             && memcmp(p-4, "<!--", sizeof(char[4])))
1902c2c66affSColin Finck     {
1903c2c66affSColin Finck         if(*p=='\n' || (*p=='\r' && *(p+1)!='\n'))
1904c2c66affSColin Finck             This->line--;
1905c2c66affSColin Finck         p--;
1906c2c66affSColin Finck     }
1907c2c66affSColin Finck 
1908c2c66affSColin Finck     This->column = 0;
1909c2c66affSColin Finck     for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--)
1910c2c66affSColin Finck         This->column++;
1911c2c66affSColin Finck 
1912c2c66affSColin Finck     if (!saxreader_has_handler(This, SAXLexicalHandler)) return;
1913c2c66affSColin Finck 
1914c2c66affSColin Finck     bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
1915c2c66affSColin Finck 
1916c2c66affSColin Finck     if (This->vbInterface)
1917c2c66affSColin Finck         hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue);
1918c2c66affSColin Finck     else
1919c2c66affSColin Finck         hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue));
1920c2c66affSColin Finck 
1921c2c66affSColin Finck     if(FAILED(hr))
1922c2c66affSColin Finck         format_error_message_from_id(This, hr);
1923c2c66affSColin Finck }
1924c2c66affSColin Finck 
libxmlFatalError(void * ctx,const char * msg,...)1925c2c66affSColin Finck static void libxmlFatalError(void *ctx, const char *msg, ...)
1926c2c66affSColin Finck {
1927c2c66affSColin Finck     saxlocator *This = ctx;
1928c2c66affSColin Finck     struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
1929c2c66affSColin Finck     char message[1024];
1930c2c66affSColin Finck     WCHAR *error;
1931c2c66affSColin Finck     DWORD len;
1932c2c66affSColin Finck     va_list args;
1933c2c66affSColin Finck 
1934c2c66affSColin Finck     if(This->ret != S_OK) {
1935c2c66affSColin Finck         xmlStopParser(This->pParserCtxt);
1936c2c66affSColin Finck         return;
1937c2c66affSColin Finck     }
1938c2c66affSColin Finck 
1939c2c66affSColin Finck     va_start(args, msg);
1940c2c66affSColin Finck     vsprintf(message, msg, args);
1941c2c66affSColin Finck     va_end(args);
1942c2c66affSColin Finck 
1943c2c66affSColin Finck     len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0);
1944c2c66affSColin Finck     error = heap_alloc(sizeof(WCHAR)*len);
1945c2c66affSColin Finck     if(error)
1946c2c66affSColin Finck     {
1947c2c66affSColin Finck         MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len);
1948c2c66affSColin Finck         TRACE("fatal error for %p: %s\n", This, debugstr_w(error));
1949c2c66affSColin Finck     }
1950c2c66affSColin Finck 
1951c2c66affSColin Finck     if (!saxreader_has_handler(This, SAXErrorHandler))
1952c2c66affSColin Finck     {
1953c2c66affSColin Finck         xmlStopParser(This->pParserCtxt);
1954c2c66affSColin Finck         This->ret = E_FAIL;
1955c2c66affSColin Finck         heap_free(error);
1956c2c66affSColin Finck         return;
1957c2c66affSColin Finck     }
1958c2c66affSColin Finck 
1959c2c66affSColin Finck     FIXME("Error handling is not compatible.\n");
1960c2c66affSColin Finck 
1961c2c66affSColin Finck     if(This->vbInterface)
1962c2c66affSColin Finck     {
1963c2c66affSColin Finck         BSTR bstrError = SysAllocString(error);
1964c2c66affSColin Finck         IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface,
1965c2c66affSColin Finck                 &bstrError, E_FAIL);
1966c2c66affSColin Finck         SysFreeString(bstrError);
1967c2c66affSColin Finck     }
1968c2c66affSColin Finck     else
1969c2c66affSColin Finck         ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL);
1970c2c66affSColin Finck 
1971c2c66affSColin Finck     heap_free(error);
1972c2c66affSColin Finck 
1973c2c66affSColin Finck     xmlStopParser(This->pParserCtxt);
1974c2c66affSColin Finck     This->ret = E_FAIL;
1975c2c66affSColin Finck }
1976c2c66affSColin Finck 
1977c2c66affSColin Finck /* The only reason this helper exists is that CDATA section are reported by chunks,
1978c2c66affSColin Finck    newlines are used as delimiter. More than that, reader even alters input data before reporting.
1979c2c66affSColin Finck 
1980c2c66affSColin Finck    This helper should be called for substring with trailing newlines.
1981c2c66affSColin Finck */
saxreader_get_cdata_chunk(const xmlChar * str,int len)1982c2c66affSColin Finck static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len)
1983c2c66affSColin Finck {
1984c2c66affSColin Finck     BSTR bstr = bstr_from_xmlCharN(str, len), ret;
1985c2c66affSColin Finck     WCHAR *ptr;
1986c2c66affSColin Finck 
19870506c933SAmine Khaldi     len = SysStringLen(bstr);
1988c2c66affSColin Finck     ptr = bstr + len - 1;
1989c2c66affSColin Finck     while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr)
1990c2c66affSColin Finck         ptr--;
1991c2c66affSColin Finck 
1992c2c66affSColin Finck     while (*++ptr)
1993c2c66affSColin Finck     {
1994c2c66affSColin Finck         /* replace returns as:
1995c2c66affSColin Finck 
1996c2c66affSColin Finck            - "\r<char>" -> "\n<char>"
1997c2c66affSColin Finck            - "\r\r" -> "\r"
1998c2c66affSColin Finck            - "\r\n" -> "\n"
1999c2c66affSColin Finck         */
2000c2c66affSColin Finck         if (*ptr == '\r')
2001c2c66affSColin Finck         {
2002c2c66affSColin Finck             if (*(ptr+1) == '\r' || *(ptr+1) == '\n')
2003c2c66affSColin Finck             {
2004c2c66affSColin Finck                 /* shift tail */
2005c2c66affSColin Finck                 memmove(ptr, ptr+1, len-- - (ptr-bstr));
2006c2c66affSColin Finck             }
2007c2c66affSColin Finck             else
2008c2c66affSColin Finck                 *ptr = '\n';
2009c2c66affSColin Finck         }
2010c2c66affSColin Finck     }
2011c2c66affSColin Finck 
2012c2c66affSColin Finck     ret = SysAllocStringLen(bstr, len);
2013c2c66affSColin Finck     SysFreeString(bstr);
2014c2c66affSColin Finck     return ret;
2015c2c66affSColin Finck }
2016c2c66affSColin Finck 
libxml_cdatablock(void * ctx,const xmlChar * value,int len)2017c2c66affSColin Finck static void libxml_cdatablock(void *ctx, const xmlChar *value, int len)
2018c2c66affSColin Finck {
2019c2c66affSColin Finck     const xmlChar *start, *end;
2020c2c66affSColin Finck     saxlocator *locator = ctx;
2021c2c66affSColin Finck     struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader);
2022c2c66affSColin Finck     HRESULT hr = S_OK;
2023c2c66affSColin Finck     BSTR chars;
2024c2c66affSColin Finck     int i;
2025c2c66affSColin Finck 
2026c2c66affSColin Finck     update_position(locator, FALSE);
2027c2c66affSColin Finck     if (saxreader_has_handler(locator, SAXLexicalHandler))
2028c2c66affSColin Finck     {
2029c2c66affSColin Finck        if (locator->vbInterface)
2030c2c66affSColin Finck            hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
2031c2c66affSColin Finck        else
2032c2c66affSColin Finck            hr = ISAXLexicalHandler_startCDATA(lexical->handler);
2033c2c66affSColin Finck     }
2034c2c66affSColin Finck 
2035c2c66affSColin Finck     if(FAILED(hr))
2036c2c66affSColin Finck     {
2037c2c66affSColin Finck         format_error_message_from_id(locator, hr);
2038c2c66affSColin Finck         return;
2039c2c66affSColin Finck     }
2040c2c66affSColin Finck 
2041c2c66affSColin Finck     start = value;
2042c2c66affSColin Finck     end = NULL;
2043c2c66affSColin Finck     i = 0;
2044c2c66affSColin Finck 
2045c2c66affSColin Finck     while (i < len)
2046c2c66affSColin Finck     {
2047c2c66affSColin Finck         /* scan for newlines */
2048c2c66affSColin Finck         if (value[i] == '\r' || value[i] == '\n')
2049c2c66affSColin Finck         {
2050c2c66affSColin Finck             /* skip newlines/linefeeds */
2051c2c66affSColin Finck             while (i < len)
2052c2c66affSColin Finck             {
2053c2c66affSColin Finck                 if (value[i] != '\r' && value[i] != '\n') break;
2054c2c66affSColin Finck                 i++;
2055c2c66affSColin Finck             }
2056c2c66affSColin Finck             end = &value[i];
2057c2c66affSColin Finck 
2058c2c66affSColin Finck             /* report */
2059c2c66affSColin Finck             chars = saxreader_get_cdata_chunk(start, end-start);
2060c2c66affSColin Finck             TRACE("(chunk %s)\n", debugstr_w(chars));
2061c2c66affSColin Finck             hr = saxreader_saxcharacters(locator, chars);
2062c2c66affSColin Finck             SysFreeString(chars);
2063c2c66affSColin Finck 
2064c2c66affSColin Finck             start = &value[i];
2065c2c66affSColin Finck             end = NULL;
2066c2c66affSColin Finck         }
2067c2c66affSColin Finck         i++;
2068c2c66affSColin Finck         locator->column++;
2069c2c66affSColin Finck     }
2070c2c66affSColin Finck 
2071c2c66affSColin Finck     /* no newline chars (or last chunk) report as a whole */
2072c2c66affSColin Finck     if (!end && start == value)
2073c2c66affSColin Finck     {
2074c2c66affSColin Finck         /* report */
2075c2c66affSColin Finck         chars = bstr_from_xmlCharN(start, len-(start-value));
2076c2c66affSColin Finck         TRACE("(%s)\n", debugstr_w(chars));
2077c2c66affSColin Finck         hr = saxreader_saxcharacters(locator, chars);
2078c2c66affSColin Finck         SysFreeString(chars);
2079c2c66affSColin Finck     }
2080c2c66affSColin Finck 
2081c2c66affSColin Finck     if (saxreader_has_handler(locator, SAXLexicalHandler))
2082c2c66affSColin Finck     {
2083c2c66affSColin Finck         if (locator->vbInterface)
2084c2c66affSColin Finck             hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
2085c2c66affSColin Finck         else
2086c2c66affSColin Finck             hr = ISAXLexicalHandler_endCDATA(lexical->handler);
2087c2c66affSColin Finck     }
2088c2c66affSColin Finck 
2089c2c66affSColin Finck     if(FAILED(hr))
2090c2c66affSColin Finck         format_error_message_from_id(locator, hr);
2091c2c66affSColin Finck }
2092c2c66affSColin Finck 
libxmlresolveentity(void * ctx,const xmlChar * publicid,const xmlChar * systemid)2093c2c66affSColin Finck static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid)
2094c2c66affSColin Finck {
2095c2c66affSColin Finck     FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid);
2096c2c66affSColin Finck     return xmlSAX2ResolveEntity(ctx, publicid, systemid);
2097c2c66affSColin Finck }
2098c2c66affSColin Finck 
2099c2c66affSColin Finck /*** IVBSAXLocator interface ***/
2100c2c66affSColin Finck /*** IUnknown methods ***/
ivbsaxlocator_QueryInterface(IVBSAXLocator * iface,REFIID riid,void ** ppvObject)2101c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
2102c2c66affSColin Finck {
2103c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2104c2c66affSColin Finck 
2105c2c66affSColin Finck     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
2106c2c66affSColin Finck 
2107c2c66affSColin Finck     *ppvObject = NULL;
2108c2c66affSColin Finck 
2109c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2110c2c66affSColin Finck             IsEqualGUID( riid, &IID_IDispatch) ||
2111c2c66affSColin Finck             IsEqualGUID( riid, &IID_IVBSAXLocator ))
2112c2c66affSColin Finck     {
2113c2c66affSColin Finck         *ppvObject = iface;
2114c2c66affSColin Finck     }
2115c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
2116c2c66affSColin Finck     {
2117c2c66affSColin Finck         *ppvObject = &This->IVBSAXAttributes_iface;
2118c2c66affSColin Finck     }
2119c2c66affSColin Finck     else
2120c2c66affSColin Finck     {
2121c2c66affSColin Finck         FIXME("interface %s not implemented\n", debugstr_guid(riid));
2122c2c66affSColin Finck         return E_NOINTERFACE;
2123c2c66affSColin Finck     }
2124c2c66affSColin Finck 
2125c2c66affSColin Finck     IVBSAXLocator_AddRef( iface );
2126c2c66affSColin Finck 
2127c2c66affSColin Finck     return S_OK;
2128c2c66affSColin Finck }
2129c2c66affSColin Finck 
ivbsaxlocator_AddRef(IVBSAXLocator * iface)2130c2c66affSColin Finck static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
2131c2c66affSColin Finck {
2132c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2133c2c66affSColin Finck     TRACE("%p\n", This );
2134c2c66affSColin Finck     return ISAXLocator_AddRef(&This->ISAXLocator_iface);
2135c2c66affSColin Finck }
2136c2c66affSColin Finck 
ivbsaxlocator_Release(IVBSAXLocator * iface)2137c2c66affSColin Finck static ULONG WINAPI ivbsaxlocator_Release(IVBSAXLocator* iface)
2138c2c66affSColin Finck {
2139c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2140c2c66affSColin Finck     return ISAXLocator_Release(&This->ISAXLocator_iface);
2141c2c66affSColin Finck }
2142c2c66affSColin Finck 
2143c2c66affSColin Finck /*** IDispatch methods ***/
ivbsaxlocator_GetTypeInfoCount(IVBSAXLocator * iface,UINT * pctinfo)2144c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
2145c2c66affSColin Finck {
2146c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2147c2c66affSColin Finck 
2148c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, pctinfo);
2149c2c66affSColin Finck 
2150c2c66affSColin Finck     *pctinfo = 1;
2151c2c66affSColin Finck 
2152c2c66affSColin Finck     return S_OK;
2153c2c66affSColin Finck }
2154c2c66affSColin Finck 
ivbsaxlocator_GetTypeInfo(IVBSAXLocator * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2155c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
2156c2c66affSColin Finck     IVBSAXLocator *iface,
2157c2c66affSColin Finck     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2158c2c66affSColin Finck {
2159c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2160c2c66affSColin Finck 
2161c2c66affSColin Finck     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2162c2c66affSColin Finck 
2163c2c66affSColin Finck     return get_typeinfo(IVBSAXLocator_tid, ppTInfo);
2164c2c66affSColin Finck }
2165c2c66affSColin Finck 
ivbsaxlocator_GetIDsOfNames(IVBSAXLocator * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2166c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
2167c2c66affSColin Finck     IVBSAXLocator *iface,
2168c2c66affSColin Finck     REFIID riid,
2169c2c66affSColin Finck     LPOLESTR* rgszNames,
2170c2c66affSColin Finck     UINT cNames,
2171c2c66affSColin Finck     LCID lcid,
2172c2c66affSColin Finck     DISPID* rgDispId)
2173c2c66affSColin Finck {
2174c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2175c2c66affSColin Finck     ITypeInfo *typeinfo;
2176c2c66affSColin Finck     HRESULT hr;
2177c2c66affSColin Finck 
2178c2c66affSColin Finck     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
2179c2c66affSColin Finck           lcid, rgDispId);
2180c2c66affSColin Finck 
2181c2c66affSColin Finck     if(!rgszNames || cNames == 0 || !rgDispId)
2182c2c66affSColin Finck         return E_INVALIDARG;
2183c2c66affSColin Finck 
2184c2c66affSColin Finck     hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
2185c2c66affSColin Finck     if(SUCCEEDED(hr))
2186c2c66affSColin Finck     {
2187c2c66affSColin Finck         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2188c2c66affSColin Finck         ITypeInfo_Release(typeinfo);
2189c2c66affSColin Finck     }
2190c2c66affSColin Finck 
2191c2c66affSColin Finck     return hr;
2192c2c66affSColin Finck }
2193c2c66affSColin Finck 
ivbsaxlocator_Invoke(IVBSAXLocator * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2194c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_Invoke(
2195c2c66affSColin Finck     IVBSAXLocator *iface,
2196c2c66affSColin Finck     DISPID dispIdMember,
2197c2c66affSColin Finck     REFIID riid,
2198c2c66affSColin Finck     LCID lcid,
2199c2c66affSColin Finck     WORD wFlags,
2200c2c66affSColin Finck     DISPPARAMS* pDispParams,
2201c2c66affSColin Finck     VARIANT* pVarResult,
2202c2c66affSColin Finck     EXCEPINFO* pExcepInfo,
2203c2c66affSColin Finck     UINT* puArgErr)
2204c2c66affSColin Finck {
2205c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2206c2c66affSColin Finck     ITypeInfo *typeinfo;
2207c2c66affSColin Finck     HRESULT hr;
2208c2c66affSColin Finck 
2209c2c66affSColin Finck     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2210c2c66affSColin Finck           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2211c2c66affSColin Finck 
2212c2c66affSColin Finck     hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
2213c2c66affSColin Finck     if(SUCCEEDED(hr))
2214c2c66affSColin Finck     {
2215c2c66affSColin Finck         hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags,
2216c2c66affSColin Finck                 pDispParams, pVarResult, pExcepInfo, puArgErr);
2217c2c66affSColin Finck         ITypeInfo_Release(typeinfo);
2218c2c66affSColin Finck     }
2219c2c66affSColin Finck 
2220c2c66affSColin Finck     return hr;
2221c2c66affSColin Finck }
2222c2c66affSColin Finck 
2223c2c66affSColin Finck /*** IVBSAXLocator methods ***/
ivbsaxlocator_get_columnNumber(IVBSAXLocator * iface,int * pnColumn)2224c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
2225c2c66affSColin Finck         IVBSAXLocator* iface,
2226c2c66affSColin Finck         int *pnColumn)
2227c2c66affSColin Finck {
2228c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2229c2c66affSColin Finck     return ISAXLocator_getColumnNumber(&This->ISAXLocator_iface, pnColumn);
2230c2c66affSColin Finck }
2231c2c66affSColin Finck 
ivbsaxlocator_get_lineNumber(IVBSAXLocator * iface,int * pnLine)2232c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
2233c2c66affSColin Finck         IVBSAXLocator* iface,
2234c2c66affSColin Finck         int *pnLine)
2235c2c66affSColin Finck {
2236c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2237c2c66affSColin Finck     return ISAXLocator_getLineNumber(&This->ISAXLocator_iface, pnLine);
2238c2c66affSColin Finck }
2239c2c66affSColin Finck 
ivbsaxlocator_get_publicId(IVBSAXLocator * iface,BSTR * ret)2240c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_get_publicId(IVBSAXLocator* iface, BSTR *ret)
2241c2c66affSColin Finck {
2242c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2243c2c66affSColin Finck     const WCHAR *publicidW;
2244c2c66affSColin Finck     HRESULT hr;
2245c2c66affSColin Finck 
2246c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, ret);
2247c2c66affSColin Finck 
2248c2c66affSColin Finck     if (!ret)
2249c2c66affSColin Finck         return E_POINTER;
2250c2c66affSColin Finck 
2251c2c66affSColin Finck     *ret = NULL;
2252c2c66affSColin Finck     hr = ISAXLocator_getPublicId(&This->ISAXLocator_iface, &publicidW);
2253c2c66affSColin Finck     if (FAILED(hr))
2254c2c66affSColin Finck         return hr;
2255c2c66affSColin Finck 
2256c2c66affSColin Finck     return return_bstr(publicidW, ret);
2257c2c66affSColin Finck }
2258c2c66affSColin Finck 
ivbsaxlocator_get_systemId(IVBSAXLocator * iface,BSTR * ret)2259c2c66affSColin Finck static HRESULT WINAPI ivbsaxlocator_get_systemId(IVBSAXLocator* iface, BSTR *ret)
2260c2c66affSColin Finck {
2261c2c66affSColin Finck     saxlocator *This = impl_from_IVBSAXLocator( iface );
2262c2c66affSColin Finck     const WCHAR *systemidW;
2263c2c66affSColin Finck     HRESULT hr;
2264c2c66affSColin Finck 
2265c2c66affSColin Finck     TRACE("(%p)->(%p)\n", This, ret);
2266c2c66affSColin Finck 
2267c2c66affSColin Finck     if (!ret)
2268c2c66affSColin Finck         return E_POINTER;
2269c2c66affSColin Finck 
2270c2c66affSColin Finck     *ret = NULL;
2271c2c66affSColin Finck     hr = ISAXLocator_getSystemId(&This->ISAXLocator_iface, &systemidW);
2272c2c66affSColin Finck     if (FAILED(hr))
2273c2c66affSColin Finck         return hr;
2274c2c66affSColin Finck 
2275c2c66affSColin Finck     return return_bstr(systemidW, ret);
2276c2c66affSColin Finck }
2277c2c66affSColin Finck 
2278c2c66affSColin Finck static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl =
2279c2c66affSColin Finck {
2280c2c66affSColin Finck     ivbsaxlocator_QueryInterface,
2281c2c66affSColin Finck     ivbsaxlocator_AddRef,
2282c2c66affSColin Finck     ivbsaxlocator_Release,
2283c2c66affSColin Finck     ivbsaxlocator_GetTypeInfoCount,
2284c2c66affSColin Finck     ivbsaxlocator_GetTypeInfo,
2285c2c66affSColin Finck     ivbsaxlocator_GetIDsOfNames,
2286c2c66affSColin Finck     ivbsaxlocator_Invoke,
2287c2c66affSColin Finck     ivbsaxlocator_get_columnNumber,
2288c2c66affSColin Finck     ivbsaxlocator_get_lineNumber,
2289c2c66affSColin Finck     ivbsaxlocator_get_publicId,
2290c2c66affSColin Finck     ivbsaxlocator_get_systemId
2291c2c66affSColin Finck };
2292c2c66affSColin Finck 
2293c2c66affSColin Finck /*** ISAXLocator interface ***/
2294c2c66affSColin Finck /*** IUnknown methods ***/
isaxlocator_QueryInterface(ISAXLocator * iface,REFIID riid,void ** ppvObject)2295c2c66affSColin Finck static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
2296c2c66affSColin Finck {
2297c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2298c2c66affSColin Finck 
2299c2c66affSColin Finck     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2300c2c66affSColin Finck 
2301c2c66affSColin Finck     *ppvObject = NULL;
2302c2c66affSColin Finck 
2303c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2304c2c66affSColin Finck             IsEqualGUID( riid, &IID_ISAXLocator ))
2305c2c66affSColin Finck     {
2306c2c66affSColin Finck         *ppvObject = iface;
2307c2c66affSColin Finck     }
2308c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
2309c2c66affSColin Finck     {
2310c2c66affSColin Finck         *ppvObject = &This->ISAXAttributes_iface;
2311c2c66affSColin Finck     }
2312c2c66affSColin Finck     else
2313c2c66affSColin Finck     {
2314c2c66affSColin Finck         WARN("interface %s not implemented\n", debugstr_guid(riid));
2315c2c66affSColin Finck         return E_NOINTERFACE;
2316c2c66affSColin Finck     }
2317c2c66affSColin Finck 
2318c2c66affSColin Finck     ISAXLocator_AddRef( iface );
2319c2c66affSColin Finck 
2320c2c66affSColin Finck     return S_OK;
2321c2c66affSColin Finck }
2322c2c66affSColin Finck 
isaxlocator_AddRef(ISAXLocator * iface)2323c2c66affSColin Finck static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
2324c2c66affSColin Finck {
2325c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2326c2c66affSColin Finck     ULONG ref = InterlockedIncrement( &This->ref );
2327c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, ref);
2328c2c66affSColin Finck     return ref;
2329c2c66affSColin Finck }
2330c2c66affSColin Finck 
isaxlocator_Release(ISAXLocator * iface)2331c2c66affSColin Finck static ULONG WINAPI isaxlocator_Release(
2332c2c66affSColin Finck         ISAXLocator* iface)
2333c2c66affSColin Finck {
2334c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2335c2c66affSColin Finck     LONG ref = InterlockedDecrement( &This->ref );
2336c2c66affSColin Finck 
2337c2c66affSColin Finck     TRACE("(%p)->(%d)\n", This, ref );
2338c2c66affSColin Finck 
2339c2c66affSColin Finck     if (ref == 0)
2340c2c66affSColin Finck     {
2341c2c66affSColin Finck         element_entry *element, *element2;
2342c2c66affSColin Finck         int index;
2343c2c66affSColin Finck 
2344c2c66affSColin Finck         SysFreeString(This->publicId);
2345c2c66affSColin Finck         SysFreeString(This->systemId);
2346c2c66affSColin Finck         SysFreeString(This->namespaceUri);
2347c2c66affSColin Finck 
2348c2c66affSColin Finck         for(index = 0; index < This->attr_alloc_count; index++)
2349c2c66affSColin Finck         {
2350c2c66affSColin Finck             SysFreeString(This->attributes[index].szLocalname);
2351c2c66affSColin Finck             SysFreeString(This->attributes[index].szValue);
2352c2c66affSColin Finck             SysFreeString(This->attributes[index].szQName);
2353c2c66affSColin Finck         }
2354c2c66affSColin Finck         heap_free(This->attributes);
2355c2c66affSColin Finck 
2356c2c66affSColin Finck         /* element stack */
2357c2c66affSColin Finck         LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry)
2358c2c66affSColin Finck         {
2359c2c66affSColin Finck             list_remove(&element->entry);
2360c2c66affSColin Finck             free_element_entry(element);
2361c2c66affSColin Finck         }
2362c2c66affSColin Finck 
2363c2c66affSColin Finck         ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface);
2364c2c66affSColin Finck         heap_free( This );
2365c2c66affSColin Finck     }
2366c2c66affSColin Finck 
2367c2c66affSColin Finck     return ref;
2368c2c66affSColin Finck }
2369c2c66affSColin Finck 
2370c2c66affSColin Finck /*** ISAXLocator methods ***/
isaxlocator_getColumnNumber(ISAXLocator * iface,int * pnColumn)2371c2c66affSColin Finck static HRESULT WINAPI isaxlocator_getColumnNumber(
2372c2c66affSColin Finck         ISAXLocator* iface,
2373c2c66affSColin Finck         int *pnColumn)
2374c2c66affSColin Finck {
2375c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2376c2c66affSColin Finck 
2377c2c66affSColin Finck     *pnColumn = This->column;
2378c2c66affSColin Finck     return S_OK;
2379c2c66affSColin Finck }
2380c2c66affSColin Finck 
isaxlocator_getLineNumber(ISAXLocator * iface,int * pnLine)2381c2c66affSColin Finck static HRESULT WINAPI isaxlocator_getLineNumber(
2382c2c66affSColin Finck         ISAXLocator* iface,
2383c2c66affSColin Finck         int *pnLine)
2384c2c66affSColin Finck {
2385c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2386c2c66affSColin Finck 
2387c2c66affSColin Finck     *pnLine = This->line;
2388c2c66affSColin Finck     return S_OK;
2389c2c66affSColin Finck }
2390c2c66affSColin Finck 
isaxlocator_getPublicId(ISAXLocator * iface,const WCHAR ** ppwchPublicId)2391c2c66affSColin Finck static HRESULT WINAPI isaxlocator_getPublicId(
2392c2c66affSColin Finck         ISAXLocator* iface,
2393c2c66affSColin Finck         const WCHAR ** ppwchPublicId)
2394c2c66affSColin Finck {
2395c2c66affSColin Finck     BSTR publicId;
2396c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2397c2c66affSColin Finck 
2398c2c66affSColin Finck     SysFreeString(This->publicId);
2399c2c66affSColin Finck 
2400c2c66affSColin Finck     publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
2401c2c66affSColin Finck     if(SysStringLen(publicId))
2402c2c66affSColin Finck         This->publicId = publicId;
2403c2c66affSColin Finck     else
2404c2c66affSColin Finck     {
2405c2c66affSColin Finck         SysFreeString(publicId);
2406c2c66affSColin Finck         This->publicId = NULL;
2407c2c66affSColin Finck     }
2408c2c66affSColin Finck 
2409c2c66affSColin Finck     *ppwchPublicId = This->publicId;
2410c2c66affSColin Finck     return S_OK;
2411c2c66affSColin Finck }
2412c2c66affSColin Finck 
isaxlocator_getSystemId(ISAXLocator * iface,const WCHAR ** ppwchSystemId)2413c2c66affSColin Finck static HRESULT WINAPI isaxlocator_getSystemId(
2414c2c66affSColin Finck         ISAXLocator* iface,
2415c2c66affSColin Finck         const WCHAR ** ppwchSystemId)
2416c2c66affSColin Finck {
2417c2c66affSColin Finck     BSTR systemId;
2418c2c66affSColin Finck     saxlocator *This = impl_from_ISAXLocator( iface );
2419c2c66affSColin Finck 
2420c2c66affSColin Finck     SysFreeString(This->systemId);
2421c2c66affSColin Finck 
2422c2c66affSColin Finck     systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
2423c2c66affSColin Finck     if(SysStringLen(systemId))
2424c2c66affSColin Finck         This->systemId = systemId;
2425c2c66affSColin Finck     else
2426c2c66affSColin Finck     {
2427c2c66affSColin Finck         SysFreeString(systemId);
2428c2c66affSColin Finck         This->systemId = NULL;
2429c2c66affSColin Finck     }
2430c2c66affSColin Finck 
2431c2c66affSColin Finck     *ppwchSystemId = This->systemId;
2432c2c66affSColin Finck     return S_OK;
2433c2c66affSColin Finck }
2434c2c66affSColin Finck 
2435c2c66affSColin Finck static const struct ISAXLocatorVtbl SAXLocatorVtbl =
2436c2c66affSColin Finck {
2437c2c66affSColin Finck     isaxlocator_QueryInterface,
2438c2c66affSColin Finck     isaxlocator_AddRef,
2439c2c66affSColin Finck     isaxlocator_Release,
2440c2c66affSColin Finck     isaxlocator_getColumnNumber,
2441c2c66affSColin Finck     isaxlocator_getLineNumber,
2442c2c66affSColin Finck     isaxlocator_getPublicId,
2443c2c66affSColin Finck     isaxlocator_getSystemId
2444c2c66affSColin Finck };
2445c2c66affSColin Finck 
SAXLocator_create(saxreader * reader,saxlocator ** ppsaxlocator,BOOL vbInterface)2446c2c66affSColin Finck static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
2447c2c66affSColin Finck {
2448c2c66affSColin Finck     static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
2449c2c66affSColin Finck         'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
2450c2c66affSColin Finck 
2451c2c66affSColin Finck     saxlocator *locator;
2452c2c66affSColin Finck 
2453c2c66affSColin Finck     locator = heap_alloc( sizeof (*locator) );
2454c2c66affSColin Finck     if( !locator )
2455c2c66affSColin Finck         return E_OUTOFMEMORY;
2456c2c66affSColin Finck 
2457c2c66affSColin Finck     locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl;
2458c2c66affSColin Finck     locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl;
2459c2c66affSColin Finck     locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl;
2460c2c66affSColin Finck     locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl;
2461c2c66affSColin Finck     locator->ref = 1;
2462c2c66affSColin Finck     locator->vbInterface = vbInterface;
2463c2c66affSColin Finck 
2464c2c66affSColin Finck     locator->saxreader = reader;
2465c2c66affSColin Finck     ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface);
2466c2c66affSColin Finck 
2467c2c66affSColin Finck     locator->pParserCtxt = NULL;
2468c2c66affSColin Finck     locator->publicId = NULL;
2469c2c66affSColin Finck     locator->systemId = NULL;
2470c2c66affSColin Finck     locator->line = reader->version < MSXML4 ? 0 : 1;
2471c2c66affSColin Finck     locator->column = 0;
2472c2c66affSColin Finck     locator->ret = S_OK;
2473c2c66affSColin Finck     if (locator->saxreader->version >= MSXML6)
2474c2c66affSColin Finck         locator->namespaceUri = SysAllocString(w3xmlns);
2475c2c66affSColin Finck     else
2476c2c66affSColin Finck         locator->namespaceUri = SysAllocStringLen(NULL, 0);
2477c2c66affSColin Finck     if(!locator->namespaceUri)
2478c2c66affSColin Finck     {
2479c2c66affSColin Finck         ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2480c2c66affSColin Finck         heap_free(locator);
2481c2c66affSColin Finck         return E_OUTOFMEMORY;
2482c2c66affSColin Finck     }
2483c2c66affSColin Finck 
2484c2c66affSColin Finck     locator->attr_alloc_count = 8;
2485c2c66affSColin Finck     locator->attr_count = 0;
2486c2c66affSColin Finck     locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attr_alloc_count);
2487c2c66affSColin Finck     if(!locator->attributes)
2488c2c66affSColin Finck     {
2489c2c66affSColin Finck         ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2490c2c66affSColin Finck         SysFreeString(locator->namespaceUri);
2491c2c66affSColin Finck         heap_free(locator);
2492c2c66affSColin Finck         return E_OUTOFMEMORY;
2493c2c66affSColin Finck     }
2494c2c66affSColin Finck 
2495c2c66affSColin Finck     list_init(&locator->elements);
2496c2c66affSColin Finck 
2497c2c66affSColin Finck     *ppsaxlocator = locator;
2498c2c66affSColin Finck 
2499c2c66affSColin Finck     TRACE("returning %p\n", *ppsaxlocator);
2500c2c66affSColin Finck 
2501c2c66affSColin Finck     return S_OK;
2502c2c66affSColin Finck }
2503c2c66affSColin Finck 
2504c2c66affSColin Finck /*** SAXXMLReader internal functions ***/
internal_parseBuffer(saxreader * This,const char * buffer,int size,BOOL vbInterface)2505c2c66affSColin Finck static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
2506c2c66affSColin Finck {
2507c2c66affSColin Finck     xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
2508c2c66affSColin Finck     xmlChar *enc_name = NULL;
2509c2c66affSColin Finck     saxlocator *locator;
2510c2c66affSColin Finck     HRESULT hr;
2511c2c66affSColin Finck 
2512c2c66affSColin Finck     TRACE("(%p)->(%p %d)\n", This, buffer, size);
2513c2c66affSColin Finck 
2514c2c66affSColin Finck     hr = SAXLocator_create(This, &locator, vbInterface);
2515c2c66affSColin Finck     if (FAILED(hr))
2516c2c66affSColin Finck         return hr;
2517c2c66affSColin Finck 
2518c2c66affSColin Finck     if (size >= 4)
2519c2c66affSColin Finck     {
2520c2c66affSColin Finck         const unsigned char *buff = (unsigned char*)buffer;
2521c2c66affSColin Finck 
2522c2c66affSColin Finck         encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4);
2523c2c66affSColin Finck         enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2524c2c66affSColin Finck         TRACE("detected encoding: %s\n", enc_name);
2525c2c66affSColin Finck         /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2526c2c66affSColin Finck         if ((encoding == XML_CHAR_ENCODING_UTF8) &&
2527c2c66affSColin Finck             buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF)
2528c2c66affSColin Finck         {
2529c2c66affSColin Finck             buffer += 3;
2530c2c66affSColin Finck             size -= 3;
2531c2c66affSColin Finck         }
2532c2c66affSColin Finck     }
2533c2c66affSColin Finck 
2534c2c66affSColin Finck     /* if libxml2 detection failed try to guess */
2535c2c66affSColin Finck     if (encoding == XML_CHAR_ENCODING_NONE)
2536c2c66affSColin Finck     {
2537c2c66affSColin Finck         const WCHAR *ptr = (WCHAR*)buffer;
2538c2c66affSColin Finck         /* an xml declaration with optional encoding will still be handled by the parser */
2539c2c66affSColin Finck         if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
2540c2c66affSColin Finck         {
2541c2c66affSColin Finck             enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE);
2542c2c66affSColin Finck             encoding = XML_CHAR_ENCODING_UTF16LE;
2543c2c66affSColin Finck         }
2544c2c66affSColin Finck     }
2545c2c66affSColin Finck     else if (encoding == XML_CHAR_ENCODING_UTF8)
2546c2c66affSColin Finck         enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2547c2c66affSColin Finck     else
2548c2c66affSColin Finck         enc_name = NULL;
2549c2c66affSColin Finck 
2550c2c66affSColin Finck     locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size);
2551c2c66affSColin Finck     if (!locator->pParserCtxt)
2552c2c66affSColin Finck     {
2553c2c66affSColin Finck         ISAXLocator_Release(&locator->ISAXLocator_iface);
2554c2c66affSColin Finck         return E_FAIL;
2555c2c66affSColin Finck     }
2556c2c66affSColin Finck 
2557c2c66affSColin Finck     if (enc_name)
2558c2c66affSColin Finck     {
2559c2c66affSColin Finck         locator->pParserCtxt->encoding = xmlStrdup(enc_name);
2560c2c66affSColin Finck         if (encoding == XML_CHAR_ENCODING_UTF16LE) {
2561c2c66affSColin Finck             TRACE("switching to %s\n", enc_name);
2562c2c66affSColin Finck             xmlSwitchEncoding(locator->pParserCtxt, encoding);
2563c2c66affSColin Finck         }
2564c2c66affSColin Finck     }
2565c2c66affSColin Finck 
2566c2c66affSColin Finck     xmlFree(locator->pParserCtxt->sax);
2567c2c66affSColin Finck     locator->pParserCtxt->sax = &locator->saxreader->sax;
2568c2c66affSColin Finck     locator->pParserCtxt->userData = locator;
2569c2c66affSColin Finck 
2570c2c66affSColin Finck     This->isParsing = TRUE;
2571c2c66affSColin Finck     if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK)
2572c2c66affSColin Finck         hr = E_FAIL;
2573c2c66affSColin Finck     else
2574c2c66affSColin Finck         hr = locator->ret;
2575c2c66affSColin Finck     This->isParsing = FALSE;
2576c2c66affSColin Finck 
2577c2c66affSColin Finck     if(locator->pParserCtxt)
2578c2c66affSColin Finck     {
2579c2c66affSColin Finck         locator->pParserCtxt->sax = NULL;
2580c2c66affSColin Finck         xmlFreeParserCtxt(locator->pParserCtxt);
2581c2c66affSColin Finck         locator->pParserCtxt = NULL;
2582c2c66affSColin Finck     }
2583c2c66affSColin Finck 
2584c2c66affSColin Finck     ISAXLocator_Release(&locator->ISAXLocator_iface);
2585c2c66affSColin Finck     return hr;
2586c2c66affSColin Finck }
2587c2c66affSColin Finck 
internal_parseStream(saxreader * This,ISequentialStream * stream,BOOL vbInterface)2588c2c66affSColin Finck static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, BOOL vbInterface)
2589c2c66affSColin Finck {
2590c2c66affSColin Finck     saxlocator *locator;
2591c2c66affSColin Finck     HRESULT hr;
2592c2c66affSColin Finck     ULONG dataRead;
2593c2c66affSColin Finck     char data[2048];
2594c2c66affSColin Finck     int ret;
2595c2c66affSColin Finck 
2596c2c66affSColin Finck     dataRead = 0;
2597c2c66affSColin Finck     hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2598c2c66affSColin Finck     if(FAILED(hr)) return hr;
2599c2c66affSColin Finck 
2600c2c66affSColin Finck     hr = SAXLocator_create(This, &locator, vbInterface);
2601c2c66affSColin Finck     if(FAILED(hr)) return hr;
2602c2c66affSColin Finck 
2603c2c66affSColin Finck     locator->pParserCtxt = xmlCreatePushParserCtxt(
2604c2c66affSColin Finck             &locator->saxreader->sax, locator,
2605c2c66affSColin Finck             data, dataRead, NULL);
2606c2c66affSColin Finck     if(!locator->pParserCtxt)
2607c2c66affSColin Finck     {
2608c2c66affSColin Finck         ISAXLocator_Release(&locator->ISAXLocator_iface);
2609c2c66affSColin Finck         return E_FAIL;
2610c2c66affSColin Finck     }
2611c2c66affSColin Finck 
2612c2c66affSColin Finck     This->isParsing = TRUE;
2613c2c66affSColin Finck 
2614c2c66affSColin Finck     do {
2615c2c66affSColin Finck         dataRead = 0;
2616c2c66affSColin Finck         hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
2617c2c66affSColin Finck         if (FAILED(hr) || !dataRead) break;
2618c2c66affSColin Finck 
2619c2c66affSColin Finck         ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
2620c2c66affSColin Finck         hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2621c2c66affSColin Finck     }while(hr == S_OK);
2622c2c66affSColin Finck 
2623c2c66affSColin Finck     if(SUCCEEDED(hr))
2624c2c66affSColin Finck     {
2625c2c66affSColin Finck         ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2626c2c66affSColin Finck         hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2627c2c66affSColin Finck     }
2628c2c66affSColin Finck 
2629c2c66affSColin Finck 
2630c2c66affSColin Finck     This->isParsing = FALSE;
2631c2c66affSColin Finck 
2632c2c66affSColin Finck     xmlFreeParserCtxt(locator->pParserCtxt);
2633c2c66affSColin Finck     locator->pParserCtxt = NULL;
2634c2c66affSColin Finck     ISAXLocator_Release(&locator->ISAXLocator_iface);
2635c2c66affSColin Finck     return hr;
2636c2c66affSColin Finck }
2637c2c66affSColin Finck 
internal_parse(saxreader * This,VARIANT varInput,BOOL vbInterface)2638c2c66affSColin Finck static HRESULT internal_parse(
2639c2c66affSColin Finck         saxreader* This,
2640c2c66affSColin Finck         VARIANT varInput,
2641c2c66affSColin Finck         BOOL vbInterface)
2642c2c66affSColin Finck {
2643c2c66affSColin Finck     HRESULT hr;
2644c2c66affSColin Finck 
2645c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput));
2646c2c66affSColin Finck 
2647c2c66affSColin Finck     /* Dispose of the BSTRs in the pool from a prior run, if any. */
2648c2c66affSColin Finck     free_bstr_pool(&This->pool);
2649c2c66affSColin Finck 
2650c2c66affSColin Finck     switch(V_VT(&varInput))
2651c2c66affSColin Finck     {
2652c2c66affSColin Finck         case VT_BSTR:
2653c2c66affSColin Finck         case VT_BSTR|VT_BYREF:
2654c2c66affSColin Finck         {
2655c2c66affSColin Finck             BSTR str = V_ISBYREF(&varInput) ? *V_BSTRREF(&varInput) : V_BSTR(&varInput);
2656c2c66affSColin Finck             hr = internal_parseBuffer(This, (const char*)str, strlenW(str)*sizeof(WCHAR), vbInterface);
2657c2c66affSColin Finck             break;
2658c2c66affSColin Finck         }
2659c2c66affSColin Finck         case VT_ARRAY|VT_UI1: {
2660c2c66affSColin Finck             void *pSAData;
2661c2c66affSColin Finck             LONG lBound, uBound;
2662c2c66affSColin Finck             ULONG dataRead;
2663c2c66affSColin Finck 
2664c2c66affSColin Finck             hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2665c2c66affSColin Finck             if(hr != S_OK) break;
2666c2c66affSColin Finck             hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2667c2c66affSColin Finck             if(hr != S_OK) break;
2668c2c66affSColin Finck             dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2669c2c66affSColin Finck             hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2670c2c66affSColin Finck             if(hr != S_OK) break;
2671c2c66affSColin Finck             hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2672c2c66affSColin Finck             SafeArrayUnaccessData(V_ARRAY(&varInput));
2673c2c66affSColin Finck             break;
2674c2c66affSColin Finck         }
2675c2c66affSColin Finck         case VT_UNKNOWN:
2676c2c66affSColin Finck         case VT_DISPATCH: {
2677c2c66affSColin Finck             ISequentialStream *stream = NULL;
2678c2c66affSColin Finck             IXMLDOMDocument *xmlDoc;
2679c2c66affSColin Finck 
2680c2c66affSColin Finck             if (!V_UNKNOWN(&varInput))
2681c2c66affSColin Finck                 return E_INVALIDARG;
2682c2c66affSColin Finck 
2683c2c66affSColin Finck             if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2684c2c66affSColin Finck                         &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2685c2c66affSColin Finck             {
2686c2c66affSColin Finck                 BSTR bstrData;
2687c2c66affSColin Finck 
2688c2c66affSColin Finck                 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2689c2c66affSColin Finck                 hr = internal_parseBuffer(This, (const char*)bstrData,
2690c2c66affSColin Finck                         SysStringByteLen(bstrData), vbInterface);
2691c2c66affSColin Finck                 IXMLDOMDocument_Release(xmlDoc);
2692c2c66affSColin Finck                 SysFreeString(bstrData);
2693c2c66affSColin Finck                 break;
2694c2c66affSColin Finck             }
2695c2c66affSColin Finck 
2696c2c66affSColin Finck             /* try base interface first */
2697c2c66affSColin Finck             IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
2698c2c66affSColin Finck             if (!stream)
2699c2c66affSColin Finck                 /* this should never happen if IStream is implemented properly, but just in case */
2700c2c66affSColin Finck                 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
2701c2c66affSColin Finck 
2702c2c66affSColin Finck             if(stream)
2703c2c66affSColin Finck             {
2704c2c66affSColin Finck                 hr = internal_parseStream(This, stream, vbInterface);
2705c2c66affSColin Finck                 ISequentialStream_Release(stream);
2706c2c66affSColin Finck             }
2707c2c66affSColin Finck             else
2708c2c66affSColin Finck             {
2709c2c66affSColin Finck                 WARN("IUnknown* input doesn't support any of expected interfaces\n");
2710c2c66affSColin Finck                 hr = E_INVALIDARG;
2711c2c66affSColin Finck             }
2712c2c66affSColin Finck 
2713c2c66affSColin Finck             break;
2714c2c66affSColin Finck         }
2715c2c66affSColin Finck         default:
2716c2c66affSColin Finck             WARN("vt %d not implemented\n", V_VT(&varInput));
2717c2c66affSColin Finck             hr = E_INVALIDARG;
2718c2c66affSColin Finck     }
2719c2c66affSColin Finck 
2720c2c66affSColin Finck     return hr;
2721c2c66affSColin Finck }
2722c2c66affSColin Finck 
internal_vbonDataAvailable(void * obj,char * ptr,DWORD len)2723c2c66affSColin Finck static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2724c2c66affSColin Finck {
2725c2c66affSColin Finck     saxreader *This = obj;
2726c2c66affSColin Finck 
2727c2c66affSColin Finck     return internal_parseBuffer(This, ptr, len, TRUE);
2728c2c66affSColin Finck }
2729c2c66affSColin Finck 
internal_onDataAvailable(void * obj,char * ptr,DWORD len)2730c2c66affSColin Finck static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2731c2c66affSColin Finck {
2732c2c66affSColin Finck     saxreader *This = obj;
2733c2c66affSColin Finck 
2734c2c66affSColin Finck     return internal_parseBuffer(This, ptr, len, FALSE);
2735c2c66affSColin Finck }
2736c2c66affSColin Finck 
internal_parseURL(saxreader * This,const WCHAR * url,BOOL vbInterface)2737c2c66affSColin Finck static HRESULT internal_parseURL(
2738c2c66affSColin Finck         saxreader* This,
2739c2c66affSColin Finck         const WCHAR *url,
2740c2c66affSColin Finck         BOOL vbInterface)
2741c2c66affSColin Finck {
2742c2c66affSColin Finck     IMoniker *mon;
2743c2c66affSColin Finck     bsc_t *bsc;
2744c2c66affSColin Finck     HRESULT hr;
2745c2c66affSColin Finck 
2746c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2747c2c66affSColin Finck 
2748c2c66affSColin Finck     hr = create_moniker_from_url(url, &mon);
2749c2c66affSColin Finck     if(FAILED(hr))
2750c2c66affSColin Finck         return hr;
2751c2c66affSColin Finck 
2752c2c66affSColin Finck     if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc);
2753c2c66affSColin Finck     else hr = bind_url(mon, internal_onDataAvailable, This, &bsc);
2754c2c66affSColin Finck     IMoniker_Release(mon);
2755c2c66affSColin Finck 
2756c2c66affSColin Finck     if(FAILED(hr))
2757c2c66affSColin Finck         return hr;
2758c2c66affSColin Finck 
2759c2c66affSColin Finck     return detach_bsc(bsc);
2760c2c66affSColin Finck }
2761c2c66affSColin Finck 
saxreader_put_handler_from_variant(saxreader * This,enum saxhandler_type type,const VARIANT * v,BOOL vb)2762c2c66affSColin Finck static HRESULT saxreader_put_handler_from_variant(saxreader *This, enum saxhandler_type type, const VARIANT *v, BOOL vb)
2763c2c66affSColin Finck {
2764c2c66affSColin Finck     const IID *riid;
2765c2c66affSColin Finck 
2766c2c66affSColin Finck     if (V_VT(v) == VT_EMPTY)
2767c2c66affSColin Finck         return saxreader_put_handler(This, type, NULL, vb);
2768c2c66affSColin Finck 
2769c2c66affSColin Finck     switch (type)
2770c2c66affSColin Finck     {
2771c2c66affSColin Finck     case SAXDeclHandler:
2772c2c66affSColin Finck         riid = vb ? &IID_IVBSAXDeclHandler : &IID_ISAXDeclHandler;
2773c2c66affSColin Finck         break;
2774c2c66affSColin Finck     case SAXLexicalHandler:
2775c2c66affSColin Finck         riid = vb ? &IID_IVBSAXLexicalHandler : &IID_ISAXLexicalHandler;
2776c2c66affSColin Finck         break;
2777c2c66affSColin Finck     default:
2778c2c66affSColin Finck         ERR("wrong handler type %d\n", type);
2779c2c66affSColin Finck         return E_FAIL;
2780c2c66affSColin Finck     }
2781c2c66affSColin Finck 
2782c2c66affSColin Finck     switch (V_VT(v))
2783c2c66affSColin Finck     {
2784c2c66affSColin Finck     case VT_DISPATCH:
2785c2c66affSColin Finck     case VT_UNKNOWN:
2786c2c66affSColin Finck     {
2787c2c66affSColin Finck         IUnknown *handler = NULL;
2788c2c66affSColin Finck 
2789c2c66affSColin Finck         if (V_UNKNOWN(v))
2790c2c66affSColin Finck         {
2791c2c66affSColin Finck             HRESULT hr = IUnknown_QueryInterface(V_UNKNOWN(v), riid, (void**)&handler);
2792c2c66affSColin Finck             if (FAILED(hr)) return hr;
2793c2c66affSColin Finck         }
2794c2c66affSColin Finck 
2795c2c66affSColin Finck         saxreader_put_handler(This, type, handler, vb);
2796c2c66affSColin Finck         if (handler) IUnknown_Release(handler);
2797c2c66affSColin Finck         break;
2798c2c66affSColin Finck     }
2799c2c66affSColin Finck     default:
2800c2c66affSColin Finck         ERR("value type %d not supported\n", V_VT(v));
2801c2c66affSColin Finck         return E_INVALIDARG;
2802c2c66affSColin Finck     }
2803c2c66affSColin Finck 
2804c2c66affSColin Finck     return S_OK;
2805c2c66affSColin Finck }
2806c2c66affSColin Finck 
internal_putProperty(saxreader * This,const WCHAR * prop,VARIANT value,BOOL vbInterface)2807c2c66affSColin Finck static HRESULT internal_putProperty(
2808c2c66affSColin Finck     saxreader* This,
2809c2c66affSColin Finck     const WCHAR *prop,
2810c2c66affSColin Finck     VARIANT value,
2811c2c66affSColin Finck     BOOL vbInterface)
2812c2c66affSColin Finck {
2813c2c66affSColin Finck     VARIANT *v;
2814c2c66affSColin Finck 
2815c2c66affSColin Finck     TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
2816c2c66affSColin Finck 
2817c2c66affSColin Finck     if (This->isParsing) return E_FAIL;
2818c2c66affSColin Finck 
2819c2c66affSColin Finck     v = V_VT(&value) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(&value) : &value;
2820c2c66affSColin Finck     if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
2821c2c66affSColin Finck         return saxreader_put_handler_from_variant(This, SAXDeclHandler, v, vbInterface);
2822c2c66affSColin Finck 
2823c2c66affSColin Finck     if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
2824c2c66affSColin Finck         return saxreader_put_handler_from_variant(This, SAXLexicalHandler, v, vbInterface);
2825c2c66affSColin Finck 
2826c2c66affSColin Finck     if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
2827c2c66affSColin Finck     {
2828c2c66affSColin Finck         if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK;
2829c2c66affSColin Finck         FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(v));
2830c2c66affSColin Finck         return E_NOTIMPL;
2831c2c66affSColin Finck     }
2832c2c66affSColin Finck 
2833c2c66affSColin Finck     if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
2834c2c66affSColin Finck     {
2835c2c66affSColin Finck         if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK;
2836c2c66affSColin Finck         FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(v));
2837c2c66affSColin Finck         return E_NOTIMPL;
2838c2c66affSColin Finck     }
2839c2c66affSColin Finck 
2840c2c66affSColin Finck     FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(v));
2841c2c66affSColin Finck 
2842c2c66affSColin Finck     if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
2843c2c66affSColin Finck         return E_NOTIMPL;
2844c2c66affSColin Finck 
2845c2c66affSColin Finck     if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
2846c2c66affSColin Finck         return E_FAIL;
2847c2c66affSColin Finck 
2848c2c66affSColin Finck     if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
2849c2c66affSColin Finck         return E_NOTIMPL;
2850c2c66affSColin Finck 
2851c2c66affSColin Finck     if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
2852c2c66affSColin Finck         return E_NOTIMPL;
2853c2c66affSColin Finck 
2854c2c66affSColin Finck     if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
2855c2c66affSColin Finck         return E_FAIL;
2856c2c66affSColin Finck 
2857c2c66affSColin Finck     if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
2858c2c66affSColin Finck         return E_FAIL;
2859c2c66affSColin Finck 
2860c2c66affSColin Finck     if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
2861c2c66affSColin Finck         return E_FAIL;
2862c2c66affSColin Finck 
2863c2c66affSColin Finck     return E_INVALIDARG;
2864c2c66affSColin Finck }
2865c2c66affSColin Finck 
internal_getProperty(const saxreader * This,const WCHAR * prop,VARIANT * value,BOOL vb)2866c2c66affSColin Finck static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
2867c2c66affSColin Finck {
2868c2c66affSColin Finck     TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
2869c2c66affSColin Finck 
2870c2c66affSColin Finck     if (!value) return E_POINTER;
2871c2c66affSColin Finck 
2872c2c66affSColin Finck     if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
2873c2c66affSColin Finck     {
2874c2c66affSColin Finck         V_VT(value) = VT_UNKNOWN;
2875c2c66affSColin Finck         saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value));
2876c2c66affSColin Finck         return S_OK;
2877c2c66affSColin Finck     }
2878c2c66affSColin Finck 
2879c2c66affSColin Finck     if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
2880c2c66affSColin Finck     {
2881c2c66affSColin Finck         V_VT(value) = VT_UNKNOWN;
2882c2c66affSColin Finck         saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value));
2883c2c66affSColin Finck         return S_OK;
2884c2c66affSColin Finck     }
2885c2c66affSColin Finck 
2886c2c66affSColin Finck     if (!memcmp(PropertyXmlDeclVersionW, prop, sizeof(PropertyXmlDeclVersionW)))
2887c2c66affSColin Finck     {
2888c2c66affSColin Finck         V_VT(value) = VT_BSTR;
2889c2c66affSColin Finck         V_BSTR(value) = SysAllocString(This->xmldecl_version);
2890c2c66affSColin Finck         return S_OK;
2891c2c66affSColin Finck     }
2892c2c66affSColin Finck 
2893c2c66affSColin Finck     FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
2894c2c66affSColin Finck 
2895c2c66affSColin Finck     return E_NOTIMPL;
2896c2c66affSColin Finck }
2897c2c66affSColin Finck 
2898c2c66affSColin Finck /*** IVBSAXXMLReader interface ***/
2899c2c66affSColin Finck /*** IUnknown methods ***/
saxxmlreader_QueryInterface(IVBSAXXMLReader * iface,REFIID riid,void ** ppvObject)2900c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2901c2c66affSColin Finck {
2902c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
2903c2c66affSColin Finck 
2904c2c66affSColin Finck     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2905c2c66affSColin Finck 
2906c2c66affSColin Finck     *ppvObject = NULL;
2907c2c66affSColin Finck 
2908c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2909c2c66affSColin Finck          IsEqualGUID( riid, &IID_IDispatch ) ||
2910c2c66affSColin Finck          IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2911c2c66affSColin Finck     {
2912c2c66affSColin Finck         *ppvObject = iface;
2913c2c66affSColin Finck     }
2914c2c66affSColin Finck     else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2915c2c66affSColin Finck     {
2916c2c66affSColin Finck         *ppvObject = &This->ISAXXMLReader_iface;
2917c2c66affSColin Finck     }
2918c2c66affSColin Finck     else if (dispex_query_interface(&This->dispex, riid, ppvObject))
2919c2c66affSColin Finck     {
2920c2c66affSColin Finck         return *ppvObject ? S_OK : E_NOINTERFACE;
2921c2c66affSColin Finck     }
2922c2c66affSColin Finck     else
2923c2c66affSColin Finck     {
2924c2c66affSColin Finck         FIXME("interface %s not implemented\n", debugstr_guid(riid));
2925c2c66affSColin Finck         return E_NOINTERFACE;
2926c2c66affSColin Finck     }
2927c2c66affSColin Finck 
2928c2c66affSColin Finck     IVBSAXXMLReader_AddRef( iface );
2929c2c66affSColin Finck 
2930c2c66affSColin Finck     return S_OK;
2931c2c66affSColin Finck }
2932c2c66affSColin Finck 
saxxmlreader_AddRef(IVBSAXXMLReader * iface)2933c2c66affSColin Finck static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2934c2c66affSColin Finck {
2935c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
2936c2c66affSColin Finck     TRACE("%p\n", This );
2937c2c66affSColin Finck     return InterlockedIncrement( &This->ref );
2938c2c66affSColin Finck }
2939c2c66affSColin Finck 
saxxmlreader_Release(IVBSAXXMLReader * iface)2940c2c66affSColin Finck static ULONG WINAPI saxxmlreader_Release(
2941c2c66affSColin Finck     IVBSAXXMLReader* iface)
2942c2c66affSColin Finck {
2943c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
2944c2c66affSColin Finck     LONG ref;
2945c2c66affSColin Finck 
2946c2c66affSColin Finck     TRACE("%p\n", This );
2947c2c66affSColin Finck 
2948c2c66affSColin Finck     ref = InterlockedDecrement( &This->ref );
2949c2c66affSColin Finck     if ( ref == 0 )
2950c2c66affSColin Finck     {
2951c2c66affSColin Finck         int i;
2952c2c66affSColin Finck 
2953c2c66affSColin Finck         for (i = 0; i < SAXHandler_Last; i++)
2954c2c66affSColin Finck         {
2955c2c66affSColin Finck             struct saxanyhandler_iface *saxiface = &This->saxhandlers[i].u.anyhandler;
2956c2c66affSColin Finck 
2957c2c66affSColin Finck             if (saxiface->handler)
2958c2c66affSColin Finck                 IUnknown_Release(saxiface->handler);
2959c2c66affSColin Finck 
2960c2c66affSColin Finck             if (saxiface->vbhandler)
2961c2c66affSColin Finck                 IUnknown_Release(saxiface->vbhandler);
2962c2c66affSColin Finck         }
2963c2c66affSColin Finck 
2964c2c66affSColin Finck         SysFreeString(This->xmldecl_version);
2965c2c66affSColin Finck         free_bstr_pool(&This->pool);
2966c2c66affSColin Finck 
2967c2c66affSColin Finck         heap_free( This );
2968c2c66affSColin Finck     }
2969c2c66affSColin Finck 
2970c2c66affSColin Finck     return ref;
2971c2c66affSColin Finck }
2972c2c66affSColin Finck /*** IDispatch ***/
saxxmlreader_GetTypeInfoCount(IVBSAXXMLReader * iface,UINT * pctinfo)2973c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2974c2c66affSColin Finck {
2975c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
2976c2c66affSColin Finck     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2977c2c66affSColin Finck }
2978c2c66affSColin Finck 
saxxmlreader_GetTypeInfo(IVBSAXXMLReader * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2979c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2980c2c66affSColin Finck     IVBSAXXMLReader *iface,
2981c2c66affSColin Finck     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2982c2c66affSColin Finck {
2983c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
2984c2c66affSColin Finck     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
2985c2c66affSColin Finck         iTInfo, lcid, ppTInfo);
2986c2c66affSColin Finck }
2987c2c66affSColin Finck 
saxxmlreader_GetIDsOfNames(IVBSAXXMLReader * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2988c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2989c2c66affSColin Finck     IVBSAXXMLReader *iface,
2990c2c66affSColin Finck     REFIID riid,
2991c2c66affSColin Finck     LPOLESTR* rgszNames,
2992c2c66affSColin Finck     UINT cNames,
2993c2c66affSColin Finck     LCID lcid,
2994c2c66affSColin Finck     DISPID* rgDispId)
2995c2c66affSColin Finck {
2996c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
2997c2c66affSColin Finck     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2998c2c66affSColin Finck         riid, rgszNames, cNames, lcid, rgDispId);
2999c2c66affSColin Finck }
3000c2c66affSColin Finck 
saxxmlreader_Invoke(IVBSAXXMLReader * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)3001c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_Invoke(
3002c2c66affSColin Finck     IVBSAXXMLReader *iface,
3003c2c66affSColin Finck     DISPID dispIdMember,
3004c2c66affSColin Finck     REFIID riid,
3005c2c66affSColin Finck     LCID lcid,
3006c2c66affSColin Finck     WORD wFlags,
3007c2c66affSColin Finck     DISPPARAMS* pDispParams,
3008c2c66affSColin Finck     VARIANT* pVarResult,
3009c2c66affSColin Finck     EXCEPINFO* pExcepInfo,
3010c2c66affSColin Finck     UINT* puArgErr)
3011c2c66affSColin Finck {
3012c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3013c2c66affSColin Finck     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
3014c2c66affSColin Finck         dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3015c2c66affSColin Finck }
3016c2c66affSColin Finck 
3017c2c66affSColin Finck /*** IVBSAXXMLReader methods ***/
saxxmlreader_getFeature(IVBSAXXMLReader * iface,BSTR feature_name,VARIANT_BOOL * value)3018c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_getFeature(
3019c2c66affSColin Finck     IVBSAXXMLReader* iface,
3020c2c66affSColin Finck     BSTR feature_name,
3021c2c66affSColin Finck     VARIANT_BOOL *value)
3022c2c66affSColin Finck {
3023c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3024c2c66affSColin Finck     return ISAXXMLReader_getFeature(&This->ISAXXMLReader_iface, feature_name, value);
3025c2c66affSColin Finck }
3026c2c66affSColin Finck 
saxxmlreader_putFeature(IVBSAXXMLReader * iface,BSTR feature_name,VARIANT_BOOL value)3027c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_putFeature(
3028c2c66affSColin Finck     IVBSAXXMLReader* iface,
3029c2c66affSColin Finck     BSTR feature_name,
3030c2c66affSColin Finck     VARIANT_BOOL value)
3031c2c66affSColin Finck {
3032c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3033c2c66affSColin Finck     return ISAXXMLReader_putFeature(&This->ISAXXMLReader_iface, feature_name, value);
3034c2c66affSColin Finck }
3035c2c66affSColin Finck 
saxxmlreader_getProperty(IVBSAXXMLReader * iface,BSTR prop,VARIANT * value)3036c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_getProperty(
3037c2c66affSColin Finck     IVBSAXXMLReader* iface,
3038c2c66affSColin Finck     BSTR prop,
3039c2c66affSColin Finck     VARIANT *value)
3040c2c66affSColin Finck {
3041c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3042c2c66affSColin Finck     return internal_getProperty(This, prop, value, TRUE);
3043c2c66affSColin Finck }
3044c2c66affSColin Finck 
saxxmlreader_putProperty(IVBSAXXMLReader * iface,BSTR pProp,VARIANT value)3045c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_putProperty(
3046c2c66affSColin Finck     IVBSAXXMLReader* iface,
3047c2c66affSColin Finck     BSTR pProp,
3048c2c66affSColin Finck     VARIANT value)
3049c2c66affSColin Finck {
3050c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3051c2c66affSColin Finck     return internal_putProperty(This, pProp, value, TRUE);
3052c2c66affSColin Finck }
3053c2c66affSColin Finck 
saxxmlreader_get_entityResolver(IVBSAXXMLReader * iface,IVBSAXEntityResolver ** resolver)3054c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_get_entityResolver(
3055c2c66affSColin Finck     IVBSAXXMLReader* iface,
3056c2c66affSColin Finck     IVBSAXEntityResolver **resolver)
3057c2c66affSColin Finck {
3058c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3059c2c66affSColin Finck     return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver);
3060c2c66affSColin Finck }
3061c2c66affSColin Finck 
saxxmlreader_put_entityResolver(IVBSAXXMLReader * iface,IVBSAXEntityResolver * resolver)3062c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_put_entityResolver(
3063c2c66affSColin Finck     IVBSAXXMLReader* iface,
3064c2c66affSColin Finck     IVBSAXEntityResolver *resolver)
3065c2c66affSColin Finck {
3066c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3067c2c66affSColin Finck     return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE);
3068c2c66affSColin Finck }
3069c2c66affSColin Finck 
saxxmlreader_get_contentHandler(IVBSAXXMLReader * iface,IVBSAXContentHandler ** handler)3070c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_get_contentHandler(
3071c2c66affSColin Finck     IVBSAXXMLReader* iface,
3072c2c66affSColin Finck     IVBSAXContentHandler **handler)
3073c2c66affSColin Finck {
3074c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3075c2c66affSColin Finck     return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler);
3076c2c66affSColin Finck }
3077c2c66affSColin Finck 
saxxmlreader_put_contentHandler(IVBSAXXMLReader * iface,IVBSAXContentHandler * handler)3078c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_put_contentHandler(
3079c2c66affSColin Finck     IVBSAXXMLReader* iface,
3080c2c66affSColin Finck     IVBSAXContentHandler *handler)
3081c2c66affSColin Finck {
3082c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3083c2c66affSColin Finck     return saxreader_put_handler(This, SAXContentHandler, handler, TRUE);
3084c2c66affSColin Finck }
3085c2c66affSColin Finck 
saxxmlreader_get_dtdHandler(IVBSAXXMLReader * iface,IVBSAXDTDHandler ** handler)3086c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_get_dtdHandler(
3087c2c66affSColin Finck     IVBSAXXMLReader* iface,
3088c2c66affSColin Finck     IVBSAXDTDHandler **handler)
3089c2c66affSColin Finck {
3090c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3091c2c66affSColin Finck     return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler);
3092c2c66affSColin Finck }
3093c2c66affSColin Finck 
saxxmlreader_put_dtdHandler(IVBSAXXMLReader * iface,IVBSAXDTDHandler * handler)3094c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_put_dtdHandler(
3095c2c66affSColin Finck     IVBSAXXMLReader* iface,
3096c2c66affSColin Finck     IVBSAXDTDHandler *handler)
3097c2c66affSColin Finck {
3098c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3099c2c66affSColin Finck     return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE);
3100c2c66affSColin Finck }
3101c2c66affSColin Finck 
saxxmlreader_get_errorHandler(IVBSAXXMLReader * iface,IVBSAXErrorHandler ** handler)3102c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_get_errorHandler(
3103c2c66affSColin Finck     IVBSAXXMLReader* iface,
3104c2c66affSColin Finck     IVBSAXErrorHandler **handler)
3105c2c66affSColin Finck {
3106c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3107c2c66affSColin Finck     return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler);
3108c2c66affSColin Finck }
3109c2c66affSColin Finck 
saxxmlreader_put_errorHandler(IVBSAXXMLReader * iface,IVBSAXErrorHandler * handler)3110c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_put_errorHandler(
3111c2c66affSColin Finck     IVBSAXXMLReader* iface,
3112c2c66affSColin Finck     IVBSAXErrorHandler *handler)
3113c2c66affSColin Finck {
3114c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3115c2c66affSColin Finck     return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE);
3116c2c66affSColin Finck }
3117c2c66affSColin Finck 
saxxmlreader_get_baseURL(IVBSAXXMLReader * iface,BSTR * pBaseUrl)3118c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_get_baseURL(
3119c2c66affSColin Finck     IVBSAXXMLReader* iface,
3120c2c66affSColin Finck     BSTR *pBaseUrl)
3121c2c66affSColin Finck {
3122c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3123c2c66affSColin Finck 
3124c2c66affSColin Finck     FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
3125c2c66affSColin Finck     return E_NOTIMPL;
3126c2c66affSColin Finck }
3127c2c66affSColin Finck 
saxxmlreader_put_baseURL(IVBSAXXMLReader * iface,BSTR pBaseUrl)3128c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_put_baseURL(
3129c2c66affSColin Finck     IVBSAXXMLReader* iface,
3130c2c66affSColin Finck     BSTR pBaseUrl)
3131c2c66affSColin Finck {
3132c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3133c2c66affSColin Finck     return ISAXXMLReader_putBaseURL(&This->ISAXXMLReader_iface, pBaseUrl);
3134c2c66affSColin Finck }
3135c2c66affSColin Finck 
saxxmlreader_get_secureBaseURL(IVBSAXXMLReader * iface,BSTR * pSecureBaseUrl)3136c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
3137c2c66affSColin Finck     IVBSAXXMLReader* iface,
3138c2c66affSColin Finck     BSTR *pSecureBaseUrl)
3139c2c66affSColin Finck {
3140c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3141c2c66affSColin Finck 
3142c2c66affSColin Finck     FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
3143c2c66affSColin Finck     return E_NOTIMPL;
3144c2c66affSColin Finck }
3145c2c66affSColin Finck 
saxxmlreader_put_secureBaseURL(IVBSAXXMLReader * iface,BSTR secureBaseUrl)3146c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
3147c2c66affSColin Finck     IVBSAXXMLReader* iface,
3148c2c66affSColin Finck     BSTR secureBaseUrl)
3149c2c66affSColin Finck {
3150c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3151c2c66affSColin Finck     return ISAXXMLReader_putSecureBaseURL(&This->ISAXXMLReader_iface, secureBaseUrl);
3152c2c66affSColin Finck }
3153c2c66affSColin Finck 
saxxmlreader_parse(IVBSAXXMLReader * iface,VARIANT varInput)3154c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_parse(
3155c2c66affSColin Finck     IVBSAXXMLReader* iface,
3156c2c66affSColin Finck     VARIANT varInput)
3157c2c66affSColin Finck {
3158c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3159c2c66affSColin Finck     return internal_parse(This, varInput, TRUE);
3160c2c66affSColin Finck }
3161c2c66affSColin Finck 
saxxmlreader_parseURL(IVBSAXXMLReader * iface,BSTR url)3162c2c66affSColin Finck static HRESULT WINAPI saxxmlreader_parseURL(
3163c2c66affSColin Finck     IVBSAXXMLReader* iface,
3164c2c66affSColin Finck     BSTR url)
3165c2c66affSColin Finck {
3166c2c66affSColin Finck     saxreader *This = impl_from_IVBSAXXMLReader( iface );
3167c2c66affSColin Finck     return internal_parseURL(This, url, TRUE);
3168c2c66affSColin Finck }
3169c2c66affSColin Finck 
3170c2c66affSColin Finck static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl =
3171c2c66affSColin Finck {
3172c2c66affSColin Finck     saxxmlreader_QueryInterface,
3173c2c66affSColin Finck     saxxmlreader_AddRef,
3174c2c66affSColin Finck     saxxmlreader_Release,
3175c2c66affSColin Finck     saxxmlreader_GetTypeInfoCount,
3176c2c66affSColin Finck     saxxmlreader_GetTypeInfo,
3177c2c66affSColin Finck     saxxmlreader_GetIDsOfNames,
3178c2c66affSColin Finck     saxxmlreader_Invoke,
3179c2c66affSColin Finck     saxxmlreader_getFeature,
3180c2c66affSColin Finck     saxxmlreader_putFeature,
3181c2c66affSColin Finck     saxxmlreader_getProperty,
3182c2c66affSColin Finck     saxxmlreader_putProperty,
3183c2c66affSColin Finck     saxxmlreader_get_entityResolver,
3184c2c66affSColin Finck     saxxmlreader_put_entityResolver,
3185c2c66affSColin Finck     saxxmlreader_get_contentHandler,
3186c2c66affSColin Finck     saxxmlreader_put_contentHandler,
3187c2c66affSColin Finck     saxxmlreader_get_dtdHandler,
3188c2c66affSColin Finck     saxxmlreader_put_dtdHandler,
3189c2c66affSColin Finck     saxxmlreader_get_errorHandler,
3190c2c66affSColin Finck     saxxmlreader_put_errorHandler,
3191c2c66affSColin Finck     saxxmlreader_get_baseURL,
3192c2c66affSColin Finck     saxxmlreader_put_baseURL,
3193c2c66affSColin Finck     saxxmlreader_get_secureBaseURL,
3194c2c66affSColin Finck     saxxmlreader_put_secureBaseURL,
3195c2c66affSColin Finck     saxxmlreader_parse,
3196c2c66affSColin Finck     saxxmlreader_parseURL
3197c2c66affSColin Finck };
3198c2c66affSColin Finck 
3199c2c66affSColin Finck /*** ISAXXMLReader interface ***/
3200c2c66affSColin Finck /*** IUnknown methods ***/
isaxxmlreader_QueryInterface(ISAXXMLReader * iface,REFIID riid,void ** ppvObject)3201c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
3202c2c66affSColin Finck {
3203c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3204c2c66affSColin Finck     return IVBSAXXMLReader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
3205c2c66affSColin Finck }
3206c2c66affSColin Finck 
isaxxmlreader_AddRef(ISAXXMLReader * iface)3207c2c66affSColin Finck static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
3208c2c66affSColin Finck {
3209c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3210c2c66affSColin Finck     return IVBSAXXMLReader_AddRef(&This->IVBSAXXMLReader_iface);
3211c2c66affSColin Finck }
3212c2c66affSColin Finck 
isaxxmlreader_Release(ISAXXMLReader * iface)3213c2c66affSColin Finck static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
3214c2c66affSColin Finck {
3215c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3216c2c66affSColin Finck     return IVBSAXXMLReader_Release(&This->IVBSAXXMLReader_iface);
3217c2c66affSColin Finck }
3218c2c66affSColin Finck 
3219c2c66affSColin Finck /*** ISAXXMLReader methods ***/
isaxxmlreader_getFeature(ISAXXMLReader * iface,const WCHAR * feature_name,VARIANT_BOOL * value)3220c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getFeature(
3221c2c66affSColin Finck         ISAXXMLReader* iface,
3222c2c66affSColin Finck         const WCHAR *feature_name,
3223c2c66affSColin Finck         VARIANT_BOOL *value)
3224c2c66affSColin Finck {
3225c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3226c2c66affSColin Finck     saxreader_feature feature;
3227c2c66affSColin Finck 
3228c2c66affSColin Finck     TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
3229c2c66affSColin Finck 
3230c2c66affSColin Finck     feature = get_saxreader_feature(feature_name);
3231bab6b90fSAmine Khaldi 
3232bab6b90fSAmine Khaldi     if (This->version < MSXML4 && (feature == ExhaustiveErrors || feature == SchemaValidation))
3233bab6b90fSAmine Khaldi         return E_INVALIDARG;
3234bab6b90fSAmine Khaldi 
3235bab6b90fSAmine Khaldi     if (feature == Namespaces ||
3236bab6b90fSAmine Khaldi             feature == NamespacePrefixes ||
3237bab6b90fSAmine Khaldi             feature == ExhaustiveErrors ||
3238bab6b90fSAmine Khaldi             feature == SchemaValidation)
3239c2c66affSColin Finck         return get_feature_value(This, feature, value);
3240c2c66affSColin Finck 
3241c2c66affSColin Finck     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
3242c2c66affSColin Finck     return E_NOTIMPL;
3243c2c66affSColin Finck }
3244c2c66affSColin Finck 
isaxxmlreader_putFeature(ISAXXMLReader * iface,const WCHAR * feature_name,VARIANT_BOOL value)3245c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putFeature(
3246c2c66affSColin Finck         ISAXXMLReader* iface,
3247c2c66affSColin Finck         const WCHAR *feature_name,
3248c2c66affSColin Finck         VARIANT_BOOL value)
3249c2c66affSColin Finck {
3250c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3251c2c66affSColin Finck     saxreader_feature feature;
3252c2c66affSColin Finck 
3253c2c66affSColin Finck     TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
3254c2c66affSColin Finck 
3255c2c66affSColin Finck     feature = get_saxreader_feature(feature_name);
3256c2c66affSColin Finck 
3257c2c66affSColin Finck     /* accepted cases */
3258bab6b90fSAmine Khaldi     if ((feature == ExhaustiveErrors && value == VARIANT_FALSE) ||
3259bab6b90fSAmine Khaldi         (feature == SchemaValidation && value == VARIANT_FALSE) ||
3260c2c66affSColin Finck          feature == Namespaces ||
3261c2c66affSColin Finck          feature == NamespacePrefixes)
3262c2c66affSColin Finck     {
3263c2c66affSColin Finck         return set_feature_value(This, feature, value);
3264c2c66affSColin Finck     }
3265c2c66affSColin Finck 
3266bab6b90fSAmine Khaldi     if (feature == LexicalHandlerParEntities ||
3267bab6b90fSAmine Khaldi             feature == ProhibitDTD ||
3268bab6b90fSAmine Khaldi             feature == ExternalGeneralEntities ||
3269bab6b90fSAmine Khaldi             feature == ExternalParameterEntities)
3270c2c66affSColin Finck     {
3271c2c66affSColin Finck         FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
3272c2c66affSColin Finck         return set_feature_value(This, feature, value);
3273c2c66affSColin Finck     }
3274c2c66affSColin Finck 
3275c2c66affSColin Finck     FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
3276c2c66affSColin Finck     return E_NOTIMPL;
3277c2c66affSColin Finck }
3278c2c66affSColin Finck 
isaxxmlreader_getProperty(ISAXXMLReader * iface,const WCHAR * prop,VARIANT * value)3279c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getProperty(
3280c2c66affSColin Finck         ISAXXMLReader* iface,
3281c2c66affSColin Finck         const WCHAR *prop,
3282c2c66affSColin Finck         VARIANT *value)
3283c2c66affSColin Finck {
3284c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3285c2c66affSColin Finck     return internal_getProperty(This, prop, value, FALSE);
3286c2c66affSColin Finck }
3287c2c66affSColin Finck 
isaxxmlreader_putProperty(ISAXXMLReader * iface,const WCHAR * pProp,VARIANT value)3288c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putProperty(
3289c2c66affSColin Finck         ISAXXMLReader* iface,
3290c2c66affSColin Finck         const WCHAR *pProp,
3291c2c66affSColin Finck         VARIANT value)
3292c2c66affSColin Finck {
3293c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3294c2c66affSColin Finck     return internal_putProperty(This, pProp, value, FALSE);
3295c2c66affSColin Finck }
3296c2c66affSColin Finck 
isaxxmlreader_getEntityResolver(ISAXXMLReader * iface,ISAXEntityResolver ** resolver)3297c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getEntityResolver(
3298c2c66affSColin Finck         ISAXXMLReader* iface,
3299c2c66affSColin Finck         ISAXEntityResolver **resolver)
3300c2c66affSColin Finck {
3301c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3302c2c66affSColin Finck     return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver);
3303c2c66affSColin Finck }
3304c2c66affSColin Finck 
isaxxmlreader_putEntityResolver(ISAXXMLReader * iface,ISAXEntityResolver * resolver)3305c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putEntityResolver(
3306c2c66affSColin Finck         ISAXXMLReader* iface,
3307c2c66affSColin Finck         ISAXEntityResolver *resolver)
3308c2c66affSColin Finck {
3309c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3310c2c66affSColin Finck     return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE);
3311c2c66affSColin Finck }
3312c2c66affSColin Finck 
isaxxmlreader_getContentHandler(ISAXXMLReader * iface,ISAXContentHandler ** handler)3313c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getContentHandler(
3314c2c66affSColin Finck         ISAXXMLReader* iface,
3315c2c66affSColin Finck         ISAXContentHandler **handler)
3316c2c66affSColin Finck {
3317c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3318c2c66affSColin Finck     return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler);
3319c2c66affSColin Finck }
3320c2c66affSColin Finck 
isaxxmlreader_putContentHandler(ISAXXMLReader * iface,ISAXContentHandler * handler)3321c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putContentHandler(
3322c2c66affSColin Finck     ISAXXMLReader* iface,
3323c2c66affSColin Finck     ISAXContentHandler *handler)
3324c2c66affSColin Finck {
3325c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3326c2c66affSColin Finck     return saxreader_put_handler(This, SAXContentHandler, handler, FALSE);
3327c2c66affSColin Finck }
3328c2c66affSColin Finck 
isaxxmlreader_getDTDHandler(ISAXXMLReader * iface,ISAXDTDHandler ** handler)3329c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getDTDHandler(
3330c2c66affSColin Finck         ISAXXMLReader* iface,
3331c2c66affSColin Finck         ISAXDTDHandler **handler)
3332c2c66affSColin Finck {
3333c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3334c2c66affSColin Finck     return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler);
3335c2c66affSColin Finck }
3336c2c66affSColin Finck 
isaxxmlreader_putDTDHandler(ISAXXMLReader * iface,ISAXDTDHandler * handler)3337c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putDTDHandler(
3338c2c66affSColin Finck         ISAXXMLReader* iface,
3339c2c66affSColin Finck         ISAXDTDHandler *handler)
3340c2c66affSColin Finck {
3341c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3342c2c66affSColin Finck     return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE);
3343c2c66affSColin Finck }
3344c2c66affSColin Finck 
isaxxmlreader_getErrorHandler(ISAXXMLReader * iface,ISAXErrorHandler ** handler)3345c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getErrorHandler(
3346c2c66affSColin Finck         ISAXXMLReader* iface,
3347c2c66affSColin Finck         ISAXErrorHandler **handler)
3348c2c66affSColin Finck {
3349c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3350c2c66affSColin Finck     return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler);
3351c2c66affSColin Finck }
3352c2c66affSColin Finck 
isaxxmlreader_putErrorHandler(ISAXXMLReader * iface,ISAXErrorHandler * handler)3353c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler)
3354c2c66affSColin Finck {
3355c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3356c2c66affSColin Finck     return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE);
3357c2c66affSColin Finck }
3358c2c66affSColin Finck 
isaxxmlreader_getBaseURL(ISAXXMLReader * iface,const WCHAR ** base_url)3359c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getBaseURL(
3360c2c66affSColin Finck         ISAXXMLReader* iface,
3361c2c66affSColin Finck         const WCHAR **base_url)
3362c2c66affSColin Finck {
3363c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3364c2c66affSColin Finck 
3365c2c66affSColin Finck     FIXME("(%p)->(%p) stub\n", This, base_url);
3366c2c66affSColin Finck     return E_NOTIMPL;
3367c2c66affSColin Finck }
3368c2c66affSColin Finck 
isaxxmlreader_putBaseURL(ISAXXMLReader * iface,const WCHAR * pBaseUrl)3369c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putBaseURL(
3370c2c66affSColin Finck         ISAXXMLReader* iface,
3371c2c66affSColin Finck         const WCHAR *pBaseUrl)
3372c2c66affSColin Finck {
3373c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3374c2c66affSColin Finck 
3375c2c66affSColin Finck     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
3376c2c66affSColin Finck     return E_NOTIMPL;
3377c2c66affSColin Finck }
3378c2c66affSColin Finck 
isaxxmlreader_getSecureBaseURL(ISAXXMLReader * iface,const WCHAR ** pSecureBaseUrl)3379c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
3380c2c66affSColin Finck         ISAXXMLReader* iface,
3381c2c66affSColin Finck         const WCHAR **pSecureBaseUrl)
3382c2c66affSColin Finck {
3383c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3384c2c66affSColin Finck     FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
3385c2c66affSColin Finck     return E_NOTIMPL;
3386c2c66affSColin Finck }
3387c2c66affSColin Finck 
isaxxmlreader_putSecureBaseURL(ISAXXMLReader * iface,const WCHAR * secureBaseUrl)3388c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
3389c2c66affSColin Finck         ISAXXMLReader* iface,
3390c2c66affSColin Finck         const WCHAR *secureBaseUrl)
3391c2c66affSColin Finck {
3392c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3393c2c66affSColin Finck 
3394c2c66affSColin Finck     FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
3395c2c66affSColin Finck     return E_NOTIMPL;
3396c2c66affSColin Finck }
3397c2c66affSColin Finck 
isaxxmlreader_parse(ISAXXMLReader * iface,VARIANT varInput)3398c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_parse(
3399c2c66affSColin Finck         ISAXXMLReader* iface,
3400c2c66affSColin Finck         VARIANT varInput)
3401c2c66affSColin Finck {
3402c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3403c2c66affSColin Finck     return internal_parse(This, varInput, FALSE);
3404c2c66affSColin Finck }
3405c2c66affSColin Finck 
isaxxmlreader_parseURL(ISAXXMLReader * iface,const WCHAR * url)3406c2c66affSColin Finck static HRESULT WINAPI isaxxmlreader_parseURL(
3407c2c66affSColin Finck         ISAXXMLReader* iface,
3408c2c66affSColin Finck         const WCHAR *url)
3409c2c66affSColin Finck {
3410c2c66affSColin Finck     saxreader *This = impl_from_ISAXXMLReader( iface );
3411c2c66affSColin Finck     return internal_parseURL(This, url, FALSE);
3412c2c66affSColin Finck }
3413c2c66affSColin Finck 
3414c2c66affSColin Finck static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl =
3415c2c66affSColin Finck {
3416c2c66affSColin Finck     isaxxmlreader_QueryInterface,
3417c2c66affSColin Finck     isaxxmlreader_AddRef,
3418c2c66affSColin Finck     isaxxmlreader_Release,
3419c2c66affSColin Finck     isaxxmlreader_getFeature,
3420c2c66affSColin Finck     isaxxmlreader_putFeature,
3421c2c66affSColin Finck     isaxxmlreader_getProperty,
3422c2c66affSColin Finck     isaxxmlreader_putProperty,
3423c2c66affSColin Finck     isaxxmlreader_getEntityResolver,
3424c2c66affSColin Finck     isaxxmlreader_putEntityResolver,
3425c2c66affSColin Finck     isaxxmlreader_getContentHandler,
3426c2c66affSColin Finck     isaxxmlreader_putContentHandler,
3427c2c66affSColin Finck     isaxxmlreader_getDTDHandler,
3428c2c66affSColin Finck     isaxxmlreader_putDTDHandler,
3429c2c66affSColin Finck     isaxxmlreader_getErrorHandler,
3430c2c66affSColin Finck     isaxxmlreader_putErrorHandler,
3431c2c66affSColin Finck     isaxxmlreader_getBaseURL,
3432c2c66affSColin Finck     isaxxmlreader_putBaseURL,
3433c2c66affSColin Finck     isaxxmlreader_getSecureBaseURL,
3434c2c66affSColin Finck     isaxxmlreader_putSecureBaseURL,
3435c2c66affSColin Finck     isaxxmlreader_parse,
3436c2c66affSColin Finck     isaxxmlreader_parseURL
3437c2c66affSColin Finck };
3438c2c66affSColin Finck 
3439c2c66affSColin Finck static const tid_t saxreader_iface_tids[] = {
3440c2c66affSColin Finck     IVBSAXXMLReader_tid,
3441c2c66affSColin Finck     0
3442c2c66affSColin Finck };
3443c2c66affSColin Finck static dispex_static_data_t saxreader_dispex = {
3444c2c66affSColin Finck     NULL,
3445c2c66affSColin Finck     IVBSAXXMLReader_tid,
3446c2c66affSColin Finck     NULL,
3447c2c66affSColin Finck     saxreader_iface_tids
3448c2c66affSColin Finck };
3449c2c66affSColin Finck 
SAXXMLReader_create(MSXML_VERSION version,LPVOID * ppObj)3450c2c66affSColin Finck HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj)
3451c2c66affSColin Finck {
3452c2c66affSColin Finck     saxreader *reader;
3453c2c66affSColin Finck 
3454c2c66affSColin Finck     TRACE("(%p)\n", ppObj);
3455c2c66affSColin Finck 
3456c2c66affSColin Finck     reader = heap_alloc( sizeof (*reader) );
3457c2c66affSColin Finck     if( !reader )
3458c2c66affSColin Finck         return E_OUTOFMEMORY;
3459c2c66affSColin Finck 
3460c2c66affSColin Finck     reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl;
3461c2c66affSColin Finck     reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl;
3462c2c66affSColin Finck     reader->ref = 1;
3463c2c66affSColin Finck     memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers));
3464c2c66affSColin Finck     reader->isParsing = FALSE;
3465c2c66affSColin Finck     reader->xmldecl_version = NULL;
3466c2c66affSColin Finck     reader->pool.pool = NULL;
3467c2c66affSColin Finck     reader->pool.index = 0;
3468c2c66affSColin Finck     reader->pool.len = 0;
3469c2c66affSColin Finck     reader->features = Namespaces | NamespacePrefixes;
3470c2c66affSColin Finck     reader->version = version;
3471c2c66affSColin Finck 
3472c2c66affSColin Finck     init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
3473c2c66affSColin Finck 
3474c2c66affSColin Finck     memset(&reader->sax, 0, sizeof(xmlSAXHandler));
3475c2c66affSColin Finck     reader->sax.initialized = XML_SAX2_MAGIC;
3476c2c66affSColin Finck     reader->sax.startDocument = libxmlStartDocument;
3477c2c66affSColin Finck     reader->sax.endDocument = libxmlEndDocument;
3478c2c66affSColin Finck     reader->sax.startElementNs = libxmlStartElementNS;
3479c2c66affSColin Finck     reader->sax.endElementNs = libxmlEndElementNS;
3480c2c66affSColin Finck     reader->sax.characters = libxmlCharacters;
3481c2c66affSColin Finck     reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
3482c2c66affSColin Finck     reader->sax.comment = libxmlComment;
3483c2c66affSColin Finck     reader->sax.error = libxmlFatalError;
3484c2c66affSColin Finck     reader->sax.fatalError = libxmlFatalError;
3485c2c66affSColin Finck     reader->sax.cdataBlock = libxml_cdatablock;
3486c2c66affSColin Finck     reader->sax.resolveEntity = libxmlresolveentity;
3487c2c66affSColin Finck 
3488c2c66affSColin Finck     *ppObj = &reader->IVBSAXXMLReader_iface;
3489c2c66affSColin Finck 
3490c2c66affSColin Finck     TRACE("returning iface %p\n", *ppObj);
3491c2c66affSColin Finck 
3492c2c66affSColin Finck     return S_OK;
3493c2c66affSColin Finck }
3494c2c66affSColin Finck 
3495c2c66affSColin Finck #else
3496c2c66affSColin Finck 
SAXXMLReader_create(MSXML_VERSION version,LPVOID * ppObj)3497c2c66affSColin Finck HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj)
3498c2c66affSColin Finck {
3499c2c66affSColin Finck     MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3500c2c66affSColin Finck             "libxml2 support was not present at compile time.\n");
3501c2c66affSColin Finck     return E_NOTIMPL;
3502c2c66affSColin Finck }
3503c2c66affSColin Finck 
3504c2c66affSColin Finck #endif
3505