#if !defined(_FUSION_INC_DOMHELPER_H_INCLUDED_) #define _FUSION_INC_DOMHELPER_H_INCLUDED_ #pragma once #include "smartref.h" #include "oleaut_d.h" #include "fusionparser.h" // // Be sure that you have a symbol named _Module in scope when you #include this header file // that has member functions for the OLEAUT32 functions: // // SysAllocString // SysFreeString // VariantClear // VariantInit // VariantCopy // class CDOMHelper { public: static HRESULT FindChild(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, DOMNodeType ntToMatch, LPCWSTR sz, bool fRecurse = false) { HRESULT hr = NOERROR; CSmartRef srpIXMLDOMNode; if (ppIXMLDOMNode_Out != NULL) *ppIXMLDOMNode_Out = NULL; if ((ppIXMLDOMNode_Out == NULL) || (pIXMLDOMNode_Root == NULL)) { hr = E_POINTER; goto Exit; } hr = pIXMLDOMNode_Root->get_firstChild(&srpIXMLDOMNode); if (FAILED(hr)) goto Exit; hr = CDOMHelper::FindSibling(ppIXMLDOMNode_Out, srpIXMLDOMNode, ntToMatch, sz, false, fRecurse); if (FAILED(hr)) goto Exit; hr = ((*ppIXMLDOMNode_Out) != NULL) ? NOERROR : S_FALSE; Exit: return hr; } static HRESULT FindSibling(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, DOMNodeType ntToMatch, LPCWSTR sz, bool fSkipCurrent, bool fRecurse = false) { BSTR bstrName = NULL; DOMNodeType nt; HRESULT hr = NOERROR; CSmartRef srpIXMLDOMNode, srpIXMLDOMNode_Next; if (ppIXMLDOMNode_Out != NULL) *ppIXMLDOMNode_Out = NULL; if ((ppIXMLDOMNode_Out == NULL) || (pIXMLDOMNode_Root == NULL)) { hr = E_POINTER; goto Exit; } if (fSkipCurrent) { hr = pIXMLDOMNode_Root->get_nextSibling(&srpIXMLDOMNode); if (FAILED(hr)) goto Exit; } else srpIXMLDOMNode = pIXMLDOMNode_Root; while (srpIXMLDOMNode != NULL) { hr = srpIXMLDOMNode->get_nodeType(&nt); if (FAILED(hr)) goto Exit; if (nt == ntToMatch) { hr = srpIXMLDOMNode->get_nodeName(&bstrName); if (FAILED(hr)) goto Exit; if (StrCmpIW(bstrName, sz) == 0) { *ppIXMLDOMNode_Out = srpIXMLDOMNode.Disown(); break; } _Module.SysFreeString(bstrName); bstrName = NULL; if (fRecurse) { hr = CDOMHelper::FindChild(ppIXMLDOMNode_Out, srpIXMLDOMNode, ntToMatch, sz, fRecurse); if (FAILED(hr)) goto Exit; if ((*ppIXMLDOMNode_Out) != NULL) break; } } hr = srpIXMLDOMNode->get_nextSibling(&srpIXMLDOMNode_Next); if (FAILED(hr)) goto Exit; if (hr == S_FALSE) break; srpIXMLDOMNode.Take(srpIXMLDOMNode_Next); } hr = ((*ppIXMLDOMNode_Out) != NULL) ? NOERROR : S_FALSE; Exit: if (bstrName != NULL) _Module.SysFreeString(bstrName); return hr; } static HRESULT CopyTextNodeValue(IXMLDOMNode *pIXMLDOMNode, LPWSTR sz, ULONG *pcch) { HRESULT hr = NOERROR; VARIANT varTemp; ULONG cch; varTemp.vt = VT_EMPTY; if (pcch == NULL) { hr = E_POINTER; goto Exit; } hr = pIXMLDOMNode->get_nodeValue(&varTemp); if (FAILED(hr)) goto Exit; if (varTemp.vt != VT_BSTR) { hr = E_FAIL; goto Exit; } cch = ::wcslen(varTemp.bstrVal) + 1; if ((*pcch) < cch) { *pcch = cch; hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); goto Exit; } memcpy(sz, varTemp.bstrVal, cch * sizeof(WCHAR)); hr = NOERROR; Exit: _Module.VariantClear(&varTemp); return hr; } enum Relationship { eSibling, eChild, }; static HRESULT FollowPath(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, ULONG nPathLength, Relationship r, DOMNodeType nt, LPCWSTR sz, ...) { HRESULT hr = NOERROR; va_list ap; bool fApInitialized = false; if (ppIXMLDOMNode_Out != NULL) *ppIXMLDOMNode_Out = NULL; if ((ppIXMLDOMNode_Out == NULL) || (pIXMLDOMNode_Root == NULL)) { hr = E_POINTER; goto Exit; } va_start(ap, sz); fApInitialized = true; hr = CDOMHelper::FollowPathVa(ppIXMLDOMNode_Out, pIXMLDOMNode_Root, nPathLength, r, nt, sz, ap); if (FAILED(hr)) goto Exit; hr = NOERROR; Exit: if (fApInitialized) va_end(ap); return hr; } static HRESULT FollowPathVa(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, ULONG nPathLength, Relationship r, DOMNodeType nt, LPCWSTR sz, va_list ap) { HRESULT hr = NOERROR; CSmartRef srpIXMLDOMNode, srpIXMLDOMNode_Next; ULONG i; if (ppIXMLDOMNode_Out != NULL) *ppIXMLDOMNode_Out = NULL; if ((ppIXMLDOMNode_Out == NULL) || (pIXMLDOMNode_Root == NULL)) { hr = E_POINTER; goto Exit; } srpIXMLDOMNode = pIXMLDOMNode_Root; for (i=0; i srpIXMLDOMElement; BSTR bstrName = NULL; VARIANT varValue; varValue.vt = VT_EMPTY; if (pIXMLDOMNode == NULL) { hr = E_POINTER; goto Exit; } hr = srpIXMLDOMElement.QueryInterfaceFrom(pIXMLDOMNode); if (FAILED(hr)) goto Exit; bstrName = _Module.SysAllocString(szAttributeName); if (bstrName == NULL) { hr = E_OUTOFMEMORY; goto Exit; } hr = srpIXMLDOMElement->getAttribute(bstrName, &varValue); if (FAILED(hr)) goto Exit; // If the attribute did not exist, return S_FALSE and ensure that the output // buffer is a blank string. if (hr == S_FALSE) { rbuffOut.GetBufferPtr()[0] = L'\0'; goto Exit; } if (varValue.vt != VT_BSTR) { hr = E_FAIL; goto Exit; } hr = rbuffOut.Assign(varValue.bstrVal); if (FAILED(hr)) goto Exit; hr = NOERROR; Exit: if (bstrName != NULL) _Module.SysFreeString(bstrName); _Module.VariantClear(&varValue); return hr; } static HRESULT GetAttributeValue(LPWSTR szOut, ULONG *pcch, IXMLDOMNode *pIXMLDOMNode, LPCWSTR szAttributeName) { HRESULT hr = NOERROR; CSmartRef srpIXMLDOMElement; BSTR bstrName = NULL; VARIANT varValue; ULONG cch; varValue.vt = VT_EMPTY; if (pIXMLDOMNode == NULL) { hr = E_POINTER; goto Exit; } hr = srpIXMLDOMElement.QueryInterfaceFrom(pIXMLDOMNode); if (FAILED(hr)) goto Exit; bstrName = _Module.SysAllocString(szAttributeName); if (bstrName == NULL) { hr = E_OUTOFMEMORY; goto Exit; } hr = srpIXMLDOMElement->getAttribute(bstrName, &varValue); if (FAILED(hr)) goto Exit; if (varValue.vt != VT_BSTR) { hr = E_FAIL; goto Exit; } cch = ::wcslen(varValue.bstrVal) + 1; if ((*pcch) < cch) { *pcch = cch; hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); goto Exit; } memcpy(szOut, varValue.bstrVal, cch * sizeof(WCHAR)); hr = NOERROR; Exit: if (bstrName != NULL) _Module.SysFreeString(bstrName); _Module.VariantClear(&varValue); return hr; } static HRESULT GetBooleanAttributeValue(BOOLEAN *pfValue, IXMLDOMNode *pIXMLDOMNode, LPCWSTR szAttributeName, BOOLEAN fDefaultValue) { HRESULT hr = NOERROR; CSmartRef srpIXMLDOMElement; BSTR bstrName = NULL; VARIANT varValue; varValue.vt = VT_EMPTY; if ((pIXMLDOMNode == NULL) || (pfValue == NULL)) { hr = E_POINTER; goto Exit; } hr = srpIXMLDOMElement.QueryInterfaceFrom(pIXMLDOMNode); if (FAILED(hr)) goto Exit; bstrName = _Module.SysAllocString(szAttributeName); if (bstrName == NULL) { hr = E_OUTOFMEMORY; goto Exit; } hr = srpIXMLDOMElement->getAttribute(bstrName, &varValue); if (FAILED(hr)) goto Exit; if (hr == S_FALSE) { *pfValue = fDefaultValue; goto Exit; } if (varValue.vt != VT_BSTR) { hr = E_FAIL; goto Exit; } hr = CFusionParser::ParseBoolean(*pfValue, varValue.bstrVal, ::wcslen(varValue.bstrVal)); if (FAILED(hr)) goto Exit; hr = NOERROR; Exit: if (bstrName != NULL) _Module.SysFreeString(bstrName); _Module.VariantClear(&varValue); return hr; } static HRESULT GetAttributeValue(CBaseStringBuffer &rbuffOut, IXMLDOMNode *pIXMLDOMNode_Root, LPCWSTR szAttributeName, ULONG nPathLength, Relationship r, DOMNodeType nt, LPCWSTR sz, ...) { HRESULT hr = NOERROR; va_list ap; bool fApInitialized = false; CSmartRef srpIXMLDOMNode; if (pIXMLDOMNode_Root == NULL) { hr = E_POINTER; goto Exit; } va_start(ap, sz); fApInitialized = true; hr = CDOMHelper::FollowPathVa(&srpIXMLDOMNode, pIXMLDOMNode_Root, nPathLength, r, nt, sz, ap); if (FAILED(hr)) goto Exit; hr = CDOMHelper::GetAttributeValue(rbuffOut, srpIXMLDOMNode, szAttributeName); if (FAILED(hr)) goto Exit; hr = NOERROR; Exit: if (fApInitialized) va_end(ap); return hr; } }; #endif