Jacek Caban : jscript: Added GetDispID implementation.

Alexandre Julliard julliard at winehq.org
Mon Sep 8 07:41:33 CDT 2008


Module: wine
Branch: master
Commit: 5ac404aa9c8e3279f6ad8ef6126196e54ad5a2b1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5ac404aa9c8e3279f6ad8ef6126196e54ad5a2b1

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Sep  8 00:14:58 2008 +0200

jscript: Added GetDispID implementation.

---

 dlls/jscript/dispex.c  |  147 +++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/jscript/jscript.h |   15 +++++
 2 files changed, 160 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 674a61e..d2af5f8 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -42,6 +42,131 @@ struct _dispex_prop_t {
     } u;
 };
 
+static inline DISPID prop_to_id(DispatchEx *This, dispex_prop_t *prop)
+{
+    return prop - This->props;
+}
+
+static const builtin_prop_t *find_builtin_prop(DispatchEx *This, const WCHAR *name)
+{
+    int min = 0, max, i, r;
+
+    max = This->builtin_info->props_cnt-1;
+    while(min <= max) {
+        i = (min+max)/2;
+
+        r = strcmpW(name, This->builtin_info->props[i].name);
+        if(!r)
+            return This->builtin_info->props + i;
+
+        if(r < 0)
+            max = i-1;
+        else
+            min = i+1;
+    }
+
+    return NULL;
+}
+
+static dispex_prop_t *alloc_prop(DispatchEx *This, const WCHAR *name, prop_type_t type, DWORD flags)
+{
+    dispex_prop_t *ret;
+
+    if(This->buf_size == This->prop_cnt) {
+        dispex_prop_t *tmp = heap_realloc(This->props, (This->buf_size<<=1)*sizeof(*This->props));
+        if(!tmp)
+            return NULL;
+        This->props = tmp;
+    }
+
+    ret = This->props + This->prop_cnt++;
+    ret->type = type;
+    ret->flags = flags;
+    ret->name = heap_strdupW(name);
+    if(!ret->name)
+        return NULL;
+
+    return ret;
+}
+
+static dispex_prop_t *alloc_protref(DispatchEx *This, const WCHAR *name, DWORD ref)
+{
+    dispex_prop_t *ret;
+
+    ret = alloc_prop(This, name, PROP_PROTREF, 0);
+    if(!ret)
+        return NULL;
+
+    ret->u.ref = ref;
+    return ret;
+}
+
+static HRESULT find_prop_name(DispatchEx *This, const WCHAR *name, dispex_prop_t **ret)
+{
+    const builtin_prop_t *builtin;
+    dispex_prop_t *prop;
+
+    for(prop = This->props; prop < This->props+This->prop_cnt; prop++) {
+        if(prop->name && !strcmpW(prop->name, name)) {
+            *ret = prop;
+            return S_OK;
+        }
+    }
+
+    builtin = find_builtin_prop(This, name);
+    if(builtin) {
+        prop = alloc_prop(This, name, PROP_BUILTIN, builtin->flags);
+        if(!prop)
+            return E_OUTOFMEMORY;
+
+        prop->u.p = builtin;
+        *ret = prop;
+        return S_OK;
+    }
+
+    *ret = NULL;
+    return S_OK;
+}
+
+static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL alloc, dispex_prop_t **ret)
+{
+    dispex_prop_t *prop;
+    HRESULT hres;
+
+    hres = find_prop_name(This, name, &prop);
+    if(FAILED(hres))
+        return hres;
+    if(prop) {
+        *ret = prop;
+        return S_OK;
+    }
+
+    if(This->prototype) {
+        hres = find_prop_name_prot(This->prototype, name, FALSE, &prop);
+        if(FAILED(hres))
+            return hres;
+        if(prop) {
+            prop = alloc_protref(This, prop->name, prop - This->prototype->props);
+            if(!prop)
+                return E_OUTOFMEMORY;
+            *ret = prop;
+            return S_OK;
+        }
+    }
+
+    if(alloc) {
+        TRACE("creating prop %s\n", debugstr_w(name));
+
+        prop = alloc_prop(This, name, PROP_VARIANT, PROPF_ENUM);
+        if(!prop)
+            return E_OUTOFMEMORY;
+        VariantInit(&prop->u.var);
+    }
+
+    *ret = prop;
+    return S_OK;
+}
+
 #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
 
 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
@@ -158,8 +283,26 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
 {
     DispatchEx *This = DISPATCHEX_THIS(iface);
-    FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
-    return E_NOTIMPL;
+    dispex_prop_t *prop;
+    HRESULT hres;
+
+    TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
+
+    if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit)) {
+        FIXME("Unsupported grfdex %x\n", grfdex);
+        return E_NOTIMPL;
+    }
+
+    hres = find_prop_name_prot(This, bstrName, (grfdex&fdexNameEnsure) != 0, &prop);
+    if(FAILED(hres))
+        return hres;
+    if(prop) {
+        *pid = prop_to_id(This, prop);
+        return S_OK;
+    }
+
+    TRACE("not found %s\n", debugstr_w(bstrName));
+    return DISP_E_UNKNOWNNAME;
 }
 
 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index b4c872e..1084ec4 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -151,4 +151,19 @@ static inline BOOL heap_free(void *mem)
     return HeapFree(GetProcessHeap(), 0, mem);
 }
 
+static inline LPWSTR heap_strdupW(LPCWSTR str)
+{
+    LPWSTR ret = NULL;
+
+    if(str) {
+        DWORD size;
+
+        size = (strlenW(str)+1)*sizeof(WCHAR);
+        ret = heap_alloc(size);
+        memcpy(ret, str, size);
+    }
+
+    return ret;
+}
+
 #define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))




More information about the wine-cvs mailing list