Re: [libxml++] Proposition: nodes manipulation



On Sat, 2004-05-29 at 12:26 +0200, Christophe de Vienne wrote:
> Hi,
> 
> I'd like to discuss a possible improvement of the API.
> 
> To illustrate my idea I'll take the example of the Element class, but 
> all nodes are concerned.
> 
> Currently, the lifetime of nodes is controlled by libxml2, via callbacks 
> on node ceation/deletion. The restrictions are that we cannot create a 
> standalone node, nor detach and then delete a node like a normal class 
> instance.

It might be worth a try. I'd be happy to help test a patch.

> I think there is a solution which, without breaking the current 
> behavior, would permit such things. I describe the deletion first 
> because it's more simple.
> 
> 0. Example
> With this modifications we could something like :
> 
> Document doc;
> // ...
> Element * e = <any node of the document>
> e->detach();  //  detach the node from the tree
> e->attach( new Element("achild") );
> delete e;

I'm not sure what's happening here. First we detach the element from
it's tree, so there is no object that owns it, so we need to delete it
ourselves, right?

But then you seem to reattach it to another parent that you new, but
that you don't delete. I would expect e->attach() to give ownership of e
to a new parent, so that "delete e" would not be necessary as long as
the parent was deleted somehow.

Maybe "new Element("achild")" is meant to be a child of e, so that both
are deleted when you delete e. But, for that I would expect something
like Node::add_child(Node* node), with documentation saying that it
takes ownership of the node. 

 
> 1. Deletion
> Currently the destructor of Node does not release the underlying C 
> structure, because it is supposed to be deleted from the callback 
> "on_libxml_destruct".
> To allow a safe deletion, we have to release the structure, but ensure 
> that the callback will not delete a second time the object. This can be 
> done by setting impl_->_private to 0 in Element destructor (Node 
> destructor would probably be ok too).
> The problem is that a destruction initiated by libxml2 would release 
> twice the C structure. To avoid that, we can reset the Node::impl_ field 
> before deleting the object. We would have then :
> 
> Node::~Node()
> {
>     if( impl_ )
>     {
>        imp_->_private = 0;
>        xmlFreeNode(impl_);
>     }
> }
> 
> on_libxml_destruct(xmlNode* node)
> {
>     if( node->_private = 0 )
>     {
>        return;
>     }
>     // ...
>     118   else
>     119   {
>     120     xmlpp::Node* cppNode =  
> static_cast<xmlpp::Node*>(node->_private);
>     121     if(cppNode)
>     122     {
>  >               cppNode->impl_ = 0;
>     123       delete cppNode;
>     124       bPrivateDeleted = true;
>     125     }
>     126   }
>     127
> 
> }
> 
> 
> 
> 2. Instanciation
> 
> The instanciation is a bit more complex because we can't flag anything 
> to tell the create callback that no node needs to be instanciated. My 
> idea is to deactivate the callback during the node instanciation, if the 
> default constructor is called. The callback registration in libxml2 
> being thread specific it should be safe to do so.
> 
> The implementation would be something like this :
> 
> /// This class deactivate the callback in the constructor,
> /// and reactive it in its destructor
> class ScopedCallbackDeactivator {
>     // ...
> };
> 
> 
> /// Static function
> xmlNode * Element::initXmlNode(Glib::ustring const & name)
> {
>     ScopedCallbackDeactivator cd;
>     return xmlNewNode((const xmlChar *)name.c_str());
> }
> 
> Element::Element(Glib::ustring const & name)
> : impl_( initXmlNode(name) )
> {
>     impl_->_private = static_cast<Node*>(this);
> }
> 
> 
> To be consistent, this technic could be used for destruction.
> 
> 
> 
> 
> Comments / critics are welcome, before I eventually produce a patch.
> 
> 
> Regards,
> 
> Christophe
> 
> 
> 
> 
> -------------------------------------------------------
> This SF.Net email is sponsored by: Oracle 10g
> Get certified on the hottest thing ever to hit the market... Oracle 10g. 
> Take an Oracle 10g class now, and we'll give you the exam FREE.
> http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
> _______________________________________________
> Libxmlplusplus-general mailing list
> Libxmlplusplus-general lists sourceforge net
> https://lists.sourceforge.net/lists/listinfo/libxmlplusplus-general
-- 
Murray Cumming
murrayc murrayc com
www.murrayc.com






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]