Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlelem.c
Go to the documentation of this file.
00001 /* 00002 * XML Element implementation 00003 * 00004 * Copyright 2007 James Hawkins 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #define COBJMACROS 00022 00023 #include "config.h" 00024 00025 #include <stdarg.h> 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winuser.h" 00029 #include "ole2.h" 00030 #include "msxml2.h" 00031 #include "ocidl.h" 00032 00033 #include "wine/debug.h" 00034 00035 #include "msxml_private.h" 00036 00037 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 00038 00039 #ifdef HAVE_LIBXML2 00040 00041 static HRESULT XMLElementCollection_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj ); 00042 00043 /********************************************************************** 00044 * IXMLElement 00045 */ 00046 typedef struct _xmlelem 00047 { 00048 const IXMLElementVtbl *lpVtbl; 00049 LONG ref; 00050 xmlNodePtr node; 00051 BOOL own; 00052 } xmlelem; 00053 00054 static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface) 00055 { 00056 return (xmlelem *)((char*)iface - FIELD_OFFSET(xmlelem, lpVtbl)); 00057 } 00058 00059 static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement *iface, REFIID riid, void** ppvObject) 00060 { 00061 xmlelem *This = impl_from_IXMLElement(iface); 00062 00063 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 00064 00065 if (IsEqualGUID(riid, &IID_IUnknown) || 00066 IsEqualGUID(riid, &IID_IXMLElement)) 00067 { 00068 *ppvObject = iface; 00069 } 00070 else 00071 { 00072 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 00073 return E_NOINTERFACE; 00074 } 00075 00076 IXMLElement_AddRef(iface); 00077 00078 return S_OK; 00079 } 00080 00081 static ULONG WINAPI xmlelem_AddRef(IXMLElement *iface) 00082 { 00083 xmlelem *This = impl_from_IXMLElement(iface); 00084 TRACE("%p\n", This); 00085 return InterlockedIncrement(&This->ref); 00086 } 00087 00088 static ULONG WINAPI xmlelem_Release(IXMLElement *iface) 00089 { 00090 xmlelem *This = impl_from_IXMLElement(iface); 00091 LONG ref; 00092 00093 TRACE("%p\n", This); 00094 00095 ref = InterlockedDecrement(&This->ref); 00096 if (ref == 0) 00097 { 00098 if (This->own) xmlFreeNode(This->node); 00099 heap_free(This); 00100 } 00101 00102 return ref; 00103 } 00104 00105 static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement *iface, UINT* pctinfo) 00106 { 00107 xmlelem *This = impl_from_IXMLElement(iface); 00108 00109 TRACE("(%p)->(%p)\n", This, pctinfo); 00110 00111 *pctinfo = 1; 00112 00113 return S_OK; 00114 } 00115 00116 static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement *iface, UINT iTInfo, 00117 LCID lcid, ITypeInfo** ppTInfo) 00118 { 00119 xmlelem *This = impl_from_IXMLElement(iface); 00120 HRESULT hr; 00121 00122 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); 00123 00124 hr = get_typeinfo(IXMLElement_tid, ppTInfo); 00125 00126 return hr; 00127 } 00128 00129 static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement *iface, REFIID riid, 00130 LPOLESTR* rgszNames, UINT cNames, 00131 LCID lcid, DISPID* rgDispId) 00132 { 00133 xmlelem *This = impl_from_IXMLElement(iface); 00134 ITypeInfo *typeinfo; 00135 HRESULT hr; 00136 00137 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, 00138 lcid, rgDispId); 00139 00140 if(!rgszNames || cNames == 0 || !rgDispId) 00141 return E_INVALIDARG; 00142 00143 hr = get_typeinfo(IXMLElement_tid, &typeinfo); 00144 if(SUCCEEDED(hr)) 00145 { 00146 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); 00147 ITypeInfo_Release(typeinfo); 00148 } 00149 00150 return hr; 00151 } 00152 00153 static HRESULT WINAPI xmlelem_Invoke(IXMLElement *iface, DISPID dispIdMember, 00154 REFIID riid, LCID lcid, WORD wFlags, 00155 DISPPARAMS* pDispParams, VARIANT* pVarResult, 00156 EXCEPINFO* pExcepInfo, UINT* puArgErr) 00157 { 00158 xmlelem *This = impl_from_IXMLElement(iface); 00159 ITypeInfo *typeinfo; 00160 HRESULT hr; 00161 00162 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), 00163 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 00164 00165 hr = get_typeinfo(IXMLElement_tid, &typeinfo); 00166 if(SUCCEEDED(hr)) 00167 { 00168 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams, 00169 pVarResult, pExcepInfo, puArgErr); 00170 ITypeInfo_Release(typeinfo); 00171 } 00172 00173 return hr; 00174 } 00175 00176 static HRESULT WINAPI xmlelem_get_tagName(IXMLElement *iface, BSTR *p) 00177 { 00178 xmlelem *This = impl_from_IXMLElement(iface); 00179 00180 TRACE("(%p, %p)\n", iface, p); 00181 00182 if (!p) 00183 return E_INVALIDARG; 00184 00185 *p = bstr_from_xmlChar(This->node->name); 00186 CharUpperBuffW(*p, SysStringLen(*p)); 00187 00188 TRACE("returning %s\n", debugstr_w(*p)); 00189 00190 return S_OK; 00191 } 00192 00193 static HRESULT WINAPI xmlelem_put_tagName(IXMLElement *iface, BSTR p) 00194 { 00195 FIXME("(%p, %p): stub\n", iface, p); 00196 00197 if (!p) 00198 return E_INVALIDARG; 00199 00200 return E_NOTIMPL; 00201 } 00202 00203 static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **parent) 00204 { 00205 xmlelem *This = impl_from_IXMLElement(iface); 00206 00207 TRACE("(%p, %p)\n", iface, parent); 00208 00209 if (!parent) 00210 return E_INVALIDARG; 00211 00212 *parent = NULL; 00213 00214 if (!This->node->parent) 00215 return S_FALSE; 00216 00217 return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent, FALSE); 00218 } 00219 00220 static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName, 00221 VARIANT PropertyValue) 00222 { 00223 xmlelem *This = impl_from_IXMLElement(iface); 00224 xmlChar *name, *value; 00225 xmlAttrPtr attr; 00226 00227 TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName)); 00228 00229 if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR) 00230 return E_INVALIDARG; 00231 00232 name = xmlChar_from_wchar(strPropertyName); 00233 value = xmlChar_from_wchar(V_BSTR(&PropertyValue)); 00234 attr = xmlSetProp(This->node, name, value); 00235 00236 heap_free(name); 00237 heap_free(value); 00238 return (attr) ? S_OK : S_FALSE; 00239 } 00240 00241 static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR name, 00242 VARIANT *value) 00243 { 00244 static const WCHAR xmllangW[] = { 'x','m','l',':','l','a','n','g',0 }; 00245 xmlelem *This = impl_from_IXMLElement(iface); 00246 xmlChar *val = NULL; 00247 00248 TRACE("(%p, %s, %p)\n", iface, debugstr_w(name), value); 00249 00250 if (!value) 00251 return E_INVALIDARG; 00252 00253 VariantInit(value); 00254 V_BSTR(value) = NULL; 00255 00256 if (!name) 00257 return E_INVALIDARG; 00258 00259 /* case for xml:lang attribute */ 00260 if (!lstrcmpiW(name, xmllangW)) 00261 { 00262 xmlNsPtr ns; 00263 ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml"); 00264 val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href); 00265 } 00266 else 00267 { 00268 xmlAttrPtr attr; 00269 xmlChar *xml_name; 00270 00271 xml_name = xmlChar_from_wchar(name); 00272 attr = This->node->properties; 00273 while (attr) 00274 { 00275 BSTR attr_name; 00276 00277 attr_name = bstr_from_xmlChar(attr->name); 00278 if (!lstrcmpiW(name, attr_name)) 00279 { 00280 val = xmlNodeListGetString(attr->doc, attr->children, 1); 00281 SysFreeString(attr_name); 00282 break; 00283 } 00284 00285 attr = attr->next; 00286 SysFreeString(attr_name); 00287 } 00288 00289 heap_free(xml_name); 00290 } 00291 00292 if (val) 00293 { 00294 V_VT(value) = VT_BSTR; 00295 V_BSTR(value) = bstr_from_xmlChar(val); 00296 } 00297 00298 xmlFree(val); 00299 TRACE("returning %s\n", debugstr_w(V_BSTR(value))); 00300 return (val) ? S_OK : S_FALSE; 00301 } 00302 00303 static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement *iface, BSTR strPropertyName) 00304 { 00305 xmlelem *This = impl_from_IXMLElement(iface); 00306 xmlChar *name; 00307 xmlAttrPtr attr; 00308 int res; 00309 HRESULT hr = S_FALSE; 00310 00311 TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName)); 00312 00313 if (!strPropertyName) 00314 return E_INVALIDARG; 00315 00316 name = xmlChar_from_wchar(strPropertyName); 00317 attr = xmlHasProp(This->node, name); 00318 if (!attr) 00319 goto done; 00320 00321 res = xmlRemoveProp(attr); 00322 00323 if (res == 0) 00324 hr = S_OK; 00325 00326 done: 00327 heap_free(name); 00328 return hr; 00329 } 00330 00331 static HRESULT WINAPI xmlelem_get_children(IXMLElement *iface, IXMLElementCollection **p) 00332 { 00333 xmlelem *This = impl_from_IXMLElement(iface); 00334 00335 TRACE("(%p, %p)\n", iface, p); 00336 00337 if (!p) 00338 return E_INVALIDARG; 00339 00340 return XMLElementCollection_create((IUnknown *)iface, This->node, (LPVOID *)p); 00341 } 00342 00343 static LONG type_libxml_to_msxml(xmlElementType type) 00344 { 00345 switch (type) 00346 { 00347 case XML_ELEMENT_NODE: 00348 return XMLELEMTYPE_ELEMENT; 00349 case XML_TEXT_NODE: 00350 return XMLELEMTYPE_TEXT; 00351 case XML_COMMENT_NODE: 00352 return XMLELEMTYPE_COMMENT; 00353 case XML_DOCUMENT_NODE: 00354 return XMLELEMTYPE_DOCUMENT; 00355 case XML_DTD_NODE: 00356 return XMLELEMTYPE_DTD; 00357 case XML_PI_NODE: 00358 return XMLELEMTYPE_PI; 00359 default: 00360 break; 00361 } 00362 00363 return XMLELEMTYPE_OTHER; 00364 } 00365 00366 static HRESULT WINAPI xmlelem_get_type(IXMLElement *iface, LONG *p) 00367 { 00368 xmlelem *This = impl_from_IXMLElement(iface); 00369 00370 TRACE("(%p, %p)\n", This, p); 00371 00372 if (!p) 00373 return E_INVALIDARG; 00374 00375 *p = type_libxml_to_msxml(This->node->type); 00376 TRACE("returning %d\n", *p); 00377 return S_OK; 00378 } 00379 00380 static HRESULT WINAPI xmlelem_get_text(IXMLElement *iface, BSTR *p) 00381 { 00382 xmlelem *This = impl_from_IXMLElement(iface); 00383 xmlChar *content; 00384 00385 TRACE("(%p, %p)\n", iface, p); 00386 00387 if (!p) 00388 return E_INVALIDARG; 00389 00390 content = xmlNodeGetContent(This->node); 00391 *p = bstr_from_xmlChar(content); 00392 TRACE("returning %s\n", debugstr_w(*p)); 00393 00394 xmlFree(content); 00395 return S_OK; 00396 } 00397 00398 static HRESULT WINAPI xmlelem_put_text(IXMLElement *iface, BSTR p) 00399 { 00400 xmlelem *This = impl_from_IXMLElement(iface); 00401 xmlChar *content; 00402 00403 TRACE("(%p, %s)\n", iface, debugstr_w(p)); 00404 00405 /* FIXME: test which types can be used */ 00406 if (This->node->type == XML_ELEMENT_NODE) 00407 return E_NOTIMPL; 00408 00409 content = xmlChar_from_wchar(p); 00410 xmlNodeSetContent(This->node, content); 00411 00412 heap_free(content); 00413 00414 return S_OK; 00415 } 00416 00417 static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildElem, 00418 LONG lIndex, LONG lreserved) 00419 { 00420 xmlelem *This = impl_from_IXMLElement(iface); 00421 xmlelem *childElem = impl_from_IXMLElement(pChildElem); 00422 xmlNodePtr child; 00423 00424 TRACE("(%p, %p, %d, %d)\n", iface, pChildElem, lIndex, lreserved); 00425 00426 if (lIndex == 0) 00427 child = xmlAddChild(This->node, childElem->node); 00428 else 00429 child = xmlAddNextSibling(This->node, childElem->node->last); 00430 00431 /* parent is responsible for child data */ 00432 if (child) childElem->own = FALSE; 00433 00434 return (child) ? S_OK : S_FALSE; 00435 } 00436 00437 static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChildElem) 00438 { 00439 xmlelem *This = impl_from_IXMLElement(iface); 00440 xmlelem *childElem = impl_from_IXMLElement(pChildElem); 00441 00442 TRACE("(%p, %p)\n", This, childElem); 00443 00444 if (!pChildElem) 00445 return E_INVALIDARG; 00446 00447 /* only supported for This is childElem parent case */ 00448 if (This->node != childElem->node->parent) 00449 return E_INVALIDARG; 00450 00451 xmlUnlinkNode(childElem->node); 00452 /* standalone element now */ 00453 childElem->own = TRUE; 00454 00455 return S_OK; 00456 } 00457 00458 static const struct IXMLElementVtbl xmlelem_vtbl = 00459 { 00460 xmlelem_QueryInterface, 00461 xmlelem_AddRef, 00462 xmlelem_Release, 00463 xmlelem_GetTypeInfoCount, 00464 xmlelem_GetTypeInfo, 00465 xmlelem_GetIDsOfNames, 00466 xmlelem_Invoke, 00467 xmlelem_get_tagName, 00468 xmlelem_put_tagName, 00469 xmlelem_get_parent, 00470 xmlelem_setAttribute, 00471 xmlelem_getAttribute, 00472 xmlelem_removeAttribute, 00473 xmlelem_get_children, 00474 xmlelem_get_type, 00475 xmlelem_get_text, 00476 xmlelem_put_text, 00477 xmlelem_addChild, 00478 xmlelem_removeChild 00479 }; 00480 00481 HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own) 00482 { 00483 xmlelem *elem; 00484 00485 TRACE("(%p,%p)\n", pUnkOuter, ppObj); 00486 00487 if (!ppObj) 00488 return E_INVALIDARG; 00489 00490 *ppObj = NULL; 00491 00492 elem = heap_alloc(sizeof (*elem)); 00493 if(!elem) 00494 return E_OUTOFMEMORY; 00495 00496 elem->lpVtbl = &xmlelem_vtbl; 00497 elem->ref = 1; 00498 elem->node = node; 00499 elem->own = own; 00500 00501 *ppObj = &elem->lpVtbl; 00502 00503 TRACE("returning iface %p\n", *ppObj); 00504 return S_OK; 00505 } 00506 00507 /************************************************************************ 00508 * IXMLElementCollection 00509 */ 00510 typedef struct _xmlelem_collection 00511 { 00512 const IXMLElementCollectionVtbl *lpVtbl; 00513 const IEnumVARIANTVtbl *lpvtblIEnumVARIANT; 00514 LONG ref; 00515 LONG length; 00516 xmlNodePtr node; 00517 00518 /* IEnumVARIANT members */ 00519 xmlNodePtr current; 00520 } xmlelem_collection; 00521 00522 static inline LONG xmlelem_collection_updatelength(xmlelem_collection *collection) 00523 { 00524 xmlNodePtr ptr = collection->node->children; 00525 00526 collection->length = 0; 00527 while (ptr) 00528 { 00529 collection->length++; 00530 ptr = ptr->next; 00531 } 00532 return collection->length; 00533 } 00534 00535 static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface) 00536 { 00537 return (xmlelem_collection *)((char*)iface - FIELD_OFFSET(xmlelem_collection, lpVtbl)); 00538 } 00539 00540 static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface) 00541 { 00542 return (xmlelem_collection *)((char*)iface - FIELD_OFFSET(xmlelem_collection, lpvtblIEnumVARIANT)); 00543 } 00544 00545 static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject) 00546 { 00547 xmlelem_collection *This = impl_from_IXMLElementCollection(iface); 00548 00549 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 00550 00551 if (IsEqualGUID(riid, &IID_IUnknown) || 00552 IsEqualGUID(riid, &IID_IXMLElementCollection)) 00553 { 00554 *ppvObject = iface; 00555 } 00556 else if (IsEqualGUID(riid, &IID_IEnumVARIANT)) 00557 { 00558 *ppvObject = &(This->lpvtblIEnumVARIANT); 00559 } 00560 else 00561 { 00562 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 00563 return E_NOINTERFACE; 00564 } 00565 00566 IXMLElementCollection_AddRef(iface); 00567 00568 return S_OK; 00569 } 00570 00571 static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface) 00572 { 00573 xmlelem_collection *This = impl_from_IXMLElementCollection(iface); 00574 TRACE("%p\n", This); 00575 return InterlockedIncrement(&This->ref); 00576 } 00577 00578 static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface) 00579 { 00580 xmlelem_collection *This = impl_from_IXMLElementCollection(iface); 00581 LONG ref; 00582 00583 TRACE("%p\n", This); 00584 00585 ref = InterlockedDecrement(&This->ref); 00586 if (ref == 0) 00587 { 00588 heap_free(This); 00589 } 00590 00591 return ref; 00592 } 00593 00594 static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo) 00595 { 00596 FIXME("\n"); 00597 return E_NOTIMPL; 00598 } 00599 00600 static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo, 00601 LCID lcid, ITypeInfo** ppTInfo) 00602 { 00603 FIXME("\n"); 00604 return E_NOTIMPL; 00605 } 00606 00607 static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid, 00608 LPOLESTR* rgszNames, UINT cNames, 00609 LCID lcid, DISPID* rgDispId) 00610 { 00611 FIXME("\n"); 00612 return E_NOTIMPL; 00613 } 00614 00615 static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember, 00616 REFIID riid, LCID lcid, WORD wFlags, 00617 DISPPARAMS* pDispParams, VARIANT* pVarResult, 00618 EXCEPINFO* pExcepInfo, UINT* puArgErr) 00619 { 00620 FIXME("\n"); 00621 return E_NOTIMPL; 00622 } 00623 00624 static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, LONG v) 00625 { 00626 TRACE("(%p, %d)\n", iface, v); 00627 return E_FAIL; 00628 } 00629 00630 static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, LONG *p) 00631 { 00632 xmlelem_collection *This = impl_from_IXMLElementCollection(iface); 00633 00634 TRACE("(%p, %p)\n", iface, p); 00635 00636 if (!p) 00637 return E_INVALIDARG; 00638 00639 *p = xmlelem_collection_updatelength(This); 00640 return S_OK; 00641 } 00642 00643 static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk) 00644 { 00645 xmlelem_collection *This = impl_from_IXMLElementCollection(iface); 00646 00647 TRACE("(%p, %p)\n", iface, ppUnk); 00648 00649 if (!ppUnk) 00650 return E_INVALIDARG; 00651 00652 *ppUnk = (IUnknown *)This; 00653 IUnknown_AddRef(*ppUnk); 00654 return S_OK; 00655 } 00656 00657 static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1, 00658 VARIANT var2, IDispatch **ppDisp) 00659 { 00660 xmlelem_collection *This = impl_from_IXMLElementCollection(iface); 00661 xmlNodePtr ptr = This->node->children; 00662 int index, i; 00663 00664 TRACE("(%p, %p)\n", iface, ppDisp); 00665 00666 if (!ppDisp) 00667 return E_INVALIDARG; 00668 00669 *ppDisp = NULL; 00670 00671 index = V_I4(&var1); 00672 if (index < 0) 00673 return E_INVALIDARG; 00674 00675 xmlelem_collection_updatelength(This); 00676 if (index >= This->length) 00677 return E_FAIL; 00678 00679 for (i = 0; i < index; i++) 00680 ptr = ptr->next; 00681 00682 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp, FALSE); 00683 } 00684 00685 static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl = 00686 { 00687 xmlelem_collection_QueryInterface, 00688 xmlelem_collection_AddRef, 00689 xmlelem_collection_Release, 00690 xmlelem_collection_GetTypeInfoCount, 00691 xmlelem_collection_GetTypeInfo, 00692 xmlelem_collection_GetIDsOfNames, 00693 xmlelem_collection_Invoke, 00694 xmlelem_collection_put_length, 00695 xmlelem_collection_get_length, 00696 xmlelem_collection_get__newEnum, 00697 xmlelem_collection_item 00698 }; 00699 00700 /************************************************************************ 00701 * xmlelem_collection implementation of IEnumVARIANT. 00702 */ 00703 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface( 00704 IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj) 00705 { 00706 xmlelem_collection *this = impl_from_IEnumVARIANT(iface); 00707 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj); 00708 } 00709 00710 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef( 00711 IEnumVARIANT *iface) 00712 { 00713 xmlelem_collection *this = impl_from_IEnumVARIANT(iface); 00714 return IXMLDocument_AddRef((IXMLDocument *)this); 00715 } 00716 00717 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release( 00718 IEnumVARIANT *iface) 00719 { 00720 xmlelem_collection *this = impl_from_IEnumVARIANT(iface); 00721 return IXMLDocument_Release((IXMLDocument *)this); 00722 } 00723 00724 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next( 00725 IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched) 00726 { 00727 xmlelem_collection *This = impl_from_IEnumVARIANT(iface); 00728 xmlNodePtr ptr = This->current; 00729 00730 TRACE("(%p, %d, %p, %p)\n", iface, celt, rgVar, fetched); 00731 00732 if (!rgVar) 00733 return E_INVALIDARG; 00734 00735 /* FIXME: handle celt */ 00736 if (fetched) 00737 *fetched = 1; 00738 00739 if (This->current) 00740 This->current = This->current->next; 00741 else 00742 { 00743 V_VT(rgVar) = VT_EMPTY; 00744 if (fetched) *fetched = 0; 00745 return S_FALSE; 00746 } 00747 00748 V_VT(rgVar) = VT_DISPATCH; 00749 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE); 00750 } 00751 00752 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip( 00753 IEnumVARIANT *iface, ULONG celt) 00754 { 00755 FIXME("(%p, %d): stub\n", iface, celt); 00756 return E_NOTIMPL; 00757 } 00758 00759 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset( 00760 IEnumVARIANT *iface) 00761 { 00762 xmlelem_collection *This = impl_from_IEnumVARIANT(iface); 00763 This->current = This->node->children; 00764 return S_OK; 00765 } 00766 00767 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone( 00768 IEnumVARIANT *iface, IEnumVARIANT **ppEnum) 00769 { 00770 FIXME("(%p, %p): stub\n", iface, ppEnum); 00771 return E_NOTIMPL; 00772 } 00773 00774 static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl = 00775 { 00776 xmlelem_collection_IEnumVARIANT_QueryInterface, 00777 xmlelem_collection_IEnumVARIANT_AddRef, 00778 xmlelem_collection_IEnumVARIANT_Release, 00779 xmlelem_collection_IEnumVARIANT_Next, 00780 xmlelem_collection_IEnumVARIANT_Skip, 00781 xmlelem_collection_IEnumVARIANT_Reset, 00782 xmlelem_collection_IEnumVARIANT_Clone 00783 }; 00784 00785 static HRESULT XMLElementCollection_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj) 00786 { 00787 xmlelem_collection *collection; 00788 00789 TRACE("(%p,%p)\n", pUnkOuter, ppObj); 00790 00791 *ppObj = NULL; 00792 00793 if (!node->children) 00794 return S_FALSE; 00795 00796 collection = heap_alloc(sizeof (*collection)); 00797 if(!collection) 00798 return E_OUTOFMEMORY; 00799 00800 collection->lpVtbl = &xmlelem_collection_vtbl; 00801 collection->lpvtblIEnumVARIANT = &xmlelem_collection_IEnumVARIANTvtbl; 00802 collection->ref = 1; 00803 collection->length = 0; 00804 collection->node = node; 00805 collection->current = node->children; 00806 xmlelem_collection_updatelength(collection); 00807 00808 *ppObj = &collection->lpVtbl; 00809 00810 TRACE("returning iface %p\n", *ppObj); 00811 return S_OK; 00812 } 00813 00814 #endif Generated on Sat May 26 2012 04:23:58 for ReactOS by
1.7.6.1
|