From: Scott Cantor Date: Mon, 21 Nov 2011 21:45:56 +0000 (+0000) Subject: https://issues.shibboleth.net/jira/browse/CPPOST-70 X-Git-Tag: 1.5.0~64 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-xmltooling.git;a=commitdiff_plain;h=3a89fe08a9cc882e435aa2976210b7b1ae4cd264 https://issues.shibboleth.net/jira/browse/CPPOST-70 --- diff --git a/xmltooling/base.h b/xmltooling/base.h index d1f1e07..ff96588 100644 --- a/xmltooling/base.h +++ b/xmltooling/base.h @@ -1263,7 +1263,7 @@ /** * Implements cloning methods for an XMLObject specialization implementation class. * - * @param cname the name of the XMLObject specialization + * @param cname the name of the XMLObject specialization */ #define IMPL_XMLOBJECT_CLONE(cname) \ cname* clone##cname() const { \ @@ -1280,6 +1280,79 @@ } /** + * Implements cloning methods for an XMLObject specialization implementation class + * that must override a base class clone method. + * + * @param cname the name of the XMLObject specialization + * @param base name of base type. + */ +#define IMPL_XMLOBJECT_CLONE2(cname,base) \ + cname* clone##cname() const { \ + return dynamic_cast(clone()); \ + } \ + base* clone##base() const { \ + return dynamic_cast(clone()); \ + } \ + xmltooling::XMLObject* clone() const { \ + std::auto_ptr domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \ + cname##Impl* ret=dynamic_cast(domClone.get()); \ + if (ret) { \ + domClone.release(); \ + return ret; \ + } \ + return new cname##Impl(*this); \ + } + +/** + * Implements cloning methods for an XMLObject specialization implementation class that + * needs two stage duplication to avoid invoking virtual methods during construction. + * + * @param cname the name of the XMLObject specialization + */ +#define IMPL_XMLOBJECT_CLONE_EX(cname) \ + cname* clone##cname() const { \ + return dynamic_cast(clone()); \ + } \ + xmltooling::XMLObject* clone() const { \ + std::auto_ptr domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \ + cname##Impl* ret=dynamic_cast(domClone.get()); \ + if (ret) { \ + domClone.release(); \ + return ret; \ + } \ + std::auto_ptr ret2(new cname##Impl(*this)); \ + ret2->_clone(*this); \ + return ret2.release(); \ + } + +/** + * Implements cloning methods for an XMLObject specialization implementation class that + * needs two stage duplication to avoid invoking virtual methods during construction, + * and must override a base class clone method. + * + * @param cname the name of the XMLObject specialization + * @param base name of base type + */ +#define IMPL_XMLOBJECT_CLONE_EX2(cname,base) \ + cname* clone##cname() const { \ + return dynamic_cast(clone()); \ + } \ + base* clone##base() const { \ + return dynamic_cast(clone()); \ + } \ + xmltooling::XMLObject* clone() const { \ + std::auto_ptr domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \ + cname##Impl* ret=dynamic_cast(domClone.get()); \ + if (ret) { \ + domClone.release(); \ + return ret; \ + } \ + std::auto_ptr ret2(new cname##Impl(*this)); \ + ret2->_clone(*this); \ + return ret2.release(); \ + } + +/** * Declares an XMLObject specialization with a simple content model and type, * handling it as string data. * diff --git a/xmltooling/encryption/impl/EncryptionImpl.cpp b/xmltooling/encryption/impl/EncryptionImpl.cpp index 612db9f..8e006da 100644 --- a/xmltooling/encryption/impl/EncryptionImpl.cpp +++ b/xmltooling/encryption/impl/EncryptionImpl.cpp @@ -380,13 +380,9 @@ namespace xmlencryption { public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller { - void init() { - m_URI=nullptr; - } - protected: ReferenceTypeImpl() { - init(); + m_URI=nullptr; } public: @@ -396,19 +392,22 @@ namespace xmlencryption { ReferenceTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) : AbstractXMLObject(nsURI, localName, prefix, schemaType) { - init(); + m_URI=nullptr; } ReferenceTypeImpl(const ReferenceTypeImpl& src) : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) { - init(); + m_URI=nullptr; + } + + void _clone(const ReferenceTypeImpl& src) { setURI(src.getURI()); VectorOf(XMLObject) v=getUnknownXMLObjects(); for (vector::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i) v.push_back((*i)->clone()); } - IMPL_XMLOBJECT_CLONE(ReferenceType); + IMPL_XMLOBJECT_CLONE_EX(ReferenceType); IMPL_STRING_ATTRIB(URI); IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end()); @@ -436,11 +435,8 @@ namespace xmlencryption { : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} DataReferenceImpl(const DataReferenceImpl& src) : AbstractXMLObject(src), ReferenceTypeImpl(src) {} - - IMPL_XMLOBJECT_CLONE(DataReference); - ReferenceType* cloneReferenceType() const { - return new DataReferenceImpl(*this); - } + + IMPL_XMLOBJECT_CLONE_EX(DataReference); }; class XMLTOOL_DLLLOCAL KeyReferenceImpl : public virtual KeyReference, public ReferenceTypeImpl @@ -453,10 +449,7 @@ namespace xmlencryption { KeyReferenceImpl(const KeyReferenceImpl& src) : AbstractXMLObject(src), ReferenceTypeImpl(src) {} - IMPL_XMLOBJECT_CLONE(KeyReference); - ReferenceType* cloneReferenceType() const { - return new KeyReferenceImpl(*this); - } + IMPL_XMLOBJECT_CLONE_EX(KeyReference); }; class XMLTOOL_DLLLOCAL ReferenceListImpl : public virtual ReferenceList, @@ -548,6 +541,9 @@ namespace xmlencryption { EncryptedTypeImpl(const EncryptedTypeImpl& src) : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) { init(); + } + + void _clone(const EncryptedTypeImpl& src) { setId(src.getId()); setType(src.getType()); setMimeType(src.getMimeType()); @@ -562,7 +558,7 @@ namespace xmlencryption { setEncryptionProperties(src.getEncryptionProperties()->cloneEncryptionProperties()); } - IMPL_XMLOBJECT_CLONE(EncryptedType); + IMPL_XMLOBJECT_CLONE_EX(EncryptedType); IMPL_ID_ATTRIB_EX(Id,ID,nullptr); IMPL_STRING_ATTRIB(Type); IMPL_STRING_ATTRIB(MimeType); @@ -607,10 +603,7 @@ namespace xmlencryption { EncryptedDataImpl(const EncryptedDataImpl& src) : AbstractXMLObject(src), EncryptedTypeImpl(src) {} - IMPL_XMLOBJECT_CLONE(EncryptedData); - EncryptedType* cloneEncryptedType() const { - return new EncryptedDataImpl(*this); - } + IMPL_XMLOBJECT_CLONE_EX(EncryptedData); }; class XMLTOOL_DLLLOCAL EncryptedKeyImpl : public virtual EncryptedKey, public EncryptedTypeImpl @@ -641,10 +634,17 @@ namespace xmlencryption { init(); } - IMPL_XMLOBJECT_CLONE(EncryptedKey); - EncryptedType* cloneEncryptedType() const { - return new EncryptedKeyImpl(*this); + void _clone(const EncryptedKeyImpl& src) { + EncryptedTypeImpl::_clone(src); + setRecipient(src.getRecipient()); + if (src.getReferenceList()) + setReferenceList(src.getReferenceList()->cloneReferenceList()); + if (src.getCarriedKeyName()) + setCarriedKeyName(src.getCarriedKeyName()->cloneCarriedKeyName()); } + + IMPL_XMLOBJECT_CLONE_EX(EncryptedKey); + IMPL_STRING_ATTRIB(Recipient); IMPL_TYPED_CHILD(ReferenceList); IMPL_TYPED_CHILD(CarriedKeyName); diff --git a/xmltooling/impl/AnyElement.cpp b/xmltooling/impl/AnyElement.cpp index 5724804..72c833d 100644 --- a/xmltooling/impl/AnyElement.cpp +++ b/xmltooling/impl/AnyElement.cpp @@ -45,10 +45,25 @@ AnyElementImpl::AnyElementImpl(const XMLCh* nsURI, const XMLCh* localName, const { } +AnyElementImpl::AnyElementImpl(const AnyElementImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractComplexElement(src), + AbstractAttributeExtensibleXMLObject(src) +{ +} + AnyElementImpl::~AnyElementImpl() { } +void AnyElementImpl::_clone(const AnyElementImpl& src) +{ + const vector& children = src.getUnknownXMLObjects(); + for (vector::const_iterator i=children.begin(); i!=children.end(); ++i) + getUnknownXMLObjects().push_back((*i)->clone()); +} + XMLObject* AnyElementImpl::clone() const { auto_ptr domClone(AbstractDOMCachingXMLObject::clone()); AnyElementImpl* ret=dynamic_cast(domClone.get()); @@ -57,19 +72,11 @@ XMLObject* AnyElementImpl::clone() const { return ret; } - return new AnyElementImpl(*this); + auto_ptr ret2(new AnyElementImpl(*this)); + ret2->_clone(*ret2.get()); + return ret2.release(); } -AnyElementImpl::AnyElementImpl(const AnyElementImpl& src) - : AbstractXMLObject(src), - AbstractDOMCachingXMLObject(src), - AbstractComplexElement(src), - AbstractAttributeExtensibleXMLObject(src) { - const vector& children = src.getUnknownXMLObjects(); - for (vector::const_iterator i=children.begin(); i!=children.end(); ++i) - getUnknownXMLObjects().push_back((*i)->clone()); -} - void AnyElementImpl::marshallAttributes(DOMElement* domElement) const { marshallExtensionAttributes(domElement); diff --git a/xmltooling/impl/AnyElement.h b/xmltooling/impl/AnyElement.h index 37e629f..4a79eef 100644 --- a/xmltooling/impl/AnyElement.h +++ b/xmltooling/impl/AnyElement.h @@ -63,6 +63,15 @@ namespace xmltooling { AnyElementImpl(); AnyElementImpl(const AnyElementImpl& src); + /** + * Copies the content of a source object into a newly constructed instance. + *

Used to solve compiler problems that limit calling virtual functions + * from the actual copy constructor. + * + * @param src source to clone + */ + void _clone(const AnyElementImpl& src); + IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end()); void marshallAttributes(xercesc::DOMElement* domElement) const;