static HRESULT WINAPI domcomment_appendData( IXMLDOMComment *iface, BSTR p) { domcomment *This = impl_from_IXMLDOMComment( iface ); xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node ); xmlChar *pContent; HRESULT hr = S_FALSE; TRACE("%p\n", iface); /* Nothing to do if NULL or an Empty string passed in. */ if(p == NULL || SysStringLen(p) == 0) return S_OK; pContent = xmlChar_from_wchar( (WCHAR*)p ); if(pContent) { /* Older versions of libxml < 2.6.27 didn't correctly support xmlTextConcat on Comment nodes. Fallback to setting the contents directly if xmlTextConcat fails. NOTE: if xmlTextConcat fails, pContent is destroyed. */ if(xmlTextConcat(pDOMNode->node, pContent, SysStringLen(p) ) == 0) hr = S_OK; else { xmlChar *pNew; pContent = xmlChar_from_wchar( (WCHAR*)p ); if(pContent) { pNew = xmlStrcat(xmlNodeGetContent(pDOMNode->node), pContent); if(pNew) { xmlNodeSetContent(pDOMNode->node, pNew); hr = S_OK; } else hr = E_FAIL; } else hr = E_FAIL; } } else hr = E_FAIL; return hr; }
static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement *iface, BSTR strPropertyName) { xmlelem *This = impl_from_IXMLElement(iface); xmlChar *name; xmlAttrPtr attr; int res; HRESULT hr = S_FALSE; TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName)); if (!strPropertyName) return E_INVALIDARG; name = xmlChar_from_wchar(strPropertyName); attr = xmlHasProp(This->node, name); if (!attr) goto done; res = xmlRemoveProp(attr); if (res == 0) hr = S_OK; done: HeapFree(GetProcessHeap(), 0, name); return hr; }
static HRESULT WINAPI schema_cache_remove(IXMLDOMSchemaCollection2* iface, BSTR uri) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); xmlChar* name = xmlChar_from_wchar(uri); TRACE("(%p)->(%s)\n", This, wine_dbgstr_w(uri)); xmlHashRemoveEntry(This->cache, name, cache_free); heap_free(name); return S_OK; }
static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName, VARIANT PropertyValue) { xmlelem *This = impl_from_IXMLElement(iface); xmlChar *name, *value; xmlAttrPtr attr; TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName)); if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR) return E_INVALIDARG; name = xmlChar_from_wchar(strPropertyName); value = xmlChar_from_wchar(V_BSTR(&PropertyValue)); attr = xmlSetProp(This->node, name, value); HeapFree(GetProcessHeap(), 0, name); HeapFree(GetProcessHeap(), 0, value); return (attr) ? S_OK : S_FALSE; }
static HRESULT WINAPI xmlelem_put_text(IXMLElement *iface, BSTR p) { xmlelem *This = impl_from_IXMLElement(iface); xmlChar *content; TRACE("(%p, %s)\n", iface, debugstr_w(p)); /* FIXME: test which types can be used */ if (This->node->type == XML_ELEMENT_NODE) return E_NOTIMPL; content = xmlChar_from_wchar(p); xmlNodeSetContent(This->node, content); HeapFree( GetProcessHeap(), 0, content); return S_OK; }
HRESULT queryresult_create(xmlNodePtr node, LPWSTR szQuery, IXMLDOMNodeList **out) { queryresult *This = CoTaskMemAlloc(sizeof(queryresult)); xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc); xmlChar *str = xmlChar_from_wchar(szQuery); HRESULT hr; TRACE("(%p, %s, %p)\n", node, wine_dbgstr_w(szQuery), out); *out = NULL; if (This == NULL || ctxt == NULL || str == NULL) { hr = E_OUTOFMEMORY; goto cleanup; } This->lpVtbl = &queryresult_vtbl; This->ref = 1; This->resultPos = 0; This->node = node; xmldoc_add_ref(This->node->doc); ctxt->node = node; This->result = xmlXPathEval(str, ctxt); if (!This->result || This->result->type != XPATH_NODESET) { hr = E_FAIL; goto cleanup; } *out = (IXMLDOMNodeList *)This; hr = S_OK; TRACE("found %d matches\n", This->result->nodesetval->nodeNr); cleanup: if (This != NULL && FAILED(hr)) IXMLDOMNodeList_Release( (IXMLDOMNodeList*) &This->lpVtbl ); if (ctxt != NULL) xmlXPathFreeContext(ctxt); HeapFree(GetProcessHeap(), 0, str); return hr; }
static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR strPropertyName, VARIANT *PropertyValue) { xmlelem *This = impl_from_IXMLElement(iface); xmlChar *val = NULL, *name; xmlAttrPtr ptr; TRACE("(%p, %s, %p)\n", iface, debugstr_w(strPropertyName), PropertyValue); if (!PropertyValue) return E_INVALIDARG; VariantInit(PropertyValue); V_BSTR(PropertyValue) = NULL; if (!strPropertyName) return E_INVALIDARG; name = xmlChar_from_wchar(strPropertyName); ptr = This->node->properties; while (ptr) { if (!lstrcmpiA((LPSTR)name, (LPCSTR)ptr->name)) { val = xmlNodeListGetString(ptr->doc, ptr->children, 1); break; } ptr = ptr->next; } if (val) { V_VT(PropertyValue) = VT_BSTR; V_BSTR(PropertyValue) = bstr_from_xmlChar(val); } HeapFree(GetProcessHeap(), 0, name); xmlFree(val); TRACE("returning %s\n", debugstr_w(V_BSTR(PropertyValue))); return (val) ? S_OK : S_FALSE; }
static HRESULT WINAPI schema_cache_get(IXMLDOMSchemaCollection2* iface, BSTR uri, IXMLDOMNode** node) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); xmlChar* name; cache_entry* entry; TRACE("(%p)->(%s, %p)\n", This, wine_dbgstr_w(uri), node); if (!node) return E_POINTER; name = xmlChar_from_wchar(uri); entry = (cache_entry*) xmlHashLookup(This->cache, name); heap_free(name); /* TODO: this should be read-only */ if (entry) return DOMDocument_create_from_xmldoc(entry->doc, (IXMLDOMDocument3**)node); *node = NULL; return S_OK; }
static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri, VARIANT var) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); xmlChar* name = xmlChar_from_wchar(uri); TRACE("(%p)->(%s, var(vt %x))\n", This, debugstr_w(uri), V_VT(&var)); switch (V_VT(&var)) { case VT_NULL: { xmlHashRemoveEntry(This->cache, name, cache_free); } break; case VT_BSTR: { xmlChar* url = xmlChar_from_wchar(V_BSTR(&var)); cache_entry* entry = cache_entry_from_url((char const*)url); heap_free(url); if (entry) { cache_entry_add_ref(entry); } else { heap_free(name); return E_FAIL; } xmlHashRemoveEntry(This->cache, name, cache_free); xmlHashAddEntry(This->cache, name, entry); } break; case VT_DISPATCH: { xmlDocPtr doc = NULL; cache_entry* entry; SCHEMA_TYPE type; IXMLDOMNode* domnode = NULL; IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLDOMNode, (void**)&domnode); if (domnode) doc = xmlNodePtr_from_domnode(domnode, XML_DOCUMENT_NODE)->doc; if (!doc) { IXMLDOMNode_Release(domnode); heap_free(name); return E_INVALIDARG; } type = schema_type_from_xmlDocPtr(doc); if (type == SCHEMA_TYPE_XSD) { entry = cache_entry_from_xsd_doc(doc); } else if (type == SCHEMA_TYPE_XDR) { entry = cache_entry_from_xdr_doc(doc); } else { WARN("invalid schema!\n"); entry = NULL; } IXMLDOMNode_Release(domnode); if (entry) { cache_entry_add_ref(entry); } else { heap_free(name); return E_FAIL; } xmlHashRemoveEntry(This->cache, name, cache_free); xmlHashAddEntry(This->cache, name, entry); } break; default: { heap_free(name); return E_INVALIDARG; } } heap_free(name); return S_OK; }
HRESULT queryresult_create(xmlNodePtr node, LPCWSTR szQuery, IXMLDOMNodeList **out) { queryresult *This = heap_alloc_zero(sizeof(queryresult)); xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc); xmlChar *str = xmlChar_from_wchar(szQuery); HRESULT hr; TRACE("(%p, %s, %p)\n", node, wine_dbgstr_w(szQuery), out); *out = NULL; if (This == NULL || ctxt == NULL || str == NULL) { hr = E_OUTOFMEMORY; goto cleanup; } This->lpVtbl = &queryresult_vtbl; This->ref = 1; This->resultPos = 0; This->node = node; xmldoc_add_ref(This->node->doc); ctxt->error = query_serror; ctxt->node = node; registerNamespaces(ctxt); if (is_xpathmode(This->node->doc)) { xmlXPathRegisterAllFunctions(ctxt); } else { xmlChar* tmp; int len; tmp = XSLPattern_to_XPath(ctxt, str); len = (xmlStrlen(tmp)+1)*sizeof(xmlChar); str = heap_realloc(str, len); memcpy(str, tmp, len); xmlFree(tmp); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"index", XSLPattern_index); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"end", XSLPattern_end); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"nodeType", XSLPattern_nodeType); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IEq", XSLPattern_OP_IEq); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_INEq", XSLPattern_OP_INEq); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILt", XSLPattern_OP_ILt); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILEq", XSLPattern_OP_ILEq); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq); } This->result = xmlXPathEvalExpression(str, ctxt); if (!This->result || This->result->type != XPATH_NODESET) { hr = E_FAIL; goto cleanup; } init_dispex(&This->dispex, (IUnknown*)&This->lpVtbl, &queryresult_dispex); *out = (IXMLDOMNodeList *) &This->lpVtbl; hr = S_OK; TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval)); cleanup: if (This != NULL && FAILED(hr)) IXMLDOMNodeList_Release( (IXMLDOMNodeList*) &This->lpVtbl ); xmlXPathFreeContext(ctxt); heap_free(str); return hr; }
static HRESULT WINAPI domcomment_insertData( IXMLDOMComment *iface, long offset, BSTR p) { domcomment *This = impl_from_IXMLDOMComment( iface ); xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node ); xmlChar *pXmlContent; BSTR sNewString; HRESULT hr = S_FALSE; long nLength = 0, nLengthP = 0; xmlChar *str = NULL; TRACE("%p\n", This); /* If have a NULL or empty string, don't do anything. */ if(SysStringLen(p) == 0) return S_OK; if(offset < 0) { return E_INVALIDARG; } pXmlContent = xmlNodeGetContent(pDOMNode->node); if(pXmlContent) { BSTR sContent = bstr_from_xmlChar( pXmlContent ); nLength = SysStringLen(sContent); nLengthP = SysStringLen(p); if(nLength < offset) { SysFreeString(sContent); xmlFree(pXmlContent); return E_INVALIDARG; } sNewString = SysAllocStringLen(NULL, nLength + nLengthP + 1); if(sNewString) { if(offset > 0) memcpy(sNewString, sContent, offset * sizeof(WCHAR)); memcpy(&sNewString[offset], p, nLengthP * sizeof(WCHAR)); if(offset+nLengthP < nLength) memcpy(&sNewString[offset+nLengthP], &sContent[offset], (nLength-offset) * sizeof(WCHAR)); sNewString[nLengthP + nLength] = 0; str = xmlChar_from_wchar((WCHAR*)sNewString); if(str) { xmlNodeSetContent(pDOMNode->node, str); hr = S_OK; } SysFreeString(sNewString); } SysFreeString(sContent); xmlFree(pXmlContent); } return hr; }
static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR name, VARIANT *value) { static const WCHAR xmllangW[] = { 'x','m','l',':','l','a','n','g',0 }; xmlelem *This = impl_from_IXMLElement(iface); xmlChar *val = NULL; TRACE("(%p, %s, %p)\n", iface, debugstr_w(name), value); if (!value) return E_INVALIDARG; VariantInit(value); V_BSTR(value) = NULL; if (!name) return E_INVALIDARG; /* case for xml:lang attribute */ if (!lstrcmpiW(name, xmllangW)) { xmlNsPtr ns; ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml"); val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href); } else { xmlAttrPtr attr; xmlChar *xml_name; xml_name = xmlChar_from_wchar(name); attr = This->node->properties; while (attr) { BSTR attr_name; attr_name = bstr_from_xmlChar(attr->name); if (!lstrcmpiW(name, attr_name)) { val = xmlNodeListGetString(attr->doc, attr->children, 1); SysFreeString(attr_name); break; } attr = attr->next; SysFreeString(attr_name); } heap_free(xml_name); } if (val) { V_VT(value) = VT_BSTR; V_BSTR(value) = bstr_from_xmlChar(val); } xmlFree(val); TRACE("returning %s\n", debugstr_w(V_BSTR(value))); return (val) ? S_OK : S_FALSE; }