Commit d9c1f5a4 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Implement remainingSpace prop for sessionStorage.

And a character quota that matches native. Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com>
parent a3546267
......@@ -32,6 +32,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
/* Native defaults to 5 million chars per origin */
enum { MAX_QUOTA = 5000000 };
typedef struct {
DispatchEx dispex;
IHTMLStorage IHTMLStorage_iface;
......@@ -46,6 +49,7 @@ struct session_map_entry {
struct wine_rb_tree data_map;
struct list data_list; /* for key() */
UINT ref;
UINT quota;
UINT num_keys;
UINT origin_len;
WCHAR origin[1];
......@@ -98,6 +102,7 @@ static struct session_map_entry *grab_session_map_entry(BSTR origin)
wine_rb_init(&entry->data_map, session_entry_cmp);
list_init(&entry->data_list);
entry->ref = 1;
entry->quota = MAX_QUOTA;
entry->num_keys = 0;
entry->origin_len = origin_len;
memcpy(entry->origin, origin, origin_len * sizeof(WCHAR));
......@@ -134,11 +139,14 @@ static HRESULT get_session_entry(struct session_map_entry *entry, const WCHAR *n
}
key_len = wcslen(key);
if(entry->quota < key_len)
return E_OUTOFMEMORY; /* native returns this when quota is exceeded */
if(!(data = heap_alloc(FIELD_OFFSET(struct session_entry, key[key_len + 1]))))
return E_OUTOFMEMORY;
data->value = NULL;
memcpy(data->key, key, (key_len + 1) * sizeof(WCHAR));
entry->quota -= key_len;
entry->num_keys++;
list_add_tail(&entry->data_list, &data->list_entry);
wine_rb_put(&entry->data_map, key, &data->entry);
......@@ -156,6 +164,7 @@ static void clear_session_storage(struct session_map_entry *entry)
}
wine_rb_destroy(&entry->data_map, NULL, NULL);
list_init(&entry->data_list);
entry->quota = MAX_QUOTA;
entry->num_keys = 0;
}
......@@ -420,7 +429,15 @@ static HRESULT WINAPI HTMLStorage_get_length(IHTMLStorage *iface, LONG *p)
static HRESULT WINAPI HTMLStorage_get_remainingSpace(IHTMLStorage *iface, LONG *p)
{
HTMLStorage *This = impl_from_IHTMLStorage(iface);
FIXME("(%p)->(%p)\n", This, p);
TRACE("(%p)->(%p)\n", This, p);
if(!This->filename) {
*p = This->session_storage->quota;
return S_OK;
}
FIXME("local storage not supported\n");
return E_NOTIMPL;
}
......@@ -685,7 +702,8 @@ static HRESULT WINAPI HTMLStorage_setItem(IHTMLStorage *iface, BSTR bstrKey, BST
TRACE("(%p)->(%s %s)\n", This, debugstr_w(bstrKey), debugstr_w(bstrValue));
if(!This->filename) {
BSTR value = SysAllocString(bstrValue ? bstrValue : L"");
UINT value_len = bstrValue ? wcslen(bstrValue) : 0;
BSTR value = SysAllocStringLen(bstrValue, value_len);
if(!value)
return E_OUTOFMEMORY;
......@@ -693,6 +711,12 @@ static HRESULT WINAPI HTMLStorage_setItem(IHTMLStorage *iface, BSTR bstrKey, BST
if(FAILED(hres))
SysFreeString(value);
else {
UINT old_len = SysStringLen(session_entry->value);
if(old_len < value_len && This->session_storage->quota < value_len - old_len) {
SysFreeString(value);
return E_OUTOFMEMORY; /* native returns this when quota is exceeded */
}
This->session_storage->quota -= value_len - old_len;
SysFreeString(session_entry->value);
session_entry->value = value;
}
......@@ -757,6 +781,7 @@ static HRESULT WINAPI HTMLStorage_removeItem(IHTMLStorage *iface, BSTR bstrKey)
if(!This->filename) {
hres = get_session_entry(This->session_storage, bstrKey, FALSE, &session_entry);
if(SUCCEEDED(hres) && session_entry) {
This->session_storage->quota += wcslen(session_entry->key) + SysStringLen(session_entry->value);
This->session_storage->num_keys--;
list_remove(&session_entry->list_entry);
wine_rb_remove(&This->session_storage->data_map, &session_entry->entry);
......
......@@ -197,7 +197,7 @@ static void test_HTMLStorage(void)
{
IHTMLDocument2 *doc, *doc2;
IHTMLStorage *storage, *storage2;
LONG length, lval;
LONG space, length, lval;
VARIANT var;
BSTR key, value;
HRESULT hres;
......@@ -346,6 +346,10 @@ static void test_HTMLStorage(void)
ok(hres == S_OK, "get_length failed %08lx\n", hres);
ok(lval == 0, "length = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage, &space);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(space >= 5000000, "remainingSpace = %ld\n", space);
key = SysAllocString(L"");
V_VT(&var) = 0xdead;
hres = IHTMLStorage_getItem(storage, key, &var);
......@@ -369,6 +373,13 @@ static void test_HTMLStorage(void)
ok(hres == S_OK, "get_length failed %08lx\n", hres);
ok(lval == 1, "length = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space - 13, "remainingSpace = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage2, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space - 13, "remainingSpace = %ld\n", lval);
V_VT(&var) = 0xdead;
hres = IHTMLStorage_getItem(storage, key, &var);
ok(hres == S_OK, "getItem failed: %08lx\n", hres);
......@@ -443,6 +454,13 @@ static void test_HTMLStorage(void)
ok(hres == S_OK, "get_length failed %08lx\n", hres);
ok(lval == 2, "length = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space - 21, "remainingSpace = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage2, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space - 21, "remainingSpace = %ld\n", lval);
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));
......@@ -488,6 +506,13 @@ static void test_HTMLStorage(void)
ok(hres == S_OK, "get_length failed %08lx\n", hres);
ok(lval == 0, "length = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space, "remainingSpace = %ld\n", lval);
hres = IHTMLStorage_get_remainingSpace(storage2, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space, "remainingSpace = %ld\n", lval);
hres = IHTMLStorage_key(storage, 0, &key);
ok(hres == E_INVALIDARG, "key failed %08lx\n", hres);
......@@ -526,6 +551,10 @@ static void test_HTMLStorage(void)
ok(!wcscmp(V_BSTR(&var), L"bar"), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
VariantClear(&var);
hres = IHTMLStorage_get_remainingSpace(storage, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space - 6, "remainingSpace = %ld\n", lval);
IHTMLStorage_Release(storage2);
IHTMLDocument2_Release(doc2);
......@@ -538,6 +567,10 @@ static void test_HTMLStorage(void)
ok(hres == S_OK, "getItem failed: %08lx\n", hres);
ok(V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
hres = IHTMLStorage_get_remainingSpace(storage2, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space, "remainingSpace = %ld\n", lval);
hres = IHTMLStorage_setItem(storage2, key, value);
ok(hres == S_OK, "setItem failed: %08lx\n", hres);
......@@ -570,6 +603,10 @@ static void test_HTMLStorage(void)
ok(hres == S_OK, "getItem failed: %08lx\n", hres);
ok(V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
hres = IHTMLStorage_get_remainingSpace(storage2, &lval);
ok(hres == S_OK, "get_remainingSpace failed %08lx\n", hres);
ok(lval == space, "remainingSpace = %ld\n", lval);
hres = IHTMLStorage_clear(storage);
ok(hres == S_OK, "clear failed %08lx\n", hres);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment