-- v2: mshtml: Use the common object implementation for HTMLAttributeCollection mshtml: Use the common object implementation for HTMLStyleSheetsCollection mshtml: Use the common object implementation for HTMLRectCollection mshtml: Use the common object implementation for HTMLSelectElement enumerator. mshtml: Use the common object implementation for HTMLFormElement enumerator. mshtml: Use the common object implementation for HTMLDOMChildrenCollection mshtml: Use a common object implementation for HTMLElementCollection
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 141 +++++++++++++++++++++++++++++++++++ dlls/mshtml/htmlelemcol.c | 139 ++++------------------------------ dlls/mshtml/mshtml_private.h | 17 +++++ 3 files changed, 171 insertions(+), 126 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index cd256dba677..88d2e3e37ba 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2901,6 +2901,147 @@ static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { JSDispatchHost_ToString, };
+static inline CollectionEnum *CollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, CollectionEnum, IEnumVARIANT_iface); +} + +static HRESULT WINAPI CollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) + *ppv = &This->IEnumVARIANT_iface; + else { + FIXME("Unsupported iface %s\n", debugstr_mshtml_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CollectionEnum_AddRef(IEnumVARIANT *iface) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; +} + +static ULONG WINAPI CollectionEnum_Release(IEnumVARIANT *iface) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + DispatchEx_Release(&This->collection->IWineJSDispatchHost_iface); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + ULONG iter = This->iter, len, fetched = 0; + DispatchEx *col = This->collection; + HRESULT hres; + + TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched); + + len = This->vtbl->get_length(col); + + while(iter + fetched < len && fetched < celt) { + hres = This->vtbl->get_item(col, iter + fetched, &V_DISPATCH(rgVar + fetched)); + if(FAILED(hres)) { + while(fetched--) + VariantClear(rgVar + fetched); + return hres; + } + V_VT(rgVar + fetched) = V_DISPATCH(rgVar + fetched) ? VT_DISPATCH : VT_NULL; + fetched++; + } + + This->iter = iter + fetched; + if(pCeltFetched) + *pCeltFetched = fetched; + return fetched == celt ? S_OK : S_FALSE; +} + +static HRESULT WINAPI CollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + ULONG len; + + TRACE("(%p)->(%ld)\n", This, celt); + + len = This->vtbl->get_length(This->collection); + + if(This->iter + celt > len) { + This->iter = len; + return S_FALSE; + } + + This->iter += celt; + return S_OK; +} + +static HRESULT WINAPI CollectionEnum_Reset(IEnumVARIANT *iface) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + + TRACE("(%p)->()\n", This); + + This->iter = 0; + return S_OK; +} + +static HRESULT WINAPI CollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + + FIXME("(%p)->(%p)\n", This, ppEnum); + + return E_NOTIMPL; +} + +static const IEnumVARIANTVtbl CollectionEnumVtbl = { + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, + CollectionEnum_Next, + CollectionEnum_Skip, + CollectionEnum_Reset, + CollectionEnum_Clone +}; + +HRESULT CollectionEnum_create(DispatchEx *collection, const CollectionEnum_vtbl *vtbl, IUnknown **ret) +{ + CollectionEnum *colenum = malloc(sizeof(*colenum)); + + if(!colenum) + return E_OUTOFMEMORY; + + colenum->vtbl = vtbl; + colenum->IEnumVARIANT_iface.lpVtbl = &CollectionEnumVtbl; + colenum->ref = 1; + colenum->iter = 0; + colenum->collection = collection; + DispatchEx_AddRef(&collection->IWineJSDispatchHost_iface); + + *ret = (IUnknown*)&colenum->IEnumVARIANT_iface; + return S_OK; +} + HRESULT dispex_builtin_props_to_json(DispatchEx *dispex, HTMLInnerWindow *window, VARIANT *ret) { func_info_t *func, *end; diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c index 5b3d9b56310..937628e7b4f 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -39,15 +39,6 @@ typedef struct { DWORD len; } HTMLElementCollection;
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLElementCollection *col; -} HTMLElementCollectionEnum; - typedef struct { HTMLElement **buf; DWORD len; @@ -93,116 +84,30 @@ static inline BOOL is_elem_node(nsIDOMNode *node) return type == ELEMENT_NODE || type == COMMENT_NODE; }
-static inline HTMLElementCollectionEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLElementCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLElementCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("Unsupported iface %s\n", debugstr_mshtml_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLElementCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLElementCollectionEnum_Release(IEnumVARIANT *iface) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLElementCollection_Release(&This->col->IHTMLElementCollection_iface); - free(This); - } - - return ref; -} - -static HRESULT WINAPI HTMLElementCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) { - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - ULONG fetched = 0; - - TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched); - - while(This->iter+fetched < This->col->len && fetched < celt) { - V_VT(rgVar+fetched) = VT_DISPATCH; - V_DISPATCH(rgVar+fetched) = (IDispatch*)&This->col->elems[This->iter+fetched]->IHTMLElement_iface; - IDispatch_AddRef(V_DISPATCH(rgVar+fetched)); - fetched++; - } - - This->iter += fetched; - if(pCeltFetched) - *pCeltFetched = fetched; - return fetched == celt ? S_OK : S_FALSE; + return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); }
-static HRESULT WINAPI HTMLElementCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +static ULONG HTMLElementCollectionEnum_get_length(DispatchEx *dispex) { - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); + HTMLElementCollection *col = impl_from_DispatchEx(dispex);
- TRACE("(%p)->(%ld)\n", This, celt); - - if(This->iter + celt > This->col->len) { - This->iter = This->col->len; - return S_FALSE; - } - - This->iter += celt; - return S_OK; + return col->len; }
-static HRESULT WINAPI HTMLElementCollectionEnum_Reset(IEnumVARIANT *iface) +static HRESULT HTMLElementCollectionEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); + HTMLElementCollection *col = impl_from_DispatchEx(dispex);
- This->iter = 0; + *p = (IDispatch*)&col->elems[index]->IHTMLElement_iface; + IDispatch_AddRef(*p); return S_OK; }
-static HRESULT WINAPI HTMLElementCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; -} - -static const IEnumVARIANTVtbl HTMLElementCollectionEnumVtbl = { - HTMLElementCollectionEnum_QueryInterface, - HTMLElementCollectionEnum_AddRef, - HTMLElementCollectionEnum_Release, - HTMLElementCollectionEnum_Next, - HTMLElementCollectionEnum_Skip, - HTMLElementCollectionEnum_Reset, - HTMLElementCollectionEnum_Clone +static const CollectionEnum_vtbl HTMLElementCollectionEnum_vtbl = { + HTMLElementCollectionEnum_get_length, + HTMLElementCollectionEnum_get_item, };
static inline HTMLElementCollection *impl_from_IHTMLElementCollection(IHTMLElementCollection *iface) @@ -246,23 +151,10 @@ static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection IUnknown **p) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); - HTMLElementCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLElementCollectionEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - IHTMLElementCollection_AddRef(&This->IHTMLElementCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->dispex, &HTMLElementCollectionEnum_vtbl, p); }
static BOOL is_elem_id(HTMLElement *elem, LPCWSTR name) @@ -459,11 +351,6 @@ static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = { HTMLElementCollection_tags };
-static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); -} - static void *HTMLElementCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLElementCollection *This = impl_from_DispatchEx(dispex); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 6e4a58aee55..0966b294e46 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -360,6 +360,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN)
typedef struct DispatchEx DispatchEx; +typedef struct CollectionEnum CollectionEnum; typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback; typedef struct dispex_static_data_t dispex_static_data_t;
@@ -609,6 +610,22 @@ struct DispatchEx { } \ DISPEX_IDISPATCH_NOUNK_IMPL(prefix, iface_name, dispex)
+typedef struct { + ULONG (*get_length)(DispatchEx*); + HRESULT (*get_item)(DispatchEx*,ULONG,IDispatch**); +} CollectionEnum_vtbl; + +struct CollectionEnum { + const CollectionEnum_vtbl *vtbl; + IEnumVARIANT IEnumVARIANT_iface; + LONG ref; + + DispatchEx *collection; + ULONG iter; +}; + +HRESULT CollectionEnum_create(DispatchEx*,const CollectionEnum_vtbl*,IUnknown**); + typedef struct { void *vtbl; int ref_flags;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlnode.c | 167 +++++------------------------------------ 1 file changed, 20 insertions(+), 147 deletions(-)
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 0d9a5259935..846bf1382a5 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -43,153 +43,44 @@ typedef struct { nsIDOMNodeList *nslist; } HTMLDOMChildrenCollection;
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLDOMChildrenCollection *col; -} HTMLDOMChildrenCollectionEnum; - -static inline HTMLDOMChildrenCollectionEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLDOMChildrenCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLDOMChildrenCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLDOMChildrenCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) { - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLDOMChildrenCollection_Release(&This->col->IHTMLDOMChildrenCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); }
-static ULONG get_enum_len(HTMLDOMChildrenCollectionEnum *This) +static ULONG HTMLDOMChildrenCollectionEnum_get_length(DispatchEx *dispex) { - UINT32 len; + HTMLDOMChildrenCollection *col = impl_from_DispatchEx(dispex); nsresult nsres; + UINT32 len;
- nsres = nsIDOMNodeList_GetLength(This->col->nslist, &len); + nsres = nsIDOMNodeList_GetLength(col->nslist, &len); assert(nsres == NS_OK); return len; }
-static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static HRESULT HTMLDOMChildrenCollectionEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - ULONG fetched = 0, len; + HTMLDOMChildrenCollection *col = impl_from_DispatchEx(dispex); nsIDOMNode *nsnode; HTMLDOMNode *node; nsresult nsres; HRESULT hres;
- TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched); - - len = get_enum_len(This); - - while(This->iter+fetched < len && fetched < celt) { - nsres = nsIDOMNodeList_Item(This->col->nslist, This->iter+fetched, &nsnode); - assert(nsres == NS_OK); - - hres = get_node(nsnode, TRUE, &node); - nsIDOMNode_Release(nsnode); - if(FAILED(hres)) { - while(fetched--) - VariantClear(rgVar+fetched); - return hres; - } - - V_VT(rgVar+fetched) = VT_DISPATCH; - V_DISPATCH(rgVar+fetched) = (IDispatch*)&node->IHTMLDOMNode_iface; - fetched++; - } - - This->iter += fetched; - if(pCeltFetched) - *pCeltFetched = fetched; - return fetched == celt ? S_OK : S_FALSE; -} - -static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) -{ - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - ULONG len; - - TRACE("(%p)->(%ld)\n", This, celt); - - len = get_enum_len(This); - if(This->iter + celt > len) { - This->iter = len; - return S_FALSE; - } - - This->iter += celt; - return S_OK; -} - -static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Reset(IEnumVARIANT *iface) -{ - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); - - This->iter = 0; - return S_OK; -} + nsres = nsIDOMNodeList_Item(col->nslist, index, &nsnode); + if(NS_FAILED(nsres)) + return map_nsresult(nsres);
-static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; + hres = get_node(nsnode, TRUE, &node); + nsIDOMNode_Release(nsnode); + if(SUCCEEDED(hres)) + *p = (IDispatch*)&node->IHTMLDOMNode_iface; + return hres; }
-static const IEnumVARIANTVtbl HTMLDOMChildrenCollectionEnumVtbl = { - HTMLDOMChildrenCollectionEnum_QueryInterface, - HTMLDOMChildrenCollectionEnum_AddRef, - HTMLDOMChildrenCollectionEnum_Release, - HTMLDOMChildrenCollectionEnum_Next, - HTMLDOMChildrenCollectionEnum_Skip, - HTMLDOMChildrenCollectionEnum_Reset, - HTMLDOMChildrenCollectionEnum_Clone +static const CollectionEnum_vtbl HTMLDOMChildrenCollectionEnum_vtbl = { + HTMLDOMChildrenCollectionEnum_get_length, + HTMLDOMChildrenCollectionEnum_get_item, };
static inline HTMLDOMChildrenCollection *impl_from_IHTMLDOMChildrenCollection(IHTMLDOMChildrenCollection *iface) @@ -215,23 +106,10 @@ static HRESULT WINAPI HTMLDOMChildrenCollection_get_length(IHTMLDOMChildrenColle static HRESULT WINAPI HTMLDOMChildrenCollection_get__newEnum(IHTMLDOMChildrenCollection *iface, IUnknown **p) { HTMLDOMChildrenCollection *This = impl_from_IHTMLDOMChildrenCollection(iface); - HTMLDOMChildrenCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLDOMChildrenCollectionEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - IHTMLDOMChildrenCollection_AddRef(&This->IHTMLDOMChildrenCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->dispex, &HTMLDOMChildrenCollectionEnum_vtbl, p); }
static HRESULT WINAPI HTMLDOMChildrenCollection_item(IHTMLDOMChildrenCollection *iface, LONG index, IDispatch **ppItem) @@ -282,11 +160,6 @@ static const IHTMLDOMChildrenCollectionVtbl HTMLDOMChildrenCollectionVtbl = { HTMLDOMChildrenCollection_item };
-static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); -} - static void *HTMLDOMChildrenCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlform.c | 156 ++++------------------------------------- 1 file changed, 14 insertions(+), 142 deletions(-)
diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 29986158ca7..1007d27269d 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -42,15 +42,6 @@ struct HTMLFormElement { nsIDOMHTMLFormElement *nsform; };
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLFormElement *elem; -} HTMLFormElementEnum; - HRESULT return_nsform(nsresult nsres, nsIDOMHTMLFormElement *form, IHTMLFormElement **p) { nsIDOMNode *form_node; @@ -118,133 +109,32 @@ static HRESULT htmlform_item(HTMLFormElement *This, int i, IDispatch **ret) return S_OK; }
-static inline HTMLFormElementEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLFormElementEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLFormElementEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLFormElementEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLFormElementEnum_Release(IEnumVARIANT *iface) -{ - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLFormElement_Release(&This->elem->IHTMLFormElement_iface); - free(This); - } - - return ref; -} - -static HRESULT WINAPI HTMLFormElementEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static inline HTMLFormElement *impl_from_DispatchEx(DispatchEx *iface) { - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - nsresult nsres; - HRESULT hres; - ULONG num, i; - LONG len; - - TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched); - - nsres = nsIDOMHTMLFormElement_GetLength(This->elem->nsform, &len); - if(NS_FAILED(nsres)) - return E_FAIL; - num = min(len - This->iter, celt); - - for(i = 0; i < num; i++) { - hres = htmlform_item(This->elem, This->iter + i, &V_DISPATCH(&rgVar[i])); - if(FAILED(hres)) { - while(i--) - VariantClear(&rgVar[i]); - return hres; - } - V_VT(&rgVar[i]) = VT_DISPATCH; - } - - This->iter += num; - if(pCeltFetched) - *pCeltFetched = num; - return num == celt ? S_OK : S_FALSE; + return CONTAINING_RECORD(iface, HTMLFormElement, element.node.event_target.dispex); }
-static HRESULT WINAPI HTMLFormElementEnum_Skip(IEnumVARIANT *iface, ULONG celt) +static ULONG HTMLFormElementEnum_get_length(DispatchEx *dispex) { - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLFormElement *elem = impl_from_DispatchEx(dispex); nsresult nsres; LONG len;
- TRACE("(%p)->(%lu)\n", This, celt); - - nsres = nsIDOMHTMLFormElement_GetLength(This->elem->nsform, &len); - if(NS_FAILED(nsres)) - return E_FAIL; - - if(This->iter + celt > len) { - This->iter = len; - return S_FALSE; - } - - This->iter += celt; - return S_OK; + nsres = nsIDOMHTMLFormElement_GetLength(elem->nsform, &len); + assert(nsres == NS_OK); + return len; }
-static HRESULT WINAPI HTMLFormElementEnum_Reset(IEnumVARIANT *iface) +static HRESULT HTMLFormElementEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); + HTMLFormElement *elem = impl_from_DispatchEx(dispex);
- This->iter = 0; - return S_OK; -} - -static HRESULT WINAPI HTMLFormElementEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; + return htmlform_item(elem, index, p); }
-static const IEnumVARIANTVtbl HTMLFormElementEnumVtbl = { - HTMLFormElementEnum_QueryInterface, - HTMLFormElementEnum_AddRef, - HTMLFormElementEnum_Release, - HTMLFormElementEnum_Next, - HTMLFormElementEnum_Skip, - HTMLFormElementEnum_Reset, - HTMLFormElementEnum_Clone +static const CollectionEnum_vtbl HTMLFormElementEnum_vtbl = { + HTMLFormElementEnum_get_length, + HTMLFormElementEnum_get_item, };
static inline HTMLFormElement *impl_from_IHTMLFormElement(IHTMLFormElement *iface) @@ -633,23 +523,10 @@ static HRESULT WINAPI HTMLFormElement_get_length(IHTMLFormElement *iface, LONG * static HRESULT WINAPI HTMLFormElement__newEnum(IHTMLFormElement *iface, IUnknown **p) { HTMLFormElement *This = impl_from_IHTMLFormElement(iface); - HTMLFormElementEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLFormElementEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - HTMLFormElement_AddRef(&This->IHTMLFormElement_iface); - ret->elem = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->element.node.event_target.dispex, &HTMLFormElementEnum_vtbl, p); }
static HRESULT WINAPI HTMLFormElement_item(IHTMLFormElement *iface, VARIANT name, @@ -718,11 +595,6 @@ static const IHTMLFormElementVtbl HTMLFormElementVtbl = { HTMLFormElement_tags };
-static inline HTMLFormElement *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLFormElement, element.node.event_target.dispex); -} - static void *HTMLFormElement_query_interface(DispatchEx *dispex, REFIID riid) { HTMLFormElement *This = impl_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlselect.c | 162 ++++----------------------------------- 1 file changed, 17 insertions(+), 145 deletions(-)
diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 97a47e38762..0034defe8f3 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -529,20 +529,16 @@ struct HTMLSelectElement { nsIDOMHTMLSelectElement *nsselect; };
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLSelectElement *elem; -} HTMLSelectElementEnum; - static inline HTMLSelectElement *impl_from_IHTMLSelectElement(IHTMLSelectElement *iface) { return CONTAINING_RECORD(iface, HTMLSelectElement, IHTMLSelectElement_iface); }
+static inline HTMLSelectElement *impl_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLSelectElement, element.node.event_target.dispex); +} + static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret) { nsIDOMHTMLOptionsCollection *nscol; @@ -578,133 +574,27 @@ static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret) return S_OK; }
-static inline HTMLSelectElementEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) +static ULONG HTMLSelectElementEnum_get_length(DispatchEx *dispex) { - return CONTAINING_RECORD(iface, HTMLSelectElementEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLSelectElementEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLSelectElementEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLSelectElementEnum_Release(IEnumVARIANT *iface) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLSelectElement_Release(&This->elem->IHTMLSelectElement_iface); - free(This); - } - - return ref; -} - -static HRESULT WINAPI HTMLSelectElementEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLSelectElement *elem = impl_from_DispatchEx(dispex); nsresult nsres; - HRESULT hres; - ULONG num, i; UINT32 len;
- TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched); - - nsres = nsIDOMHTMLSelectElement_GetLength(This->elem->nsselect, &len); - if(NS_FAILED(nsres)) - return E_FAIL; - num = min(len - This->iter, celt); - - for(i = 0; i < num; i++) { - hres = htmlselect_item(This->elem, This->iter + i, &V_DISPATCH(&rgVar[i])); - if(FAILED(hres)) { - while(i--) - VariantClear(&rgVar[i]); - return hres; - } - V_VT(&rgVar[i]) = VT_DISPATCH; - } - - This->iter += num; - if(pCeltFetched) - *pCeltFetched = num; - return num == celt ? S_OK : S_FALSE; -} - -static HRESULT WINAPI HTMLSelectElementEnum_Skip(IEnumVARIANT *iface, ULONG celt) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - nsresult nsres; - UINT32 len; - - TRACE("(%p)->(%lu)\n", This, celt); - - nsres = nsIDOMHTMLSelectElement_GetLength(This->elem->nsselect, &len); - if(NS_FAILED(nsres)) - return E_FAIL; - - if(This->iter + celt > len) { - This->iter = len; - return S_FALSE; - } - - This->iter += celt; - return S_OK; + nsres = nsIDOMHTMLSelectElement_GetLength(elem->nsselect, &len); + assert(nsres == NS_OK); + return len; }
-static HRESULT WINAPI HTMLSelectElementEnum_Reset(IEnumVARIANT *iface) +static HRESULT HTMLSelectElementEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLSelectElement *elem = impl_from_DispatchEx(dispex);
- TRACE("(%p)->()\n", This); - - This->iter = 0; - return S_OK; + return htmlselect_item(elem, index, p); }
-static HRESULT WINAPI HTMLSelectElementEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; -} - -static const IEnumVARIANTVtbl HTMLSelectElementEnumVtbl = { - HTMLSelectElementEnum_QueryInterface, - HTMLSelectElementEnum_AddRef, - HTMLSelectElementEnum_Release, - HTMLSelectElementEnum_Next, - HTMLSelectElementEnum_Skip, - HTMLSelectElementEnum_Reset, - HTMLSelectElementEnum_Clone +static const CollectionEnum_vtbl HTMLSelectElementEnum_vtbl = { + HTMLSelectElementEnum_get_length, + HTMLSelectElementEnum_get_item, };
DISPEX_IDISPATCH_IMPL(HTMLSelectElement, IHTMLSelectElement, @@ -1055,23 +945,10 @@ static HRESULT WINAPI HTMLSelectElement_get_length(IHTMLSelectElement *iface, LO static HRESULT WINAPI HTMLSelectElement_get__newEnum(IHTMLSelectElement *iface, IUnknown **p) { HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); - HTMLSelectElementEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLSelectElementEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - HTMLSelectElement_AddRef(&This->IHTMLSelectElement_iface); - ret->elem = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->element.node.event_target.dispex, &HTMLSelectElementEnum_vtbl, p); }
static HRESULT WINAPI HTMLSelectElement_item(IHTMLSelectElement *iface, VARIANT name, @@ -1154,11 +1031,6 @@ static HRESULT HTMLSelectElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BO return IHTMLSelectElement_get_disabled(&This->IHTMLSelectElement_iface, p); }
-static inline HTMLSelectElement *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLSelectElement, element.node.event_target.dispex); -} - static void *HTMLSelectElement_query_interface(DispatchEx *dispex, REFIID riid) { HTMLSelectElement *This = impl_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 162 +++++++---------------------------------- 1 file changed, 26 insertions(+), 136 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 354f521697c..e12b032dfb8 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -815,137 +815,45 @@ typedef struct { nsIDOMClientRectList *rect_list; } HTMLRectCollection;
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLRectCollection *col; -} HTMLRectCollectionEnum; - -static inline HTMLRectCollectionEnum *HTMLRectCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLRectCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLRectCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLRectCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLRectCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx *iface) { - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLRectCollection_Release(&This->col->IHTMLRectCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); }
-static HRESULT WINAPI HTMLRectCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static ULONG HTMLRectCollectionEnum_get_length(DispatchEx *dispex) { - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - VARIANT index; - HRESULT hres; - ULONG num, i; + HTMLRectCollection *col = HTMLRectCollection_from_DispatchEx(dispex); + nsresult nsres; UINT32 len;
- TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched); - - nsIDOMClientRectList_GetLength(This->col->rect_list, &len); - num = min(len - This->iter, celt); - V_VT(&index) = VT_I4; - - for(i = 0; i < num; i++) { - V_I4(&index) = This->iter + i; - hres = IHTMLRectCollection_item(&This->col->IHTMLRectCollection_iface, &index, &rgVar[i]); - if(FAILED(hres)) { - while(i--) - VariantClear(&rgVar[i]); - return hres; - } - } - - This->iter += num; - if(pCeltFetched) - *pCeltFetched = num; - return num == celt ? S_OK : S_FALSE; + nsres = nsIDOMClientRectList_GetLength(col->rect_list, &len); + assert(nsres == NS_OK); + return len; }
-static HRESULT WINAPI HTMLRectCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +static HRESULT HTMLRectCollectionEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - UINT32 len; - - TRACE("(%p)->(%lu)\n", This, celt); + HTMLRectCollection *col = HTMLRectCollection_from_DispatchEx(dispex); + nsIDOMClientRect *nsrect; + nsresult nsres; + HRESULT hres;
- nsIDOMClientRectList_GetLength(This->col->rect_list, &len); - if(This->iter + celt > len) { - This->iter = len; - return S_FALSE; + nsres = nsIDOMClientRectList_Item(col->rect_list, index, &nsrect); + if(NS_FAILED(nsres)) + return map_nsresult(nsres); + if(!nsrect) { + *p = NULL; + return S_OK; }
- This->iter += celt; - return S_OK; -} - -static HRESULT WINAPI HTMLRectCollectionEnum_Reset(IEnumVARIANT *iface) -{ - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); - - This->iter = 0; - return S_OK; -} - -static HRESULT WINAPI HTMLRectCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; + hres = create_html_rect(nsrect, &col->dispex, (IHTMLRect**)p); + nsIDOMClientRect_Release(nsrect); + return hres; }
-static const IEnumVARIANTVtbl HTMLRectCollectionEnumVtbl = { - HTMLRectCollectionEnum_QueryInterface, - HTMLRectCollectionEnum_AddRef, - HTMLRectCollectionEnum_Release, - HTMLRectCollectionEnum_Next, - HTMLRectCollectionEnum_Skip, - HTMLRectCollectionEnum_Reset, - HTMLRectCollectionEnum_Clone +static const CollectionEnum_vtbl HTMLRectCollectionEnum_vtbl = { + HTMLRectCollectionEnum_get_length, + HTMLRectCollectionEnum_get_item, };
static inline HTMLRectCollection *impl_from_IHTMLRectCollection(IHTMLRectCollection *iface) @@ -972,23 +880,10 @@ static HRESULT WINAPI HTMLRectCollection_get_length(IHTMLRectCollection *iface, static HRESULT WINAPI HTMLRectCollection_get__newEnum(IHTMLRectCollection *iface, IUnknown **p) { HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface); - HTMLRectCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLRectCollectionEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - HTMLRectCollection_AddRef(&This->IHTMLRectCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->dispex, &HTMLRectCollectionEnum_vtbl, p); }
static HRESULT WINAPI HTMLRectCollection_item(IHTMLRectCollection *iface, VARIANT *index, VARIANT *result) @@ -1037,11 +932,6 @@ static const IHTMLRectCollectionVtbl HTMLRectCollectionVtbl = { HTMLRectCollection_item };
-static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); -} - static void *HTMLRectCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstylesheet.c | 162 ++++++----------------------------- 1 file changed, 25 insertions(+), 137 deletions(-)
diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index fb9d71f894f..ff422156836 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -47,15 +47,6 @@ struct HTMLStyleSheetsCollection { nsIDOMStyleSheetList *nslist; };
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLStyleSheetsCollection *col; -} HTMLStyleSheetsCollectionEnum; - struct HTMLStyleSheetRulesCollection { DispatchEx dispex; IHTMLStyleSheetRulesCollection IHTMLStyleSheetRulesCollection_iface; @@ -399,128 +390,43 @@ static HRESULT create_style_sheet_rules_collection(nsIDOMCSSRuleList *nslist, Di return S_OK; }
-static inline HTMLStyleSheetsCollectionEnum *HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyleSheetsCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLStyleSheetsCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLStyleSheetsCollectionEnum_Release(IEnumVARIANT *iface) -{ - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLStyleSheetsCollection_Release(&This->col->IHTMLStyleSheetsCollection_iface); - free(This); - } - - return ref; -} - -static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_DispatchEx(DispatchEx *iface) { - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - VARIANT index; - HRESULT hres; - ULONG num, i; - UINT32 len; - - TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched); - - nsIDOMStyleSheetList_GetLength(This->col->nslist, &len); - num = min(len - This->iter, celt); - V_VT(&index) = VT_I4; - - for(i = 0; i < num; i++) { - V_I4(&index) = This->iter + i; - hres = IHTMLStyleSheetsCollection_item(&This->col->IHTMLStyleSheetsCollection_iface, &index, &rgVar[i]); - if(FAILED(hres)) { - while(i--) - VariantClear(&rgVar[i]); - return hres; - } - } - - This->iter += num; - if(pCeltFetched) - *pCeltFetched = num; - return num == celt ? S_OK : S_FALSE; + return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); }
-static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +static ULONG HTMLStyleSheetsCollectionEnum_get_length(DispatchEx *dispex) { - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); + HTMLStyleSheetsCollection *col = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + nsresult nsres; UINT32 len;
- TRACE("(%p)->(%lu)\n", This, celt); - - nsIDOMStyleSheetList_GetLength(This->col->nslist, &len); - if(This->iter + celt > len) { - This->iter = len; - return S_FALSE; - } - - This->iter += celt; - return S_OK; + nsres = nsIDOMStyleSheetList_GetLength(col->nslist, &len); + assert(nsres == NS_OK); + return len; }
-static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Reset(IEnumVARIANT *iface) +static HRESULT HTMLStyleSheetsCollectionEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); + HTMLStyleSheetsCollection *col = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + nsIDOMStyleSheet *nsstylesheet; + nsresult nsres; + HRESULT hres;
- This->iter = 0; - return S_OK; -} + nsres = nsIDOMStyleSheetList_Item(col->nslist, index, &nsstylesheet); + if(NS_FAILED(nsres)) + return map_nsresult(nsres); + if(!nsstylesheet) + return E_INVALIDARG;
-static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; + hres = create_style_sheet(nsstylesheet, &col->dispex, (IHTMLStyleSheet**)p); + nsIDOMStyleSheet_Release(nsstylesheet); + return hres; }
-static const IEnumVARIANTVtbl HTMLStyleSheetsCollectionEnumVtbl = { - HTMLStyleSheetsCollectionEnum_QueryInterface, - HTMLStyleSheetsCollectionEnum_AddRef, - HTMLStyleSheetsCollectionEnum_Release, - HTMLStyleSheetsCollectionEnum_Next, - HTMLStyleSheetsCollectionEnum_Skip, - HTMLStyleSheetsCollectionEnum_Reset, - HTMLStyleSheetsCollectionEnum_Clone +static const CollectionEnum_vtbl HTMLStyleSheetsCollectionEnum_vtbl = { + HTMLStyleSheetsCollectionEnum_get_length, + HTMLStyleSheetsCollectionEnum_get_item, };
static inline HTMLStyleSheetsCollection *impl_from_IHTMLStyleSheetsCollection(IHTMLStyleSheetsCollection *iface) @@ -550,23 +456,10 @@ static HRESULT WINAPI HTMLStyleSheetsCollection_get__newEnum(IHTMLStyleSheetsCol IUnknown **p) { HTMLStyleSheetsCollection *This = impl_from_IHTMLStyleSheetsCollection(iface); - HTMLStyleSheetsCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLStyleSheetsCollectionEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - HTMLStyleSheetsCollection_AddRef(&This->IHTMLStyleSheetsCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->dispex, &HTMLStyleSheetsCollectionEnum_vtbl, p); }
static HRESULT WINAPI HTMLStyleSheetsCollection_item(IHTMLStyleSheetsCollection *iface, @@ -626,11 +519,6 @@ static const IHTMLStyleSheetsCollectionVtbl HTMLStyleSheetsCollectionVtbl = { HTMLStyleSheetsCollection_item };
-static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); -} - static void *HTMLStyleSheetsCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 46 +++++++--- dlls/mshtml/htmlelem.c | 169 ++++++----------------------------- dlls/mshtml/mshtml_private.h | 4 + 3 files changed, 65 insertions(+), 154 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 88d2e3e37ba..97c0f311362 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2958,20 +2958,36 @@ static HRESULT WINAPI CollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIA
TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched);
- len = This->vtbl->get_length(col); + if(This->vtbl->next_item) { + while(fetched < celt) { + hres = This->vtbl->next_item(col, &iter, &V_DISPATCH(rgVar + fetched)); + if(hres == S_FALSE) + break; + if(FAILED(hres)) { + while(fetched--) + VariantClear(rgVar + fetched); + return hres; + } + V_VT(rgVar + fetched) = V_DISPATCH(rgVar + fetched) ? VT_DISPATCH : VT_NULL; + fetched++; + } + }else { + len = This->vtbl->get_length(col);
- while(iter + fetched < len && fetched < celt) { - hres = This->vtbl->get_item(col, iter + fetched, &V_DISPATCH(rgVar + fetched)); - if(FAILED(hres)) { - while(fetched--) - VariantClear(rgVar + fetched); - return hres; + while(iter + fetched < len && fetched < celt) { + hres = This->vtbl->get_item(col, iter + fetched, &V_DISPATCH(rgVar + fetched)); + if(FAILED(hres)) { + while(fetched--) + VariantClear(rgVar + fetched); + return hres; + } + V_VT(rgVar + fetched) = V_DISPATCH(rgVar + fetched) ? VT_DISPATCH : VT_NULL; + fetched++; } - V_VT(rgVar + fetched) = V_DISPATCH(rgVar + fetched) ? VT_DISPATCH : VT_NULL; - fetched++; + iter += fetched; }
- This->iter = iter + fetched; + This->iter = iter; if(pCeltFetched) *pCeltFetched = fetched; return fetched == celt ? S_OK : S_FALSE; @@ -2984,6 +3000,12 @@ static HRESULT WINAPI CollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt)
TRACE("(%p)->(%ld)\n", This, celt);
+ if(!celt) + return S_OK; + + if(This->vtbl->skip_items) + return This->vtbl->skip_items(This->collection, &This->iter, celt); + len = This->vtbl->get_length(This->collection);
if(This->iter + celt > len) { @@ -3001,7 +3023,7 @@ static HRESULT WINAPI CollectionEnum_Reset(IEnumVARIANT *iface)
TRACE("(%p)->()\n", This);
- This->iter = 0; + This->iter = This->vtbl->initial_iter_value; return S_OK; }
@@ -3034,7 +3056,7 @@ HRESULT CollectionEnum_create(DispatchEx *collection, const CollectionEnum_vtbl colenum->vtbl = vtbl; colenum->IEnumVARIANT_iface.lpVtbl = &CollectionEnumVtbl; colenum->ref = 1; - colenum->iter = 0; + colenum->iter = vtbl->initial_iter_value; colenum->collection = collection; DispatchEx_AddRef(&collection->IWineJSDispatchHost_iface);
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index e12b032dfb8..bff7a65fd5e 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7798,154 +7798,57 @@ static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG return S_OK; }
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - DISPID iter_dispid; - HTMLAttributeCollection *col; -} HTMLAttributeCollectionEnum; - -static inline HTMLAttributeCollectionEnum *HTMLAttributeCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLAttributeCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLAttributeCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLAttributeCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLAttributeCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(DispatchEx *iface) { - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLAttributeCollection_Release(&This->col->IHTMLAttributeCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); }
-static HRESULT WINAPI HTMLAttributeCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static HRESULT HTMLAttributeCollectionEnum_next_item(DispatchEx *dispex, ULONG *iter, IDispatch **p) { - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - DISPID tmp, dispid = This->iter_dispid; + HTMLAttributeCollection *col = HTMLAttributeCollection_from_DispatchEx(dispex); HTMLDOMAttribute *attr; + DISPID dispid = *iter; LONG rel_index = 0; HRESULT hres; - ULONG i; - - TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched); - - for(i = 0; i < celt; i++) { - hres = get_attr_dispid_by_relative_idx(This->col, &rel_index, dispid, &tmp); - if(SUCCEEDED(hres)) { - dispid = tmp; - hres = get_domattr(This->col, dispid, NULL, &attr); - } - else if(hres == DISP_E_UNKNOWNNAME) - break; - - if(FAILED(hres)) { - while(i--) - VariantClear(&rgVar[i]); - return hres; - }
- V_VT(&rgVar[i]) = VT_DISPATCH; - V_DISPATCH(&rgVar[i]) = (IDispatch*)&attr->IHTMLDOMAttribute_iface; + hres = get_attr_dispid_by_relative_idx(col, &rel_index, dispid, &dispid); + if(SUCCEEDED(hres)) + hres = get_domattr(col, dispid, NULL, &attr); + else if(hres == DISP_E_UNKNOWNNAME) + return S_FALSE; + if(SUCCEEDED(hres)) { + *iter = dispid; + *p = (IDispatch*)&attr->IHTMLDOMAttribute_iface; } - - This->iter_dispid = dispid; - if(pCeltFetched) - *pCeltFetched = i; - return i == celt ? S_OK : S_FALSE; + return hres; }
-static HRESULT WINAPI HTMLAttributeCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +static HRESULT HTMLAttributeCollectionEnum_skip_items(DispatchEx *dispex, ULONG *iter, ULONG skip) { - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - LONG remaining, rel_index; + HTMLAttributeCollection *col = HTMLAttributeCollection_from_DispatchEx(dispex); + LONG remaining, rel_index = -1; DISPID dispid; HRESULT hres;
- TRACE("(%p)->(%lu)\n", This, celt); - - if(!celt) - return S_OK; - - rel_index = -1; - hres = get_attr_dispid_by_relative_idx(This->col, &rel_index, This->iter_dispid, NULL); + hres = get_attr_dispid_by_relative_idx(col, &rel_index, *iter, NULL); if(FAILED(hres)) return hres; - remaining = min(celt, rel_index); + remaining = min(skip, rel_index);
if(remaining) { rel_index = remaining - 1; - hres = get_attr_dispid_by_relative_idx(This->col, &rel_index, This->iter_dispid, &dispid); + hres = get_attr_dispid_by_relative_idx(col, &rel_index, *iter, &dispid); if(FAILED(hres)) return hres; - This->iter_dispid = dispid; + *iter = dispid; } - return celt > remaining ? S_FALSE : S_OK; + return skip > remaining ? S_FALSE : S_OK; }
-static HRESULT WINAPI HTMLAttributeCollectionEnum_Reset(IEnumVARIANT *iface) -{ - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); - - This->iter_dispid = DISPID_STARTENUM; - return S_OK; -} - -static HRESULT WINAPI HTMLAttributeCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; -} - -static const IEnumVARIANTVtbl HTMLAttributeCollectionEnumVtbl = { - HTMLAttributeCollectionEnum_QueryInterface, - HTMLAttributeCollectionEnum_AddRef, - HTMLAttributeCollectionEnum_Release, - HTMLAttributeCollectionEnum_Next, - HTMLAttributeCollectionEnum_Skip, - HTMLAttributeCollectionEnum_Reset, - HTMLAttributeCollectionEnum_Clone +static const CollectionEnum_vtbl HTMLAttributeCollectionEnum_vtbl = { + .initial_iter_value = DISPID_STARTENUM, + .next_item = HTMLAttributeCollectionEnum_next_item, + .skip_items = HTMLAttributeCollectionEnum_skip_items, };
/* interface IHTMLAttributeCollection */ @@ -7972,23 +7875,10 @@ static HRESULT WINAPI HTMLAttributeCollection_get_length(IHTMLAttributeCollectio static HRESULT WINAPI HTMLAttributeCollection__newEnum(IHTMLAttributeCollection *iface, IUnknown **p) { HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface); - HTMLAttributeCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLAttributeCollectionEnumVtbl; - ret->ref = 1; - ret->iter_dispid = DISPID_STARTENUM; - - HTMLAttributeCollection_AddRef(&This->IHTMLAttributeCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->dispex, &HTMLAttributeCollectionEnum_vtbl, p); }
static HRESULT WINAPI HTMLAttributeCollection_item(IHTMLAttributeCollection *iface, VARIANT *name, IDispatch **ppItem) @@ -8310,11 +8200,6 @@ static const IHTMLAttributeCollection4Vtbl HTMLAttributeCollection4Vtbl = { HTMLAttributeCollection4_get_length };
-static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); -} - static void *HTMLAttributeCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 0966b294e46..85bd5f8cd23 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -613,6 +613,10 @@ struct DispatchEx { typedef struct { ULONG (*get_length)(DispatchEx*); HRESULT (*get_item)(DispatchEx*,ULONG,IDispatch**); + HRESULT (*next_item)(DispatchEx*,ULONG*,IDispatch**); + HRESULT (*skip_items)(DispatchEx*,ULONG*,ULONG); + + ULONG initial_iter_value; } CollectionEnum_vtbl;
struct CollectionEnum {
On Thu Oct 9 16:57:58 2025 +0000, Gabriel Ivăncescu wrote:
Ah right. I had some problems with the attribute collection though, since it uses relative next/skip. I added optional next/skip methods in the vtbl for that but I'm not sure if it's the best way, I can use them for all the others too if you prefer.
If attributes require a special code path, they might as well avoid the shared implementation entirely. However, I don’t see why that’s necessary. Attributes already support indexed access through `get_dispid`, and we could use the same approach here. It’s unfortunate that this is slower than relative iteration for legacy attributes, but that’s a broader issue, and I don’t think we should change the shared code for it.
Also, we could add these new helpers to `dispex_static_data_vtbl_t` instead of introducing a new vtbl type. Eventually, that could also be used to share indexed `get_dispid`/`invoke` logic.
On Thu Oct 9 19:37:42 2025 +0000, Jacek Caban wrote:
If attributes require a special code path, they might as well avoid the shared implementation entirely. However, I don’t see why that’s necessary. Attributes already support indexed access through `get_dispid`, and we could use the same approach here. It’s unfortunate that this is slower than relative iteration for legacy attributes, but that’s a broader issue, and I don’t think we should change the shared code for it. Also, we could add these new helpers to `dispex_static_data_vtbl_t` instead of introducing a new vtbl type. Eventually, that could also be used to share indexed `get_dispid`/`invoke` logic.
Yeah, but are you sure it's a good idea for attributes? Since that's implemented on Next in the enumerator, it becomes basically `O(N^2)` if it's enumerated (as opposed to random access which is just one iteration in principle, so `get_dispid` isn't nearly as bad).
On Fri Oct 10 15:33:13 2025 +0000, Gabriel Ivăncescu wrote:
Yeah, but are you sure it's a good idea for attributes? Since that's implemented on Next in the enumerator, it becomes basically `O(N^2)` if it's enumerated (as opposed to random access which is just one iteration in principle, so `get_dispid` isn't nearly as bad).
I'm sure I don't want to pollute the common code with a workaround for such inefficiencies. If you think it’s important enough, you can just keep the attributes collection with their own enumerator implementation.
Theoretically, we could make random access faster. Linear `get_dispid` is just as bad, since performing `n` accesses is currently `O(n^2)` as well while it could be `O(n)`. Anyway, that’s off-topic here.
On Fri Oct 10 16:10:25 2025 +0000, Jacek Caban wrote:
I'm sure I don't want to pollute the common code with a workaround for such inefficiencies. If you think it’s important enough, you can just keep the attributes collection with their own enumerator implementation. Theoretically, we could make random access faster. Linear `get_dispid` is just as bad, since performing `n` accesses is currently `O(n^2)` as well while it could be `O(n)`. Anyway, that’s off-topic here.
Well I tried to somehow use `GetNextDispID`, at least as fallback if those new methods weren't defined, but couldn't figure out how to solve the non-attributes cleanly, so I gave up for now.
Also I had to use the common impl on attribute collections since we will need it to fix the cyclic ref leaks later, otherwise we'd have to init yet another CC object with its own vtbl just for attribute collections.