summaryrefslogtreecommitdiff
path: root/lib/XML/LibXML/Devel.pm
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2020-01-20 10:50:34 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2020-01-20 10:50:34 +0900
commitf228e79b87b7c5271c468f709e82c3f7d3305a3d (patch)
treeab2ae0ac32b5ef610a3901505b73d2fb6ce7daab /lib/XML/LibXML/Devel.pm
parentaf87c453a812a912c6585a6171e461a254bc9fc0 (diff)
downloadperl-XML-LibXML-f228e79b87b7c5271c468f709e82c3f7d3305a3d.tar.gz
perl-XML-LibXML-f228e79b87b7c5271c468f709e82c3f7d3305a3d.tar.bz2
perl-XML-LibXML-f228e79b87b7c5271c468f709e82c3f7d3305a3d.zip
Imported Upstream version 2.0134upstream/2.0134
Diffstat (limited to 'lib/XML/LibXML/Devel.pm')
-rw-r--r--lib/XML/LibXML/Devel.pm216
1 files changed, 216 insertions, 0 deletions
diff --git a/lib/XML/LibXML/Devel.pm b/lib/XML/LibXML/Devel.pm
new file mode 100644
index 0000000..d4dfe61
--- /dev/null
+++ b/lib/XML/LibXML/Devel.pm
@@ -0,0 +1,216 @@
+# $Id: $
+# This is free software, you may use it and distribute it under the same terms as
+# Perl itself.
+#
+# Copyright 2011 Joachim Zobel
+#
+package XML::LibXML::Devel;
+
+use strict;
+use warnings;
+
+use XML::LibXML;
+
+use vars qw ($VERSION);
+$VERSION = "2.0134"; # VERSION TEMPLATE: DO NOT CHANGE
+
+use 5.008_000;
+
+use parent qw(Exporter);
+
+use vars qw( @EXPORT @EXPORT_OK %EXPORT_TAGS );
+
+# This allows declaration use XML::LibXML::Devel ':all';
+# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
+# will save memory.
+our %EXPORT_TAGS = ( 'all' => [ qw(
+ node_to_perl
+ node_from_perl
+ refcnt_inc
+ refcnt_dec
+ refcnt
+ fix_owner
+ mem_used
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+# Preloaded methods go here.
+
+1;
+__END__
+
+=head1 NAME
+
+XML::LibXML::Devel - makes functions from LibXML.xs available
+
+=head1 SYNOPSIS
+
+ /**********************************************
+ * C functions you want to access
+ */
+ xmlNode *return_node();
+ void receive_node(xmlNode *);
+
+ ###############################################
+ # XS Code
+ void *
+ xs_return_node
+ CODE:
+ RETVAL = return_node();
+ OUTPUT:
+ RETVAL
+
+ void
+ xs_receive_node
+ void *n
+ CODE:
+ receive_node(n);
+
+ ###############################################
+ # Perl code
+ use XML::LibXML::Devel;
+
+ sub return_node
+ {
+ my $raw_node = xs_return_node();
+ my $node = XML::LibXML::Devel::node_to_perl($raw_node);
+ XML::LibXML::Devel::refcnt_inc($raw_node);
+ return $node;
+ }
+
+ sub receive_node
+ {
+ my ($node) = @_;
+ my $raw_node = XML::LibXML::Devel::node_from_perl($node);
+ xs_receive_node($raw_node);
+ XML::LibXML::Devel::refcnt_inc($raw_node);
+ }
+
+
+=head1 DESCRIPTION
+
+C<XML::LibXML::Devel> makes functions from LibXML.xs available that
+are needed to wrap libxml2 nodes in and out of XML::LibXML::Nodes.
+This gives cleaner dependencies than using LibXML.so directly.
+
+To XS a library that uses libxml2 nodes the first step is to
+do this so that xmlNodePtr is passed as void *. These raw nodes
+are then turned into libxml nodes by using this C<Devel> functions.
+
+Be aware that this module is currently rather experimental. The function
+names may change if I XS more functions and introduce a reasonable
+naming convention.
+
+Be also aware that this module is a great tool to cause segfaults and
+introduce memory leaks. It does however provide a partial cure by making
+C<xmlMemUsed> available as C<mem_used>.
+
+=head1 FUNCTIONS
+
+=head2 NODE MANAGEMENT
+
+=over 1
+
+=item node_to_perl
+
+ node_to_perl($raw_node);
+
+Returns a LibXML::Node object. This has a proxy node with a reference
+counter and an owner attached. The raw node will be deleted as soon
+as the reference counter reaches zero.
+If the C library is keeping a
+pointer to the raw node, you need to call refcnt_inc immediately.
+You also need to replace xmlFreeNode by a call to refcnt_dec.
+
+=item node_to_perl
+
+ node_from_perl($node);
+
+Returns a raw node. This is a void * pointer and you can do nothing
+but passing it to functions that treat it as an xmlNodePtr. The
+raw node will be freed as soon as its reference counter reaches zero.
+If the C library is keeping a
+pointer to the raw node, you need to call refcnt_inc immediately.
+You also need to replace xmlFreeNode by a call to refcnt_dec.
+
+=item refcnt_inc
+
+ refcnt_inc($raw_node);
+
+Increments the raw nodes reference counter. The raw node must already
+be known to perl to have a reference counter.
+
+=item refcnt_dec
+
+ refcnt_dec($raw_node);
+
+Decrements the raw nodes reference counter and returns the value it
+had before. if the counter becomes zero or less,
+this method will free the proxy node holding the reference counter.
+If the node is part of a
+subtree, refcnt_dec will fix the reference counts and delete
+the subtree if it is not required any more.
+
+=item refcnt
+
+ refcnt($raw_node);
+
+Returns the value of the reference counter.
+
+=item fix_owner
+
+ fix_owner($raw_node, $raw_parent);
+
+This functions fixes the reference counts for an entire subtree.
+it is very important to fix an entire subtree after node operations
+where the documents or the owner node may get changed. this method is
+aware about nodes that already belong to a certain owner node.
+
+=back
+
+=head2 MEMORY DEBUGGING
+
+=over 1
+
+=item $ENV{DEBUG_MEMORY}
+
+ BEGIN {$ENV{DEBUG_MEMORY} = 1;};
+ use XML::LibXML;
+
+This turns on libxml2 memory debugging. It must be set before
+XML::LibXML is loaded.
+
+
+=item mem_used
+
+ mem_used();
+
+Returns the number of bytes currently allocated.
+
+=back
+
+=head2 EXPORT
+
+None by default.
+
+=head1 SEE ALSO
+
+This was created to support the needs of Apache2::ModXml2. So this
+can serve as an example.
+
+=head1 AUTHOR
+
+Joachim Zobel E<lt>jz-2011@heute-morgen.deE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2011 by Joachim Zobel
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.10.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
+