static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI, MSXML_VERSION version) { cache_entry* entry; IXMLDOMDocument3* domdoc = NULL; xmlDocPtr doc = NULL; HRESULT hr = DOMDocument_create(version, (void**)&domdoc); VARIANT_BOOL b = VARIANT_FALSE; CacheEntryType type = CacheEntryType_Invalid; if (hr != S_OK) { FIXME("failed to create domdoc\n"); return NULL; } assert(domdoc != NULL); assert(V_VT(&url) == VT_BSTR); hr = IXMLDOMDocument3_load(domdoc, url, &b); if (hr != S_OK) { ERR("IXMLDOMDocument3_load() returned 0x%08x\n", hr); if (b != VARIANT_TRUE) { FIXME("Failed to load doc at %s\n", debugstr_w(V_BSTR(&url))); IXMLDOMDocument3_Release(domdoc); return NULL; } } doc = xmlNodePtr_from_domnode((IXMLDOMNode*)domdoc, XML_DOCUMENT_NODE)->doc; type = cache_type_from_xmlDocPtr(doc); switch (type) { case CacheEntryType_XSD: entry = cache_entry_from_xsd_doc(doc, nsURI, version); break; case CacheEntryType_XDR: entry = cache_entry_from_xdr_doc(doc, nsURI, version); break; default: entry = NULL; FIXME("invalid schema\n"); break; } IXMLDOMDocument3_Release(domdoc); return entry; }
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; }
static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri, VARIANT var) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); xmlChar* name = uri ? xmlchar_from_wchar(uri) : xmlchar_from_wchar(emptyW); TRACE("(%p)->(%s %s)\n", This, debugstr_w(uri), debugstr_variant(&var)); if (This->read_only) return E_FAIL; switch (V_VT(&var)) { case VT_NULL: { cache_remove_entry(This, name); } break; case VT_BSTR: { cache_entry* entry = cache_entry_from_url(var, name, This->version); if (entry) { cache_entry_add_ref(entry); } else { heap_free(name); return E_FAIL; } cache_add_entry(This, name, entry); } break; case VT_DISPATCH: { xmlDocPtr doc = NULL; cache_entry* entry; CacheEntryType 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 = cache_type_from_xmlDocPtr(doc); if (type == CacheEntryType_XSD) { entry = cache_entry_from_xsd_doc(doc, name, This->version); } else if (type == CacheEntryType_XDR) { entry = cache_entry_from_xdr_doc(doc, name, This->version); } else { WARN("invalid schema!\n"); entry = NULL; } IXMLDOMNode_Release(domnode); if (entry) { cache_entry_add_ref(entry); } else { heap_free(name); return E_FAIL; } cache_add_entry(This, name, entry); } break; default: { heap_free(name); return E_INVALIDARG; } } heap_free(name); return S_OK; }
static inline xmlNodePtr get_attribute( domattr *This ) { return xmlNodePtr_from_domnode( This->node, XML_ATTRIBUTE_NODE ); }