2 * IXmlReader implementation
4 * Copyright 2010 Nikolay Sivov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(xmllite
);
34 /* not defined in public headers */
35 DEFINE_GUID(IID_IXmlReaderInput
, 0x0b3ccc9b, 0x9214, 0x428b, 0xa2, 0xae, 0xef, 0x3a, 0xa8, 0x71, 0xaf, 0xda);
37 static HRESULT
xmlreaderinput_query_for_stream(IXmlReaderInput
*iface
, void **pObj
);
39 typedef struct _xmlreader
41 IXmlReader IXmlReader_iface
;
43 IXmlReaderInput
*input
;
44 ISequentialStream
*stream
;/* stored as sequential stream, cause currently
45 optimizations possible with IStream aren't implemented */
47 DtdProcessing dtdmode
;
48 UINT line
, pos
; /* reader position in XML stream */
51 typedef struct _xmlreaderinput
53 IXmlReaderInput IXmlReaderInput_iface
;
55 IUnknown
*input
; /* reference passed on IXmlReaderInput creation */
58 static inline xmlreader
*impl_from_IXmlReader(IXmlReader
*iface
)
60 return CONTAINING_RECORD(iface
, xmlreader
, IXmlReader_iface
);
63 static inline xmlreaderinput
*impl_from_IXmlReaderInput(IXmlReaderInput
*iface
)
65 return CONTAINING_RECORD(iface
, xmlreaderinput
, IXmlReaderInput_iface
);
68 static HRESULT WINAPI
xmlreader_QueryInterface(IXmlReader
*iface
, REFIID riid
, void** ppvObject
)
70 xmlreader
*This
= impl_from_IXmlReader(iface
);
72 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
74 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
75 IsEqualGUID(riid
, &IID_IXmlReader
))
81 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
85 IXmlReader_AddRef(iface
);
90 static ULONG WINAPI
xmlreader_AddRef(IXmlReader
*iface
)
92 xmlreader
*This
= impl_from_IXmlReader(iface
);
94 return InterlockedIncrement(&This
->ref
);
97 static ULONG WINAPI
xmlreader_Release(IXmlReader
*iface
)
99 xmlreader
*This
= impl_from_IXmlReader(iface
);
104 ref
= InterlockedDecrement(&This
->ref
);
107 if (This
->input
) IUnknown_Release(This
->input
);
108 if (This
->stream
) ISequentialStream_Release(This
->stream
);
109 HeapFree(GetProcessHeap(), 0, This
);
115 static HRESULT WINAPI
xmlreader_SetInput(IXmlReader
* iface
, IUnknown
*input
)
117 xmlreader
*This
= impl_from_IXmlReader(iface
);
120 TRACE("(%p %p)\n", This
, input
);
124 IUnknown_Release(This
->input
);
130 ISequentialStream_Release(This
->stream
);
134 This
->line
= This
->pos
= 0;
136 /* just reset current input */
139 This
->state
= XmlReadState_Initial
;
143 /* now try IXmlReaderInput, ISequentialStream, IStream */
144 hr
= IUnknown_QueryInterface(input
, &IID_IXmlReaderInput
, (void**)&This
->input
);
147 /* create IXmlReaderInput basing on supplied interface */
148 hr
= CreateXmlReaderInputWithEncodingName(input
,
149 NULL
, NULL
, FALSE
, NULL
, &This
->input
);
150 if (hr
!= S_OK
) return hr
;
153 /* set stream for supplied IXmlReaderInput */
154 hr
= xmlreaderinput_query_for_stream(This
->input
, (void**)&This
->stream
);
156 This
->state
= XmlReadState_Initial
;
161 static HRESULT WINAPI
xmlreader_GetProperty(IXmlReader
* iface
, UINT property
, LONG_PTR
*value
)
163 xmlreader
*This
= impl_from_IXmlReader(iface
);
165 TRACE("(%p %u %p)\n", This
, property
, value
);
167 if (!value
) return E_INVALIDARG
;
171 case XmlReaderProperty_DtdProcessing
:
172 *value
= This
->dtdmode
;
174 case XmlReaderProperty_ReadState
:
175 *value
= This
->state
;
178 FIXME("Unimplemented property (%u)\n", property
);
185 static HRESULT WINAPI
xmlreader_SetProperty(IXmlReader
* iface
, UINT property
, LONG_PTR value
)
187 xmlreader
*This
= impl_from_IXmlReader(iface
);
189 TRACE("(%p %u %lu)\n", iface
, property
, value
);
193 case XmlReaderProperty_DtdProcessing
:
194 if (value
< 0 || value
> _DtdProcessing_Last
) return E_INVALIDARG
;
195 This
->dtdmode
= value
;
198 FIXME("Unimplemented property (%u)\n", property
);
205 static HRESULT WINAPI
xmlreader_Read(IXmlReader
* iface
, XmlNodeType
*node_type
)
207 FIXME("(%p %p): stub\n", iface
, node_type
);
211 static HRESULT WINAPI
xmlreader_GetNodeType(IXmlReader
* iface
, XmlNodeType
*node_type
)
213 FIXME("(%p %p): stub\n", iface
, node_type
);
217 static HRESULT WINAPI
xmlreader_MoveToFirstAttribute(IXmlReader
* iface
)
219 FIXME("(%p): stub\n", iface
);
223 static HRESULT WINAPI
xmlreader_MoveToNextAttribute(IXmlReader
* iface
)
225 FIXME("(%p): stub\n", iface
);
229 static HRESULT WINAPI
xmlreader_MoveToAttributeByName(IXmlReader
* iface
,
231 LPCWSTR namespaceUri
)
233 FIXME("(%p %p %p): stub\n", iface
, local_name
, namespaceUri
);
237 static HRESULT WINAPI
xmlreader_MoveToElement(IXmlReader
* iface
)
239 FIXME("(%p): stub\n", iface
);
243 static HRESULT WINAPI
xmlreader_GetQualifiedName(IXmlReader
* iface
, LPCWSTR
*qualifiedName
,
244 UINT
*qualifiedName_length
)
246 FIXME("(%p %p %p): stub\n", iface
, qualifiedName
, qualifiedName_length
);
250 static HRESULT WINAPI
xmlreader_GetNamespaceUri(IXmlReader
* iface
,
251 LPCWSTR
*namespaceUri
,
252 UINT
*namespaceUri_length
)
254 FIXME("(%p %p %p): stub\n", iface
, namespaceUri
, namespaceUri_length
);
258 static HRESULT WINAPI
xmlreader_GetLocalName(IXmlReader
* iface
,
260 UINT
*local_name_length
)
262 FIXME("(%p %p %p): stub\n", iface
, local_name
, local_name_length
);
266 static HRESULT WINAPI
xmlreader_GetPrefix(IXmlReader
* iface
,
270 FIXME("(%p %p %p): stub\n", iface
, prefix
, prefix_length
);
274 static HRESULT WINAPI
xmlreader_GetValue(IXmlReader
* iface
,
278 FIXME("(%p %p %p): stub\n", iface
, value
, value_length
);
282 static HRESULT WINAPI
xmlreader_ReadValueChunk(IXmlReader
* iface
,
287 FIXME("(%p %p %u %p): stub\n", iface
, buffer
, chunk_size
, read
);
291 static HRESULT WINAPI
xmlreader_GetBaseUri(IXmlReader
* iface
,
293 UINT
*baseUri_length
)
295 FIXME("(%p %p %p): stub\n", iface
, baseUri
, baseUri_length
);
299 static BOOL WINAPI
xmlreader_IsDefault(IXmlReader
* iface
)
301 FIXME("(%p): stub\n", iface
);
305 static BOOL WINAPI
xmlreader_IsEmptyElement(IXmlReader
* iface
)
307 FIXME("(%p): stub\n", iface
);
311 static HRESULT WINAPI
xmlreader_GetLineNumber(IXmlReader
* iface
, UINT
*lineNumber
)
313 xmlreader
*This
= impl_from_IXmlReader(iface
);
315 TRACE("(%p %p)\n", This
, lineNumber
);
317 if (!lineNumber
) return E_INVALIDARG
;
319 *lineNumber
= This
->line
;
324 static HRESULT WINAPI
xmlreader_GetLinePosition(IXmlReader
* iface
, UINT
*linePosition
)
326 xmlreader
*This
= impl_from_IXmlReader(iface
);
328 TRACE("(%p %p)\n", This
, linePosition
);
330 if (!linePosition
) return E_INVALIDARG
;
332 *linePosition
= This
->pos
;
337 static HRESULT WINAPI
xmlreader_GetAttributeCount(IXmlReader
* iface
, UINT
*attributeCount
)
339 FIXME("(%p %p): stub\n", iface
, attributeCount
);
343 static HRESULT WINAPI
xmlreader_GetDepth(IXmlReader
* iface
, UINT
*depth
)
345 FIXME("(%p %p): stub\n", iface
, depth
);
349 static BOOL WINAPI
xmlreader_IsEOF(IXmlReader
* iface
)
351 FIXME("(%p): stub\n", iface
);
355 static const struct IXmlReaderVtbl xmlreader_vtbl
=
357 xmlreader_QueryInterface
,
361 xmlreader_GetProperty
,
362 xmlreader_SetProperty
,
364 xmlreader_GetNodeType
,
365 xmlreader_MoveToFirstAttribute
,
366 xmlreader_MoveToNextAttribute
,
367 xmlreader_MoveToAttributeByName
,
368 xmlreader_MoveToElement
,
369 xmlreader_GetQualifiedName
,
370 xmlreader_GetNamespaceUri
,
371 xmlreader_GetLocalName
,
374 xmlreader_ReadValueChunk
,
375 xmlreader_GetBaseUri
,
377 xmlreader_IsEmptyElement
,
378 xmlreader_GetLineNumber
,
379 xmlreader_GetLinePosition
,
380 xmlreader_GetAttributeCount
,
385 /** IXmlReaderInput **/
387 /* Queries already stored interface for IStream/ISequentialStream.
388 Interface supplied on creation will be overwritten */
389 static HRESULT
xmlreaderinput_query_for_stream(IXmlReaderInput
*iface
, void **pObj
)
391 xmlreaderinput
*This
= impl_from_IXmlReaderInput(iface
);
394 hr
= IUnknown_QueryInterface(This
->input
, &IID_IStream
, pObj
);
396 hr
= IUnknown_QueryInterface(This
->input
, &IID_ISequentialStream
, pObj
);
401 static HRESULT WINAPI
xmlreaderinput_QueryInterface(IXmlReaderInput
*iface
, REFIID riid
, void** ppvObject
)
403 xmlreaderinput
*This
= impl_from_IXmlReaderInput(iface
);
405 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
407 if (IsEqualGUID(riid
, &IID_IXmlReaderInput
) ||
408 IsEqualGUID(riid
, &IID_IUnknown
))
414 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
415 return E_NOINTERFACE
;
418 IUnknown_AddRef(iface
);
423 static ULONG WINAPI
xmlreaderinput_AddRef(IXmlReaderInput
*iface
)
425 xmlreaderinput
*This
= impl_from_IXmlReaderInput(iface
);
427 return InterlockedIncrement(&This
->ref
);
430 static ULONG WINAPI
xmlreaderinput_Release(IXmlReaderInput
*iface
)
432 xmlreaderinput
*This
= impl_from_IXmlReaderInput(iface
);
437 ref
= InterlockedDecrement(&This
->ref
);
440 if (This
->input
) IUnknown_Release(This
->input
);
441 HeapFree(GetProcessHeap(), 0, This
);
447 static const struct IUnknownVtbl xmlreaderinput_vtbl
=
449 xmlreaderinput_QueryInterface
,
450 xmlreaderinput_AddRef
,
451 xmlreaderinput_Release
454 HRESULT WINAPI
CreateXmlReader(REFIID riid
, void **pObject
, IMalloc
*pMalloc
)
458 TRACE("(%s, %p, %p)\n", wine_dbgstr_guid(riid
), pObject
, pMalloc
);
460 if (pMalloc
) FIXME("custom IMalloc not supported yet\n");
462 if (!IsEqualGUID(riid
, &IID_IXmlReader
))
464 ERR("Unexpected IID requested -> (%s)\n", wine_dbgstr_guid(riid
));
468 reader
= HeapAlloc(GetProcessHeap(), 0, sizeof (*reader
));
469 if(!reader
) return E_OUTOFMEMORY
;
471 reader
->IXmlReader_iface
.lpVtbl
= &xmlreader_vtbl
;
473 reader
->stream
= NULL
;
474 reader
->input
= NULL
;
475 reader
->state
= XmlReadState_Closed
;
476 reader
->dtdmode
= DtdProcessing_Prohibit
;
477 reader
->line
= reader
->pos
= 0;
479 *pObject
= &reader
->IXmlReader_iface
;
481 TRACE("returning iface %p\n", *pObject
);
486 HRESULT WINAPI
CreateXmlReaderInputWithEncodingName(IUnknown
*stream
,
491 IXmlReaderInput
**ppInput
)
493 xmlreaderinput
*readerinput
;
495 FIXME("%p %p %s %d %s %p: stub\n", stream
, pMalloc
, wine_dbgstr_w(encoding
),
496 hint
, wine_dbgstr_w(base_uri
), ppInput
);
498 if (!stream
|| !ppInput
) return E_INVALIDARG
;
500 readerinput
= HeapAlloc(GetProcessHeap(), 0, sizeof (*readerinput
));
501 if(!readerinput
) return E_OUTOFMEMORY
;
503 readerinput
->IXmlReaderInput_iface
.lpVtbl
= &xmlreaderinput_vtbl
;
504 readerinput
->ref
= 1;
505 IUnknown_QueryInterface(stream
, &IID_IUnknown
, (void**)&readerinput
->input
);
507 *ppInput
= &readerinput
->IXmlReaderInput_iface
;
509 TRACE("returning iface %p\n", *ppInput
);