Apache2-ModXml2

 view release on metacpan or  search on metacpan

ModXml2.xs  view on Meta::CPAN

#include <mod_perl.h>
#include <modperl_xs_typedefs.h>
#include <modperl_types.h>

/* This needs to be included before mod_xml2_intern.h
   since it redefines APR_DECLARE_OPTIONAL_FN.
 */
APR_DECLARE_OPTIONAL_FN(int, refcnt_dec,
		(xmlNode *node));

/* mod_xml2 API */
#include <mod_xml2_intern.h>

#undef NDEBUG
#include <assert.h>

/**
 * Wrapper that makes XML::LibXML::Devel::refcnt_dec callable from C code 
 * as an apr optional function.
 * @param node is assumed to have a _private from XML::LibXML
 * @return The count before decrementing 
 */
static int refcnt_dec(xmlNode *node)
{
    int ret;

    dSP;
    ENTER;
    SAVETMPS;

    /* arguments */
    PUSHMARK(SP);
    XPUSHs(sv_2mortal(newSViv(PTR2IV(node))));
    PUTBACK;

    /* call */
    ret = call_pv("XML::LibXML::Devel::refcnt_dec", G_SCALAR );
    assert(ret == 1);

    /* return value */
    SPAGAIN;
    /* Check the eval */
    /*if (SvTRUE(ERRSV))
    {
        POPs;
        croak("Call to transform function failed: %s", SvPV_nolen(ERRSV));
    }*/
    ret = POPi;
    PUTBACK;

    FREETMPS;
    LEAVE;

    return ret;
}

/**
 * Static callback to be used as an XPath callback. The 
 * perl subroutine is passed as the void * argument.
 * @param node The root node of the tree to transform. 
 *             This is assumed to have a document fragment 
 *             as its parent.
 * @param transform The coderef to call.
 * @return APR_SUCCESS (== 0) on success.
 */
static int call_transform(xmlNode *node, void *transform) {
    SV *svTransform = transform;
    assert(SvROK(svTransform));
    assert(SvTYPE(SvRV(svTransform)) == SVt_PVCV);

    /* We assume that the parent is the 
       owner document fragment */
    SV *svNode = sv_2mortal(newSViv(PTR2IV(node)));

    int ret;

    dSP;
    ENTER;
    SAVETMPS;

    /* arguments */
    PUSHMARK(SP);
    XPUSHs(svNode);
    PUTBACK;

    /* call */
    ret = call_sv(svTransform, G_SCALAR );
    assert(ret == 1);

    /* return value */
    SPAGAIN;
    ret = POPi;
    PUTBACK;

    FREETMPS;
    LEAVE;

    return ret;
} 

/*
 * Wrapper needed to give the macro a function pointer.
 */
static void wrap_SvREFCNT_dec(SV* sv) {
    SvREFCNT_dec(sv);
}

static int xml2_document_start(request_rec *r, xmlDoc *doc) 
{    
    SV *svR = sv_2mortal(newSViv(PTR2IV(r)));
    SV *svNode = sv_2mortal(newSViv(PTR2IV(doc)));

    int ret;

    dSP;
    ENTER;
    SAVETMPS;

    /* arguments */
    PUSHMARK(SP);
    XPUSHs(svR);
    XPUSHs(svNode);
    PUTBACK;

    /* call */
    ret = call_pv("Apache2::ModXml2::document_start", G_SCALAR );
    assert(ret == 1);

    /* return value */
    SPAGAIN;
    ret = POPi;
    PUTBACK;



( run in 1.124 second using v1.01-cache-2.11-cpan-b16cb0d3907 )