libxml-ruby 2.0.2-x86-mingw32 → 2.0.3-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +52 -1
- data/README.rdoc +40 -10
- data/ext/libxml/ruby_libxml.h +1 -0
- data/ext/libxml/ruby_xml_attr.c +2 -2
- data/ext/libxml/ruby_xml_document.c +57 -7
- data/ext/libxml/ruby_xml_error.c +0 -12
- data/ext/libxml/ruby_xml_node.c +107 -92
- data/ext/libxml/ruby_xml_reader.c +1085 -1057
- data/ext/libxml/ruby_xml_schema.c +2 -53
- data/ext/libxml/ruby_xml_version.h +3 -3
- data/lib/1.8/libxml_ruby.so +0 -0
- data/lib/1.9/libxml_ruby.so +0 -0
- data/test/tc_document.rb +43 -6
- data/test/tc_document_write.rb +15 -1
- data/test/tc_error.rb +33 -21
- data/test/tc_node.rb +11 -0
- data/test/tc_node_edit.rb +19 -3
- data/test/tc_parser.rb +16 -1
- data/test/tc_reader.rb +11 -3
- data/test/tc_sax_parser.rb +45 -1
- data/test/test_suite.rb +4 -2
- metadata +16 -6
- data/test/rb-magic-comment.rb +0 -33
    
        data/HISTORY
    CHANGED
    
    | @@ -1,6 +1,57 @@ | |
| 1 1 | 
             
            = Release History
         | 
| 2 2 |  | 
| 3 | 
            -
            == 2.0. | 
| 3 | 
            +
            == 2.0.3 / 2011-05-01 Charlie Savage
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * The biggest change in this release is supporting the use of libxml-ruby in
         | 
| 6 | 
            +
              native background Ruby threads.  Previously, the use of libxml-ruby in
         | 
| 7 | 
            +
              background threads in Ruby 1.9.x and higher would often cause
         | 
| 8 | 
            +
              segmentation faults.  This has now been fixed (Charlie Savage).
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            * Update Reader#expand so that returned node correctly remembers its
         | 
| 11 | 
            +
              encoding in Ruby 1.9.x (zerebubuth).
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * Add check to verify a node has not been deleted.  This can happen when
         | 
| 14 | 
            +
              a ruby variable holds a reference to a child node that gets freed
         | 
| 15 | 
            +
              when its parent gets freed.  Previously when this happened a
         | 
