621 lines
13 KiB
C++
621 lines
13 KiB
C++
#include <objbase.h>
|
|
#include "qxml.h"
|
|
//#include "dbgassrt.h"
|
|
#include <assert.h>
|
|
#include "strconv.h"
|
|
#define ASSERT(a) (assert(a))
|
|
#define INCDEBUGCOUNTER(a)
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetTextFromNode(IXMLDOMNode* pxdnode,
|
|
LPWSTR pszText, DWORD cchText)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_text(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
lstrcpyn(pszText, bstr, cchText);
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetTextFromNodeNoBuf(IXMLDOMNode* pxdnode,
|
|
LPWSTR* ppszText)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_text(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
*ppszText = bstr;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (*ppszText)
|
|
{
|
|
INCDEBUGCOUNTER(CQXML::d_cBSTRReturned);
|
|
}
|
|
#endif
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetGUIDFromNode(IXMLDOMNode* pxdnode,
|
|
GUID* pguid)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_text(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
StringToGUID(bstr, pguid);
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetFileTimeFromNode(IXMLDOMNode* pxdnode,
|
|
FILETIME* pft)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_text(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
hres = (StringToFileTime(bstr, pft) ? S_OK : E_FAIL);
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetTagTextFromNode(IXMLDOMNode* pxdnode,
|
|
LPWSTR pszText, DWORD cchText)
|
|
{
|
|
// We assume that the node passed in is a NODE_ELEMENT
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
LPWSTR pszPtr;
|
|
|
|
HRESULT hres = pxdnode->get_nodeName(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
pszPtr = wcschr(bstr,':');
|
|
if (!pszPtr)
|
|
{
|
|
lstrcpyn(pszText, bstr, cchText); // if no colon, bstr is the text
|
|
}
|
|
else
|
|
{
|
|
lstrcpyn(pszText, pszPtr + 1, cchText);
|
|
}
|
|
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetTagTextFromNodeNoBuf(IXMLDOMNode* pxdnode,
|
|
LPWSTR* ppszText)
|
|
{
|
|
// We assume that the node passed in is a NODE_ELEMENT
|
|
ASSERT(pxdnode);
|
|
LPWSTR pszPtr;
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_nodeName(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
pszPtr = wcschr(bstr,':');
|
|
if (!pszPtr)
|
|
{
|
|
*ppszText = bstr; // if no colon, bstr is the text
|
|
}
|
|
else
|
|
{
|
|
*ppszText = SysAllocStringLen(NULL, lstrlen(pszPtr + 1) + 1);
|
|
lstrcpy(*ppszText, pszPtr + 1);
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (*ppszText)
|
|
{
|
|
INCDEBUGCOUNTER(CQXML::d_cBSTRReturned);
|
|
}
|
|
#endif
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetNamespaceNameFromNode(IXMLDOMNode* pxdnode,
|
|
LPWSTR pszText, DWORD cchText)
|
|
{
|
|
// We assume that the node passed in is a NODE_ELEMENT
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_namespaceURI(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
lstrcpyn(pszText, bstr, cchText);
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetNamespaceNameFromNodeNoBuf(IXMLDOMNode* pxdnode,
|
|
LPWSTR* ppszText)
|
|
{
|
|
// We assume that the node passed in is a NODE_ELEMENT
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_namespaceURI(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
*ppszText = bstr;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (*ppszText)
|
|
{
|
|
INCDEBUGCOUNTER(CQXML::d_cBSTRReturned);
|
|
}
|
|
#endif
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetNamespaceAliasFromNode(IXMLDOMNode* pxdnode,
|
|
LPWSTR pszText, DWORD cchText)
|
|
{
|
|
// We assume that the node passed in is a NODE_ELEMENT
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
LPWSTR pszPtr;
|
|
|
|
HRESULT hres = pxdnode->get_nodeName(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
pszPtr = wcschr(bstr,':');
|
|
if (!pszPtr)
|
|
{
|
|
pszText[0] = NULL; // if no colon, alias is non
|
|
}
|
|
else
|
|
{
|
|
*pszPtr = NULL;
|
|
lstrcpyn(pszText, bstr, cchText);
|
|
*pszPtr = ':'; // replace the colon
|
|
}
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
// static
|
|
HRESULT CQXMLHelper::GetNamespaceAliasFromNodeNoBuf(IXMLDOMNode* pxdnode,
|
|
LPWSTR* ppszText)
|
|
{
|
|
// We assume that the node passed in is a NODE_ELEMENT
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
LPWSTR pszPtr;
|
|
|
|
HRESULT hres = pxdnode->get_nodeName(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
pszPtr = wcschr(bstr,':');
|
|
if (!pszPtr)
|
|
{
|
|
*ppszText = NULL; // if no colon, alias is non
|
|
}
|
|
else
|
|
{
|
|
*pszPtr = NULL;
|
|
*ppszText = SysAllocStringLen(NULL, lstrlen(bstr) + 1);
|
|
lstrcpy(*ppszText, bstr);
|
|
}
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (*ppszText)
|
|
{
|
|
INCDEBUGCOUNTER(CQXML::d_cBSTRReturned);
|
|
}
|
|
#endif
|
|
|
|
return hres;
|
|
}
|
|
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetIntFromNode(IXMLDOMNode* pxdnode, int* pi)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
*pi = 0;
|
|
|
|
HRESULT hres = pxdnode->get_text(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
if ((L'0' == *bstr) && (L'x' == *(bstr + 1)))
|
|
{
|
|
LPWSTR psz = bstr + 2;
|
|
|
|
while (*psz && ((psz - (bstr + 2)) <= 8))
|
|
{
|
|
int i = 0;
|
|
|
|
if (*psz >= L'0' && *psz <= L'9')
|
|
{
|
|
i = *psz - L'0';
|
|
}
|
|
else
|
|
{
|
|
if (*psz >= L'a' && *psz <= L'f')
|
|
{
|
|
i = *psz - L'a' + 10;
|
|
}
|
|
else
|
|
{
|
|
if (*psz >= L'A' && *psz <= L'F')
|
|
{
|
|
i = *psz - L'A' + 10;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
(*pi) *= 16;
|
|
|
|
(*pi) += i;
|
|
|
|
++psz;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*pi = _wtoi(bstr);
|
|
}
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetVariantFromNode(IXMLDOMNode* pxdnode, VARTYPE vt,
|
|
VARIANT* pvar)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_text(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
pvar->vt = vt;
|
|
|
|
switch (vt)
|
|
{
|
|
case VT_I4:
|
|
{
|
|
pvar->lVal = _wtoi(bstr);
|
|
break;
|
|
}
|
|
case VT_BSTR:
|
|
{
|
|
pvar->bstrVal = bstr;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
pvar->vt = VT_EMPTY;
|
|
hres = E_NOTIMPL;
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (vt)
|
|
{
|
|
case VT_BSTR:
|
|
{
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// free the BSTR for all
|
|
SysFreeString(bstr);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if ((VT_BSTR == pvar->vt) && (pvar->bstrVal))
|
|
{
|
|
INCDEBUGCOUNTER(CQXML::d_cBSTRReturned);
|
|
}
|
|
#endif
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetConcatenatedBSTR(LPCWSTR pszStr1, LPCWSTR pszStr2, BSTR* pbstr)
|
|
{
|
|
HRESULT hres = E_OUTOFMEMORY;
|
|
int cchStr1 = 0;
|
|
int cchStr2 = 0;
|
|
|
|
if (pszStr1)
|
|
{
|
|
cchStr1 = lstrlen(pszStr1);
|
|
}
|
|
|
|
if (pszStr2)
|
|
{
|
|
cchStr2 = lstrlen(pszStr2);
|
|
}
|
|
|
|
if (pszStr1 && pszStr2)
|
|
{
|
|
// we need a '/' between them
|
|
++cchStr1;
|
|
}
|
|
|
|
// + 1 for NULL terminator
|
|
*pbstr = SysAllocStringLen(NULL, cchStr1 + cchStr2 + 1);
|
|
|
|
if (*pbstr)
|
|
{
|
|
if (pszStr1)
|
|
{
|
|
lstrcpy(*pbstr, pszStr1);
|
|
|
|
if (pszStr2)
|
|
{
|
|
lstrcat(*pbstr, TEXT("/"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
**pbstr = 0;
|
|
}
|
|
|
|
if (pszStr2)
|
|
{
|
|
lstrcat(*pbstr, pszStr2);
|
|
}
|
|
|
|
hres = S_OK;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::CreateAndInsertNode(IXMLDOMDocument* pxddoc,
|
|
IXMLDOMNode* pxdnodeParent, LPCWSTR pszStr, LPCWSTR pszNamespaceName,
|
|
LPCWSTR pszNamespaceAlias, DOMNodeType nodetype, IXMLDOMNode** ppxdnodeNew)
|
|
{
|
|
ASSERT((pszNamespaceName && pszNamespaceAlias) || (!pszNamespaceName && !pszNamespaceAlias));
|
|
|
|
HRESULT hres = E_OUTOFMEMORY;
|
|
IXMLDOMNode* pxdnodeNewLocal;
|
|
|
|
BSTR bstr = NULL;
|
|
BSTR bstrNamespace = NULL;
|
|
|
|
if (pszNamespaceName)
|
|
{
|
|
UINT cchStr = lstrlen(pszStr);
|
|
UINT cchNamespaceName = lstrlen(pszNamespaceName);
|
|
UINT cchNamespaceAlias = lstrlen(pszNamespaceAlias);
|
|
|
|
bstr = SysAllocStringLen(NULL, cchStr + cchNamespaceAlias + 2);
|
|
|
|
if (bstr)
|
|
{
|
|
lstrcpy(bstr, pszNamespaceAlias);
|
|
lstrcpy(bstr + cchNamespaceAlias, L":");
|
|
lstrcpy(bstr + cchNamespaceAlias + 1, pszStr);
|
|
|
|
bstrNamespace = SysAllocStringLen(NULL, cchNamespaceName + 2);
|
|
|
|
if (bstrNamespace)
|
|
{
|
|
lstrcpy(bstrNamespace, pszNamespaceName);
|
|
lstrcpy(bstrNamespace + cchNamespaceName, L":");
|
|
hres = S_OK;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bstr = SysAllocStringLen(NULL, lstrlen(pszStr) + 1);
|
|
if (bstr)
|
|
{
|
|
lstrcpy(bstr, pszStr);
|
|
hres = S_OK;
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
VARIANT var;
|
|
var.vt = VT_INT;
|
|
var.intVal = nodetype;
|
|
|
|
hres = pxddoc->createNode(var, bstr, bstrNamespace, &pxdnodeNewLocal);
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
ASSERT(pxdnodeNewLocal);
|
|
|
|
VARIANT var;
|
|
var.vt = VT_EMPTY;
|
|
var.intVal = 0;
|
|
|
|
// Add it to the current Node
|
|
hres = pxdnodeParent->insertBefore(pxdnodeNewLocal, var,
|
|
ppxdnodeNew);
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
// for *pxdnodeNew which goes out
|
|
INCDEBUGCOUNTER(CQXML::d_cxdnodeRef);
|
|
}
|
|
|
|
pxdnodeNewLocal->Release();
|
|
}
|
|
|
|
}
|
|
|
|
if (bstr != NULL)
|
|
{
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
if (bstrNamespace != NULL)
|
|
{
|
|
SysFreeString(bstrNamespace);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetXMLTreeTextFromNode(IXMLDOMNode* pxdnode,
|
|
LPWSTR pszText, DWORD cchText)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_xml(&bstr);
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
lstrcpyn(pszText, bstr, cchText);
|
|
|
|
SysFreeString(bstr);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//static
|
|
HRESULT CQXMLHelper::GetXMLTreeTextFromNodeNoBuf(IXMLDOMNode* pxdnode,
|
|
LPWSTR* ppszText)
|
|
{
|
|
ASSERT(pxdnode);
|
|
|
|
BSTR bstr;
|
|
|
|
HRESULT hres = pxdnode->get_xml(&bstr);
|
|
|
|
|
|
if (SUCCEEDED(hres) && (S_FALSE != hres))
|
|
{
|
|
ASSERT(bstr);
|
|
|
|
*ppszText = bstr;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (*ppszText)
|
|
{
|
|
INCDEBUGCOUNTER(CQXML::d_cBSTRReturned);
|
|
}
|
|
#endif
|
|
|
|
return hres;
|
|
}
|