// // Parser.cpp // // Copyright (c) Microsoft Corporation. All rights reserved. // #include "stdafx.h" #include "Parser.h" #include "SkipParser.h" #include "resource.h" //////////////////////////////////////////////////////////////////////// // // CParserBase interface // //////////////////////////////////////////////////////////////////////// HRESULT CParserBase::DispatchElement( const XMLTAG *pEntry, const wchar_t *wszNamespaceUri, int cchNamespaceUri, const wchar_t *wszLocalName, int cchLocalName, const wchar_t *wszQName, int cchQName, ISAXAttributes *pAttributes) throw() { if (!pEntry) { return S_OK; } while (pEntry->szElemName) { if (CheckTagElement(pEntry, wszNamespaceUri, cchNamespaceUri, wszLocalName, cchLocalName, wszQName, cchQName)) { return (this->*pEntry->pfnTag)(wszNamespaceUri, cchNamespaceUri, wszLocalName, cchLocalName, wszQName, cchQName, pAttributes); } pEntry++; } // // unrecognized tag // return OnUnrecognizedTag(wszNamespaceUri, cchNamespaceUri, wszLocalName, cchLocalName, wszQName, cchQName, pAttributes); } HRESULT CParserBase::GetAttributes(const XMLATTR *pEntry, ISAXAttributes *pAttributes) { if (!pAttributes) { EmitError(IDS_SDL_INTERNAL); return E_FAIL; } if (GetGotAttributes() != FALSE) { return S_OK; } if (!pEntry) { return S_OK; } int nAttrs = 0; HRESULT hr = pAttributes->getLength(&nAttrs); if (FAILED(hr)) { EmitError(IDS_SDL_MSXML); return E_FAIL; } while (pEntry->wszElemName) { int i; for (i=0; igetName(i, &wszNamespaceUri, &cchUri, &wszLocalName, &cchLocalName, &wszQName, &cchQName); if (FAILED(hr)) { EmitError(IDS_SDL_MSXML); return E_FAIL; } if (CheckTagElement(pEntry, wszNamespaceUri, cchUri, wszLocalName, cchLocalName, wszQName, cchQName)) { const wchar_t *wszValue = NULL; int cchValue = 0; hr = pAttributes->getValue(i, &wszValue, &cchValue); if (SUCCEEDED(hr)) { hr = (this->*pEntry->pfnAttr)(wszNamespaceUri, cchUri, wszLocalName, cchLocalName, wszQName, cchQName, wszValue, cchValue, pAttributes); } else { EmitError(IDS_SDL_MSXML); } break; } } if (i >= nAttrs) { hr = OnMissingAttribute(pEntry->bRequired, pEntry->wszElemName, pEntry->cchElem, pEntry->wszElemNamespace, pEntry->cchNamespaceUri); } if (FAILED(hr)) { break; } pEntry++; } SetGotAttributes(TRUE); return hr; } HRESULT CParserBase::DispatchElement( const wchar_t *wszNamespaceUri, int cchNamespaceUri, const wchar_t *wszLocalName, int cchLocalName, const wchar_t *wszQName, int cchQName, ISAXAttributes *pAttributes) throw() { if (FAILED(GetAttributes(pAttributes))) { return E_FAIL; } const XMLTAG * pEntry = GetXMLTAGMap(); return DispatchElement(pEntry, wszNamespaceUri, cchNamespaceUri, wszLocalName, cchLocalName, wszQName, cchQName, pAttributes); } HRESULT CParserBase::GetAttributes(ISAXAttributes *pAttributes) { const XMLATTR * pEntry = GetXMLATTRMap(); return GetAttributes(pEntry, pAttributes); } BOOL CParserBase::CheckTagElement( const XMLTAG *pTag, const wchar_t *wszNamespaceUri, int cchNamespaceUri, const wchar_t *wszLocalName, int cchLocalName, const wchar_t *wszQName, int cchQName) { if (!pTag->wszElemName) { EmitError(IDS_SDL_INTERNAL); return FALSE; } if (pTag->cchElem == cchLocalName && !wcsncmp(pTag->wszElemName, wszLocalName, pTag->cchElem)) { // // Don't need to check default namespace for tags since SAX gives it in wszElemNamespace // if ((!pTag->wszElemNamespace) || (!pTag->cchNamespaceUri && !cchNamespaceUri) || (pTag->cchNamespaceUri == cchNamespaceUri && !wcsncmp(pTag->wszElemNamespace, wszNamespaceUri, pTag->cchNamespaceUri))) { // // namespace and tag match // it is okay if there is no namespace ("") or if the user doesn't care (NULL) // return TRUE; } } return FALSE; } void CParserBase::CrackQName(const wchar_t *wszQName, int cchQName, wchar_t **pwszNs, int *pcchNs, wchar_t **pwszName, int *pcchName) { wchar_t * wszQNameTmp = (wchar_t *) wszQName; wchar_t * wszColon = wcschr(wszQNameTmp, L':'); if (wszColon && (wszColon-wszQNameTmp) <= cchQName) { *pwszNs = wszQNameTmp; *pcchNs = (int)(wszColon-wszQNameTmp); *pwszName = wszColon+1; *pcchName = cchQName-(*pcchNs)-1; } else { *pwszNs = NULL; *pcchNs = 0; *pwszName = wszQNameTmp; *pcchName = cchQName; } } HRESULT CParserBase::OnUnrecognizedTag( const wchar_t *wszNamespaceUri, int cchNamespaceUri, const wchar_t *wszLocalName, int cchLocalName, const wchar_t *wszQName, int cchQName, ISAXAttributes *pAttributes) throw() { wszNamespaceUri; cchNamespaceUri; wszLocalName; cchLocalName; wszQName; cchQName; pAttributes; ATLTRACE( _T("%sUnrecoginzed Tag: %.*ws\n"), GetTabs(m_dwLevel), cchQName, wszQName ); int nLine; int nCol; GetLocator()->getLineNumber(&nLine); GetLocator()->getColumnNumber(&nCol); EmitFileError(IDS_SDL_UNRECOGNIZED_TAG, GetWSDLFile(), nLine, nCol, 0, wszNamespaceUri, wszLocalName); return E_FAIL; } HRESULT CParserBase::OnMissingAttribute(BOOL bRequired, const wchar_t *wszName, int cchName, const wchar_t *wszNamespace, int cchNamespace) { if (bRequired != FALSE) { ATLTRACE( _T("%sMissing Required Attribute: name %.*ws, uri %.*ws\n"), GetTabs(m_dwLevel), cchName, wszName, cchNamespace, wszNamespace ); int nLine; int nCol; GetLocator()->getLineNumber(&nLine); GetLocator()->getColumnNumber(&nCol); EmitFileError(IDS_SDL_MISSING_ATTRIBUTE, GetWSDLFile(), nLine, nCol, 0, wszNamespace, wszName); return E_FAIL; } return S_OK; } void CParserBase::EmitInvalidValue(const char *szName, const wchar_t *wszValue) { int nLine; int nCol; GetLocator()->getLineNumber(&nLine); GetLocator()->getColumnNumber(&nCol); EmitFileError(IDS_SDL_INVALID_VALUE, GetWSDLFile(), nLine, nCol, 0, szName, wszValue); } void CParserBase::EmitUnsupported(UINT nID, const wchar_t *wszUri, const wchar_t *wszName) { int nLine; int nCol; GetLocator()->getLineNumber(&nLine); GetLocator()->getColumnNumber(&nCol); EmitFileWarning(nID, GetWSDLFile(), nLine, nCol, 0, wszUri, wszName); } void CParserBase::EmitSkip(const wchar_t *wszUri, const wchar_t *wszName) { EmitUnsupported(IDS_SDL_UNSUPPORTED_TAG, wszUri, wszName); } void CParserBase::EmitString(const wchar_t *wszUri, const wchar_t *wszName) { EmitUnsupported(IDS_SDL_UNSUPPORTED_STRING, wszUri, wszName); } HRESULT CParserBase::SkipElement() { CAutoPtr p( new CSkipParser(m_spReader, this, GetLevel()) ); if (p != NULL) { if (g_ParserList.AddHead(p) != NULL) { p.Detach(); return S_OK; } } EmitErrorHr(E_OUTOFMEMORY); return E_FAIL; } //////////////////////////////////////////////////////////////////////// // // IUnknown // //////////////////////////////////////////////////////////////////////// HRESULT __stdcall CParserBase::QueryInterface(REFIID riid, void **ppv) { if (!ppv) { return E_POINTER; } if (InlineIsEqualGUID(riid, __uuidof(ISAXContentHandler)) || InlineIsEqualGUID(riid, __uuidof(IUnknown))) { *ppv = static_cast(this); return S_OK; } return E_NOINTERFACE; } ULONG __stdcall CParserBase::AddRef() { return 1; } ULONG __stdcall CParserBase::Release() { return 1; } //////////////////////////////////////////////////////////////////////// // // ISAXContentHandler // //////////////////////////////////////////////////////////////////////// HRESULT __stdcall CParserBase::putDocumentLocator(ISAXLocator *pLocator) { m_spLocator = pLocator; return S_OK; } HRESULT __stdcall CParserBase::startDocument() { return S_OK; } HRESULT __stdcall CParserBase::endDocument() { return S_OK; } HRESULT __stdcall CParserBase::startPrefixMapping( const wchar_t *wszPrefix, int cchPrefix, const wchar_t *wszUri, int cchUri) { return S_OK; } HRESULT __stdcall CParserBase::endPrefixMapping( const wchar_t *wszPrefix, int cchPrefix) { wszPrefix; cchPrefix; // REVIEW: remove from map? return S_OK; } HRESULT __stdcall CParserBase::startElement( const wchar_t *wszNamespaceUri, int cchNamespaceUri, const wchar_t *wszLocalName, int cchLocalName, const wchar_t *wszQName, int cchQName, ISAXAttributes *pAttributes) { return DispatchElement(wszNamespaceUri, cchNamespaceUri, wszLocalName, cchLocalName, wszQName, cchQName, pAttributes); } HRESULT __stdcall CParserBase::endElement( const wchar_t *wszNamespaceUri, int cchNamespaceUri, const wchar_t *wszLocalName, int cchLocalName, const wchar_t *wszQName, int cchQName) { HRESULT hr = ValidateElement(); if (GetReset() > 0) { EnableReset(); return hr; } // // Restore the parent handler // CComPtr spParentHandler = GetParentHandler(); if (spParentHandler.p != NULL) { m_spReader->putContentHandler(spParentHandler); } if (GetDynamicAlloc() != FALSE) { POSITION pos = g_ParserList.Find(this); if (pos != NULL) { g_ParserList.RemoveAt(pos); } delete this; } return hr; } HRESULT __stdcall CParserBase::characters( const wchar_t *wszChars, int cchChars) { // // REVIEW: what to do here? // // ATLTRACE( _T("CParserBase::characters: %*.ws\n"), cchChars, wszChars ); return S_OK; } HRESULT __stdcall CParserBase::ignorableWhitespace( const wchar_t *wszChars, int cchChars) { // ATLTRACE( _T("CParserBase::ignorableWhitespace: %.*ws\n"), cchChars, wszChars ); return S_OK; } HRESULT __stdcall CParserBase::processingInstruction( const wchar_t *wszTarget, int cchTarget, const wchar_t *wszData, int cchData) { wszTarget; cchTarget; wszData; cchData; ATLTRACE( _T("CParserBase::processingInstruction: target: %.*ws, data: %.*ws\n"), cchTarget, wszTarget, cchData, wszData ); return S_OK; } HRESULT __stdcall CParserBase::skippedEntity( const wchar_t *wszName, int cchName) { wszName; cchName; ATLTRACE( _T("CParserBase::skippedEntity: %.*ws\n"), wszName, cchName ); return S_OK; }