xml/xmldomandxpath/src/xmlenginedom/xmlengxpathconfiguration.cpp
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // XPath configuraion functions
       
    15 //
       
    16 
       
    17 #include "xmlengdomdefs.h"
       
    18 #include <xml/dom/xmlengxpathconfiguration.h>
       
    19 #include "xmlengxpathevaluationcontext_impl.h"
       
    20 #include "libxml2_globals_private.h"
       
    21 #include <xml/dom/xmlengxpatherrors.h>
       
    22 #include <xml/utils/xmlengmem.h>
       
    23 #include <xml/utils/xmlengxestrings.h>
       
    24 
       
    25 const TInt KHashTableSize = 32;
       
    26 
       
    27 // -----------------------------------------------------------------------------------------------------
       
    28 // Common callback for all extension functions
       
    29 //
       
    30 // Prototyped by:
       
    31 // typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
       
    32 //
       
    33 // Non-natively implemented XPath extension function cannot be registered in libxml2 XPath module 
       
    34 // directly without using libxml2 XPath API.Thus, native  implementation is impossible
       
    35 // when libxml2's APIs are hidden.
       
    36 //
       
    37 // That is why this callback is used: it is a front-end for function calls.
       
    38 // Function pointers are registered in a separate storage (xmlXPathIntermediaryExtensionFunctionsHash)
       
    39 // and are dynamically discovered during function call by function name and namespace uri.
       
    40 // -----------------------------------------------------------------------------------------------------
       
    41 //
       
    42 void XmlEngineXpathCommonExtensionCallback(xmlXPathParserContextPtr ctxt, int nargs)
       
    43     {
       
    44     // Select function to call
       
    45     const xmlChar* KFunc = ctxt->context->function;
       
    46     const xmlChar* KFuncNs = ctxt->context->functionURI;
       
    47         
       
    48     void* funcPtr = xmlHashLookup2(
       
    49                         xmlXPathIntermediaryExtensionFunctionsHash,
       
    50                         KFunc,
       
    51                         KFuncNs);
       
    52     if (!funcPtr)
       
    53         {
       
    54         XP_ERROR(XPATH_UNKNOWN_FUNC_ERROR);
       
    55         }
       
    56     MXmlEngXPathExtensionFunction* extFunc = reinterpret_cast<MXmlEngXPathExtensionFunction*>(funcPtr);
       
    57     // Check arity
       
    58     TInt maxArity = extFunc->MaxArity();
       
    59     if (nargs < ((TInt)extFunc->MinArity()) || 
       
    60         (maxArity >= 0  && nargs > maxArity))
       
    61         {
       
    62         XP_ERROR(XPATH_INVALID_ARITY);
       
    63         }
       
    64     // Wrap arguments
       
    65     TXmlEngXPathEvaluationContextImpl context(ctxt, nargs); 
       
    66     if (!context.Initialize())
       
    67         {
       
    68         SET_OOM_FLAG;
       
    69         XP_ERROR(XPATH_MEMORY_ERROR);
       
    70         }
       
    71     // Call function
       
    72     MXmlEngXPathExtensionFunction::TXmlEngEvaluationStatus status = extFunc->Evaluate(&context);
       
    73         RXmlEngXPathResult res = context.Result();
       
    74         if (status != MXmlEngXPathExtensionFunction::ESucceeded)
       
    75             {
       
    76 	        xmlXPathFreeObject(INTERNAL_XPATHOBJPTR(res));
       
    77             XP_ERROR(XPATH_XE_EXTENSION_FUNC_ERROR);
       
    78             }
       
    79         // Remove arguments from the evaluation stack
       
    80         
       
    81         for (TInt i = 0; i < nargs; i++)
       
    82             {
       
    83             xmlXPathFreeObject(valuePop(ctxt));
       
    84             }
       
    85        
       
    86         // Push the result to the stack
       
    87         valuePush(ctxt, INTERNAL_XPATHOBJPTR(res)); // Note: no need to check OOM flag -- later...
       
    88 
       
    89     }
       
    90 
       
    91 // -----------------------------------------------------------------------------------------------------
       
    92 // Default constructor
       
    93 // -----------------------------------------------------------------------------------------------------
       
    94 //
       
    95 EXPORT_C TXmlEngExtensionFunctionDescriptor::TXmlEngExtensionFunctionDescriptor()
       
    96 	{
       
    97 	iFunc = NULL;
       
    98     iName = NULL;
       
    99     iNamespaceUri = NULL;     
       
   100 	iReserved = 0;
       
   101 	}
       
   102 
       
   103 // -----------------------------------------------------------------------------------------------------
       
   104 // Switches On or Off support of XForms extensions by XML Engine:
       
   105 //     - instance() function
       
   106 //
       
   107 // @param aEnable  ETrue/EFalse to Enable/Disable additional functions
       
   108 //
       
   109 // @note
       
   110 //     Currently, XForms extensions are always ON and this method does nothing.
       
   111 // -----------------------------------------------------------------------------------------------------
       
   112 //
       
   113 EXPORT_C void XmlEngXPathConfiguration::Unused_Func1(TBool /*aEnable*/)
       
   114     {
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------------------------------
       
   118 // Disables support of any previously registered extension functions
       
   119 // and switches to support of only XPath Function Library.
       
   120 // -----------------------------------------------------------------------------------------------------
       
   121 //
       
   122 EXPORT_C void XmlEngXPathConfiguration::ResetExtensionFunctionsL()
       
   123     {
       
   124     // Set the hash tables free:   
       
   125     //      xmlXPathIntermediaryExtensionFunctionsHash  and
       
   126     //      xmlXPathDefaultFunctionsHash
       
   127     //
       
   128     
       
   129     xmlHashTablePtr& fExtHash = xmlXPathIntermediaryExtensionFunctionsHash;
       
   130     xmlHashFree(fExtHash, NULL);
       
   131     fExtHash = NULL;
       
   132     //
       
   133     xmlHashTablePtr& fHash = xmlXPathDefaultFunctionsHash;
       
   134     xmlHashFree(fHash, NULL);
       
   135     fHash = NULL;
       
   136 
       
   137     // Fill the hash table with standard functions
       
   138     //
       
   139     // This reinitializes hash tables of XPath functions
       
   140     xmlXPathContextPtr ctxt = xmlXPathNewContext(NULL);
       
   141     OOM_IF_NULL(ctxt);
       
   142     xmlXPathFreeContext(ctxt);
       
   143     }
       
   144      
       
   145 EXPORT_C TBool XmlEngXPathConfiguration::IsFunctionSupportedL(
       
   146     const TDesC8& aFunc, 
       
   147     const TDesC8& aNsUri )
       
   148     {
       
   149     if(!xmlXPathDefaultFunctionsHash)
       
   150         {
       
   151         return FALSE;
       
   152         }
       
   153 	// If the function hashes are not initialized -- we should do it!
       
   154     
       
   155     
       
   156     
       
   157     
       
   158 
       
   159 	
       
   160     
       
   161     xmlChar* func = xmlCharFromDesC8L(aFunc);
       
   162     CleanupStack::PushL(func);
       
   163     xmlChar* ns = NULL;
       
   164     if(aNsUri.Length())
       
   165         ns =  xmlCharFromDesC8L(aNsUri);
       
   166     void* test = xmlHashLookup2(
       
   167                                 xmlXPathDefaultFunctionsHash, 
       
   168                                 func, 
       
   169                                 ns);
       
   170     TBool res = (NULL != test);
       
   171     delete ns;
       
   172     CleanupStack::PopAndDestroy(func);
       
   173     return res;
       
   174     }
       
   175 
       
   176 EXPORT_C void XmlEngXPathConfiguration::AddExtensionFunctionL(const TXmlEngExtensionFunctionDescriptor& aFuncDes )
       
   177     {
       
   178     xmlHashTablePtr fHash = xmlXPathIntermediaryExtensionFunctionsHash;
       
   179     // store new function to XPath Extensions storage
       
   180     if (!fHash)
       
   181         {
       
   182         
       
   183         
       
   184         xmlXPathIntermediaryExtensionFunctionsHash = fHash = xmlHashCreate(KHashTableSize);
       
   185         OOM_IF_NULL(fHash);
       
   186         }
       
   187     
       
   188     
       
   189     
       
   190     //     Note: it is not critical, since redefinitions of core XPath function won't be found
       
   191     TInt res = xmlHashUpdateEntry2(
       
   192                     fHash, 
       
   193                     (const xmlChar*)aFuncDes.iName, 
       
   194                     (const xmlChar*)aFuncDes.iNamespaceUri, 
       
   195                     aFuncDes.iFunc, 
       
   196                     NULL);
       
   197     if (res == -1)
       
   198         {
       
   199         TEST_OOM_FLAG;
       
   200 		User::Leave(KXmlEngErrXPathResult);	
       
   201         }
       
   202     // Note: for now it is fixed that once defined, an extension is available in all
       
   203     //       evaluations of XPath in this thread.
       
   204     xmlXPathDefineExtensionFunctionsGlobally = 1;
       
   205     // register common callback in XPath engine with new function's name
       
   206     if (!xmlXPathDefaultFunctionsHash)
       
   207         {
       
   208         // It was not initialized yet
       
   209         // This is temporal solution to force initialization
       
   210         xmlXPathContextPtr tmpCtxt = xmlXPathNewContext(NULL);
       
   211         OOM_IF_NULL(tmpCtxt);
       
   212         xmlXPathFreeContext(tmpCtxt);
       
   213         
       
   214         }
       
   215 
       
   216     if ( !xmlXPathDefaultFunctionsHash )
       
   217     	{
       
   218     	User::Leave(KXmlEngErrWrongUseOfAPI);
       
   219     	}
       
   220     res = xmlHashUpdateEntry2(
       
   221         xmlXPathDefaultFunctionsHash, 
       
   222         (const xmlChar*)aFuncDes.iName,
       
   223         (const xmlChar*)aFuncDes.iNamespaceUri,
       
   224         (void*)XmlEngineXpathCommonExtensionCallback,
       
   225         NULL);
       
   226 
       
   227     if (res == -1)
       
   228         {
       
   229         TEST_OOM_FLAG;
       
   230 		User::Leave(KXmlEngErrXPathResult); 
       
   231         }
       
   232     // Now, XmlEngineXpathCommonExtensionCallback is called for registered function.
       
   233     // XmlEngineXpathCommonExtensionCallback performs lookup in 
       
   234     // xmlXPathIntermediaryExtensionFunctionsHash for a function pointer by function name
       
   235     // wraps XPath evaluation context (arguments) and calls Evaluate() method of
       
   236     // registered function
       
   237     }
       
   238      
       
   239 EXPORT_C void XmlEngXPathConfiguration::AddExtensionFunctionVectorL (const RArray<TXmlEngExtensionFunctionDescriptor>& aFuncVector, TUint aSize)
       
   240     {
       
   241     for (TUint i = 0; i < aSize; i++)
       
   242         {
       
   243         AddExtensionFunctionL(aFuncVector[i]);
       
   244         }
       
   245     }
       
   246 
       
   247 EXPORT_C void XmlEngXPathConfiguration::AddNativeExtensionFunctionL(const TXmlEngExtensionFunctionDescriptor& aNativeFuncDes )
       
   248     {
       
   249     if (!xmlXPathDefaultFunctionsHash)
       
   250         {
       
   251         // It was not initialized yet
       
   252         // This is temporal solution to force initialization
       
   253         xmlXPathContextPtr tmpCtxt = xmlXPathNewContext(NULL);
       
   254         OOM_IF_NULL(tmpCtxt);
       
   255         xmlXPathFreeContext(tmpCtxt);
       
   256         }
       
   257     
       
   258     if ( !xmlXPathDefaultFunctionsHash )
       
   259     	{
       
   260     	User::Leave(KXmlEngErrWrongUseOfAPI);
       
   261     	}
       
   262         
       
   263     TInt res = xmlHashUpdateEntry2(
       
   264         xmlXPathDefaultFunctionsHash, 
       
   265         (const xmlChar*)aNativeFuncDes.iName,
       
   266         (const xmlChar*)aNativeFuncDes.iNamespaceUri,
       
   267         aNativeFuncDes.iFunc,
       
   268         NULL);
       
   269 
       
   270     if (res == -1)
       
   271         {
       
   272         TEST_OOM_FLAG;
       
   273 		User::Leave(KXmlEngErrXPathResult); 
       
   274         }     
       
   275     }
       
   276      
       
   277 EXPORT_C void XmlEngXPathConfiguration::AddNativeExtensionFunctionVectorL(const RArray<TXmlEngExtensionFunctionDescriptor>& aNativeFuncVector, TUint aSize)
       
   278     {
       
   279     for (TUint i = 0; i < aSize; i++)
       
   280         {
       
   281         AddNativeExtensionFunctionL(aNativeFuncVector[i]);
       
   282         }     
       
   283     }
       
   284 
       
   285 EXPORT_C void XmlEngXPathConfiguration::RemoveExtensionFunction(const TXmlEngExtensionFunctionDescriptor& aFuncDes )
       
   286     {
       
   287     xmlHashRemoveEntry2(
       
   288         xmlXPathDefaultFunctionsHash, 
       
   289         (const xmlChar*)aFuncDes.iName,
       
   290         (const xmlChar*)aFuncDes.iNamespaceUri,
       
   291         NULL /* deallocator function */);
       
   292     }
       
   293      
       
   294 EXPORT_C void XmlEngXPathConfiguration::RemoveExtensionFunctionVector(const RArray<TXmlEngExtensionFunctionDescriptor>& aFuncVector, TUint aSize )
       
   295     {
       
   296     for (TUint i = 0; i < aSize; i++)
       
   297         {
       
   298         RemoveExtensionFunction(aFuncVector[i]);
       
   299         }      
       
   300     }