winejoystick: Fix a crash on accessing a CFArray past its end due to an off-by-one...
[wine/multimedia.git] / dlls / mshtml / htmltextnode.c
blob411123dd5bbfde081351cd00607c4037102e2b72
1 /*
2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
21 #include <assert.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
30 #include "mshtml_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36 struct HTMLDOMTextNode {
37 HTMLDOMNode node;
38 IHTMLDOMTextNode IHTMLDOMTextNode_iface;
39 IHTMLDOMTextNode2 IHTMLDOMTextNode2_iface;
41 nsIDOMText *nstext;
44 static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode(IHTMLDOMTextNode *iface)
46 return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode_iface);
49 static HRESULT WINAPI HTMLDOMTextNode_QueryInterface(IHTMLDOMTextNode *iface,
50 REFIID riid, void **ppv)
52 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
54 return IHTMLDOMNode_QueryInterface(&This->node.IHTMLDOMNode_iface, riid, ppv);
57 static ULONG WINAPI HTMLDOMTextNode_AddRef(IHTMLDOMTextNode *iface)
59 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
61 return IHTMLDOMNode_AddRef(&This->node.IHTMLDOMNode_iface);
64 static ULONG WINAPI HTMLDOMTextNode_Release(IHTMLDOMTextNode *iface)
66 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
68 return IHTMLDOMNode_Release(&This->node.IHTMLDOMNode_iface);
71 static HRESULT WINAPI HTMLDOMTextNode_GetTypeInfoCount(IHTMLDOMTextNode *iface, UINT *pctinfo)
73 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
74 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
77 static HRESULT WINAPI HTMLDOMTextNode_GetTypeInfo(IHTMLDOMTextNode *iface, UINT iTInfo,
78 LCID lcid, ITypeInfo **ppTInfo)
80 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
81 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
84 static HRESULT WINAPI HTMLDOMTextNode_GetIDsOfNames(IHTMLDOMTextNode *iface, REFIID riid,
85 LPOLESTR *rgszNames, UINT cNames,
86 LCID lcid, DISPID *rgDispId)
88 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
89 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
90 lcid, rgDispId);
93 static HRESULT WINAPI HTMLDOMTextNode_Invoke(IHTMLDOMTextNode *iface, DISPID dispIdMember,
94 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
95 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
97 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
98 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
99 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
102 static HRESULT WINAPI HTMLDOMTextNode_put_data(IHTMLDOMTextNode *iface, BSTR v)
104 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
105 nsAString nsstr;
106 nsresult nsres;
108 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
110 nsAString_InitDepend(&nsstr, v);
111 nsres = nsIDOMText_SetData(This->nstext, &nsstr);
112 nsAString_Finish(&nsstr);
113 return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
116 static HRESULT WINAPI HTMLDOMTextNode_get_data(IHTMLDOMTextNode *iface, BSTR *p)
118 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
119 nsAString nsstr;
120 nsresult nsres;
122 TRACE("(%p)->(%p)\n", This, p);
124 nsAString_Init(&nsstr, NULL);
125 nsres = nsIDOMText_GetData(This->nstext, &nsstr);
126 return return_nsstr(nsres, &nsstr, p);
129 static HRESULT WINAPI HTMLDOMTextNode_toString(IHTMLDOMTextNode *iface, BSTR *String)
131 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
132 FIXME("(%p)->(%p)\n", This, String);
133 return E_NOTIMPL;
136 static HRESULT WINAPI HTMLDOMTextNode_get_length(IHTMLDOMTextNode *iface, LONG *p)
138 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
139 UINT32 length = 0;
140 nsresult nsres;
142 TRACE("(%p)->(%p)\n", This, p);
144 nsres = nsIDOMText_GetLength(This->nstext, &length);
145 if(NS_FAILED(nsres))
146 ERR("GetLength failed: %08x\n", nsres);
148 *p = length;
149 return S_OK;
152 static HRESULT WINAPI HTMLDOMTextNode_splitText(IHTMLDOMTextNode *iface, LONG offset, IHTMLDOMNode **pRetNode)
154 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
155 HTMLDOMNode *node;
156 nsIDOMText *text;
157 nsresult nsres;
158 HRESULT hres;
160 TRACE("(%p)->(%d %p)\n", This, offset, pRetNode);
162 nsres = nsIDOMText_SplitText(This->nstext, offset, &text);
163 if(NS_FAILED(nsres)) {
164 ERR("SplitText failed: %x08x\n", nsres);
165 return E_FAIL;
168 if(!text) {
169 *pRetNode = NULL;
170 return S_OK;
173 hres = get_node(This->node.doc, (nsIDOMNode*)text, TRUE, &node);
174 nsIDOMText_Release(text);
175 if(FAILED(hres))
176 return hres;
178 *pRetNode = &node->IHTMLDOMNode_iface;
179 return S_OK;
182 static const IHTMLDOMTextNodeVtbl HTMLDOMTextNodeVtbl = {
183 HTMLDOMTextNode_QueryInterface,
184 HTMLDOMTextNode_AddRef,
185 HTMLDOMTextNode_Release,
186 HTMLDOMTextNode_GetTypeInfoCount,
187 HTMLDOMTextNode_GetTypeInfo,
188 HTMLDOMTextNode_GetIDsOfNames,
189 HTMLDOMTextNode_Invoke,
190 HTMLDOMTextNode_put_data,
191 HTMLDOMTextNode_get_data,
192 HTMLDOMTextNode_toString,
193 HTMLDOMTextNode_get_length,
194 HTMLDOMTextNode_splitText
197 static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode2(IHTMLDOMTextNode2 *iface)
199 return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode2_iface);
202 static HRESULT WINAPI HTMLDOMTextNode2_QueryInterface(IHTMLDOMTextNode2 *iface, REFIID riid, void **ppv)
204 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
206 return IHTMLDOMNode_QueryInterface(&This->node.IHTMLDOMNode_iface, riid, ppv);
209 static ULONG WINAPI HTMLDOMTextNode2_AddRef(IHTMLDOMTextNode2 *iface)
211 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
213 return IHTMLDOMNode_AddRef(&This->node.IHTMLDOMNode_iface);
216 static ULONG WINAPI HTMLDOMTextNode2_Release(IHTMLDOMTextNode2 *iface)
218 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
220 return IHTMLDOMNode_Release(&This->node.IHTMLDOMNode_iface);
223 static HRESULT WINAPI HTMLDOMTextNode2_GetTypeInfoCount(IHTMLDOMTextNode2 *iface, UINT *pctinfo)
225 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
226 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
229 static HRESULT WINAPI HTMLDOMTextNode2_GetTypeInfo(IHTMLDOMTextNode2 *iface, UINT iTInfo,
230 LCID lcid, ITypeInfo **ppTInfo)
232 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
233 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
236 static HRESULT WINAPI HTMLDOMTextNode2_GetIDsOfNames(IHTMLDOMTextNode2 *iface, REFIID riid,
237 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
239 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
240 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
241 lcid, rgDispId);
244 static HRESULT WINAPI HTMLDOMTextNode2_Invoke(IHTMLDOMTextNode2 *iface, DISPID dispIdMember,
245 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
246 EXCEPINFO *pExcepInfo, UINT *puArgErr)
248 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
249 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
250 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
253 static HRESULT WINAPI HTMLDOMTextNode2_substringData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count, BSTR *string)
255 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
256 FIXME("(%p)->(%d %d %p)\n", This, offset, count, string);
257 return E_NOTIMPL;
260 static HRESULT WINAPI HTMLDOMTextNode2_appendData(IHTMLDOMTextNode2 *iface, BSTR string)
262 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
263 nsAString nsstr;
264 nsresult nsres;
266 TRACE("(%p)->(%s)\n", This, debugstr_w(string));
268 nsAString_InitDepend(&nsstr, string);
269 nsres = nsIDOMText_AppendData(This->nstext, &nsstr);
270 nsAString_Finish(&nsstr);
271 if(NS_FAILED(nsres)) {
272 ERR("AppendData failed: %08x\n", nsres);
273 return E_FAIL;
276 return S_OK;
279 static HRESULT WINAPI HTMLDOMTextNode2_insertData(IHTMLDOMTextNode2 *iface, LONG offset, BSTR string)
281 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
282 FIXME("(%p)->(%d %s)\n", This, offset, debugstr_w(string));
283 return E_NOTIMPL;
286 static HRESULT WINAPI HTMLDOMTextNode2_deleteData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count)
288 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
289 FIXME("(%p)->(%d %d)\n", This, offset, count);
290 return E_NOTIMPL;
293 static HRESULT WINAPI HTMLDOMTextNode2_replaceData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count, BSTR string)
295 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
296 FIXME("(%p)->(%d %d %s)\n", This, offset, count, debugstr_w(string));
297 return E_NOTIMPL;
300 static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = {
301 HTMLDOMTextNode2_QueryInterface,
302 HTMLDOMTextNode2_AddRef,
303 HTMLDOMTextNode2_Release,
304 HTMLDOMTextNode2_GetTypeInfoCount,
305 HTMLDOMTextNode2_GetTypeInfo,
306 HTMLDOMTextNode2_GetIDsOfNames,
307 HTMLDOMTextNode2_Invoke,
308 HTMLDOMTextNode2_substringData,
309 HTMLDOMTextNode2_appendData,
310 HTMLDOMTextNode2_insertData,
311 HTMLDOMTextNode2_deleteData,
312 HTMLDOMTextNode2_replaceData
315 static inline HTMLDOMTextNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
317 return CONTAINING_RECORD(iface, HTMLDOMTextNode, node);
320 static HRESULT HTMLDOMTextNode_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
322 HTMLDOMTextNode *This = impl_from_HTMLDOMNode(iface);
324 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
326 if(IsEqualGUID(&IID_IHTMLDOMTextNode, riid))
327 *ppv = &This->IHTMLDOMTextNode_iface;
328 else if(IsEqualGUID(&IID_IHTMLDOMTextNode2, riid))
329 *ppv = &This->IHTMLDOMTextNode2_iface;
330 else
331 return HTMLDOMNode_QI(&This->node, riid, ppv);
333 IUnknown_AddRef((IUnknown*)*ppv);
334 return S_OK;
337 static HRESULT HTMLDOMTextNode_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
339 HTMLDOMTextNode *This = impl_from_HTMLDOMNode(iface);
341 return HTMLDOMTextNode_Create(This->node.doc, nsnode, ret);
344 static const cpc_entry_t HTMLDOMTextNode_cpc[] = {{NULL}};
346 static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
347 HTMLDOMTextNode_QI,
348 HTMLDOMNode_destructor,
349 HTMLDOMTextNode_cpc,
350 HTMLDOMTextNode_clone
353 static const tid_t HTMLDOMTextNode_iface_tids[] = {
354 IHTMLDOMNode_tid,
355 IHTMLDOMNode2_tid,
356 IHTMLDOMTextNode_tid,
357 IHTMLDOMTextNode2_tid,
360 static dispex_static_data_t HTMLDOMTextNode_dispex = {
361 NULL,
362 DispHTMLDOMTextNode_tid,
364 HTMLDOMTextNode_iface_tids
367 HRESULT HTMLDOMTextNode_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNode **node)
369 HTMLDOMTextNode *ret;
370 nsresult nsres;
372 ret = heap_alloc_zero(sizeof(*ret));
373 if(!ret)
374 return E_OUTOFMEMORY;
376 ret->node.vtbl = &HTMLDOMTextNodeImplVtbl;
377 ret->IHTMLDOMTextNode_iface.lpVtbl = &HTMLDOMTextNodeVtbl;
378 ret->IHTMLDOMTextNode2_iface.lpVtbl = &HTMLDOMTextNode2Vtbl;
380 init_dispex(&ret->node.dispex, (IUnknown*)&ret->IHTMLDOMTextNode_iface,
381 &HTMLDOMTextNode_dispex);
383 HTMLDOMNode_Init(doc, &ret->node, nsnode);
385 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMText, (void**)&ret->nstext);
386 assert(nsres == NS_OK && (nsIDOMNode*)ret->nstext == ret->node.nsnode);
388 /* Share reference with nsnode */
389 nsIDOMNode_Release(ret->node.nsnode);
391 *node = &ret->node;
392 return S_OK;