| 16 | 
            +
              segmentation fault would occur, now an exception is raised (Charlie Savage, fixes
         | 
| 17 | 
            +
              RubyForge #26839.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * Do not unlink nodes before internal validations have run - avoids
         | 
| 20 | 
            +
              segmentation faults caused by freeing a node twice (Charlie Savage).
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            * Add support for Document#canonicalization (Victor Lin).
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            * Fix memory leak in Reader#lookup_namespace (Charlie Savage).
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            * Fix memory leak in Reader#[] (Nathan Kriege).
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            * Fix usage of @io instance variable (Jeffrey Taylor)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            * Removed old sax error handling code that has been fixed in newer
         | 
| 31 | 
            +
              versions of libxml (Charlie Savage).
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            * Code cleanup - remove unused variables and commented out code (Charlie Savage)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            * Minor text changes and documentation fixes (Charlie Savage).
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            * Fix documentation error (fixes RubyForge #26888).
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            * Update documentation for Document#validation* methods (fixes RubyForge #24833).
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            * Update documentation and test (fixes Ruby Forge Issue #28770).
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            * Updated documentation in README (Anurag Priyam):
         | 
| 44 | 
            +
            1. rake doc does not work; use rake rdoc.
         | 
| 45 | 
            +
            2. gem mislav-hanna does not exist; use hanna.
         | 
| 46 | 
            +
            3. rake rdoc 'depends' on hanna; no need of RDOCOPTS
         | 
| 47 | 
            +
            4. Point to the github issue tracker instead of Ruby Forge
         | 
| 48 | 
            +
            5. Point to the github (gh-pages) site for docs
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            * Add tc_error to test suite (Charlie Savage).
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            * Add sax test (Stanislav O.Pogrebnyak).
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            == 2.0.2 / 2011-04-17 Charlie Savage
         | 
| 4 55 |  | 
| 5 56 | 
             
            * Added binaries for windows (Charlie Savage).
         | 
| 6 57 |  | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -75,9 +75,9 @@ then install the libxslt gem which is available at | |
| 75 75 | 
             
            http://rubyforge.org/projects/libxsl/.
         | 
| 76 76 |  | 
| 77 77 | 
             
            == Usage
         | 
| 78 | 
            -
            For information about using libxml-ruby please refer
         | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 78 | 
            +
            For information about using libxml-ruby please refer to its documentation at
         | 
| 79 | 
            +
            http://xml4r.github.com/libxml-ruby/rdoc/index.html Some tutorials are also
         | 
| 80 | 
            +
            available at https://github.com/xml4r/libxml-ruby/wiki.
         | 
| 81 81 |  | 
| 82 82 | 
             
            All libxml classes are in the LibXML::XML module. The easiest
         | 
| 83 83 | 
             
            way to use libxml is to require 'xml'.  This will mixin
         | 
| @@ -111,6 +111,34 @@ For example: | |
| 111 111 |  | 
| 112 112 | 
             
            For simplicity's sake, the documentation uses the xml module in its examples.
         | 
| 113 113 |  | 
| 114 | 
            +
            == Memory Management
         | 
| 115 | 
            +
            libxml-ruby automatically manages memory associated with the
         | 
| 116 | 
            +
            underlying libxml2 library.  There is however one corner case that
         | 
| 117 | 
            +
            your code must handle.  If a node is imported into a document, but not
         | 
| 118 | 
            +
            added to the document, a segmentation fault may occur on program termination.
         | 
| 119 | 
            +
             | 
| 120 | 
            +
              # Do NOT do this
         | 
| 121 | 
            +
              require 'xml'
         | 
| 122 | 
            +
              doc1 = XML::Document.string("test1")
         | 
| 123 | 
            +
              doc2 = XML::Document.string("test2")
         | 
| 124 | 
            +
              node = doc2.import(doc1.root)
         | 
| 125 | 
            +
             | 
| 126 | 
            +
            If doc2 is freed before node2 a segmentatin fault will occur since
         | 
| 127 | 
            +
            node2 references the document.  To avoid this, simply make sure to add the
         | 
| 128 | 
            +
            node to the document:
         | 
| 129 | 
            +
             | 
| 130 | 
            +
              # DO this instead
         | 
| 131 | 
            +
              doc1 = XML::Document.string("test1")
         | 
| 132 | 
            +
              doc2 = XML::Document.string("test2")
         | 
| 133 | 
            +
              doc2.root << doc2.import(doc1.root)
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            Alternatively, you can call node2.remove! to disassociate node2 from doc2.
         | 
| 136 | 
            +
             | 
| 137 | 
            +
            == Threading
         | 
| 138 | 
            +
            libxml-ruby fully supports native, background Ruby threads.  This of course
         | 
| 139 | 
            +
            only applies to Ruby 1.9.x and higher since earlier versions of Ruby do not
         | 
| 140 | 
            +
            support native threads.
         | 
| 141 | 
            +
             | 
| 114 142 | 
             
            == Performance
         | 
| 115 143 | 
             
            In addition to being feature rich and conformation, the main reason
         | 
| 116 144 | 
             
            people use libxml-ruby is for performance.  Here are the results 
         | 
| @@ -134,12 +162,14 @@ From https://svn.concord.org/svn/projects/trunk/common/ruby/xml_benchmarks/ | |
| 134 162 |  | 
| 135 163 |  | 
| 136 164 | 
             
            == Documentation
         | 
| 137 | 
            -
            Documentation is available via rdoc | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 165 | 
            +
            Documentation is available via rdoc, and is installed automatically with the
         | 
| 166 | 
            +
            gem.
         | 
| 167 | 
            +
             | 
| 168 | 
            +
            libxml-ruby's online documentation is generated using Hanna.  To generate
         | 
| 169 | 
            +
            documentation from source:
         | 
| 140 170 |  | 
| 141 | 
            -
              gem install  | 
| 142 | 
            -
              rake rdoc | 
| 171 | 
            +
              gem install hanna
         | 
| 172 | 
            +
              rake rdoc
         | 
| 143 173 |  | 
| 144 174 | 
             
            Note that older versions of Rdoc, which ship with Ruby 1.8.x, will report
         | 
| 145 175 | 
             
            a number of errors.  To avoid them, install Rdoc 2.1 or higher from
         | 
| @@ -152,8 +182,8 @@ ruby/lib/ruby/1.8/rdoc_old. | |
| 152 182 |  | 
| 153 183 | 
             
            If you have any questions about using libxml-ruby, please send them to
         | 
| 154 184 | 
             
            libxml-devel@rubyforge.org.  If you have found any bugs in libxml-devel,
         | 
| 155 | 
            -
            or have developed new patches, please submit them to  | 
| 156 | 
            -
             | 
| 185 | 
            +
            or have developed new patches, please submit them to Git Hub at
         | 
| 186 | 
            +
            https://github.com/xml4r/libxml-ruby/issues.
         | 
| 157 187 |  | 
| 158 188 | 
             
            == License
         | 
| 159 189 | 
             
            See LICENSE for license information.
         | 
    
        data/ext/libxml/ruby_libxml.h
    CHANGED
    
    
    
        data/ext/libxml/ruby_xml_attr.c
    CHANGED
    
    | @@ -186,7 +186,7 @@ static VALUE rxml_attr_name_get(VALUE self) | |
| 186 186 | 
             
              if (xattr->name == NULL)
         | 
| 187 187 | 
             
                return Qnil;
         | 
| 188 188 | 
             
              else
         | 
| 189 | 
            -
                return rxml_str_new2((const char*) xattr->name, xattr->doc->encoding);
         | 
| 189 | 
            +
                return rxml_str_new2((const char*) xattr->name, (xattr->doc ? xattr->doc->encoding : NULL));
         | 
| 190 190 | 
             
            }
         | 
| 191 191 |  | 
| 192 192 | 
             
            /*
         | 
| @@ -302,7 +302,7 @@ VALUE rxml_attr_value_get(VALUE self) | |
| 302 302 |  | 
| 303 303 | 
             
              if (value != NULL)
         | 
| 304 304 | 
             
              {
         | 
| 305 | 
            -
                result = rxml_str_new2((const char*) value, xattr->doc->encoding);
         | 
| 305 | 
            +
                result = rxml_str_new2((const char*) value, (xattr->doc ? xattr->doc->encoding : NULL));
         | 
| 306 306 | 
             
                xmlFree(value);
         | 
| 307 307 | 
             
              }
         | 
| 308 308 | 
             
              return result;
         | 
| @@ -20,7 +20,7 @@ | |
| 20 20 | 
             
             *  doc = XML::Document.new()
         | 
| 21 21 | 
             
             *  doc.root = XML::Node.new('root_node')
         | 
| 22 22 | 
             
             *  doc.root << XML::Node.new('elem1')
         | 
| 23 | 
            -
             *  doc.save(filename, :indent => true, :encoding =>  | 
| 23 | 
            +
             *  doc.save(filename, :indent => true, :encoding => XML::Encoding::UTF_8)
         | 
| 24 24 | 
             
             *
         | 
| 25 25 | 
             
             * To write a document to a file:
         | 
| 26 26 | 
             
             *
         | 
| @@ -45,7 +45,7 @@ | |
| 45 45 | 
             
             *
         | 
| 46 46 | 
             
             *  elem3['attr'] = 'baz'
         | 
| 47 47 | 
             
             *
         | 
| 48 | 
            -
             *  doc.save(filename, :indent => true, :encoding =>  | 
| 48 | 
            +
             *  doc.save(filename, :indent => true, :encoding => XML::Encoding::UTF_8)
         | 
| 49 49 | 
             
             */
         | 
| 50 50 |  | 
| 51 51 | 
             
            #include <stdarg.h>
         | 
| @@ -123,6 +123,40 @@ static VALUE rxml_document_initialize(int argc, VALUE *argv, VALUE self) | |
| 123 123 | 
             
              return self;
         | 
| 124 124 | 
             
            }
         | 
| 125 125 |  | 
| 126 | 
            +
              /*
         | 
| 127 | 
            +
               * call-seq:
         | 
| 128 | 
            +
              *    document.canonicalize(comments) -> String 
         | 
| 129 | 
            +
               *
         | 
| 130 | 
            +
               * 	Returns a string containing the canonicalized form of the document.
         | 
| 131 | 
            +
               *
         | 
| 132 | 
            +
               *  :comments - Specifies if comments should be output.  This is an optional
         | 
| 133 | 
            +
               *              parameter whose default value is false.
         | 
| 134 | 
            +
               */
         | 
| 135 | 
            +
            static VALUE rxml_document_canonicalize(int argc, VALUE *argv, VALUE self)
         | 
| 136 | 
            +
            {
         | 
| 137 | 
            +
              VALUE result = Qnil;
         | 
| 138 | 
            +
              VALUE comments = Qnil ;
         | 
| 139 | 
            +
              xmlDocPtr xdoc;
         | 
| 140 | 
            +
              xmlChar *buffer = NULL;
         | 
| 141 | 
            +
              int length;
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              rb_scan_args(argc, argv, "01", &comments);
         | 
| 144 | 
            +
              
         | 
| 145 | 
            +
              Data_Get_Struct(self, xmlDoc, xdoc);
         | 
| 146 | 
            +
              length = xmlC14NDocDumpMemory(xdoc, NULL, XML_C14N_1_1, NULL, 
         | 
| 147 | 
            +
                                            (comments == Qtrue ? 1 : 0),
         | 
| 148 | 
            +
                                            &buffer);
         | 
| 149 | 
            +
             | 
| 150 | 
            +
              if (buffer)
         | 
| 151 | 
            +
              {
         | 
| 152 | 
            +
                result = rxml_str_new2((const char*) buffer, (const char*)xdoc->encoding);
         | 
| 153 | 
            +
                xmlFree(buffer);
         | 
| 154 | 
            +
              }
         | 
| 155 | 
            +
             | 
| 156 | 
            +
              return result;
         | 
| 157 | 
            +
            }
         | 
| 158 | 
            +
              
         | 
| 159 | 
            +
             
         | 
| 126 160 | 
             
            /*
         | 
| 127 161 | 
             
             * call-seq:
         | 
| 128 162 | 
             
             *    document.compression -> num
         | 
| @@ -285,16 +319,17 @@ static VALUE rxml_document_encoding_get(VALUE self) | |
| 285 319 | 
             
             * Returns the Ruby encoding specified by this document
         | 
| 286 320 | 
             
             * (available on Ruby 1.9.x and higher).
         | 
| 287 321 | 
             
             */
         | 
| 322 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 288 323 | 
             
            static VALUE rxml_document_rb_encoding_get(VALUE self)
         | 
| 289 324 | 
             
            {
         | 
| 290 325 | 
             
              xmlDocPtr xdoc;
         | 
| 291 326 | 
             
              const char *xencoding;
         | 
| 292 | 
            -
              VALUE encoding;
         | 
| 293 327 | 
             
              Data_Get_Struct(self, xmlDoc, xdoc);
         | 
| 294 328 |  | 
| 295 329 | 
             
              xencoding = (const char*)xdoc->encoding;
         | 
| 296 330 | 
             
              return rxml_xml_encoding_to_rb_encoding(mXMLEncoding, xmlParseCharEncoding(xencoding));
         | 
| 297 331 | 
             
            }
         | 
| 332 | 
            +
            #endif 
         | 
| 298 333 |  | 
| 299 334 | 
             
            /*
         | 
| 300 335 | 
             
             * call-seq:
         | 
| @@ -322,6 +357,11 @@ static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding) | |
| 322 357 | 
             
             *
         | 
| 323 358 | 
             
             * Creates a copy of the node that can be inserted into the
         | 
| 324 359 | 
             
             * current document.
         | 
| 360 | 
            +
             *
         | 
| 361 | 
            +
             * IMPORTANT - The returned node MUST be inserted into the document.
         | 
| 362 | 
            +
             * This is because the returned node refereces internal LibXML data
         | 
| 363 | 
            +
             * structures owned by the document.  Therefore, if the document is
         | 
| 364 | 
            +
             * is freed before the the node is freed a segmentation fault will occur.
         | 
| 325 365 | 
             
             */
         | 
| 326 366 | 
             
            static VALUE rxml_document_import(VALUE self, VALUE node)
         | 
| 327 367 | 
             
            {
         | 
| @@ -534,6 +574,9 @@ static VALUE rxml_document_root_set(VALUE self, VALUE node) | |
| 534 574 | 
             
              Data_Get_Struct(self, xmlDoc, xdoc);
         | 
| 535 575 | 
             
              Data_Get_Struct(node, xmlNode, xnode);
         | 
| 536 576 |  | 
| 577 | 
            +
              if (xnode->doc != NULL && xnode->doc != xdoc)
         | 
| 578 | 
            +
                rb_raise(eXMLError, "Nodes belong to different documents.  You must first import the node by calling XML::Document.import");
         | 
| 579 | 
            +
             | 
| 537 580 | 
             
              xroot = xmlDocSetRootElement(xdoc, xnode);
         | 
| 538 581 | 
             
              return node;
         | 
| 539 582 | 
             
            }
         | 
| @@ -541,7 +584,7 @@ static VALUE rxml_document_root_set(VALUE self, VALUE node) | |
| 541 584 | 
             
            /*
         | 
| 542 585 | 
             
             * call-seq:
         | 
| 543 586 | 
             
             *    document.save(filename) -> int
         | 
| 544 | 
            -
             *    document.save(filename, :indent => true, :encoding =>  | 
| 587 | 
            +
             *    document.save(filename, :indent => true, :encoding => XML::Encoding::UTF_8) -> int
         | 
| 545 588 | 
             
             *
         | 
| 546 589 | 
             
             * Saves a document to a file.  You may provide an optional hash table
         | 
| 547 590 | 
             
             * to control how the string is generated.  Valid options are:
         | 
| @@ -619,7 +662,7 @@ static VALUE rxml_document_standalone_q(VALUE self) | |
| 619 662 | 
             
            /*
         | 
| 620 663 | 
             
             * call-seq:
         | 
| 621 664 | 
             
             *    document.to_s -> "string"
         | 
| 622 | 
            -
             *    document.to_s(:indent => true, :encoding =>  | 
| 665 | 
            +
             *    document.to_s(:indent => true, :encoding => XML::Encoding::UTF_8) -> "string"
         | 
| 623 666 | 
             
             *
         | 
| 624 667 | 
             
             * Converts a document, and all of its children, to a string representation.
         | 
| 625 668 | 
             
             * You may provide an optional hash table to control how the string is 
         | 
| @@ -771,9 +814,11 @@ static VALUE rxml_document_order_elements(VALUE self) | |
| 771 814 |  | 
| 772 815 | 
             
            /*
         | 
| 773 816 | 
             
             * call-seq:
         | 
| 774 | 
            -
             *    document.validate_schema(schema)  | 
| 817 | 
            +
             *    document.validate_schema(schema) 
         | 
| 775 818 | 
             
             *
         | 
| 776 819 | 
             
             * Validate this document against the specified XML::Schema.
         | 
| 820 | 
            +
             * If the document is valid the method returns true.  Otherwise an
         | 
| 821 | 
            +
             * exception is raised with validation information.
         | 
| 777 822 | 
             
             */
         | 
| 778 823 | 
             
            static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
         | 
| 779 824 | 
             
            {
         | 
| @@ -802,9 +847,11 @@ static VALUE rxml_document_validate_schema(VALUE self, VALUE schema) | |
| 802 847 |  | 
| 803 848 | 
             
            /*
         | 
| 804 849 | 
             
             * call-seq:
         | 
| 805 | 
            -
             *    document. | 
| 850 | 
            +
             *    document.validate_relaxng(relaxng) 
         | 
| 806 851 | 
             
             *
         | 
| 807 852 | 
             
             * Validate this document against the specified XML::RelaxNG.
         | 
| 853 | 
            +
             * If the document is valid the method returns true.  Otherwise an
         | 
| 854 | 
            +
             * exception is raised with validation information.
         | 
| 808 855 | 
             
             */
         | 
| 809 856 | 
             
            static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
         | 
| 810 857 | 
             
            {
         | 
| @@ -836,6 +883,8 @@ static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng) | |
| 836 883 | 
             
             *    document.validate(dtd) -> (true|false)
         | 
| 837 884 | 
             
             *
         | 
| 838 885 | 
             
             * Validate this document against the specified XML::DTD.
         | 
| 886 | 
            +
             * If the document is valid the method returns true.  Otherwise an
         | 
| 887 | 
            +
             * exception is raised with validation information.
         | 
| 839 888 | 
             
             */
         | 
| 840 889 | 
             
            static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
         | 
| 841 890 | 
             
            {
         | 
| @@ -871,6 +920,7 @@ void rxml_init_document(void) | |
| 871 920 | 
             
              rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
         | 
| 872 921 |  | 
| 873 922 | 
             
              rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
         | 
| 923 | 
            +
              rb_define_method(cXMLDocument, "canonicalize", rxml_document_canonicalize, -1);
         | 
| 874 924 | 
             
              rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
         | 
| 875 925 | 
             
              rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
         | 
| 876 926 | 
             
              rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
         | 
    
        data/ext/libxml/ruby_xml_error.c
    CHANGED
    
    | @@ -131,18 +131,6 @@ static void structuredErrorFunc(void *userData, xmlErrorPtr xerror) | |
| 131 131 | 
             
              /* Wrap error up as Ruby object and send it off to ruby */
         | 
| 132 132 | 
             
              VALUE block = rb_cvar_get(eXMLError, ERROR_HANDLER_ID);
         | 
| 133 133 |  | 
| 134 | 
            -
              /* This next bit of code is a total hack to get around a bug
         | 
| 135 | 
            -
                 in libxml which causes error handlers on sax handlers to
         | 
| 136 | 
            -
                 be ignored in favor of the global handler.  In addition,
         | 
| 137 | 
            -
                 the correct context is also not passed in.  So try to 
         | 
| 138 | 
            -
                 dig it out. */
         | 
| 139 | 
            -
              if (!userData && xerror->ctxt)
         | 
| 140 | 
            -
              {
         | 
| 141 | 
            -
                xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) xerror->ctxt;
         | 
| 142 | 
            -
                if (ctxt != ctxt->userData)
         | 
| 143 | 
            -
                  userData = ctxt->userData;
         | 
| 144 | 
            -
              }
         | 
| 145 | 
            -
             | 
| 146 134 | 
             
              /* Now call global handler */
         | 
| 147 135 | 
             
              if (block != Qnil)
         | 
| 148 136 | 
             
              {
         | 
    
        data/ext/libxml/ruby_xml_node.c
    CHANGED
    
    | @@ -33,11 +33,11 @@ VALUE cXMLNode; | |
| 33 33 | 
             
             * a libxml document.  When a Ruby node is freed, the _private
         | 
| 34 34 | 
             
             * field is set back to null.  
         | 
| 35 35 | 
             
             *
         | 
| 36 | 
            -
             * In the sweep phase in Ruby 1.9 | 
| 37 | 
            -
             * the nodes.  To support  | 
| 38 | 
            -
             * function with libxml that is called each time a node | 
| 39 | 
            -
             * In that case, the data_ptr is set to null, so the bindings
         | 
| 40 | 
            -
             * can recognize the  | 
| 36 | 
            +
             * In the sweep phase in Ruby 1.9.*, the document tends to be
         | 
| 37 | 
            +
             * freed before the nodes.  To support this, the bindings register
         | 
| 38 | 
            +
             * a callback function with libxml that is called each time a node
         | 
| 39 | 
            +
             * is freed.  In that case, the data_ptr is set to null, so the bindings
         | 
| 40 | 
            +
             * can recognize the situation.
         | 
| 41 41 | 
             
             */
         | 
| 42 42 |  | 
| 43 43 | 
             
            static void rxml_node_deregisterNode(xmlNodePtr xnode)
         | 
| @@ -50,6 +50,8 @@ static void rxml_node_deregisterNode(xmlNodePtr xnode) | |
| 50 50 | 
             
                  try to free the node a second time. */
         | 
| 51 51 | 
             
                VALUE node = (VALUE) xnode->_private;
         | 
| 52 52 | 
             
                RDATA(node)->data = NULL;
         | 
| 53 | 
            +
                RDATA(node)->dfree = NULL;
         | 
| 54 | 
            +
                RDATA(node)->dmark = NULL;
         | 
| 53 55 | 
             
              }
         | 
| 54 56 | 
             
            }
         | 
| 55 57 |  | 
| @@ -64,40 +66,46 @@ static void rxml_node_free(xmlNodePtr xnode) | |
| 64 66 | 
             
              /* The ruby object wrapping the xml object no longer exists. */
         | 
| 65 67 | 
             
              xnode->_private = NULL;
         | 
| 66 68 |  | 
| 67 | 
            -
              /* Ruby is responsible for freeing this node  | 
| 68 | 
            -
                  | 
| 69 | 
            +
              /* Ruby is responsible for freeing this node if it does not
         | 
| 70 | 
            +
                 have a parent and is not owned by a document.  Note a corner
         | 
| 71 | 
            +
                 case here - calling node2 = doc.import(node1) will cause node2
         | 
| 72 | 
            +
                 to not have a parent but to have a document. */
         | 
| 69 73 | 
             
              if (xnode->parent == NULL)
         | 
| 74 | 
            +
              {
         | 
| 70 75 | 
             
                xmlFreeNode(xnode);
         | 
| 76 | 
            +
              }
         | 
| 71 77 | 
             
            }
         | 
| 72 78 |  | 
| 73 79 | 
             
             void rxml_node_mark(xmlNodePtr xnode)
         | 
| 74 80 | 
             
            {
         | 
| 75 | 
            -
              /* Either the node has been created yet in initialize
         | 
| 81 | 
            +
              /* Either the node has not been created yet in initialize
         | 
| 76 82 | 
             
                 or it has been freed by libxml already in Ruby's 
         | 
| 77 83 | 
             
                 mark phase. */
         | 
| 78 84 | 
             
              if (xnode == NULL)
         | 
| 79 85 | 
             
                return;
         | 
| 80 86 |  | 
| 81 | 
            -
              if (xnode->doc  | 
| 87 | 
            +
              if (xnode->doc && xnode->doc->_private)
         | 
| 82 88 | 
             
                rb_gc_mark((VALUE) xnode->doc->_private);
         | 
| 83 89 |  | 
| 84 | 
            -
              if (xnode->parent  | 
| 90 | 
            +
              if (xnode->parent && xnode->parent->_private)
         | 
| 85 91 | 
             
                rb_gc_mark((VALUE) xnode->_private);
         | 
| 86 92 | 
             
            }
         | 
| 87 93 |  | 
| 88 94 | 
             
            VALUE rxml_node_wrap(xmlNodePtr xnode)
         | 
| 89 95 | 
             
            {
         | 
| 96 | 
            +
              VALUE result;
         | 
| 97 | 
            +
             | 
| 90 98 | 
             
              /* Is the node already wrapped? */
         | 
| 91 99 | 
             
              if (xnode->_private != NULL)
         | 
| 92 100 | 
             
              {
         | 
| 93 | 
            -
                 | 
| 101 | 
            +
                result = (VALUE) xnode->_private;
         | 
| 94 102 | 
             
              }
         | 
| 95 103 | 
             
              else
         | 
| 96 104 | 
             
              {
         | 
| 97 | 
            -
                 | 
| 98 | 
            -
                xnode->_private = (void*)  | 
| 99 | 
            -
                return node;
         | 
| 105 | 
            +
                result = Data_Wrap_Struct(cXMLNode, rxml_node_mark, rxml_node_free, xnode);
         | 
| 106 | 
            +
                xnode->_private = (void*) result;
         | 
| 100 107 | 
             
              }
         | 
| 108 | 
            +
              return result;
         | 
| 101 109 | 
             
            }
         | 
| 102 110 |  | 
| 103 111 | 
             
            static VALUE rxml_node_alloc(VALUE klass)
         | 
| @@ -107,6 +115,17 @@ static VALUE rxml_node_alloc(VALUE klass) | |
| 107 115 | 
             
              return Data_Wrap_Struct(klass, rxml_node_mark, rxml_node_free, NULL);
         | 
| 108 116 | 
             
            }
         | 
| 109 117 |  | 
| 118 | 
            +
            static xmlNodePtr rxml_get_xnode(VALUE node)
         | 
| 119 | 
            +
            {
         | 
| 120 | 
            +
               xmlNodePtr result;
         | 
| 121 | 
            +
               Data_Get_Struct(node, xmlNode, result);
         | 
| 122 | 
            +
             | 
| 123 | 
            +
               if (!result)
         | 
| 124 | 
            +
                rb_raise(rb_eRuntimeError, "This node has already been freed.");
         | 
| 125 | 
            +
             | 
| 126 | 
            +
               return result;
         | 
| 127 | 
            +
            }
         | 
| 128 | 
            +
             | 
| 110 129 | 
             
            /*
         | 
| 111 130 | 
             
             * call-seq:
         | 
| 112 131 | 
             
             *    XML::Node.new_cdata(content = nil) -> XML::Node
         | 
| @@ -237,11 +256,13 @@ static VALUE rxml_node_modify_dom(VALUE self, VALUE target, | |
| 237 256 | 
             
              if (rb_obj_is_kind_of(target, cXMLNode) == Qfalse)
         | 
| 238 257 | 
             
                rb_raise(rb_eTypeError, "Must pass an XML::Node object");
         | 
| 239 258 |  | 
| 240 | 
            -
               | 
| 241 | 
            -
               | 
| 259 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 260 | 
            +
              xtarget = rxml_get_xnode(target);
         | 
| 242 261 |  | 
| 243 262 | 
             
              if (xtarget->doc != NULL && xtarget->doc != xnode->doc)
         | 
| 244 | 
            -
                rb_raise(eXMLError, "Nodes belong to different documents.  You must first import the by calling XML::Document.import");
         | 
| 263 | 
            +
                rb_raise(eXMLError, "Nodes belong to different documents.  You must first import the node by calling XML::Document.import");
         | 
| 264 | 
            +
             | 
| 265 | 
            +
              xmlUnlinkNode(xtarget);
         | 
| 245 266 |  | 
| 246 267 | 
             
              /* This target node could be freed here. */  
         | 
| 247 268 | 
             
              xresult = xmlFunc(xnode, xtarget);
         | 
| @@ -271,7 +292,7 @@ static VALUE rxml_node_base_uri_get(VALUE self) | |
| 271 292 | 
             
              xmlChar* base_uri;
         | 
| 272 293 | 
             
              VALUE result = Qnil;
         | 
| 273 294 |  | 
| 274 | 
            -
               | 
| 295 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 275 296 |  | 
| 276 297 | 
             
              if (xnode->doc == NULL)
         | 
| 277 298 | 
             
                return (result);
         | 
| @@ -299,7 +320,7 @@ static VALUE rxml_node_base_uri_set(VALUE self, VALUE uri) | |
| 299 320 | 
             
              xmlNodePtr xnode;
         | 
| 300 321 |  | 
| 301 322 | 
             
              Check_Type(uri, T_STRING);
         | 
| 302 | 
            -
               | 
| 323 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 303 324 | 
             
              if (xnode->doc == NULL)
         | 
| 304 325 | 
             
                return (Qnil);
         | 
| 305 326 |  | 
| @@ -319,7 +340,7 @@ static VALUE rxml_node_content_get(VALUE self) | |
| 319 340 | 
             
              xmlChar *content;
         | 
| 320 341 | 
             
              VALUE result = Qnil;
         | 
| 321 342 |  | 
| 322 | 
            -
               | 
| 343 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 323 344 | 
             
              content = xmlNodeGetContent(xnode);
         | 
| 324 345 | 
             
              if (content)
         | 
| 325 346 | 
             
              {
         | 
| @@ -341,7 +362,7 @@ static VALUE rxml_node_content_set(VALUE self, VALUE content) | |
| 341 362 | 
             
              xmlNodePtr xnode;
         | 
| 342 363 |  | 
| 343 364 | 
             
              Check_Type(content, T_STRING);
         | 
| 344 | 
            -
               | 
| 365 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 345 366 | 
             
              // XXX docs indicate need for escaping entites, need to be done? danj
         | 
| 346 367 | 
             
              xmlNodeSetContent(xnode, (xmlChar*) StringValuePtr(content));
         | 
| 347 368 | 
             
              return (Qtrue);
         | 
| @@ -362,7 +383,7 @@ static VALUE rxml_node_content_stripped_get(VALUE self) | |
| 362 383 | 
             
              xmlChar* content;
         | 
| 363 384 | 
             
              VALUE result = Qnil;
         | 
| 364 385 |  | 
| 365 | 
            -
               | 
| 386 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 366 387 |  | 
| 367 388 | 
             
              if (!xnode->content)
         | 
| 368 389 | 
             
                return result;
         | 
| @@ -387,7 +408,7 @@ static VALUE rxml_node_debug(VALUE self) | |
| 387 408 | 
             
            {
         | 
| 388 409 | 
             
            #ifdef LIBXML_DEBUG_ENABLED
         | 
| 389 410 | 
             
              xmlNodePtr xnode;
         | 
| 390 | 
            -
               | 
| 411 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 391 412 | 
             
              xmlDebugDumpNode(NULL, xnode, 2);
         | 
| 392 413 | 
             
              return Qtrue;
         | 
| 393 414 | 
             
            #else
         | 
| @@ -406,7 +427,7 @@ static VALUE rxml_node_first_get(VALUE self) | |
| 406 427 | 
             
            {
         | 
| 407 428 | 
             
              xmlNodePtr xnode;
         | 
| 408 429 |  | 
| 409 | 
            -
               | 
| 430 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 410 431 |  | 
| 411 432 | 
             
              if (xnode->children)
         | 
| 412 433 | 
             
                return (rxml_node_wrap(xnode->children));
         | 
| @@ -434,16 +455,14 @@ static VALUE rxml_node_content_add(VALUE self, VALUE obj) | |
| 434 455 | 
             
              xmlNodePtr xnode;
         | 
| 435 456 | 
             
              VALUE str;
         | 
| 436 457 |  | 
| 437 | 
            -
               | 
| 458 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 459 | 
            +
             | 
| 438 460 | 
             
              /* XXX This should only be legal for a CDATA type node, I think,
         | 
| 439 461 | 
             
               * resulting in a merge of content, as if a string were passed
         | 
| 440 462 | 
             
               * danj 070827
         | 
| 441 463 | 
             
               */
         | 
| 442 464 | 
             
              if (rb_obj_is_kind_of(obj, cXMLNode))
         | 
| 443 465 | 
             
              { 
         | 
| 444 | 
            -
                xmlNodePtr xtarget;
         | 
| 445 | 
            -
                Data_Get_Struct(obj, xmlNode, xtarget);
         | 
| 446 | 
            -
                xmlUnlinkNode(xtarget);
         | 
| 447 466 | 
             
                rxml_node_modify_dom(self, obj, xmlAddChild);
         | 
| 448 467 | 
             
              }
         | 
| 449 468 | 
             
              else
         | 
| @@ -465,41 +484,32 @@ static VALUE rxml_node_content_add(VALUE self, VALUE obj) | |
| 465 484 | 
             
             */
         | 
| 466 485 | 
             
            static VALUE rxml_node_doc(VALUE self)
         | 
| 467 486 | 
             
            {
         | 
| 468 | 
            -
               | 
| 469 | 
            -
               | 
| 470 | 
            -
             | 
| 471 | 
            -
              Data_Get_Struct(self, xmlNode, xnode);
         | 
| 487 | 
            +
              xmlDocPtr xdoc = NULL;
         | 
| 488 | 
            +
              xmlNodePtr xnode = rxml_get_xnode(self);
         | 
| 472 489 |  | 
| 473 490 | 
             
              switch (xnode->type)
         | 
| 474 491 | 
             
              {
         | 
| 475 492 | 
             
              case XML_DOCUMENT_NODE:
         | 
| 476 493 | 
             
            #ifdef LIBXML_DOCB_ENABLED
         | 
| 477 | 
            -
             | 
| 494 | 
            +
              case XML_DOCB_DOCUMENT_NODE:
         | 
| 478 495 | 
             
            #endif
         | 
| 479 496 | 
             
              case XML_HTML_DOCUMENT_NODE:
         | 
| 480 | 
            -
             | 
| 497 | 
            +
              case XML_NAMESPACE_DECL:
         | 
| 481 498 | 
             
                break;
         | 
| 482 499 | 
             
              case XML_ATTRIBUTE_NODE:
         | 
| 483 | 
            -
             | 
| 484 | 
            -
                xmlAttrPtr attr = (xmlAttrPtr) xnode;
         | 
| 485 | 
            -
                doc = attr->doc;
         | 
| 486 | 
            -
                break;
         | 
| 487 | 
            -
              }
         | 
| 488 | 
            -
              case XML_NAMESPACE_DECL:
         | 
| 489 | 
            -
                doc = NULL;
         | 
| 500 | 
            +
                xdoc = (xmlDocPtr)((xmlAttrPtr) xnode->doc);
         | 
| 490 501 | 
             
                break;
         | 
| 491 502 | 
             
              default:
         | 
| 492 | 
            -
                 | 
| 493 | 
            -
                break;
         | 
| 503 | 
            +
                xdoc = xnode->doc;
         | 
| 494 504 | 
             
              }
         | 
| 495 505 |  | 
| 496 | 
            -
              if ( | 
| 506 | 
            +
              if (xdoc == NULL)
         | 
| 497 507 | 
             
                return (Qnil);
         | 
| 498 | 
            -
             | 
| 499 | 
            -
             | 
| 500 | 
            -
             | 
| 501 | 
            -
             | 
| 502 | 
            -
             | 
| 508 | 
            +
              else if (xdoc->_private)
         | 
| 509 | 
            +
                return (VALUE) xdoc->_private;
         | 
| 510 | 
            +
              else
         | 
| 511 | 
            +
                /* This can happen by calling Reader#expand.doc */
         | 
| 512 | 
            +
                rb_raise(eXMLError, "Document is not accessible to Ruby (hint - did you call Reader#expand?)");
         | 
| 503 513 | 
             
            }
         | 
| 504 514 |  | 
| 505 515 | 
             
            /*
         | 
| @@ -567,7 +577,8 @@ static VALUE rxml_node_to_s(int argc, VALUE *argv, VALUE self) | |
| 567 577 | 
             
              encodingHandler = xmlFindCharEncodingHandler(xencoding);
         | 
| 568 578 | 
             
              output = xmlAllocOutputBuffer(encodingHandler);
         | 
| 569 579 |  | 
| 570 | 
            -
               | 
| 580 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 581 | 
            +
             | 
| 571 582 | 
             
              xmlNodeDumpOutput(output, xnode->doc, xnode, level, indent, xencoding);
         | 
| 572 583 | 
             
              xmlOutputBufferFlush(output);
         | 
| 573 584 |  | 
| @@ -597,7 +608,7 @@ static VALUE rxml_node_each(VALUE self) | |
| 597 608 | 
             
            {
         | 
| 598 609 | 
             
              xmlNodePtr xnode;
         | 
| 599 610 | 
             
              xmlNodePtr xcurrent;
         | 
| 600 | 
            -
               | 
| 611 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 601 612 |  | 
| 602 613 | 
             
              xcurrent = xnode->children;
         | 
| 603 614 |  | 
| @@ -617,12 +628,12 @@ static VALUE rxml_node_each(VALUE self) | |
| 617 628 | 
             
             * call-seq:
         | 
| 618 629 | 
             
             *    node.empty? -> (true|false)
         | 
| 619 630 | 
             
             *
         | 
| 620 | 
            -
             * Determine whether this node is empty.
         | 
| 631 | 
            +
             * Determine whether this node is an empty or whitespace only text-node.
         | 
| 621 632 | 
             
             */
         | 
| 622 633 | 
             
            static VALUE rxml_node_empty_q(VALUE self)
         | 
| 623 634 | 
             
            {
         | 
| 624 635 | 
             
              xmlNodePtr xnode;
         | 
| 625 | 
            -
               | 
| 636 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 626 637 | 
             
              if (xnode == NULL)
         | 
| 627 638 | 
             
                return (Qnil);
         | 
| 628 639 |  | 
| @@ -638,26 +649,26 @@ static VALUE rxml_node_empty_q(VALUE self) | |
| 638 649 | 
             
             * if they are the same node or have the same XML representation.*/
         | 
| 639 650 | 
             
            static VALUE rxml_node_eql_q(VALUE self, VALUE other)
         | 
| 640 651 | 
             
            {
         | 
| 641 | 
            -
            if(self == other)
         | 
| 642 | 
            -
            {
         | 
| 643 | 
            -
             | 
| 644 | 
            -
            }
         | 
| 645 | 
            -
            else if (NIL_P(other))
         | 
| 646 | 
            -
            {
         | 
| 647 | 
            -
             | 
| 648 | 
            -
            }
         | 
| 649 | 
            -
            else
         | 
| 650 | 
            -
            {
         | 
| 651 | 
            -
             | 
| 652 | 
            -
             | 
| 652 | 
            +
              if(self == other)
         | 
| 653 | 
            +
              {
         | 
| 654 | 
            +
                return Qtrue;
         | 
| 655 | 
            +
              }
         | 
| 656 | 
            +
              else if (NIL_P(other))
         | 
| 657 | 
            +
              {
         | 
| 658 | 
            +
                return Qfalse;
         | 
| 659 | 
            +
              }
         | 
| 660 | 
            +
              else
         | 
| 661 | 
            +
              {
         | 
| 662 | 
            +
                VALUE self_xml;
         | 
| 663 | 
            +
                VALUE other_xml;
         | 
| 653 664 |  | 
| 654 | 
            -
             | 
| 655 | 
            -
             | 
| 665 | 
            +
                if (rb_obj_is_kind_of(other, cXMLNode) == Qfalse)
         | 
| 666 | 
            +
                  rb_raise(rb_eTypeError, "Nodes can only be compared against other nodes");
         | 
| 656 667 |  | 
| 657 | 
            -
             | 
| 658 | 
            -
             | 
| 659 | 
            -
             | 
| 660 | 
            -
            }
         | 
| 668 | 
            +
                self_xml = rxml_node_to_s(0, NULL, self);
         | 
| 669 | 
            +
                other_xml = rxml_node_to_s(0, NULL, other);
         | 
| 670 | 
            +
                return(rb_funcall(self_xml, rb_intern("=="), 1, other_xml));
         | 
| 671 | 
            +
              }
         | 
| 661 672 | 
             
            }
         | 
| 662 673 |  | 
| 663 674 | 
             
            /*
         | 
| @@ -673,7 +684,7 @@ static VALUE rxml_node_lang_get(VALUE self) | |
| 673 684 | 
             
              xmlChar *lang;
         | 
| 674 685 | 
             
              VALUE result = Qnil;
         | 
| 675 686 |  | 
| 676 | 
            -
               | 
| 687 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 677 688 | 
             
              lang = xmlNodeGetLang(xnode);
         | 
| 678 689 |  | 
| 679 690 | 
             
              if (lang)
         | 
| @@ -699,7 +710,7 @@ static VALUE rxml_node_lang_set(VALUE self, VALUE lang) | |
| 699 710 | 
             
              xmlNodePtr xnode;
         | 
| 700 711 |  | 
| 701 712 | 
             
              Check_Type(lang, T_STRING);
         | 
| 702 | 
            -
               | 
| 713 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 703 714 | 
             
              xmlNodeSetLang(xnode, (xmlChar*) StringValuePtr(lang));
         | 
| 704 715 |  | 
| 705 716 | 
             
              return (Qtrue);
         | 
| @@ -715,7 +726,7 @@ static VALUE rxml_node_last_get(VALUE self) | |
| 715 726 | 
             
            {
         | 
| 716 727 | 
             
              xmlNodePtr xnode;
         | 
| 717 728 |  | 
| 718 | 
            -
               | 
| 729 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 719 730 |  | 
| 720 731 | 
             
              if (xnode->last)
         | 
| 721 732 | 
             
                return (rxml_node_wrap(xnode->last));
         | 
| @@ -735,7 +746,7 @@ static VALUE rxml_node_line_num(VALUE self) | |
| 735 746 | 
             
            {
         | 
| 736 747 | 
             
              xmlNodePtr xnode;
         | 
| 737 748 | 
             
              long line_num;
         | 
| 738 | 
            -
               | 
| 749 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 739 750 |  | 
| 740 751 | 
             
              if (!xmlLineNumbersDefaultValue)
         | 
| 741 752 | 
             
                rb_warn(
         | 
| @@ -759,7 +770,7 @@ static VALUE rxml_node_xlink_q(VALUE self) | |
| 759 770 | 
             
              xmlNodePtr xnode;
         | 
| 760 771 | 
             
              xlinkType xlt;
         | 
| 761 772 |  | 
| 762 | 
            -
               | 
| 773 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 763 774 | 
             
              xlt = xlinkIsLink(xnode->doc, xnode);
         | 
| 764 775 |  | 
| 765 776 | 
             
              if (xlt == XLINK_TYPE_NONE)
         | 
| @@ -781,7 +792,7 @@ static VALUE rxml_node_xlink_type(VALUE self) | |
| 781 792 | 
             
              xmlNodePtr xnode;
         | 
| 782 793 | 
             
              xlinkType xlt;
         | 
| 783 794 |  | 
| 784 | 
            -
               | 
| 795 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 785 796 | 
             
              xlt = xlinkIsLink(xnode->doc, xnode);
         | 
| 786 797 |  | 
| 787 798 | 
             
              if (xlt == XLINK_TYPE_NONE)
         | 
| @@ -803,7 +814,7 @@ static VALUE rxml_node_xlink_type_name(VALUE self) | |
| 803 814 | 
             
              xmlNodePtr xnode;
         | 
| 804 815 | 
             
              xlinkType xlt;
         | 
| 805 816 |  | 
| 806 | 
            -
               | 
| 817 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 807 818 | 
             
              xlt = xlinkIsLink(xnode->doc, xnode);
         | 
| 808 819 |  | 
| 809 820 | 
             
              switch (xlt)
         | 
| @@ -832,7 +843,7 @@ static VALUE rxml_node_name_get(VALUE self) | |
| 832 843 | 
             
              xmlNodePtr xnode;
         | 
| 833 844 | 
             
              const xmlChar *name;
         | 
| 834 845 |  | 
| 835 | 
            -
               | 
| 846 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 836 847 |  | 
| 837 848 | 
             
              switch (xnode->type)
         | 
| 838 849 | 
             
              {
         | 
| @@ -881,7 +892,7 @@ static VALUE rxml_node_name_set(VALUE self, VALUE name) | |
| 881 892 | 
             
              const xmlChar *xname;
         | 
| 882 893 |  | 
| 883 894 | 
             
              Check_Type(name, T_STRING);
         | 
| 884 | 
            -
               | 
| 895 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 885 896 | 
             
              xname = (const xmlChar*)StringValuePtr(name);
         | 
| 886 897 |  | 
| 887 898 | 
             
            	/* Note: calling xmlNodeSetName() for a text node is ignored by libXML. */
         | 
| @@ -900,7 +911,7 @@ static VALUE rxml_node_next_get(VALUE self) | |
| 900 911 | 
             
            {
         | 
| 901 912 | 
             
              xmlNodePtr xnode;
         | 
| 902 913 |  | 
| 903 | 
            -
               | 
| 914 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 904 915 |  | 
| 905 916 | 
             
              if (xnode->next)
         | 
| 906 917 | 
             
                return (rxml_node_wrap(xnode->next));
         | 
| @@ -933,7 +944,7 @@ static VALUE rxml_node_parent_get(VALUE self) | |
| 933 944 | 
             
            {
         | 
| 934 945 | 
             
              xmlNodePtr xnode;
         | 
| 935 946 |  | 
| 936 | 
            -
               | 
| 947 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 937 948 |  | 
| 938 949 | 
             
              if (xnode->parent)
         | 
| 939 950 | 
             
                return (rxml_node_wrap(xnode->parent));
         | 
| @@ -952,7 +963,7 @@ static VALUE rxml_node_path(VALUE self) | |
| 952 963 | 
             
              xmlNodePtr xnode;
         | 
| 953 964 | 
             
              xmlChar *path;
         | 
| 954 965 |  | 
| 955 | 
            -
               | 
| 966 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 956 967 | 
             
              path = xmlGetNodePath(xnode);
         | 
| 957 968 |  | 
| 958 969 | 
             
              if (path == NULL)
         | 
| @@ -982,7 +993,7 @@ static VALUE rxml_node_prev_get(VALUE self) | |
| 982 993 | 
             
            {
         | 
| 983 994 | 
             
              xmlNodePtr xnode;
         | 
| 984 995 | 
             
              xmlNodePtr node;
         | 
| 985 | 
            -
               | 
| 996 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 986 997 |  | 
| 987 998 | 
             
              switch (xnode->type)
         | 
| 988 999 | 
             
              {
         | 
| @@ -1036,7 +1047,7 @@ static VALUE rxml_node_attributes_get(VALUE self) | |
| 1036 1047 | 
             
            {
         | 
| 1037 1048 | 
             
              xmlNodePtr xnode;
         | 
| 1038 1049 |  | 
| 1039 | 
            -
               | 
| 1050 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1040 1051 | 
             
              return rxml_attributes_new(xnode);
         | 
| 1041 1052 | 
             
            }
         | 
| 1042 1053 |  | 
| @@ -1077,7 +1088,7 @@ static VALUE rxml_node_property_set(VALUE self, VALUE name, VALUE value) | |
| 1077 1088 | 
             
            static VALUE rxml_node_remove_ex(VALUE self)
         | 
| 1078 1089 | 
             
            {
         | 
| 1079 1090 | 
             
              xmlNodePtr xnode, xresult;
         | 
| 1080 | 
            -
               | 
| 1091 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1081 1092 |  | 
| 1082 1093 | 
             
              /* First unlink the node from its parent. */
         | 
| 1083 1094 | 
             
              xmlUnlinkNode(xnode);
         | 
| @@ -1137,7 +1148,7 @@ static VALUE rxml_node_sibling_set(VALUE self, VALUE sibling) | |
| 1137 1148 | 
             
            static VALUE rxml_node_output_escaping_q(VALUE self)
         | 
| 1138 1149 | 
             
            {
         | 
| 1139 1150 | 
             
              xmlNodePtr xnode;
         | 
| 1140 | 
            -
               | 
| 1151 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1141 1152 |  | 
| 1142 1153 | 
             
              switch (xnode->type) {
         | 
| 1143 1154 | 
             
              case XML_TEXT_NODE:
         | 
| @@ -1184,7 +1195,7 @@ static VALUE rxml_node_output_escaping_q(VALUE self) | |
| 1184 1195 | 
             
            static VALUE rxml_node_output_escaping_set(VALUE self, VALUE bool)
         | 
| 1185 1196 | 
             
            {
         | 
| 1186 1197 | 
             
              xmlNodePtr xnode;
         | 
| 1187 | 
            -
               | 
| 1198 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1188 1199 |  | 
| 1189 1200 | 
             
              switch (xnode->type) {
         | 
| 1190 1201 | 
             
              case XML_TEXT_NODE:
         | 
| @@ -1217,7 +1228,7 @@ static VALUE rxml_node_space_preserve_get(VALUE self) | |
| 1217 1228 | 
             
            {
         | 
| 1218 1229 | 
             
              xmlNodePtr xnode;
         | 
| 1219 1230 |  | 
| 1220 | 
            -
               | 
| 1231 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1221 1232 | 
             
              return (INT2NUM(xmlNodeGetSpacePreserve(xnode)));
         | 
| 1222 1233 | 
             
            }
         | 
| 1223 1234 |  | 
| @@ -1230,7 +1241,7 @@ static VALUE rxml_node_space_preserve_get(VALUE self) | |
| 1230 1241 | 
             
            static VALUE rxml_node_space_preserve_set(VALUE self, VALUE bool)
         | 
| 1231 1242 | 
             
            {
         | 
| 1232 1243 | 
             
              xmlNodePtr xnode;
         | 
| 1233 | 
            -
               | 
| 1244 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1234 1245 |  | 
| 1235 1246 | 
             
              if (TYPE(bool) == T_FALSE)
         | 
| 1236 1247 | 
             
                xmlNodeSetSpacePreserve(xnode, 0);
         | 
| @@ -1249,7 +1260,7 @@ static VALUE rxml_node_space_preserve_set(VALUE self, VALUE bool) | |
| 1249 1260 | 
             
            static VALUE rxml_node_type(VALUE self)
         | 
| 1250 1261 | 
             
            {
         | 
| 1251 1262 | 
             
              xmlNodePtr xnode;
         | 
| 1252 | 
            -
               | 
| 1263 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1253 1264 | 
             
              return (INT2NUM(xnode->type));
         | 
| 1254 1265 | 
             
            }
         | 
| 1255 1266 |  | 
| @@ -1268,7 +1279,7 @@ static VALUE rxml_node_copy(VALUE self, VALUE deep) | |
| 1268 1279 | 
             
              xmlNodePtr xnode;
         | 
| 1269 1280 | 
             
              xmlNodePtr xcopy;
         | 
| 1270 1281 | 
             
              int recursive = (deep == Qnil || deep == Qfalse) ? 0 : 1;
         | 
| 1271 | 
            -
               | 
| 1282 | 
            +
              xnode = rxml_get_xnode(self);
         | 
| 1272 1283 |  | 
| 1273 1284 | 
             
              xcopy = xmlCopyNode(xnode, recursive);
         | 
| 1274 1285 |  | 
| @@ -1280,8 +1291,12 @@ static VALUE rxml_node_copy(VALUE self, VALUE deep) | |
| 1280 1291 |  | 
| 1281 1292 | 
             
            void rxml_init_node(void)
         | 
| 1282 1293 | 
             
            {
         | 
| 1294 | 
            +
              /* Register callback for main thread */
         | 
| 1283 1295 | 
             
              xmlDeregisterNodeDefault(rxml_node_deregisterNode);
         | 
| 1284 1296 |  | 
| 1297 | 
            +
              /* Register callback for all other threads */
         | 
| 1298 | 
            +
              xmlThrDefDeregisterNodeDefault(rxml_node_deregisterNode);
         | 
| 1299 | 
            +
             | 
| 1285 1300 | 
             
              cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
         | 
| 1286 1301 |  | 
| 1287 1302 | 
             
              rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
         |