📄 devtreeparsing.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "pch.h"
#pragma hdrstop
struct CoGate
{
CoGate(DWORD dwCoInit = COINIT_MULTITHREADED)
{CoInitializeEx(NULL, dwCoInit); }
~CoGate()
{CoUninitialize(); }
};
// Parse
BOOL HostedDeviceTree::Parse(LPCWSTR pwszDeviceDescription)
{
HRESULT hr;
CoGate co;
ce::SAXReader Reader;
// first pass - verify specVersion and get URLBase (optional)
if(Reader.valid())
{
Reader->putContentHandler(this);
VARIANT vt;
vt.vt = VT_BSTR;
vt.bstrVal = SysAllocString(pwszDeviceDescription);
hr = Reader->parse(vt);
if(FAILED(hr))
TraceTag(ttidError, "SAXXMLReader::parse returned error 0x%08x", hr);
// avoid VariantClear to minimize dependency on oleaut32
SysFreeString(vt.bstrVal);
}
else
hr = Reader.Error();
if(SUCCEEDED(hr))
{
// verify spec version
m_strSpecVersionMajor.trim(L"\n\r\t ");
m_strSpecVersionMinor.trim(L"\n\r\t ");
if(m_strSpecVersionMajor != L"1" || m_strSpecVersionMinor != L"0")
// invalid spec version
return false;
}
return SUCCEEDED(hr);
}
static wchar_t pwszSpecVersionElement[] =
L"<urn:schemas-upnp-org:device-1-0>"
L"<root>"
L"<urn:schemas-upnp-org:device-1-0>"
L"<specVersion>";
static wchar_t pwszDeviceElement[] =
L"<urn:schemas-upnp-org:device-1-0>"
L"<root>"
L"<urn:schemas-upnp-org:device-1-0>"
L"<device>";
// startDocument
HRESULT STDMETHODCALLTYPE HostedDeviceTree::startDocument(void)
{
SAXContentHandler::startDocument();
m_SAXWriter.Open(m_pszDescFileName);
m_SAXWriter.startDocument();
return S_OK;
}
// startElement
HRESULT STDMETHODCALLTYPE HostedDeviceTree::startElement(
/* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
/* [in] */ int cchNamespaceUri,
/* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
/* [in] */ int cchLocalName,
/* [in] */ const wchar_t __RPC_FAR *pwchQName,
/* [in] */ int cchQName,
/* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
{
SAXContentHandler::startElement(pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchQName, cchQName, pAttributes);
if(m_pTempDevice)
m_pTempDevice->startElement(pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchQName, cchQName, pAttributes);
else
{
// Device element
if(pwszDeviceElement == m_strFullElementName)
{
// start of root device
// this section will be parsed by new device object
m_pTempDevice = new HostedDevice(this);
if(m_pTempDevice)
{
// simulate startDocument for the device
m_pTempDevice->startDocument();
}
}
m_SAXWriter.startElement(pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchQName, cchQName, pAttributes);
}
return S_OK;
}
// endElement
HRESULT STDMETHODCALLTYPE HostedDeviceTree::endElement(
/* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
/* [in] */ int cchNamespaceUri,
/* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
/* [in] */ int cchLocalName,
/* [in] */ const wchar_t __RPC_FAR *pwchQName,
/* [in] */ int cchQName)
{
// Device element
if(pwszDeviceElement == m_strFullElementName)
{
Assert(m_pTempDevice);
// finished parsing root device;
// simulate endDocument
m_pTempDevice->endDocument();
Assert(m_pRootDevice == NULL);
m_pRootDevice = m_pTempDevice;
m_pTempDevice = NULL;
}
if(m_pTempDevice)
m_pTempDevice->endElement(pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchQName, cchQName);
else
m_SAXWriter.endElement(pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchQName, cchQName);
return SAXContentHandler::endElement(pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchQName, cchQName);
}
// characters
HRESULT STDMETHODCALLTYPE HostedDeviceTree::characters(
/* [in] */ const wchar_t __RPC_FAR *pwchChars,
/* [in] */ int cchChars)
{
// specVersion
static const int nSpecVersionLength = sizeof(pwszSpecVersionElement)/sizeof(*pwszSpecVersionElement) - 1;
if(0 == wcsncmp(pwszSpecVersionElement, m_strFullElementName, nSpecVersionLength))
{
// major
if(0 == wcscmp(L"<urn:schemas-upnp-org:device-1-0><major>", static_cast<LPCWSTR>(m_strFullElementName) + nSpecVersionLength))
m_strSpecVersionMajor.append(pwchChars, cchChars);
// major
if(0 == wcscmp(L"<urn:schemas-upnp-org:device-1-0><minor>", static_cast<LPCWSTR>(m_strFullElementName) + nSpecVersionLength))
m_strSpecVersionMinor.append(pwchChars, cchChars);
}
if(m_pTempDevice)
m_pTempDevice->characters(pwchChars, cchChars);
else
m_SAXWriter.characters(pwchChars, cchChars);
return S_OK;
}
// endDocument
HRESULT STDMETHODCALLTYPE HostedDeviceTree::endDocument(void)
{
SAXContentHandler::endDocument();
m_SAXWriter.endDocument();
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -