ext/xml/ruby_xml_attr.c in libxml-ruby-0.3.8 vs ext/xml/ruby_xml_attr.c in libxml-ruby-0.3.8.2
- old
+ new
@@ -1,22 +1,29 @@
-/* $Id: ruby_xml_attr.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+/* $Id: ruby_xml_attr.c,v 1.2 2006/11/20 01:22:07 roscopeco Exp $ */
/* Please see the LICENSE file for copyright and distribution information */
#include "libxml.h"
#include "ruby_xml_attr.h"
VALUE cXMLAttr;
void
ruby_xml_attr_free(ruby_xml_attr *rxa) {
- if (rxa->attr != NULL && !rxa->is_ptr) {
- xmlUnlinkNode((xmlNodePtr)rxa->attr);
- xmlFreeNode((xmlNodePtr)rxa->attr);
- rxa->attr = NULL;
+ if (rxa->attr != NULL && // got an attr?
+ rxa->attr->parent == NULL && // unparented (otherwise, it gets freed with parent)
+ rxa->attr->doc == NULL) { // No document? (otherwise, freed with doc)
+ if ((int)rxa->attr->_private <= 1) {
+ // is null or last reference,
+ xmlFreeNode((xmlNodePtr)rxa->attr);
+ } else {
+ // other pointers remain
+ rxa->attr->_private--;
+ }
}
+ rxa->attr = NULL;
free(rxa);
}
/*
@@ -30,11 +37,11 @@
ruby_xml_attr *rxa;
Data_Get_Struct(self, ruby_xml_attr, rxa);
if (rxa->attr->children == NULL)
return(Qnil);
else
- return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->children));
+ return(ruby_xml_node_new_ptr(cXMLNode, rxa->xd, rxa->attr->children));
}
/*
* call-seq:
@@ -100,11 +107,11 @@
ruby_xml_attr *rxa;
Data_Get_Struct(self, ruby_xml_attr, rxa);
if (rxa->attr->last == NULL)
return(Qnil);
else
- return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->last));
+ return(ruby_xml_node_new_ptr(cXMLNode, rxa->xd, rxa->attr->last));
}
/*
* call-seq:
@@ -148,29 +155,39 @@
}
VALUE
ruby_xml_attr_new(VALUE class, VALUE xd, xmlAttrPtr attr) {
- ruby_xml_attr *rxa;
-
- rxa = ALLOC(ruby_xml_attr);
- rxa->attr = attr;
- rxa->xd = xd;
- rxa->is_ptr = 0;
- return(Data_Wrap_Struct(class, ruby_xml_attr_mark,
- ruby_xml_attr_free, rxa));
+ return(ruby_xml_attr_new2(class, xd, attr));
}
VALUE
ruby_xml_attr_new2(VALUE class, VALUE xd, xmlAttrPtr attr) {
ruby_xml_attr *rxa;
rxa = ALLOC(ruby_xml_attr);
- rxa->attr = xmlCopyProp(attr->parent, attr);
- rxa->xd = xd;
- rxa->is_ptr = 0;
+
+ rxa->attr = attr;
+ if (attr->_private) {
+ attr->_private++;
+ } else {
+ attr->_private = (void*)1;
+ }
+
+ if (NIL_P(xd)) {
+ rxa->xd = Qnil;
+ rxa->attr->doc = NULL;
+ } else {
+ /* Have to set node->doc too so we don't doublefree this node */
+ ruby_xml_document *xdoc;
+ Data_Get_Struct(xd, ruby_xml_document, xdoc);
+
+ rxa->xd = xd;
+ rxa->attr->doc = xdoc->doc;
+ }
+
return(Data_Wrap_Struct(class, ruby_xml_attr_mark,
ruby_xml_attr_free, rxa));
}
@@ -214,11 +231,10 @@
*
* Obtain this attribute node's type name.
*/
VALUE
ruby_xml_attr_node_type_name(VALUE self) {
- /* I think libxml2's naming convention blows monkey ass */
return(rb_str_new2("attribute"));
}
/*
@@ -267,10 +283,10 @@
ruby_xml_attr *rxa;
Data_Get_Struct(self, ruby_xml_attr, rxa);
if (rxa->attr->parent == NULL)
return(Qnil);
else
- return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->parent));
+ return(ruby_xml_node_new_ptr(cXMLNode, rxa->xd, rxa->attr->parent));
}
/*
* call-seq: