ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

xmlelem.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.