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 + -
显示快捷键?