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