/*################################################################################### # # Embperl - Copyright (c) 1997-2008 Gerald Richter / ecos gmbh www.ecos.de # Embperl - Copyright (c) 2008-2015 Gerald Richter # Embperl - Copyright (c) 2015-2023 actevy.io # # You may distribute under the terms of either the GNU General Public # License or the Artistic License, as specified in the Perl README file. # For use with Apache httpd and mod_perl, see also Apache copyright. # # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. # ###################################################################################*/ /* undef some defines that clashs with c++ includes */ #undef bool #undef HAS_BOOL extern "C" { #include "../ep.h" #include "../epmacro.h" } #undef assert #undef vform #include <Include/PlatformDefinitions.hpp> #if defined(XALAN_OLD_STREAM_HEADERS) #include <iostream.h> #include <strstream.h> #include <fstream.h> #else #include <iostream> #include <strstream> #include <fstream> #endif #include <util/PlatformUtils.hpp> #include <XalanTransformer/XalanTransformer.hpp> extern "C" { XalanTransformer * theXalanTransformer; static int bInitDone = 0 ; /*! Provider that reads compiles xalan stylesheet */ typedef struct tProviderXalanXSL { tProvider Provider ; } tProviderXalanXSL ; /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalanXSL_New */ /* */ /*! * \_en * Creates a new xalan stylesheet provider and fills it with data from the hash pParam * The resulting provider is put into the cache structure * * @param r Embperl request record * @param pItem CacheItem which holds the output of the provider * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash of this Providers * stylesheet filename or provider for the * stylesheet * @param pParam All Parameters * @param nParamIndex If pParam is an AV, this parameter gives the index into the Array * @return error code * \endif * * \_de * Erzeugt einen neue Provider für Xalan Stylesheets. Der ein Zeiger * auf den resultierenden Provider wird in die Cachestrutr eingefügt * * @param r Embperl request record * @param pItem CacheItem welches die Ausgabe des Providers * speichert * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash dieses Providers * stylesheet dateiname oder provider für das * stylesheet * @param pParam Parameter insgesamt * @param nParamIndex Wenn pParam ein AV ist, gibt dieser Parameter den Index an * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXSL_New (/*in*/ req * r, /*in*/ tCacheItem * pItem, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pProviderParam, /*in*/ SV * pParam, /*in*/ IV nParamIndex) { int rc ; if ((rc = Provider_NewDependOne (r, sizeof(tProviderXalanXSL), "stylesheet", pItem, pProviderClass, pProviderParam, pParam, nParamIndex)) != ok) return rc ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderFile_AppendKey */ /* */ /*! * \_en * Append it's key to the keystring. If it depends on anything it must * call Cache_AppendKey for any dependency. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash of this Providers * stylesheet filename or provider for the * stylesheet * @param pParam All Parameters * @param nParamIndex If pParam is an AV, this parameter gives the index into the Array * @param pKey Key to which string should be appended * @return error code * \endif * * \_de * Hängt ein eigenen Schlüssel an den Schlüsselstring an. Wenn irgednwelche * Abhänigkeiten bestehen, muß Cache_AppendKey für alle Abhänigkeiten aufgerufen * werden. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash dieses Providers * stylesheet dateiname oder provider für das * stylesheet * @param pParam Parameter insgesamt * @param nParamIndex Wenn pParam ein AV ist, gibt dieser Parameter den Index an * @param pKey Schlüssel zu welchem hinzugefügt wird * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXSL_AppendKey (/*in*/ req * r, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pProviderParam, /*in*/ SV * pParam, /*in*/ IV nParamIndex, /*i/o*/ SV * pKey) { epTHX_ int rc ; if ((rc = Cache_AppendKey (r, pProviderParam, "stylesheet", pParam, nParamIndex, pKey)) != ok) return rc; sv_catpv (pKey, "*xalan-compile-xsl") ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalanXSL_GetContentPtr */ /* */ /*! * \_en * Get the whole content from the provider. * This gets the stylesheet and compiles it * * @param r Embperl request record * @param pProvider The provider record * @param pData Returns the content * @param bUseCache Set if the content should not recomputed * @return error code * \endif * * \_de * Holt den gesamt Inhalt vom Provider. * Die Funktion holt sich das Stylesheet und kompiliert es * * @param r Embperl request record * @param pProvider The provider record * @param pData Liefert den Inhalt * @param bUseCache Gesetzt wenn der Inhalt nicht neu berechnet werden soll * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXSL_GetContentPtr (/*in*/ req * r, /*in*/ tProvider * pProvider, /*in*/ void * * pData, /*in*/ bool bUseCache) { epTHX_ int rc ; char * p ; STRLEN len ; SV * pSource ; const XalanCompiledStylesheet* pCompiledStylesheet = NULL ; tCacheItem * pFileCache = Cache_GetDependency(r, pProvider -> pCache, 0) ; if ((rc = Cache_GetContentSV (r, pFileCache, &pSource, bUseCache)) != ok) return rc ; if (!bUseCache) { // Our input streams... p = SvPV (pSource, len) ; if (p == NULL || len == 0) { strncpy (r -> errdat1, "Xalan XML stylesheet", sizeof (r -> errdat1)) ; return rcMissingInput ; } r -> Component.pCurrPos = NULL ; r -> Component.nSourceline = 1 ; r -> Component.pSourcelinePos = NULL ; r -> Component.pLineNoCurrPos = NULL ; istrstream theXMLStream(p, len); if (theXalanTransformer -> compileStylesheet(&theXMLStream, pCompiledStylesheet)) { Cache_ReleaseContent (r, pFileCache) ; strncpy (r -> errdat1, "XSL compile", sizeof (r -> errdat1)) ; strncpy (r -> errdat2, theXalanTransformer -> getLastError(), sizeof (r -> errdat2) - 2) ; return rcXalanError ; } *pData = (void *)pCompiledStylesheet ; } return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalanXSL_FreeContent */ /* */ /*! * \_en * Free the cached data * * @param r Embperl request record * @param pProvider The provider record * @return error code * \endif * * \_de * Gibt die gecachten Daten frei * * @param r Embperl request record * @param pProvider The provider record * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXSL_FreeContent(/*in*/ req * r, /*in*/ tCacheItem * pItem) { XalanCompiledStylesheet* pCompiledStylesheet = (XalanCompiledStylesheet*)pItem -> pData ; if (pCompiledStylesheet) theXalanTransformer -> destroyStylesheet (pCompiledStylesheet) ; return ok ; } /* ------------------------------------------------------------------------ */ static tProviderClass ProviderClassXalanXSL = { "text/*", &ProviderXalanXSL_New, &ProviderXalanXSL_AppendKey, NULL, NULL, &ProviderXalanXSL_GetContentPtr, NULL, &ProviderXalanXSL_FreeContent, NULL, } ; /*! Provider that reads compiles xalan stylesheet */ typedef struct tProviderXalanXML { tProvider Provider ; } tProviderXalanXML ; /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalanXML_New */ /* */ /*! * \_en * Creates a new xalan xml source provider and fills it with data from the hash pParam * The resulting provider is put into the cache structure * * @param r Embperl request record * @param pItem CacheItem which holds the output of the provider * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash of this Providers * @param pParam All Parameters * @param nParamIndex If pParam is an AV, this parameter gives the index into the Array * @return error code * \endif * * \_de * Erzeugt einen neue Provider für Xalan XML Quellen. Der ein Zeiger * auf den resultierenden Provider wird in die Cachestrutr eingefügt * * @param r Embperl request record * @param pItem CacheItem welches die Ausgabe des Providers * speichert * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash dieses Providers * @param pParam Parameter insgesamt * @param nParamIndex Wenn pParam ein AV ist, gibt dieser Parameter den Index an * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXML_New (/*in*/ req * r, /*in*/ tCacheItem * pItem, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pProviderParam, /*in*/ SV * pParam, /*in*/ IV nParamIndex) { int rc ; if ((rc = Provider_NewDependOne (r, sizeof(tProviderXalanXML), "source", pItem, pProviderClass, pProviderParam, pParam, nParamIndex)) != ok) return rc ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderFile_AppendKey */ /* */ /*! * \_en * Append it's key to the keystring. If it depends on anything it must * call Cache_AppendKey for any dependency. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash of this Providers * @param pParam All Parameters * @param nParamIndex If pParam is an AV, this parameter gives the index into the Array * @param pKey Key to which string should be appended * @return error code * \endif * * \_de * Hängt ein eigenen Schlüssel an den Schlüsselstring an. Wenn irgednwelche * Abhänigkeiten bestehen, muß Cache_AppendKey für alle Abhänigkeiten aufgerufen * werden. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash dieses Providers * @param pParam Parameter insgesamt * @param nParamIndex Wenn pParam ein AV ist, gibt dieser Parameter den Index an * @param pKey Schlüssel zu welchem hinzugefügt wird * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXML_AppendKey (/*in*/ req * r, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pProviderParam, /*in*/ SV * pParam, /*in*/ IV nParamIndex, /*i/o*/ SV * pKey) { epTHX_ int rc ; if ((rc = Cache_AppendKey (r, pProviderParam, "source", pParam, nParamIndex, pKey)) != ok) return rc; sv_catpv (pKey, "*xalan-parse-xml") ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalanXML_GetContentPtr */ /* */ /*! * \_en * Get the whole content from the provider. * This gets the stylesheet and compiles it * * @param r Embperl request record * @param pProvider The provider record * @param pData Returns the content * @param bUseCache Set if the content should not recomputed * @return error code * \endif * * \_de * Holt den gesamt Inhalt vom Provider. * Die Funktion holt sich das Stylesheet und kompiliert es * * @param r Embperl request record * @param pProvider The provider record * @param pData Liefert den Inhalt * @param bUseCache Gesetzt wenn der Inhalt nicht neu berechnet werden soll * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXML_GetContentPtr (/*in*/ req * r, /*in*/ tProvider * pProvider, /*in*/ void * * pData, /*in*/ bool bUseCache) { epTHX_ int rc ; char * p ; STRLEN len ; SV * pSource ; const XalanParsedSource * parsedXML = NULL ; tCacheItem * pFileCache = Cache_GetDependency(r, pProvider -> pCache, 0) ; if ((rc = Cache_GetContentSV (r, pFileCache, &pSource, bUseCache)) != ok) return rc ; if (!bUseCache) { // Our input streams... p = SvPV (pSource, len) ; if (p == NULL || len == 0) { strncpy (r -> errdat1, "Xalan XML source", sizeof (r -> errdat1)) ; return rcMissingInput ; } r -> Component.pCurrPos = NULL ; r -> Component.nSourceline = 1 ; r -> Component.pSourcelinePos = NULL ; r -> Component.pLineNoCurrPos = NULL ; istrstream theXMLStream(p, len); if (theXalanTransformer -> parseSource(&theXMLStream, parsedXML)) { Cache_ReleaseContent (r, pFileCache) ; strncpy (r -> errdat1, "XSL compile", sizeof (r -> errdat1)) ; strncpy (r -> errdat2, theXalanTransformer -> getLastError(), sizeof (r -> errdat2) - 2) ; return rcXalanError ; } *pData = (void *)parsedXML ; } return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalanXML_FreeContent */ /* */ /*! * \_en * Free the cached data * * @param r Embperl request record * @param pProvider The provider record * @return error code * \endif * * \_de * Gibt die gecachten Daten frei * * @param r Embperl request record * @param pProvider The provider record * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalanXML_FreeContent(/*in*/ req * r, /*in*/ tCacheItem * pItem) { const XalanParsedSource * parsedXML = (XalanParsedSource *)pItem -> pData ; if (parsedXML) theXalanTransformer -> destroyParsedSource (parsedXML); return ok ; } /* ------------------------------------------------------------------------ */ static tProviderClass ProviderClassXalanXML = { "text/*", &ProviderXalanXML_New, &ProviderXalanXML_AppendKey, NULL, NULL, &ProviderXalanXML_GetContentPtr, NULL, &ProviderXalanXML_FreeContent, NULL, } ; /* ------------------------------------------------------------------------ */ /* */ /* iowrite */ /* */ /* output callback */ /* */ /* ------------------------------------------------------------------------ */ static long unsigned int iowrite (const char *buffer, long unsigned int len, void *context) { return owrite ((tReq *)context, buffer, len) ; } #if 0 /* ------------------------------------------------------------------------ */ /* */ /* embperl_Xalan_Text2Text */ /* */ /* Do an XSL transformation using LibXSLT. Input and Output is Text. */ /* The stylesheet is directly read from disk */ /* */ /* in pReqParameter Parameter for request */ /* xsltparameter Hash which is passed as parameters to libxslt */ /* xsltstylesheet filename of stylsheet */ /* pSource XML source in memory */ /* */ /* ------------------------------------------------------------------------ */ int embperl_Xalan_Text2Text (/*in*/ tReq * r, /*in*/ HV * pReqParameter, /*in*/ SV * pSource) { epTHX_ int rc ; HE * pEntry ; HV * pParam ; SV * pStylesheetParam ; SV * * ppSV ; char * pKey ; SV * pValue ; STRLEN len ; IV l ; int n ; const char * * pParamArray ; const char * sStylesheet ; char * p ; #if !defined(XALAN_NO_NAMESPACES) using std::istrstream; #endif sStylesheet = GetHashValueStr (aTHX_ pReqParameter, "xsltstylesheet", NULL) ; if (!sStylesheet) { strncpy (r -> errdat1, "XSLT", sizeof (r -> errdat1)) ; strncpy (r -> errdat2, "No stylesheet given", sizeof (r -> errdat2)) ; return 9999 ; } ppSV = hv_fetch (pReqParameter, "xsltparameter", sizeof("xsltparameter") - 1, 0) ; if (ppSV && *ppSV) { if (!SvROK (*ppSV) || SvTYPE ((SV *)(pParam = (HV *)SvRV (*ppSV))) != SVt_PVHV) { strncpy (r -> errdat1, "XSLT", sizeof (r -> errdat1)) ; sprintf (r -> errdat2, "%s", pKey) ; return rcNotHashRef ; } n = hv_iterinit (pParam) ; if (!(pParamArray = (const char * *)_malloc(r, sizeof (const char *) * (n + 1) * 2))) return rcOutOfMemory ; n = 0 ; while ((pEntry = hv_iternext (pParam))) { pKey = hv_iterkey (pEntry, &l) ; pValue = hv_iterval (pParam, pEntry) ; pParamArray[n++] = pKey ; pParamArray[n++] = SvPV (pValue, len) ; } pParamArray[n++] = NULL ; } else { pParamArray = NULL ; } // Our input streams... p = SvPV (pSource, len) ; istrstream theXMLStream(p, len); pStylesheetParam = sv_2mortal (CreateHashRef (r, (char *)"provider", hashtsv, CreateHashRef (r, (char *)"type", hashtstr, (char *)"xalan-compile-xsl", (char *)"stylesheet", hashtsv, CreateHashRef (r, (char *)"provider", hashtsv, CreateHashRef (r, (char *)"type", hashtstr, (char *)"file", (char *)"filename", hashtstr, sStylesheet, NULL), (char *)"cache", hashtint, 0, NULL), NULL), NULL)) ; if (!SvROK (pStylesheetParam) || SvTYPE(SvRV(pStylesheetParam)) != SVt_PVHV) { strncpy (r -> errdat2, "stylesheet", sizeof(r -> errdat2) - 1) ; return rcNotHashRef ; } tCacheItem * pXSLCache ; // does not work !!!!!!!!!!!!!!!!!!!! //if ((rc = Cache_New (r, (HV *)SvRV(pStylesheetParam), &pXSLCache)) != ok) // return rc ; XalanCompiledStylesheet * pCompiledXSL ; bool bUseCache = 0 ; if ((rc = Cache_GetContentPtr (r, pXSLCache, (void * *)&pCompiledXSL, bUseCache)) != ok) return rc ; // Do the transform. const XalanParsedSource * parsedXML = 0; theXalanTransformer -> parseSource(&theXMLStream, parsedXML); int theResult = theXalanTransformer -> transform(*parsedXML, pCompiledXSL, r, iowrite, NULL); Cache_ReleaseContent (r, pXSLCache) ; if(theResult != 0) { strncpy (r -> errdat1, "XSLT", sizeof (r -> errdat1)) ; strncpy (r -> errdat2, theXalanTransformer -> getLastError(), sizeof (r -> errdat2) - 2) ; return rcXalanError ; } // Terminate Xalan. //XalanTransformer::terminate(); // Call the static terminator for Xerces. //XMLPlatformUtils::Terminate(); return(0); } #endif /*! Provider that reads compiles xalan stylesheet */ typedef struct tProviderXalan { tProvider Provider ; SV * pOutputSV ; HV * pParamHV ; } tProviderXalan ; /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalan_New */ /* */ /*! * \_en * Creates a new xalan provider and fills it with data from the hash pParam * The resulting provider is put into the cache structure * * @param r Embperl request record * @param pItem CacheItem which holds the output of the provider * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash of this Providers * stylesheet filename or provider for the * stylesheet * @param pParam All Parameters * @param nParamIndex If pParam is an AV, this parameter gives the index into the Array * @return error code * \endif * * \_de * Erzeugt einen neue Provider für Xalan. Der ein Zeiger * auf den resultierenden Provider wird in die Cachestrutr eingefügt * * @param r Embperl request record * @param pItem CacheItem welches die Ausgabe des Providers * speichert * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash dieses Providers * stylesheet dateiname oder provider für das * stylesheet * @param pParam Parameter insgesamt * @param nParamIndex Wenn pParam ein AV ist, gibt dieser Parameter den Index an * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ int ProviderXalan_New (/*in*/ req * r, /*in*/ tCacheItem * pItem, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pProviderParam, /*in*/ SV * pParam, /*in*/ IV nParamIndex) { int rc ; if ((rc = Provider_NewDependOne (r, sizeof(tProviderXalan), "source", pItem, pProviderClass, pProviderParam, pParam, nParamIndex)) != ok) return rc ; if ((rc = Provider_AddDependOne (r, pItem -> pProvider, "stylesheet", pItem, pProviderClass, pProviderParam, NULL, 0)) != ok) return rc ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderFile_AppendKey */ /* */ /*! * \_en * Append it's key to the keystring. If it depends on anything it must * call Cache_AppendKey for any dependency. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash of this Providers * stylesheet filename or provider for the * stylesheet * @param pParam All Parameters * @param nParamIndex If pParam is an AV, this parameter gives the index into the Array * @param pKey Key to which string should be appended * @return error code * \endif * * \_de * Hängt ein eigenen Schlüssel an den Schlüsselstring an. Wenn irgednwelche * Abhänigkeiten bestehen, muß Cache_AppendKey für alle Abhänigkeiten aufgerufen * werden. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pProviderParam Parameter Hash dieses Providers * stylesheet dateiname oder provider für das * stylesheet * @param pParam Parameter insgesamt * @param nParamIndex Wenn pParam ein AV ist, gibt dieser Parameter den Index an * @param pKey Schlüssel zu welchem hinzugefügt wird * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalan_AppendKey (/*in*/ req * r, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pProviderParam, /*in*/ SV * pParam, /*in*/ IV nParamIndex, /*i/o*/ SV * pKey) { epTHX_ int rc ; if ((rc = Cache_AppendKey (r, pProviderParam, "source", pParam, nParamIndex, pKey)) != ok) return rc; if ((rc = Cache_AppendKey (r, pProviderParam, "stylesheet", NULL, 0, pKey)) != ok) return rc; sv_catpv (pKey, "*xalan") ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderLibXalan_UpdateParam */ /* */ /*! * \_en * Update the parameter of the provider * * @param r Embperl request record * @param pProvider Provider record * @param pParam Parameter Hash * param hash with parameter * @param pKey Key to which string should be appended * @return error code * \endif * * \_de * Aktualisiert die Parameter des Providers * * @param r Embperl request record * @param pProvider Provider record * @param pParam Parameter Hash * param hash mit parametern * @param pKey Schlüssel zu welchem hinzugefügt wird * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalan_UpdateParam(/*in*/ req * r, /*in*/ tProvider * pProvider, /*in*/ HV * pParam) { epTHX_ int rc ; HV * pParamHV ; if ((rc = GetHashValueHREF (r, pParam, "param", &pParamHV)) != ok) { pParamHV = r -> Component.Param.pXsltParam ; } if (((tProviderXalan *)pProvider) -> pParamHV) SvREFCNT_dec (((tProviderXalan *)pProvider) -> pParamHV) ; ((tProviderXalan *)pProvider) -> pParamHV = pParamHV ; if (pParamHV) { SV * pSV = (SV *)((tProviderXalan *)pProvider) -> pParamHV ; #ifdef SOLARIS ATOMIC_INC(SvREFCNT((pSV))) ; #else SvREFCNT_inc((pSV)) ; #endif } return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalan_iowrite */ /* */ /* output callback */ /* */ /* ------------------------------------------------------------------------ */ struct iowrite { tProviderXalan * pProvider ; tReq * pReq ; } ; static long unsigned int ProviderXalan_iowrite (const char *buffer, long unsigned int len, void *context) { tReq * r = ((struct iowrite *)context) -> pReq ; epTHX_ sv_catpvn (((struct iowrite *)context) -> pProvider -> pOutputSV, (char *)buffer, len) ; return len ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalan_GetContentSV */ /* */ /*! * \_en * Get the whole content from the provider. * This gets the stylesheet and compiles it * * @param r Embperl request record * @param pProvider The provider record * @param pData Returns the content * @param bUseCache Set if the content should not recomputed * @return error code * \endif * * \_de * Holt den gesamt Inhalt vom Provider. * Die Funktion holt sich das Stylesheet und kompiliert es * * @param r Embperl request record * @param pProvider The provider record * @param pData Liefert den Inhalt * @param bUseCache Gesetzt wenn der Inhalt nicht neu berechnet werden soll * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalan_GetContentSV (/*in*/ req * r, /*in*/ tProvider * pProvider, /*in*/ SV * * pData, /*in*/ bool bUseCache) { epTHX_ int rc ; XalanParsedSource * parsedXML ; XalanCompiledStylesheet * pCompiledXSL ; HV * pParamHV ; HE * pEntry ; char * pKey ; SV * pValue ; IV l ; STRLEN len ; struct iowrite iowrite ; r -> Component.pCurrPos = NULL ; r -> Component.nSourceline = 1 ; r -> Component.pSourcelinePos = NULL ; r -> Component.pLineNoCurrPos = NULL ; tCacheItem * pSrcCache = Cache_GetDependency(r, pProvider -> pCache, 0) ; tCacheItem * pXSLCache = Cache_GetDependency(r, pProvider -> pCache, 1) ; if ((rc = Cache_GetContentPtr (r, pSrcCache, (void * *)&parsedXML, bUseCache)) != ok) return rc ; if ((rc = Cache_GetContentPtr (r, pXSLCache, (void * *)&pCompiledXSL, bUseCache)) != ok) return rc ; if (!bUseCache) { if (((tProviderXalan *)pProvider) -> pOutputSV) SvREFCNT_dec (((tProviderXalan *)pProvider) -> pOutputSV) ; ((tProviderXalan *)pProvider) -> pOutputSV = newSVpv("",0) ; pParamHV = ((tProviderXalan *)pProvider) -> pParamHV ; if (pParamHV) { hv_iterinit (pParamHV) ; while ((pEntry = hv_iternext (pParamHV))) { pKey = hv_iterkey (pEntry, &l) ; pValue = hv_iterval (pParamHV, pEntry) ; theXalanTransformer -> setStylesheetParam (XalanDOMString(pKey), XalanDOMString(SvPV(pValue, len))) ; } } iowrite.pProvider = (tProviderXalan *)pProvider ; iowrite.pReq = r ; // Do the transform. int theResult = theXalanTransformer -> transform(*parsedXML, pCompiledXSL, &iowrite, ProviderXalan_iowrite, NULL); if(theResult != 0) { strncpy (r -> errdat1, "XSLT", sizeof (r -> errdat1)) ; strncpy (r -> errdat2, theXalanTransformer -> getLastError(), sizeof (r -> errdat2) - 2) ; return rcXalanError ; } *pData = iowrite.pProvider -> pOutputSV ; #ifdef SOLARIS ATOMIC_INC(SvREFCNT((*pData))) ; #else SvREFCNT_inc((*pData)) ; #endif } return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderXalan_FreeContent */ /* */ /*! * \_en * Free the cached data * * @param r Embperl request record * @param pProvider The provider record * @return error code * \endif * * \_de * Gibt die gecachten Daten frei * * @param r Embperl request record * @param pProvider The provider record * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderXalan_FreeContent(/*in*/ req * r, /*in*/ tCacheItem * pItem) { epTHX_ tProviderXalan * pProvider = ((tProviderXalan *)pItem -> pProvider) ; if (pProvider -> pOutputSV) SvREFCNT_dec (pProvider -> pOutputSV) ; pProvider -> pOutputSV = NULL ; /* if (pProvider -> pParamHV) SvREFCNT_dec (pProvider -> pParamHV) ; pProvider -> pParamHV = NULL ; */ return ok ; } /* ------------------------------------------------------------------------ */ static tProviderClass ProviderClassXalan = { "text/*", &ProviderXalan_New, &ProviderXalan_AppendKey, &ProviderXalan_UpdateParam, &ProviderXalan_GetContentSV, NULL, NULL, &ProviderXalan_FreeContent, NULL, } ; /* ------------------------------------------------------------------------ */ int embperl_Xalan_Init () { Cache_AddProviderClass ("xalan-compile-xsl", &ProviderClassXalanXSL) ; Cache_AddProviderClass ("xalan-parse-xml", &ProviderClassXalanXML) ; Cache_AddProviderClass ("xalan", &ProviderClassXalan) ; // Call the static initializer for Xerces. XMLPlatformUtils::Initialize(); // Initialize Xalan. XalanTransformer::initialize(); theXalanTransformer = new XalanTransformer ; return ok ; } } /* extern C */