#include "shlwapi.h"
#include "wine/debug.h"
-#include "wine/list.h"
#include "msxml_private.h"
-WINE_DEFAULT_DEBUG_CHANNEL(msxml);
-
#ifdef HAVE_LIBXML2
+WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+
typedef enum
{
FeatureUnknown = 0,
'/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
};
+static const WCHAR ExhaustiveErrorsW[] = {
+ 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
+};
+
+static const WCHAR SchemaValidationW[] = {
+ 's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0
+};
+
struct saxreader_feature_pair
{
saxreader_feature feature;
};
static const struct saxreader_feature_pair saxreader_feature_map[] = {
+ { ExhaustiveErrors, ExhaustiveErrorsW },
{ ExternalGeneralEntities, FeatureExternalGeneralEntitiesW },
{ ExternalParameterEntities, FeatureExternalParameterEntitiesW },
{ LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW },
{ NamespacePrefixes, FeatureNamespacePrefixesW },
{ Namespaces, FeatureNamespacesW },
- { ProhibitDTD, FeatureProhibitDTDW }
+ { ProhibitDTD, FeatureProhibitDTDW },
+ { SchemaValidation, SchemaValidationW },
};
static saxreader_feature get_saxreader_feature(const WCHAR *name)
int min, max, n, c;
min = 0;
- max = sizeof(saxreader_feature_map)/sizeof(struct saxreader_feature_pair) - 1;
+ max = ARRAY_SIZE(saxreader_feature_map) - 1;
while (min <= max)
{
return FeatureUnknown;
}
+static const WCHAR empty_str;
+
struct bstrpool
{
BSTR *pool;
SAXContentHandler = 0,
SAXDeclHandler,
SAXDTDHandler,
+ SAXEntityResolver,
SAXErrorHandler,
SAXLexicalHandler,
SAXHandler_Last
};
-struct saxhandler_iface
+struct saxanyhandler_iface
{
IUnknown *handler;
IUnknown *vbhandler;
IVBSAXLexicalHandler *vbhandler;
};
+struct saxentityresolver_iface
+{
+ ISAXEntityResolver *handler;
+ IVBSAXEntityResolver *vbhandler;
+};
+
+struct saxhandler_iface
+{
+ union {
+ struct saxcontenthandler_iface content;
+ struct saxentityresolver_iface entityresolver;
+ struct saxerrorhandler_iface error;
+ struct saxlexicalhandler_iface lexical;
+ struct saxanyhandler_iface anyhandler;
+ } u;
+};
+
typedef struct
{
DispatchEx dispex;
static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
{
- struct saxhandler_iface *iface = &reader->saxhandlers[type];
+ struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
IUnknown *unk = (IUnknown*)ptr;
if (unk)
static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
{
- const struct saxhandler_iface *iface = &reader->saxhandlers[type];
+ const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler;
if (!ret) return E_POINTER;
static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
{
- return (struct saxcontenthandler_iface*)&reader->saxhandlers[SAXContentHandler];
+ return &reader->saxhandlers[SAXContentHandler].u.content;
}
static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
{
- return (struct saxerrorhandler_iface*)&reader->saxhandlers[SAXErrorHandler];
+ return &reader->saxhandlers[SAXErrorHandler].u.error;
}
static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
{
- return (struct saxlexicalhandler_iface*)&reader->saxhandlers[SAXLexicalHandler];
+ return &reader->saxhandlers[SAXLexicalHandler].u.lexical;
}
typedef struct
saxreader *saxreader;
HRESULT ret;
xmlParserCtxtPtr pParserCtxt;
- WCHAR *publicId;
- WCHAR *systemId;
+ BSTR publicId;
+ BSTR systemId;
int line;
int column;
BOOL vbInterface;
struct list elements;
BSTR namespaceUri;
- int attributesSize;
- int nb_attributes;
+ int attr_alloc_count;
+ int attr_count;
struct _attributes
{
BSTR szLocalname;
return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
}
-static inline int saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type)
+static inline BOOL saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type)
{
- return (locator->vbInterface && locator->saxreader->saxhandlers[type].vbhandler) ||
- (!locator->vbInterface && locator->saxreader->saxhandlers[type].handler);
+ struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler;
+ return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler);
+}
+
+static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars)
+{
+ struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader);
+ HRESULT hr;
+
+ if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK;
+
+ if (locator->vbInterface)
+ hr = IVBSAXContentHandler_characters(content->vbhandler, &chars);
+ else
+ hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars));
+
+ return hr;
}
/* property names */
SysFreeString(element->prefix);
SysFreeString(element->local);
+ SysFreeString(element->qname);
heap_free(element->ns);
heap_free(element);
{
if (!pool->pool)
{
- pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool));
+ pool->pool = heap_alloc(16 * sizeof(*pool->pool));
if (!pool->pool)
return FALSE;
}
else if (pool->index == pool->len)
{
- BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc));
+ BSTR *realloc = heap_realloc(pool->pool, pool->len * 2 * sizeof(*realloc));
if (!realloc)
return FALSE;
for (i = 0; i < pool->index; i++)
SysFreeString(pool->pool[i]);
- HeapFree(GetProcessHeap(), 0, pool->pool);
+ heap_free(pool->pool);
pool->pool = NULL;
pool->index = pool->len = 0;
{
WCHAR msg[1024];
if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, hr, 0, msg, sizeof(msg), NULL))
+ NULL, hr, 0, msg, ARRAY_SIZE(msg), NULL))
{
FIXME("MSXML errors not yet supported.\n");
msg[0] = '\0';
static void update_position(saxlocator *This, BOOL fix_column)
{
const xmlChar *p = This->pParserCtxt->input->cur-1;
+ const xmlChar *baseP = This->pParserCtxt->input->base;
This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
if(fix_column)
{
This->column = 1;
- for(; *p!='\n' && *p!='\r' && p>=This->pParserCtxt->input->base; p--)
+ for(;p>=baseP && *p!='\n' && *p!='\r'; p--)
This->column++;
}
else
}
/*** IVBSAXAttributes interface ***/
-/*** IUnknown methods ***/
static HRESULT WINAPI ivbsaxattributes_QueryInterface(
IVBSAXAttributes* iface,
REFIID riid,
static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
{
saxlocator *This = impl_from_IVBSAXAttributes(iface);
- return ISAXLocator_AddRef(&This->ISAXLocator_iface);
+ return IVBSAXLocator_AddRef(&This->IVBSAXLocator_iface);
}
static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
{
saxlocator *This = impl_from_IVBSAXAttributes(iface);
- return ISAXLocator_Release(&This->ISAXLocator_iface);
+ return IVBSAXLocator_Release(&This->IVBSAXLocator_iface);
}
-/*** IDispatch methods ***/
static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
{
saxlocator *This = impl_from_IVBSAXAttributes( iface );
UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
{
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- HRESULT hr;
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
- hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
-
- return hr;
+ return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
}
static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
int nIndex,
BSTR *uri)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)uri, &len);
+ const WCHAR *uriW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%d %p)\n", This, nIndex, uri);
+
+ if (!uri)
+ return E_POINTER;
+
+ *uri = NULL;
+ hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, &uriW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(uriW, len, uri);
}
static HRESULT WINAPI ivbsaxattributes_getLocalName(
IVBSAXAttributes* iface,
int nIndex,
- BSTR *localName)
+ BSTR *name)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex,
- (const WCHAR**)localName, &len);
+ const WCHAR *nameW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%d %p)\n", This, nIndex, name);
+
+ if (!name)
+ return E_POINTER;
+
+ *name = NULL;
+ hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex, &nameW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(nameW, len, name);
}
static HRESULT WINAPI ivbsaxattributes_getQName(
int nIndex,
BSTR *QName)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)QName, &len);
+ const WCHAR *nameW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%d %p)\n", This, nIndex, QName);
+
+ if (!QName)
+ return E_POINTER;
+
+ *QName = NULL;
+ hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, &nameW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(nameW, len, QName);
}
static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
int nIndex,
BSTR *type)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)type, &len);
+ const WCHAR *typeW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%d %p)\n", This, nIndex, type);
+
+ if (!type)
+ return E_POINTER;
+
+ *type = NULL;
+ hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, &typeW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(typeW, len, type);
}
static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
BSTR localName,
BSTR *type)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
- localName, SysStringLen(localName), (const WCHAR**)type, &len);
+ const WCHAR *typeW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), type);
+
+ if (!type)
+ return E_POINTER;
+
+ *type = NULL;
+ hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
+ localName, SysStringLen(localName), &typeW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(typeW, len, type);
}
static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
BSTR QName,
BSTR *type)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
- (const WCHAR**)type, &len);
+ const WCHAR *typeW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), type);
+
+ if (!type)
+ return E_POINTER;
+
+ *type = NULL;
+ hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
+ &typeW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(typeW, len, type);
}
static HRESULT WINAPI ivbsaxattributes_getValue(
int nIndex,
BSTR *value)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)value, &len);
+ const WCHAR *valueW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%d %p)\n", This, nIndex, value);
+
+ if (!value)
+ return E_POINTER;
+
+ *value = NULL;
+ hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, &valueW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(valueW, len, value);
}
static HRESULT WINAPI ivbsaxattributes_getValueFromName(
BSTR localName,
BSTR *value)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
- localName, SysStringLen(localName), (const WCHAR**)value, &len);
+ const WCHAR *valueW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), value);
+
+ if (!value)
+ return E_POINTER;
+
+ *value = NULL;
+ hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
+ localName, SysStringLen(localName), &valueW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(valueW, len, value);
}
static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
BSTR QName,
BSTR *value)
{
- int len;
saxlocator *This = impl_from_IVBSAXAttributes( iface );
- return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
- SysStringLen(QName), (const WCHAR**)value, &len);
+ const WCHAR *valueW;
+ HRESULT hr;
+ int len;
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), value);
+
+ if (!value)
+ return E_POINTER;
+
+ *value = NULL;
+ hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
+ SysStringLen(QName), &valueW, &len);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstrn(valueW, len, value);
}
static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
{
saxlocator *This = impl_from_ISAXAttributes( iface );
- *length = This->nb_attributes;
+ *length = This->attr_count;
TRACE("Length set to %d\n", *length);
return S_OK;
}
+static inline BOOL is_valid_attr_index(const saxlocator *locator, int index)
+{
+ return index < locator->attr_count && index >= 0;
+}
+
static HRESULT WINAPI isaxattributes_getURI(
ISAXAttributes* iface,
int index,
saxlocator *This = impl_from_ISAXAttributes( iface );
TRACE("(%p)->(%d)\n", This, index);
- if(index >= This->nb_attributes || index < 0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!url || !size) return E_POINTER;
*size = SysStringLen(This->attributes[index].szURI);
static HRESULT WINAPI isaxattributes_getLocalName(
ISAXAttributes* iface,
- int nIndex,
+ int index,
const WCHAR **pLocalName,
int *pLocalNameLength)
{
saxlocator *This = impl_from_ISAXAttributes( iface );
- TRACE("(%p)->(%d)\n", This, nIndex);
+ TRACE("(%p)->(%d)\n", This, index);
- if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!pLocalName || !pLocalNameLength) return E_POINTER;
- *pLocalNameLength = SysStringLen(This->attributes[nIndex].szLocalname);
- *pLocalName = This->attributes[nIndex].szLocalname;
+ *pLocalNameLength = SysStringLen(This->attributes[index].szLocalname);
+ *pLocalName = This->attributes[index].szLocalname;
return S_OK;
}
static HRESULT WINAPI isaxattributes_getQName(
ISAXAttributes* iface,
- int nIndex,
+ int index,
const WCHAR **pQName,
int *pQNameLength)
{
saxlocator *This = impl_from_ISAXAttributes( iface );
- TRACE("(%p)->(%d)\n", This, nIndex);
+ TRACE("(%p)->(%d)\n", This, index);
- if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!pQName || !pQNameLength) return E_POINTER;
- *pQNameLength = SysStringLen(This->attributes[nIndex].szQName);
- *pQName = This->attributes[nIndex].szQName;
+ *pQNameLength = SysStringLen(This->attributes[index].szQName);
+ *pQName = This->attributes[index].szQName;
return S_OK;
}
saxlocator *This = impl_from_ISAXAttributes( iface );
TRACE("(%p)->(%d)\n", This, index);
- if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!uri || !pUriLength || !localName || !pLocalNameSize
|| !QName || !pQNameLength) return E_POINTER;
if(!pUri || !pLocalName || !index) return E_POINTER;
- for(i=0; i<This->nb_attributes; i++)
+ for(i=0; i<This->attr_count; i++)
{
if(cUriLength!=SysStringLen(This->attributes[i].szURI)
|| cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
if(!pQName || !index) return E_POINTER;
if(!nQNameLength) return E_INVALIDARG;
- for(i=0; i<This->nb_attributes; i++)
+ for(i=0; i<This->attr_count; i++)
{
if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
saxlocator *This = impl_from_ISAXAttributes( iface );
TRACE("(%p)->(%d)\n", This, index);
- if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!value || !nValue) return E_POINTER;
*nValue = SysStringLen(This->attributes[index].szValue);
isaxattributes_getValueFromQName
};
+/* Libxml2 escapes '&' back to char reference '&' in attribute value,
+ so when document has escaped value with '&' it's parsed to '&' and then
+ escaped to '&'. This function takes care of ampersands only. */
+static BSTR saxreader_get_unescaped_value(const xmlChar *buf, int len)
+{
+ static const WCHAR ampescW[] = {'&','#','3','8',';',0};
+ WCHAR *dest, *ptrW, *str;
+ DWORD str_len;
+ BSTR bstr;
+
+ if (!buf)
+ return NULL;
+
+ str_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
+ if (len != -1) str_len++;
+
+ str = heap_alloc(str_len*sizeof(WCHAR));
+ if (!str) return NULL;
+
+ MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, str_len);
+ if (len != -1) str[str_len-1] = 0;
+
+ ptrW = str;
+ while ((dest = strstrW(ptrW, ampescW)))
+ {
+ WCHAR *src;
+
+ /* leave first '&' from a reference as a value */
+ src = dest + ARRAY_SIZE(ampescW) - 1;
+ dest++;
+
+ /* move together with null terminator */
+ memmove(dest, src, (strlenW(src) + 1)*sizeof(WCHAR));
+
+ ptrW++;
+ }
+
+ bstr = SysAllocString(str);
+ heap_free(str);
+
+ return bstr;
+}
+
+static void free_attribute_values(saxlocator *locator)
+{
+ int i;
+
+ for (i = 0; i < locator->attr_count; i++)
+ {
+ SysFreeString(locator->attributes[i].szLocalname);
+ locator->attributes[i].szLocalname = NULL;
+
+ SysFreeString(locator->attributes[i].szValue);
+ locator->attributes[i].szValue = NULL;
+
+ SysFreeString(locator->attributes[i].szQName);
+ locator->attributes[i].szQName = NULL;
+ }
+}
+
static HRESULT SAXAttributes_populate(saxlocator *locator,
int nb_namespaces, const xmlChar **xmlNamespaces,
int nb_attributes, const xmlChar **xmlAttributes)
if ((locator->saxreader->features & NamespacePrefixes) == 0)
nb_namespaces = 0;
- locator->nb_attributes = nb_namespaces + nb_attributes;
- if(locator->nb_attributes > locator->attributesSize)
+ locator->attr_count = nb_namespaces + nb_attributes;
+ if(locator->attr_count > locator->attr_alloc_count)
{
- attrs = heap_realloc(locator->attributes, sizeof(struct _attributes)*locator->nb_attributes*2);
+ int new_size = locator->attr_count * 2;
+ attrs = heap_realloc_zero(locator->attributes, new_size * sizeof(struct _attributes));
if(!attrs)
{
- locator->nb_attributes = 0;
+ free_attribute_values(locator);
+ locator->attr_count = 0;
return E_OUTOFMEMORY;
}
locator->attributes = attrs;
+ locator->attr_alloc_count = new_size;
}
else
{
for (i = 0; i < nb_namespaces; i++)
{
+ SysFreeString(attrs[nb_attributes+i].szLocalname);
attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0);
+
attrs[nb_attributes+i].szURI = locator->namespaceUri;
+
+ SysFreeString(attrs[nb_attributes+i].szValue);
attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]);
+
+ SysFreeString(attrs[nb_attributes+i].szQName);
if(!xmlNamespaces[2*i])
attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW);
else
/* that's an important feature to keep same uri pointer for every reported attribute */
attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
+ SysFreeString(attrs[i].szLocalname);
attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
- attrs[i].szValue = bstr_from_xmlCharN(xmlAttributes[i*5+3],
- xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
- attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1],
- xmlAttributes[i*5]);
+
+ SysFreeString(attrs[i].szValue);
+ attrs[i].szValue = saxreader_get_unescaped_value(xmlAttributes[i*5+3], xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
+
+ SysFreeString(attrs[i].szQName);
+ attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1], xmlAttributes[i*5]);
}
return S_OK;
&uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
else
hr = ISAXContentHandler_startElement(handler->handler,
- uri, SysStringLen(uri),
- local, SysStringLen(local),
+ uri ? uri : &empty_str, SysStringLen(uri),
+ local ? local : &empty_str, SysStringLen(local),
element->qname, SysStringLen(element->qname),
&This->ISAXAttributes_iface);
if (!saxreader_has_handler(This, SAXContentHandler))
{
- This->nb_attributes = 0;
+ free_attribute_values(This);
+ This->attr_count = 0;
free_element_entry(element);
return;
}
else
hr = ISAXContentHandler_endElement(
handler->handler,
- uri, SysStringLen(uri),
- local, SysStringLen(local),
+ uri ? uri : &empty_str, SysStringLen(uri),
+ local ? local : &empty_str, SysStringLen(local),
element->qname, SysStringLen(element->qname));
- This->nb_attributes = 0;
+ free_attribute_values(This);
+ This->attr_count = 0;
if (sax_callback_failed(This, hr))
{
int len)
{
saxlocator *This = ctx;
- struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
BSTR Chars;
HRESULT hr;
xmlChar *cur, *end;
}
Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
- if(This->vbInterface)
- hr = IVBSAXContentHandler_characters(handler->vbhandler, &Chars);
- else
- hr = ISAXContentHandler_characters(handler->handler, Chars, SysStringLen(Chars));
+ hr = saxreader_saxcharacters(This, Chars);
if (sax_callback_failed(This, hr))
{
This->ret = E_FAIL;
}
-static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
+/* The only reason this helper exists is that CDATA section are reported by chunks,
+ newlines are used as delimiter. More than that, reader even alters input data before reporting.
+
+ This helper should be called for substring with trailing newlines.
+*/
+static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len)
{
- saxlocator *This = ctx;
- struct saxcontenthandler_iface *content = saxreader_get_contenthandler(This->saxreader);
- struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(This->saxreader);
- HRESULT hr = S_OK;
- xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len;
- xmlChar *cur, *end;
- int realLen;
- BSTR Chars;
- BOOL lastEvent = FALSE, change;
+ BSTR bstr = bstr_from_xmlCharN(str, len), ret;
+ WCHAR *ptr;
- update_position(This, FALSE);
- while(beg-9>=This->pParserCtxt->input->base
- && memcmp(beg-9, "<![CDATA[", sizeof(char[9])))
+ len = SysStringLen(bstr);
+ ptr = bstr + len - 1;
+ while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr)
+ ptr--;
+
+ while (*++ptr)
{
- if(*beg=='\n' || (*beg=='\r' && *(beg+1)!='\n'))
- This->line--;
- beg--;
+ /* replace returns as:
+
+ - "\r<char>" -> "\n<char>"
+ - "\r\r" -> "\r"
+ - "\r\n" -> "\n"
+ */
+ if (*ptr == '\r')
+ {
+ if (*(ptr+1) == '\r' || *(ptr+1) == '\n')
+ {
+ /* shift tail */
+ memmove(ptr, ptr+1, len-- - (ptr-bstr));
+ }
+ else
+ *ptr = '\n';
+ }
}
- This->column = 0;
- for(; beg>=This->pParserCtxt->input->base && *beg!='\n' && *beg!='\r'; beg--)
- This->column++;
- if (saxreader_has_handler(This, SAXLexicalHandler))
+ ret = SysAllocStringLen(bstr, len);
+ SysFreeString(bstr);
+ return ret;
+}
+
+static void libxml_cdatablock(void *ctx, const xmlChar *value, int len)
+{
+ const xmlChar *start, *end;
+ saxlocator *locator = ctx;
+ struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader);
+ HRESULT hr = S_OK;
+ BSTR chars;
+ int i;
+
+ update_position(locator, FALSE);
+ if (saxreader_has_handler(locator, SAXLexicalHandler))
{
- if (This->vbInterface)
+ if (locator->vbInterface)
hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
else
hr = ISAXLexicalHandler_startCDATA(lexical->handler);
if(FAILED(hr))
{
- format_error_message_from_id(This, hr);
+ format_error_message_from_id(locator, hr);
return;
}
- realLen = This->pParserCtxt->input->cur-beg-3;
- cur = beg;
- end = beg;
+ start = value;
+ end = NULL;
+ i = 0;
- while(1)
+ while (i < len)
{
- while(end-beg<realLen && *end!='\r') end++;
- if(end-beg==realLen)
+ /* scan for newlines */
+ if (value[i] == '\r' || value[i] == '\n')
{
- end--;
- lastEvent = TRUE;
- }
- else if(end-beg==realLen-1 && *end=='\r' && *(end+1)=='\n')
- lastEvent = TRUE;
-
- if(*end == '\r') change = TRUE;
- else change = FALSE;
+ /* skip newlines/linefeeds */
+ while (i < len)
+ {
+ if (value[i] != '\r' && value[i] != '\n') break;
+ i++;
+ }
+ end = &value[i];
- if(change) *end = '\n';
+ /* report */
+ chars = saxreader_get_cdata_chunk(start, end-start);
+ TRACE("(chunk %s)\n", debugstr_w(chars));
+ hr = saxreader_saxcharacters(locator, chars);
+ SysFreeString(chars);
- if (saxreader_has_handler(This, SAXContentHandler))
- {
- Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1);
- if (This->vbInterface)
- hr = IVBSAXContentHandler_characters(content->vbhandler, &Chars);
- else
- hr = ISAXContentHandler_characters(content->handler, Chars, SysStringLen(Chars));
+ start = &value[i];
+ end = NULL;
}
+ i++;
+ locator->column++;
+ }
- if(change) *end = '\r';
-
- if(lastEvent)
- break;
-
- This->column += end-cur+2;
- end += 2;
- cur = end;
+ /* no newline chars (or last chunk) report as a whole */
+ if (!end && start == value)
+ {
+ /* report */
+ chars = bstr_from_xmlCharN(start, len-(start-value));
+ TRACE("(%s)\n", debugstr_w(chars));
+ hr = saxreader_saxcharacters(locator, chars);
+ SysFreeString(chars);
}
- if (saxreader_has_handler(This, SAXLexicalHandler))
+ if (saxreader_has_handler(locator, SAXLexicalHandler))
{
- if (This->vbInterface)
+ if (locator->vbInterface)
hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
else
hr = ISAXLexicalHandler_endCDATA(lexical->handler);
}
if(FAILED(hr))
- format_error_message_from_id(This, hr);
+ format_error_message_from_id(locator, hr);
+}
- This->column += 4+end-cur;
+static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid)
+{
+ FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid);
+ return xmlSAX2ResolveEntity(ctx, publicid, systemid);
}
/*** IVBSAXLocator interface ***/
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
TRACE("%p\n", This );
- return InterlockedIncrement( &This->ref );
+ return ISAXLocator_AddRef(&This->ISAXLocator_iface);
}
-static ULONG WINAPI ivbsaxlocator_Release(
- IVBSAXLocator* iface)
+static ULONG WINAPI ivbsaxlocator_Release(IVBSAXLocator* iface)
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
- return ISAXLocator_Release((ISAXLocator*)&This->IVBSAXLocator_iface);
+ return ISAXLocator_Release(&This->ISAXLocator_iface);
}
/*** IDispatch methods ***/
UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
- HRESULT hr;
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
- hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo);
-
- return hr;
+ return get_typeinfo(IVBSAXLocator_tid, ppTInfo);
}
static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
int *pnColumn)
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
- return ISAXLocator_getColumnNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnColumn);
+ return ISAXLocator_getColumnNumber(&This->ISAXLocator_iface, pnColumn);
}
static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
int *pnLine)
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
- return ISAXLocator_getLineNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnLine);
+ return ISAXLocator_getLineNumber(&This->ISAXLocator_iface, pnLine);
}
-static HRESULT WINAPI ivbsaxlocator_get_publicId(
- IVBSAXLocator* iface,
- BSTR* publicId)
+static HRESULT WINAPI ivbsaxlocator_get_publicId(IVBSAXLocator* iface, BSTR *ret)
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
- return ISAXLocator_getPublicId((ISAXLocator*)&This->IVBSAXLocator_iface,
- (const WCHAR**)publicId);
+ const WCHAR *publicidW;
+ HRESULT hr;
+
+ TRACE("(%p)->(%p)\n", This, ret);
+
+ if (!ret)
+ return E_POINTER;
+
+ *ret = NULL;
+ hr = ISAXLocator_getPublicId(&This->ISAXLocator_iface, &publicidW);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstr(publicidW, ret);
}
-static HRESULT WINAPI ivbsaxlocator_get_systemId(
- IVBSAXLocator* iface,
- BSTR* systemId)
+static HRESULT WINAPI ivbsaxlocator_get_systemId(IVBSAXLocator* iface, BSTR *ret)
{
saxlocator *This = impl_from_IVBSAXLocator( iface );
- return ISAXLocator_getSystemId((ISAXLocator*)&This->IVBSAXLocator_iface,
- (const WCHAR**)systemId);
+ const WCHAR *systemidW;
+ HRESULT hr;
+
+ TRACE("(%p)->(%p)\n", This, ret);
+
+ if (!ret)
+ return E_POINTER;
+
+ *ret = NULL;
+ hr = ISAXLocator_getSystemId(&This->ISAXLocator_iface, &systemidW);
+ if (FAILED(hr))
+ return hr;
+
+ return return_bstr(systemidW, ret);
}
static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl =
SysFreeString(This->systemId);
SysFreeString(This->namespaceUri);
- for(index=0; index<This->nb_attributes; index++)
+ for(index = 0; index < This->attr_alloc_count; index++)
{
SysFreeString(This->attributes[index].szLocalname);
SysFreeString(This->attributes[index].szValue);
publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
if(SysStringLen(publicId))
- This->publicId = (WCHAR*)&publicId;
+ This->publicId = publicId;
else
{
SysFreeString(publicId);
systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
if(SysStringLen(systemId))
- This->systemId = (WCHAR*)&systemId;
+ This->systemId = systemId;
else
{
SysFreeString(systemId);
return E_OUTOFMEMORY;
}
- locator->attributesSize = 8;
- locator->nb_attributes = 0;
- locator->attributes = heap_alloc(sizeof(struct _attributes)*locator->attributesSize);
+ locator->attr_alloc_count = 8;
+ locator->attr_count = 0;
+ locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attr_alloc_count);
if(!locator->attributes)
{
ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
if (encoding == XML_CHAR_ENCODING_NONE)
{
const WCHAR *ptr = (WCHAR*)buffer;
- /* xml declaration with possibly specfied encoding will be still handled by parser */
+ /* an xml declaration with optional encoding will still be handled by the parser */
if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
{
enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE);
saxlocator *locator;
HRESULT hr;
ULONG dataRead;
- char data[1024];
+ char data[2048];
int ret;
dataRead = 0;
This->isParsing = TRUE;
- if(dataRead != sizeof(data))
+ do {
+ dataRead = 0;
+ hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
+ if (FAILED(hr) || !dataRead) break;
+
+ ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
+ hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
+ }while(hr == S_OK);
+
+ if(SUCCEEDED(hr))
{
ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
}
- else
- {
- while(1)
- {
- dataRead = 0;
- hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
- if (FAILED(hr)) break;
-
- ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
- hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
- if (hr != S_OK) break;
-
- if (dataRead != sizeof(data))
- {
- ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
- hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
- break;
- }
- }
- }
This->isParsing = FALSE;
return hr;
}
-static HRESULT internal_getEntityResolver(
- saxreader *This,
- void *pEntityResolver,
- BOOL vbInterface)
-{
- FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
- return E_NOTIMPL;
-}
-
-static HRESULT internal_putEntityResolver(
- saxreader *This,
- void *pEntityResolver,
- BOOL vbInterface)
-{
- FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
- return E_NOTIMPL;
-}
-
static HRESULT internal_parse(
saxreader* This,
VARIANT varInput,
switch(V_VT(&varInput))
{
case VT_BSTR:
- hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput),
- strlenW(V_BSTR(&varInput))*sizeof(WCHAR), vbInterface);
+ case VT_BSTR|VT_BYREF:
+ {
+ BSTR str = V_ISBYREF(&varInput) ? *V_BSTRREF(&varInput) : V_BSTR(&varInput);
+ hr = internal_parseBuffer(This, (const char*)str, strlenW(str)*sizeof(WCHAR), vbInterface);
break;
+ }
case VT_ARRAY|VT_UI1: {
void *pSAData;
LONG lBound, uBound;
}
case VT_UNKNOWN:
case VT_DISPATCH: {
- IPersistStream *persistStream;
ISequentialStream *stream = NULL;
IXMLDOMDocument *xmlDoc;
+ if (!V_UNKNOWN(&varInput))
+ return E_INVALIDARG;
+
if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
&IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
{
break;
}
- if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
- &IID_IPersistStream, (void**)&persistStream) == S_OK)
- {
- IStream *stream_copy;
-
- hr = CreateStreamOnHGlobal(NULL, TRUE, &stream_copy);
- if(hr != S_OK)
- {
- IPersistStream_Release(persistStream);
- return hr;
- }
-
- hr = IPersistStream_Save(persistStream, stream_copy, TRUE);
- IPersistStream_Release(persistStream);
- if(hr == S_OK)
- IStream_QueryInterface(stream_copy, &IID_ISequentialStream, (void**)&stream);
-
- IStream_Release(stream_copy);
- }
-
/* try base interface first */
- if(!stream)
- {
- IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
- if (!stream)
- /* this should never happen if IStream is implemented properly, but just in case */
- IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
- }
+ IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
+ if (!stream)
+ /* this should never happen if IStream is implemented properly, but just in case */
+ IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
if(stream)
{
return detach_bsc(bsc);
}
-static HRESULT internal_putProperty(
- saxreader* This,
- const WCHAR *prop,
- VARIANT value,
- BOOL vbInterface)
+static HRESULT saxreader_put_handler_from_variant(saxreader *This, enum saxhandler_type type, const VARIANT *v, BOOL vb)
{
- TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
-
- if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
- {
- if(This->isParsing) return E_FAIL;
+ const IID *riid;
- switch (V_VT(&value))
- {
- case VT_EMPTY:
- saxreader_put_handler(This, SAXDeclHandler, NULL, vbInterface);
- break;
- case VT_UNKNOWN:
- {
- IUnknown *handler = NULL;
+ if (V_VT(v) == VT_EMPTY)
+ return saxreader_put_handler(This, type, NULL, vb);
- if (V_UNKNOWN(&value))
- {
- HRESULT hr;
+ switch (type)
+ {
+ case SAXDeclHandler:
+ riid = vb ? &IID_IVBSAXDeclHandler : &IID_ISAXDeclHandler;
+ break;
+ case SAXLexicalHandler:
+ riid = vb ? &IID_IVBSAXLexicalHandler : &IID_ISAXLexicalHandler;
+ break;
+ default:
+ ERR("wrong handler type %d\n", type);
+ return E_FAIL;
+ }
- if (vbInterface)
- hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&handler);
- else
- hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&handler);
- if (FAILED(hr)) return hr;
- }
+ switch (V_VT(v))
+ {
+ case VT_DISPATCH:
+ case VT_UNKNOWN:
+ {
+ IUnknown *handler = NULL;
- saxreader_put_handler(This, SAXDeclHandler, handler, vbInterface);
- if (handler) IUnknown_Release(handler);
- break;
- }
- default:
- return E_INVALIDARG;
+ if (V_UNKNOWN(v))
+ {
+ HRESULT hr = IUnknown_QueryInterface(V_UNKNOWN(v), riid, (void**)&handler);
+ if (FAILED(hr)) return hr;
}
- return S_OK;
+ saxreader_put_handler(This, type, handler, vb);
+ if (handler) IUnknown_Release(handler);
+ break;
+ }
+ default:
+ ERR("value type %d not supported\n", V_VT(v));
+ return E_INVALIDARG;
}
- if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
- {
- if(This->isParsing) return E_FAIL;
+ return S_OK;
+}
- switch (V_VT(&value))
- {
- case VT_EMPTY:
- saxreader_put_handler(This, SAXLexicalHandler, NULL, vbInterface);
- break;
- case VT_UNKNOWN:
- {
- IUnknown *handler = NULL;
+static HRESULT internal_putProperty(
+ saxreader* This,
+ const WCHAR *prop,
+ VARIANT value,
+ BOOL vbInterface)
+{
+ VARIANT *v;
- if (V_UNKNOWN(&value))
- {
- HRESULT hr;
+ TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
- if (vbInterface)
- hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXLexicalHandler, (void**)&handler);
- else
- hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXLexicalHandler, (void**)&handler);
- if (FAILED(hr)) return hr;
- }
+ if (This->isParsing) return E_FAIL;
- saxreader_put_handler(This, SAXLexicalHandler, handler, vbInterface);
- if (handler) IUnknown_Release(handler);
- break;
- }
- default:
- return E_INVALIDARG;
- }
+ v = V_VT(&value) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(&value) : &value;
+ if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
+ return saxreader_put_handler_from_variant(This, SAXDeclHandler, v, vbInterface);
- return S_OK;
- }
+ if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
+ return saxreader_put_handler_from_variant(This, SAXLexicalHandler, v, vbInterface);
if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
{
- if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
- FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(&value));
+ if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK;
+ FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(v));
return E_NOTIMPL;
}
if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
{
- if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
- FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(&value));
+ if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK;
+ FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(v));
return E_NOTIMPL;
}
- FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(&value));
+ FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(v));
if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
return E_NOTIMPL;
for (i = 0; i < SAXHandler_Last; i++)
{
- struct saxhandler_iface *iface = &This->saxhandlers[i];
+ struct saxanyhandler_iface *saxiface = &This->saxhandlers[i].u.anyhandler;
- if (iface->handler)
- IUnknown_Release(iface->handler);
+ if (saxiface->handler)
+ IUnknown_Release(saxiface->handler);
- if (iface->vbhandler)
- IUnknown_Release(iface->vbhandler);
+ if (saxiface->vbhandler)
+ IUnknown_Release(saxiface->vbhandler);
}
SysFreeString(This->xmldecl_version);
free_bstr_pool(&This->pool);
- release_dispex(&This->dispex);
heap_free( This );
}
/*** IVBSAXXMLReader methods ***/
static HRESULT WINAPI saxxmlreader_getFeature(
IVBSAXXMLReader* iface,
- const WCHAR *feature_name,
+ BSTR feature_name,
VARIANT_BOOL *value)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
- saxreader_feature feature;
-
- TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
-
- feature = get_saxreader_feature(feature_name);
- if (feature == Namespaces || feature == NamespacePrefixes)
- return get_feature_value(This, feature, value);
-
- FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
- return E_NOTIMPL;
+ return ISAXXMLReader_getFeature(&This->ISAXXMLReader_iface, feature_name, value);
}
static HRESULT WINAPI saxxmlreader_putFeature(
IVBSAXXMLReader* iface,
- const WCHAR *feature_name,
+ BSTR feature_name,
VARIANT_BOOL value)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
- saxreader_feature feature;
-
- TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
-
- feature = get_saxreader_feature(feature_name);
-
- /* accepted cases */
- if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) ||
- (feature == ExternalParameterEntities && value == VARIANT_FALSE) ||
- feature == Namespaces ||
- feature == NamespacePrefixes)
- {
- return set_feature_value(This, feature, value);
- }
-
- if (feature == LexicalHandlerParEntities || feature == ProhibitDTD)
- {
- FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
- return set_feature_value(This, feature, value);
- }
-
- FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
- return E_NOTIMPL;
+ return ISAXXMLReader_putFeature(&This->ISAXXMLReader_iface, feature_name, value);
}
static HRESULT WINAPI saxxmlreader_getProperty(
IVBSAXXMLReader* iface,
- const WCHAR *prop,
+ BSTR prop,
VARIANT *value)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
static HRESULT WINAPI saxxmlreader_putProperty(
IVBSAXXMLReader* iface,
- const WCHAR *pProp,
+ BSTR pProp,
VARIANT value)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
static HRESULT WINAPI saxxmlreader_get_entityResolver(
IVBSAXXMLReader* iface,
- IVBSAXEntityResolver **pEntityResolver)
+ IVBSAXEntityResolver **resolver)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
- return internal_getEntityResolver(This, pEntityResolver, TRUE);
+ return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver);
}
static HRESULT WINAPI saxxmlreader_put_entityResolver(
IVBSAXXMLReader* iface,
- IVBSAXEntityResolver *pEntityResolver)
+ IVBSAXEntityResolver *resolver)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
- return internal_putEntityResolver(This, pEntityResolver, TRUE);
+ return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE);
}
static HRESULT WINAPI saxxmlreader_get_contentHandler(
static HRESULT WINAPI saxxmlreader_get_baseURL(
IVBSAXXMLReader* iface,
- const WCHAR **pBaseUrl)
+ BSTR *pBaseUrl)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
static HRESULT WINAPI saxxmlreader_put_baseURL(
IVBSAXXMLReader* iface,
- const WCHAR *pBaseUrl)
+ BSTR pBaseUrl)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
-
- FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
- return E_NOTIMPL;
+ return ISAXXMLReader_putBaseURL(&This->ISAXXMLReader_iface, pBaseUrl);
}
static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
IVBSAXXMLReader* iface,
- const WCHAR **pSecureBaseUrl)
+ BSTR *pSecureBaseUrl)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return E_NOTIMPL;
}
-
static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
IVBSAXXMLReader* iface,
- const WCHAR *secureBaseUrl)
+ BSTR secureBaseUrl)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
-
- FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
- return E_NOTIMPL;
+ return ISAXXMLReader_putSecureBaseURL(&This->ISAXXMLReader_iface, secureBaseUrl);
}
static HRESULT WINAPI saxxmlreader_parse(
static HRESULT WINAPI saxxmlreader_parseURL(
IVBSAXXMLReader* iface,
- const WCHAR *url)
+ BSTR url)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_parseURL(This, url, TRUE);
static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return saxxmlreader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
+ return IVBSAXXMLReader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
}
static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return saxxmlreader_AddRef(&This->IVBSAXXMLReader_iface);
+ return IVBSAXXMLReader_AddRef(&This->IVBSAXXMLReader_iface);
}
static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return saxxmlreader_Release(&This->IVBSAXXMLReader_iface);
+ return IVBSAXXMLReader_Release(&This->IVBSAXXMLReader_iface);
}
/*** ISAXXMLReader methods ***/
static HRESULT WINAPI isaxxmlreader_getFeature(
ISAXXMLReader* iface,
- const WCHAR *pFeature,
- VARIANT_BOOL *pValue)
+ const WCHAR *feature_name,
+ VARIANT_BOOL *value)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return IVBSAXXMLReader_getFeature(&This->IVBSAXXMLReader_iface, pFeature, pValue);
+ saxreader_feature feature;
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
+
+ feature = get_saxreader_feature(feature_name);
+
+ if (This->version < MSXML4 && (feature == ExhaustiveErrors || feature == SchemaValidation))
+ return E_INVALIDARG;
+
+ if (feature == Namespaces ||
+ feature == NamespacePrefixes ||
+ feature == ExhaustiveErrors ||
+ feature == SchemaValidation)
+ return get_feature_value(This, feature, value);
+
+ FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
+ return E_NOTIMPL;
}
static HRESULT WINAPI isaxxmlreader_putFeature(
ISAXXMLReader* iface,
- const WCHAR *pFeature,
- VARIANT_BOOL vfValue)
+ const WCHAR *feature_name,
+ VARIANT_BOOL value)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return IVBSAXXMLReader_putFeature(&This->IVBSAXXMLReader_iface, pFeature, vfValue);
+ saxreader_feature feature;
+
+ TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value);
+
+ feature = get_saxreader_feature(feature_name);
+
+ /* accepted cases */
+ if ((feature == ExhaustiveErrors && value == VARIANT_FALSE) ||
+ (feature == SchemaValidation && value == VARIANT_FALSE) ||
+ feature == Namespaces ||
+ feature == NamespacePrefixes)
+ {
+ return set_feature_value(This, feature, value);
+ }
+
+ if (feature == LexicalHandlerParEntities ||
+ feature == ProhibitDTD ||
+ feature == ExternalGeneralEntities ||
+ feature == ExternalParameterEntities)
+ {
+ FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
+ return set_feature_value(This, feature, value);
+ }
+
+ FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
+ return E_NOTIMPL;
}
static HRESULT WINAPI isaxxmlreader_getProperty(
static HRESULT WINAPI isaxxmlreader_getEntityResolver(
ISAXXMLReader* iface,
- ISAXEntityResolver **ppEntityResolver)
+ ISAXEntityResolver **resolver)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return internal_getEntityResolver(This, ppEntityResolver, FALSE);
+ return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver);
}
static HRESULT WINAPI isaxxmlreader_putEntityResolver(
ISAXXMLReader* iface,
- ISAXEntityResolver *pEntityResolver)
+ ISAXEntityResolver *resolver)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return internal_putEntityResolver(This, pEntityResolver, FALSE);
+ return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE);
}
static HRESULT WINAPI isaxxmlreader_getContentHandler(
static HRESULT WINAPI isaxxmlreader_getBaseURL(
ISAXXMLReader* iface,
- const WCHAR **pBaseUrl)
+ const WCHAR **base_url)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return IVBSAXXMLReader_get_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
+
+ FIXME("(%p)->(%p) stub\n", This, base_url);
+ return E_NOTIMPL;
}
static HRESULT WINAPI isaxxmlreader_putBaseURL(
const WCHAR *pBaseUrl)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return IVBSAXXMLReader_put_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
+
+ FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
+ return E_NOTIMPL;
}
static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
const WCHAR **pSecureBaseUrl)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return IVBSAXXMLReader_get_secureBaseURL(&This->IVBSAXXMLReader_iface, pSecureBaseUrl);
+ FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
+ return E_NOTIMPL;
}
static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
const WCHAR *secureBaseUrl)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
- return IVBSAXXMLReader_put_secureBaseURL(&This->IVBSAXXMLReader_iface, secureBaseUrl);
+
+ FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
+ return E_NOTIMPL;
}
static HRESULT WINAPI isaxxmlreader_parse(
saxreader_iface_tids
};
-HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *outer, LPVOID *ppObj)
+HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj)
{
saxreader *reader;
- TRACE("(%p, %p)\n", outer, ppObj);
+ TRACE("(%p)\n", ppObj);
reader = heap_alloc( sizeof (*reader) );
if( !reader )
reader->sax.comment = libxmlComment;
reader->sax.error = libxmlFatalError;
reader->sax.fatalError = libxmlFatalError;
- reader->sax.cdataBlock = libxmlCDataBlock;
+ reader->sax.cdataBlock = libxml_cdatablock;
+ reader->sax.resolveEntity = libxmlresolveentity;
*ppObj = &reader->IVBSAXXMLReader_iface;
#else
-HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
+HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj)
{
MESSAGE("This program tried to use a SAX XML Reader object, but\n"
"libxml2 support was not present at compile time.\n");