From: Petr P. <pa...@us...> - 2003-03-20 17:10:07
|
Update of /cvsroot/perl-xml/XML-LibXML-XPathContext In directory sc8-pr-cvs1:/tmp/cvs-serv28371 Modified Files: XPathContext.xs Log Message: added node pool Index: XPathContext.xs =================================================================== RCS file: /cvsroot/perl-xml/XML-LibXML-XPathContext/XPathContext.xs,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- XPathContext.xs 20 Mar 2003 13:55:25 -0000 1.13 +++ XPathContext.xs 20 Mar 2003 17:10:01 -0000 1.14 @@ -72,6 +72,47 @@ } /* **************************************************************** + * Temporary node pool + * **************************************************************** */ + +/* Stores pnode in context node-pool hash table in order to preserve */ +/* at least one reference. */ +/* If pnode is NULL, only return current value for hashkey */ +static +SV* LibXML_XPathContext_pool ( xmlXPathContextPtr ctxt, int hashkey, SV * pnode ) { + SV ** value; + HV * pool; + SV * key; + SV * pnode2; + STRLEN len; + char * strkey; + + if (XPathContextDATA(ctxt)->pool == NULL) { + if (pnode == NULL) { + return &PL_sv_undef; + } else { + xs_warn("initializing node pool"); + XPathContextDATA(ctxt)->pool = newHV(); + } + } + + key = newSViv(hashkey); + strkey = SvPV(key, len); + if (pnode != NULL && !hv_exists(XPathContextDATA(ctxt)->pool,strkey,len)) { + value = hv_store(XPathContextDATA(ctxt)->pool,strkey,len, SvREFCNT_inc(pnode),0); + } else { + value = hv_fetch(XPathContextDATA(ctxt)->pool,strkey,len, 0); + } + SvREFCNT_dec(key); + + if (value == NULL) { + return &PL_sv_undef; + } else { + return *value; + } +} + +/* **************************************************************** * Variable Lookup * **************************************************************** */ /* Much of the code is borrowed from Matt Sergeant's XML::LibXSLT */ @@ -370,6 +411,8 @@ sv_derived_from(*pnode,"XML::LibXML::Node")) { xmlXPathNodeSetAdd(ret->nodesetval, (xmlNodePtr)PmmSvNode(*pnode)); + LibXML_XPathContext_pool(ctxt->context, + (int) PmmSvNode(*pnode), *pnode); } else { warn("XPathContext: ignoring non-node member of a nodelist"); } @@ -383,6 +426,8 @@ ret = (xmlXPathObjectPtr)xmlXPathNewNodeSet(NULL); tmp_node = (xmlNodePtr)PmmSvNode(perl_result); xmlXPathNodeSetAdd(ret->nodesetval,tmp_node); + LibXML_XPathContext_pool(ctxt->context, (int) PmmSvNode(perl_result), + perl_result); goto FINISH; } else if (sv_isa(perl_result, "XML::LibXML::Boolean")) { @@ -717,6 +762,7 @@ XPathContextDATA(ctxt)->lock=0; if (XPathContextDATA(ctxt)->pool != NULL) { SvREFCNT_dec((SV *)XPathContextDATA(ctxt)->pool); + XPathContextDATA(ctxt)->pool = NULL; } void |