Module: wine Branch: master Commit: 5ac404aa9c8e3279f6ad8ef6126196e54ad5a2b1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5ac404aa9c8e3279f6ad8ef612...
Author: Jacek Caban jacek@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)))