--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/xmldomandxpath/src/xmlenginedom/xmlengxpathconfiguration.cpp Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,300 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// XPath configuraion functions
+//
+
+#include "xmlengdomdefs.h"
+#include <xml/dom/xmlengxpathconfiguration.h>
+#include "xmlengxpathevaluationcontext_impl.h"
+#include "libxml2_globals_private.h"
+#include <xml/dom/xmlengxpatherrors.h>
+#include <xml/utils/xmlengmem.h>
+#include <xml/utils/xmlengxestrings.h>
+
+const TInt KHashTableSize = 32;
+
+// -----------------------------------------------------------------------------------------------------
+// Common callback for all extension functions
+//
+// Prototyped by:
+// typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
+//
+// Non-natively implemented XPath extension function cannot be registered in libxml2 XPath module
+// directly without using libxml2 XPath API.Thus, native implementation is impossible
+// when libxml2's APIs are hidden.
+//
+// That is why this callback is used: it is a front-end for function calls.
+// Function pointers are registered in a separate storage (xmlXPathIntermediaryExtensionFunctionsHash)
+// and are dynamically discovered during function call by function name and namespace uri.
+// -----------------------------------------------------------------------------------------------------
+//
+void XmlEngineXpathCommonExtensionCallback(xmlXPathParserContextPtr ctxt, int nargs)
+ {
+ // Select function to call
+ const xmlChar* KFunc = ctxt->context->function;
+ const xmlChar* KFuncNs = ctxt->context->functionURI;
+
+ void* funcPtr = xmlHashLookup2(
+ xmlXPathIntermediaryExtensionFunctionsHash,
+ KFunc,
+ KFuncNs);
+ if (!funcPtr)
+ {
+ XP_ERROR(XPATH_UNKNOWN_FUNC_ERROR);
+ }
+ MXmlEngXPathExtensionFunction* extFunc = reinterpret_cast<MXmlEngXPathExtensionFunction*>(funcPtr);
+ // Check arity
+ TInt maxArity = extFunc->MaxArity();
+ if (nargs < ((TInt)extFunc->MinArity()) ||
+ (maxArity >= 0 && nargs > maxArity))
+ {
+ XP_ERROR(XPATH_INVALID_ARITY);
+ }
+ // Wrap arguments
+ TXmlEngXPathEvaluationContextImpl context(ctxt, nargs);
+ if (!context.Initialize())
+ {
+ SET_OOM_FLAG;
+ XP_ERROR(XPATH_MEMORY_ERROR);
+ }
+ // Call function
+ MXmlEngXPathExtensionFunction::TXmlEngEvaluationStatus status = extFunc->Evaluate(&context);
+ RXmlEngXPathResult res = context.Result();
+ if (status != MXmlEngXPathExtensionFunction::ESucceeded)
+ {
+ xmlXPathFreeObject(INTERNAL_XPATHOBJPTR(res));
+ XP_ERROR(XPATH_XE_EXTENSION_FUNC_ERROR);
+ }
+ // Remove arguments from the evaluation stack
+
+ for (TInt i = 0; i < nargs; i++)
+ {
+ xmlXPathFreeObject(valuePop(ctxt));
+ }
+
+ // Push the result to the stack
+ valuePush(ctxt, INTERNAL_XPATHOBJPTR(res)); // Note: no need to check OOM flag -- later...
+
+ }
+
+// -----------------------------------------------------------------------------------------------------
+// Default constructor
+// -----------------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngExtensionFunctionDescriptor::TXmlEngExtensionFunctionDescriptor()
+ {
+ iFunc = NULL;
+ iName = NULL;
+ iNamespaceUri = NULL;
+ iReserved = 0;
+ }
+
+// -----------------------------------------------------------------------------------------------------
+// Switches On or Off support of XForms extensions by XML Engine:
+// - instance() function
+//
+// @param aEnable ETrue/EFalse to Enable/Disable additional functions
+//
+// @note
+// Currently, XForms extensions are always ON and this method does nothing.
+// -----------------------------------------------------------------------------------------------------
+//
+EXPORT_C void XmlEngXPathConfiguration::Unused_Func1(TBool /*aEnable*/)
+ {
+ }
+
+// -----------------------------------------------------------------------------------------------------
+// Disables support of any previously registered extension functions
+// and switches to support of only XPath Function Library.
+// -----------------------------------------------------------------------------------------------------
+//
+EXPORT_C void XmlEngXPathConfiguration::ResetExtensionFunctionsL()
+ {
+ // Set the hash tables free:
+ // xmlXPathIntermediaryExtensionFunctionsHash and
+ // xmlXPathDefaultFunctionsHash
+ //
+
+ xmlHashTablePtr& fExtHash = xmlXPathIntermediaryExtensionFunctionsHash;
+ xmlHashFree(fExtHash, NULL);
+ fExtHash = NULL;
+ //
+ xmlHashTablePtr& fHash = xmlXPathDefaultFunctionsHash;
+ xmlHashFree(fHash, NULL);
+ fHash = NULL;
+
+ // Fill the hash table with standard functions
+ //
+ // This reinitializes hash tables of XPath functions
+ xmlXPathContextPtr ctxt = xmlXPathNewContext(NULL);
+ OOM_IF_NULL(ctxt);
+ xmlXPathFreeContext(ctxt);
+ }
+
+EXPORT_C TBool XmlEngXPathConfiguration::IsFunctionSupportedL(
+ const TDesC8& aFunc,
+ const TDesC8& aNsUri )
+ {
+ if(!xmlXPathDefaultFunctionsHash)
+ {
+ return FALSE;
+ }
+ // If the function hashes are not initialized -- we should do it!
+
+
+
+
+
+
+
+ xmlChar* func = xmlCharFromDesC8L(aFunc);
+ CleanupStack::PushL(func);
+ xmlChar* ns = NULL;
+ if(aNsUri.Length())
+ ns = xmlCharFromDesC8L(aNsUri);
+ void* test = xmlHashLookup2(
+ xmlXPathDefaultFunctionsHash,
+ func,
+ ns);
+ TBool res = (NULL != test);
+ delete ns;
+ CleanupStack::PopAndDestroy(func);
+ return res;
+ }
+
+EXPORT_C void XmlEngXPathConfiguration::AddExtensionFunctionL(const TXmlEngExtensionFunctionDescriptor& aFuncDes )
+ {
+ xmlHashTablePtr fHash = xmlXPathIntermediaryExtensionFunctionsHash;
+ // store new function to XPath Extensions storage
+ if (!fHash)
+ {
+
+
+ xmlXPathIntermediaryExtensionFunctionsHash = fHash = xmlHashCreate(KHashTableSize);
+ OOM_IF_NULL(fHash);
+ }
+
+
+
+ // Note: it is not critical, since redefinitions of core XPath function won't be found
+ TInt res = xmlHashUpdateEntry2(
+ fHash,
+ (const xmlChar*)aFuncDes.iName,
+ (const xmlChar*)aFuncDes.iNamespaceUri,
+ aFuncDes.iFunc,
+ NULL);
+ if (res == -1)
+ {
+ TEST_OOM_FLAG;
+ User::Leave(KXmlEngErrXPathResult);
+ }
+ // Note: for now it is fixed that once defined, an extension is available in all
+ // evaluations of XPath in this thread.
+ xmlXPathDefineExtensionFunctionsGlobally = 1;
+ // register common callback in XPath engine with new function's name
+ if (!xmlXPathDefaultFunctionsHash)
+ {
+ // It was not initialized yet
+ // This is temporal solution to force initialization
+ xmlXPathContextPtr tmpCtxt = xmlXPathNewContext(NULL);
+ OOM_IF_NULL(tmpCtxt);
+ xmlXPathFreeContext(tmpCtxt);
+
+ }
+
+ if ( !xmlXPathDefaultFunctionsHash )
+ {
+ User::Leave(KXmlEngErrWrongUseOfAPI);
+ }
+ res = xmlHashUpdateEntry2(
+ xmlXPathDefaultFunctionsHash,
+ (const xmlChar*)aFuncDes.iName,
+ (const xmlChar*)aFuncDes.iNamespaceUri,
+ (void*)XmlEngineXpathCommonExtensionCallback,
+ NULL);
+
+ if (res == -1)
+ {
+ TEST_OOM_FLAG;
+ User::Leave(KXmlEngErrXPathResult);
+ }
+ // Now, XmlEngineXpathCommonExtensionCallback is called for registered function.
+ // XmlEngineXpathCommonExtensionCallback performs lookup in
+ // xmlXPathIntermediaryExtensionFunctionsHash for a function pointer by function name
+ // wraps XPath evaluation context (arguments) and calls Evaluate() method of
+ // registered function
+ }
+
+EXPORT_C void XmlEngXPathConfiguration::AddExtensionFunctionVectorL (const RArray<TXmlEngExtensionFunctionDescriptor>& aFuncVector, TUint aSize)
+ {
+ for (TUint i = 0; i < aSize; i++)
+ {
+ AddExtensionFunctionL(aFuncVector[i]);
+ }
+ }
+
+EXPORT_C void XmlEngXPathConfiguration::AddNativeExtensionFunctionL(const TXmlEngExtensionFunctionDescriptor& aNativeFuncDes )
+ {
+ if (!xmlXPathDefaultFunctionsHash)
+ {
+ // It was not initialized yet
+ // This is temporal solution to force initialization
+ xmlXPathContextPtr tmpCtxt = xmlXPathNewContext(NULL);
+ OOM_IF_NULL(tmpCtxt);
+ xmlXPathFreeContext(tmpCtxt);
+ }
+
+ if ( !xmlXPathDefaultFunctionsHash )
+ {
+ User::Leave(KXmlEngErrWrongUseOfAPI);
+ }
+
+ TInt res = xmlHashUpdateEntry2(
+ xmlXPathDefaultFunctionsHash,
+ (const xmlChar*)aNativeFuncDes.iName,
+ (const xmlChar*)aNativeFuncDes.iNamespaceUri,
+ aNativeFuncDes.iFunc,
+ NULL);
+
+ if (res == -1)
+ {
+ TEST_OOM_FLAG;
+ User::Leave(KXmlEngErrXPathResult);
+ }
+ }
+
+EXPORT_C void XmlEngXPathConfiguration::AddNativeExtensionFunctionVectorL(const RArray<TXmlEngExtensionFunctionDescriptor>& aNativeFuncVector, TUint aSize)
+ {
+ for (TUint i = 0; i < aSize; i++)
+ {
+ AddNativeExtensionFunctionL(aNativeFuncVector[i]);
+ }
+ }
+
+EXPORT_C void XmlEngXPathConfiguration::RemoveExtensionFunction(const TXmlEngExtensionFunctionDescriptor& aFuncDes )
+ {
+ xmlHashRemoveEntry2(
+ xmlXPathDefaultFunctionsHash,
+ (const xmlChar*)aFuncDes.iName,
+ (const xmlChar*)aFuncDes.iNamespaceUri,
+ NULL /* deallocator function */);
+ }
+
+EXPORT_C void XmlEngXPathConfiguration::RemoveExtensionFunctionVector(const RArray<TXmlEngExtensionFunctionDescriptor>& aFuncVector, TUint aSize )
+ {
+ for (TUint i = 0; i < aSize; i++)
+ {
+ RemoveExtensionFunction(aFuncVector[i]);
+ }
+ }