Listing 3: Major functions of the CompositeContentHandler<Data, Functor> class.
// only partial listing
template <class Data, class Functor>
class CompositeContentHandler : public BaseContentHandler
{
BaseContentHandler* m_pDocumentHandler;
Functor* m_pFunctor;
Data m_Data;
vector<ContentHandlerPtr> m_ChildHandlers;
public:
CompositeContentHandler(const XmlString& name,
BaseContentHandler* pDocumentHandler, Functor* pFunctor)
: BaseContentHandler(name), m_pDocumentHandler(pDocumentHandler),
m_pFunctor(pFunctor)
{
BaseContentHandler* pTempHandler;
const XmlBindingEntry* pEntry = m_Data.GetXmlBindingEntries();
while(pEntry->eDataType != eXML_EMPTY)
{
pTempHandler = CreateHandler(pDocumentHandler, pEntry);
m_ChildHandlers.push_back(pTempHandler);
m_pDocumentHandler->AddContentHandler(pTempHandler);
++pEntry;
}
m_pDocumentHandler->AddContentHandler(this);
}
virtual HRESULT STDMETHODCALLTYPE endElement(
/* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
/* [in] */ int cchNamespaceUri,
/* [in] */ wchar_t __RPC_FAR *pwchLocalName,
/* [in] */ int cchLocalName,
/* [in] */ wchar_t __RPC_FAR *pwchRawName,
/* [in] */ int cchRawName)
{
CopyTo(&m_Data);
(*m_pFunctor)(m_Data);
return m_pDocumentHandler->endElement(
pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName,
pwchRawName, cchRawName);
}
virtual void CopyTo(void* dest)
{
ClassContentHandlers::iterator iter, iterEnd;
iter=m_ChildHandlers.begin();
iterEnd = m_ChildHandlers.end();
for(;iter!= iterEnd; ++iter)
(*iter)->CopyTo(dest);
}
};