From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 99 ++++++++++++++++++++++++++++++++------- dlls/mshtml/tests/misc.c | 13 +++++ 2 files changed, 96 insertions(+), 16 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 610a5d0d4b3..f1c5801764d 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -340,6 +340,46 @@ done: return hres; }
+static HRESULT get_root_node(IXMLDOMDocument *doc, IXMLDOMNode **root) +{ + HRESULT hres; + BSTR str; + + str = SysAllocString(L"root"); + if(!str) + return E_OUTOFMEMORY; + + hres = IXMLDOMDocument_selectSingleNode(doc, str, root); + SysFreeString(str); + return hres; +} + +static HRESULT get_node_list(const WCHAR *filename, IXMLDOMNodeList **node_list) +{ + IXMLDOMDocument *doc; + IXMLDOMNode *root; + HRESULT hres; + BSTR query; + + hres = open_document(filename, &doc); + if(hres != S_OK) + return hres; + + hres = get_root_node(doc, &root); + IXMLDOMDocument_Release(doc); + if(hres != S_OK) + return hres; + + if(!(query = SysAllocString(L"item"))) + hres = E_OUTOFMEMORY; + else { + hres = IXMLDOMNode_selectNodes(root, query, node_list); + SysFreeString(query); + } + IXMLDOMNode_Release(root); + return hres; +} + static HRESULT WINAPI HTMLStorage_get_length(IHTMLStorage *iface, LONG *p) { HTMLStorage *This = impl_from_IHTMLStorage(iface); @@ -354,10 +394,48 @@ static HRESULT WINAPI HTMLStorage_get_remainingSpace(IHTMLStorage *iface, LONG * return E_NOTIMPL; }
+static HRESULT get_key(const WCHAR *filename, LONG index, BSTR *ret) +{ + IXMLDOMNodeList *node_list; + IXMLDOMElement *elem; + IXMLDOMNode *node; + HRESULT hres; + VARIANT key; + + hres = get_node_list(filename, &node_list); + if(FAILED(hres)) + return hres; + + hres = IXMLDOMNodeList_get_item(node_list, index, &node); + IXMLDOMNodeList_Release(node_list); + if(hres != S_OK) + return FAILED(hres) ? hres : E_INVALIDARG; + + hres = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem); + IXMLDOMNode_Release(node); + if(hres != S_OK) + return E_INVALIDARG; + + hres = IXMLDOMElement_getAttribute(elem, (BSTR)L"name", &key); + IXMLDOMElement_Release(elem); + if(FAILED(hres)) + return hres; + + if(V_VT(&key) != VT_BSTR) { + FIXME("non-string key %s\n", debugstr_variant(&key)); + VariantClear(&key); + return E_NOTIMPL; + } + + *ret = V_BSTR(&key); + return S_OK; +} + static HRESULT WINAPI HTMLStorage_key(IHTMLStorage *iface, LONG lIndex, BSTR *p) { HTMLStorage *This = impl_from_IHTMLStorage(iface); struct session_entry *session_entry; + HRESULT hres;
TRACE("(%p)->(%ld %p)\n", This, lIndex, p);
@@ -375,8 +453,11 @@ static HRESULT WINAPI HTMLStorage_key(IHTMLStorage *iface, LONG lIndex, BSTR *p) return *p ? S_OK : E_OUTOFMEMORY; }
- FIXME("local storage not supported\n"); - return E_NOTIMPL; + WaitForSingleObject(This->mutex, INFINITE); + hres = get_key(This->filename, lIndex, p); + ReleaseMutex(This->mutex); + + return hres; }
static BSTR build_query(const WCHAR *key) @@ -390,20 +471,6 @@ static BSTR build_query(const WCHAR *key) return ret; }
-static HRESULT get_root_node(IXMLDOMDocument *doc, IXMLDOMNode **root) -{ - HRESULT hres; - BSTR str; - - str = SysAllocString(L"root"); - if(!str) - return E_OUTOFMEMORY; - - hres = IXMLDOMDocument_selectSingleNode(doc, str, root); - SysFreeString(str); - return hres; -} - static HRESULT get_item(const WCHAR *filename, BSTR key, VARIANT *value) { IXMLDOMDocument *doc; diff --git a/dlls/mshtml/tests/misc.c b/dlls/mshtml/tests/misc.c index 660c191ac99..d898b04fffa 100644 --- a/dlls/mshtml/tests/misc.c +++ b/dlls/mshtml/tests/misc.c @@ -229,6 +229,19 @@ static void test_HTMLStorage(void) ok(hres == S_OK, "getItem failed: %08lx\n", hres); ok(V_VT(&var) == VT_BSTR, "got %d\n", V_VT(&var)); if (V_VT(&var) == VT_BSTR) ok(!wcscmp(V_BSTR(&var), L"null"), "got %s\n", wine_dbgstr_w(V_BSTR(&var))); + SysFreeString(key); + + hres = IHTMLStorage_key(storage, 0, &key); + ok(hres == S_OK, "key failed %08lx\n", hres); + ok(!wcscmp(key, L"undefined"), "key(0) = %s\n", wine_dbgstr_w(key)); + SysFreeString(key); + + hres = IHTMLStorage_key(storage, 1, &key); + ok(hres == E_INVALIDARG, "key failed %08lx\n", hres); + hres = IHTMLStorage_key(storage, -1, &key); + ok(hres == E_INVALIDARG, "key failed %08lx\n", hres); + + key = SysAllocString(L"undefined"); hres = IHTMLStorage_removeItem(storage, key); ok(hres == S_OK, "removeItem failed: %08lx\n", hres); SysFreeString(key);