xmldomutil.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 937 行 · 第 1/2 页

CPP
937
字号
/* * Copyright 1999-2001,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: XMLDOMUtil.cpp,v 1.4 2004/09/08 13:55:36 peiyongz Exp $ */#include "stdafx.h"#include "xml4com.h"#include "XMLDOMElement.h"#include "XMLDOMAttribute.h"#include "XMLDOMText.h"#include "XMLDOMCDATASection.h"#include "XMLDOMEntityReference.h"#include "XMLDOMEntity.h"#include "XMLDOMProcessingInstruction.h"#include "XMLDOMComment.h"#include "XMLDOMDocument.h"#include "XMLDOMDocumentType.h"#include "XMLDOMDocumentFragment.h"#include "XMLDOMNotation.h"#include "XMLDOMUtil.h"#include <xercesc/util/PlatformUtils.hpp>#include <xercesc/util/XMLUniDefs.hpp>#include <xercesc/util/XMLString.hpp>const OLECHAR* g_DomNodeName[] ={		OLESTR("invalid"),	OLESTR("element"),	OLESTR("attribute"),	OLESTR("text"),	OLESTR("cdatasection"),	OLESTR("entityreference"),	OLESTR("entity"),	OLESTR("processinginstruction"),	OLESTR("comment"),	OLESTR("document"),	OLESTR("documenttype"),	OLESTR("documentfragment"),	OLESTR("notation")};const int g_DomNodeNameSize = sizeof(g_DomNodeName) / sizeof(OLECHAR*);template <class Base>class CComObjectPool{public:	CComObjectPool(unsigned long poolSize);	virtual ~CComObjectPool();	HRESULT WINAPI CreateInstance(Base** pp);	HRESULT Deactivate(Base* obj);private:	Base** m_pool;	unsigned long m_size;	unsigned long m_hit;	unsigned long m_attempt;	HRESULT Activate(Base* obj);};template <class Base>class CPooledComObject : public Base{public:	typedef Base _BaseClass;	CPooledComObject(void* = NULL)	{		_Module.Lock();	}	// Set refcount to 1 to protect destruction	~CPooledComObject()	{		m_dwRef = 1L;		FinalRelease();#ifdef _ATL_DEBUG_INTERFACES		_Module.DeleteNonAddRefThunk(_GetRawUnknown());#endif		_Module.Unlock();	}	//If InternalAddRef or InternalRelease is undefined then your class	//doesn't derive from CComObjectRoot	STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}	STDMETHOD_(ULONG, Release)()	{		ULONG l = InternalRelease();		if (l == 0) {			if(SUCCEEDED(m_pool.Deactivate(this))) {				FinalRelease();			}			else				delete this;		}		return l;	}	//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP	STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)	{return _InternalQueryInterface(iid, ppvObject);}	template <class Q>	HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)	{		return QueryInterface(__uuidof(Q), (void**)pp);	}	static HRESULT WINAPI CreateInstance(Base** pp) {		return m_pool.CreateInstance(pp);	}private:	static CComObjectPool<Base> m_pool;};template <class Base>CComObjectPool<Base>::CComObjectPool<Base>(unsigned long poolSize) {	m_pool = NULL;	m_size = poolSize;	m_pool = new Base*[m_size];	for(unsigned long i = 0; i < m_size; i++)		m_pool[i] = NULL;	m_hit= 0;	m_attempt = 0;}template <class Base>CComObjectPool<Base>::~CComObjectPool<Base>() {	for(unsigned long i = 0; i < m_size; i++) {		if(m_pool[i]) delete m_pool[i];	}	delete [] m_pool;}template <class Base>HRESULT CComObjectPool<Base>::Deactivate(Base* obj) {	for(unsigned long i = 0; i < m_size; i++) {		if(m_pool[i] == NULL) {			m_pool[i] = obj;			return S_OK;		}	}	return E_FAIL;}template <class Base>HRESULT CComObjectPool<Base>::Activate(Base* p){	p->SetVoid(NULL);	p->InternalFinalConstructAddRef();	HRESULT hRes = p->FinalConstruct();	p->InternalFinalConstructRelease();	return hRes;}template <class Base>HRESULT WINAPI CComObjectPool<Base>::CreateInstance(Base** pp) {	ATLASSERT(pp != NULL);	HRESULT hRes = E_OUTOFMEMORY;	Base* p = NULL;	m_attempt++;	for(unsigned long i = 0; i < m_size; i++) {		if(m_pool[i]) {			p = m_pool[i];			m_pool[i] = NULL;			hRes = Activate(p);			if (SUCCEEDED(hRes)) {				m_hit++;				break;			}			else {				delete p;				p = NULL;			}		}	}	if(FAILED(hRes)) {		ATLTRY(p = new CPooledComObject<Base>())		if (p != NULL) {			hRes = Activate(p);			if (hRes != S_OK) {				delete p;				p = NULL;			}		}	}	*pp = p;	return hRes;}CComObjectPool<CXMLDOMElement> CPooledComObject<CXMLDOMElement>::m_pool(6);typedef CPooledComObject<CXMLDOMElement> CPooledXMLDOMElementObj;CComObjectPool<CXMLDOMAttribute> CPooledComObject<CXMLDOMAttribute>::m_pool(6);typedef CPooledComObject<CXMLDOMAttribute> CPooledXMLDOMAttributeObj;CComObjectPool<CXMLDOMText> CPooledComObject<CXMLDOMText>::m_pool(6);typedef CPooledComObject<CXMLDOMText> CPooledXMLDOMTextObj;CComObjectPool<CXMLDOMCDATASection> CPooledComObject<CXMLDOMCDATASection>::m_pool(6);typedef CPooledComObject<CXMLDOMCDATASection> CPooledXMLDOMCDATASectionObj;CComObjectPool<CXMLDOMEntityReference> CPooledComObject<CXMLDOMEntityReference>::m_pool(6);typedef CPooledComObject<CXMLDOMEntityReference> CPooledXMLDOMEntityReferenceObj;CComObjectPool<CXMLDOMEntity> CPooledComObject<CXMLDOMEntity>::m_pool(6);typedef CPooledComObject<CXMLDOMEntity> CPooledXMLDOMEntityObj;CComObjectPool<CXMLDOMProcessingInstruction> CPooledComObject<CXMLDOMProcessingInstruction>::m_pool(6);typedef CPooledComObject<CXMLDOMProcessingInstruction> CPooledXMLDOMProcessingInstructionObj;CComObjectPool<CXMLDOMComment> CPooledComObject<CXMLDOMComment>::m_pool(6);typedef CPooledComObject<CXMLDOMComment> CPooledXMLDOMCommentObj;HRESULT wrapNode(IXMLDOMDocument *pDoc, DOMNode* node, REFIID iid, LPVOID *pVal){	HRESULT hr = S_OK;	if (NULL == pVal)		return E_POINTER;	*pVal = NULL;	short type = node->getNodeType();	// the way we are constructing the wrappers is kind of fishy but oh well...	// the various IBM DOM wrapper classes don't ever add any members or have	// any v-tables so what we are doing should be safe.  There isn't any other	// way as far as I can tell to do this....	switch(type)	{	case DOMNode::ELEMENT_NODE:	{		CXMLDOMElement *pObj = NULL;		hr = CPooledXMLDOMElementObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);		try		{			pObj->element = static_cast<DOMElement*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)		{			pObj->Release();			return E_FAIL;		}			hr = pObj->QueryInterface(iid, pVal);		if (S_OK != hr)			*pVal = NULL;		pObj->Release();		break;	}	case DOMNode::ATTRIBUTE_NODE:	{		CXMLDOMAttribute *pObj = NULL;		hr = CPooledXMLDOMAttributeObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);		try		{			pObj->attr = static_cast<DOMAttr*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)		{			pObj->Release();			return E_FAIL;		}			hr = pObj->QueryInterface(iid, pVal);		if (S_OK != hr)			*pVal = NULL;		pObj->Release();		break;	}	case DOMNode::TEXT_NODE:	{		CXMLDOMText *pObj = NULL;		hr = CPooledXMLDOMTextObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);		try		{			pObj->text = static_cast<DOMText*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)		{			pObj->Release();			return E_FAIL;		}			hr = pObj->QueryInterface(iid, pVal);		if (S_OK != hr)			*pVal = NULL;		pObj->Release();		break;	}	case DOMNode::CDATA_SECTION_NODE:	{		CXMLDOMCDATASection *pObj = NULL;		hr = CPooledXMLDOMCDATASectionObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);		try		{			pObj->cdataSection = static_cast<DOMCDATASection*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)		{			pObj->Release();			return E_FAIL;		}			hr = pObj->QueryInterface(iid, pVal);		if (S_OK != hr)			*pVal = NULL;		pObj->Release();		break;	}	case DOMNode::ENTITY_REFERENCE_NODE:	{		CXMLDOMEntityReference *pObj = NULL;		hr = CPooledXMLDOMEntityReferenceObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);		try		{			pObj->entityReference = static_cast<DOMEntityReference*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)		{			pObj->Release();			return E_FAIL;		}			hr = pObj->QueryInterface(iid, pVal);		if (S_OK != hr)			*pVal = NULL;		pObj->Release();		break;	}	case DOMNode::ENTITY_NODE:	{		CXMLDOMEntity *pObj = NULL;		hr = CPooledXMLDOMEntityObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);				try		{			pObj->entity = static_cast<DOMEntity*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)		{			pObj->Release();			return E_FAIL;		}			hr = pObj->QueryInterface(iid, pVal);		if (S_OK != hr)			*pVal = NULL;		pObj->Release();		break;	}	case DOMNode::PROCESSING_INSTRUCTION_NODE:	{		CXMLDOMProcessingInstruction *pObj = NULL;		hr = CPooledXMLDOMProcessingInstructionObj::CreateInstance(&pObj);		if (S_OK != hr)			return hr;			pObj->AddRef();		pObj->SetOwnerDoc(pDoc);		try		{			pObj->processingInstruction = static_cast<DOMProcessingInstruction*> (node);		}		catch(DOMException& ex)		{			pObj->Release();			return MakeHRESULT(ex);		}		catch(...)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?