Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / embedding / browser / activex / src / xml / XMLElementCollection.cpp
blob4e4752e9a5382e9ee39752b383cac0b2ad438268
1 // XMLElementCollection.cpp : Implementation of CXMLElementCollection
2 #include "stdafx.h"
3 //#include "Activexml.h"
4 #include "XMLElementCollection.h"
6 CXMLElementCollection::CXMLElementCollection()
11 CXMLElementCollection::~CXMLElementCollection()
16 HRESULT CXMLElementCollection::Add(IXMLElement *pElement)
18 if (pElement == NULL)
20 return E_INVALIDARG;
23 m_cElements.push_back( CComQIPtr<IXMLElement, &IID_IXMLElement>(pElement));
24 return S_OK;
28 /////////////////////////////////////////////////////////////////////////////
29 // CXMLElementCollection
31 HRESULT STDMETHODCALLTYPE CXMLElementCollection::put_length(/* [in] */ long v)
33 // Why does MS define a method that has no purpose?
34 return S_OK;
38 HRESULT STDMETHODCALLTYPE CXMLElementCollection::get_length(/* [out][retval] */ long __RPC_FAR *p)
40 if (p == NULL)
42 return E_INVALIDARG;
44 *p = m_cElements.size();
45 return S_OK;
49 HRESULT STDMETHODCALLTYPE CXMLElementCollection::get__newEnum(/* [out][retval] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk)
51 return E_NOTIMPL;
55 // Perhaps the most overly complicated method ever...
56 HRESULT STDMETHODCALLTYPE CXMLElementCollection::item(/* [in][optional] */ VARIANT var1, /* [in][optional] */ VARIANT var2, /* [out][retval] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp)
58 if (ppDisp == NULL)
60 return E_INVALIDARG;
63 *ppDisp;
65 CComVariant vIndex;
67 // If var1 is a number, the caller wants the element at the specified index
69 if (vIndex.ChangeType(VT_I4, &var1) == S_OK)
71 long nIndex = vIndex.intVal;
72 if (nIndex < 0 || nIndex >= m_cElements.size())
74 return E_INVALIDARG;
76 // Get the element at the specified index
77 m_cElements[nIndex]->QueryInterface(IID_IDispatch, (void **) ppDisp);
78 return S_OK;
81 // If var1 is a string, the caller wants a collection of all elements with
82 // the matching tagname, unless var2 contains an index or if there is only
83 // one in which case just the element is returned.
85 CComVariant vName;
86 if (FAILED(vName.ChangeType(VT_BSTR, &var1)))
88 return E_INVALIDARG;
91 // Compile a list of elements matching the name
92 ElementList cElements;
93 ElementList::iterator i;
95 for (i = m_cElements.begin(); i != m_cElements.end(); i++)
97 CComQIPtr<IXMLElement, &IID_IXMLElement> spElement;
98 BSTR bstrTagName = NULL;
99 (*i)->get_tagName(&bstrTagName);
100 if (bstrTagName)
102 if (wcscmp(bstrTagName, vName.bstrVal) == 0)
104 cElements.push_back(*i);
106 SysFreeString(bstrTagName);
110 // Are there any matching elements?
111 if (cElements.empty())
113 return S_OK;
116 // Does var2 contain an index?
117 if (var2.vt == VT_I4)
119 long nIndex = var2.vt;
120 if (nIndex < 0 || nIndex >= cElements.size())
122 return E_INVALIDARG;
125 // Get the element at the specified index
126 cElements[nIndex]->QueryInterface(IID_IDispatch, (void **) ppDisp);
127 return S_OK;
130 // Is there more than one element?
131 if (cElements.size() > 1)
133 // Create another collection
134 CXMLElementCollectionInstance *pCollection = NULL;
135 CXMLElementCollectionInstance::CreateInstance(&pCollection);
136 if (pCollection == NULL)
138 return E_OUTOFMEMORY;
141 if (FAILED(pCollection->QueryInterface(IID_IDispatch, (void **) ppDisp)))
143 pCollection->Release();
144 return E_FAIL;
147 // Add elements to the collection
148 for (i = cElements.begin(); i != cElements.end(); i++)
150 pCollection->Add(*i);
153 return S_OK;
156 // Return the pointer to the element
157 if (FAILED(cElements[0]->QueryInterface(IID_IDispatch, (void **) ppDisp)))
159 return E_FAIL;
162 return S_OK;