#include "../config/pathan_config.h" /* * Copyright (c) 2001, DecisionSoft Limited All rights reserved. * Please see LICENSE.TXT for more information. */ #include #include #include #include #include #include #include "../exceptions/XPath2TypeCastException.hpp" #include "../exceptions/InvalidLexicalSpaceException.hpp" #include #include #include #include #include const XMLCh FunctionNumber::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_n, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_u, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_m, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_b, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_r, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:number() as xs:double * fn:number($arg as item()?) as xs:double **/ FunctionNumber::FunctionNumber(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : DataItemFunction(name,0, 1, "item()?", args, memMgr) { } DataItem* FunctionNumber::staticResolution(StaticContext *context, StaticResolutionContext *src) { if(_args.empty()) { src->contextItemUsed(true); } return resolveDataItems(_args, context, src, !_args.empty()); } Sequence FunctionNumber::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); const ATDoubleOrDerived* nan = DatatypeFactory::STR2AT::createDouble(memMgr, Numeric::NaN_string, context); const Node* node = 0; if(getNumArgs() == 1) { Sequence arg=getParamNumber(1,context); //if $srcval is the empty sequence, return NaN if (arg.isEmpty()) { return Sequence(nan, memMgr); } const Item* item = arg.first(); if(item->isNode()) { node = (const Node*)item; } else { const AnyAtomicType* atom = (const AnyAtomicType*)item; try { const ATDoubleOrDerived* result = (const ATDoubleOrDerived*)atom->castAs(XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgURI_SCHEMAFORSCHEMA, XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgDT_DOUBLE, context); return Sequence(result, memMgr); } catch (XPath2TypeCastException &e) { return Sequence(nan, memMgr); } } } else //$srcval is not specified { const Item* item = context->getContextItem(); //if context item is not a node, return NaN if(item==NULL || !item->isNode()) { return Sequence(nan, memMgr); } node = (const Node*)item; } assert(node!=0); try { const ATDoubleOrDerived* num = DatatypeFactory::STR2AT::createDouble(memMgr, node->dmStringValue(context), context); return Sequence(num, memMgr); } catch(InvalidLexicalSpaceException &e) { return Sequence(nan, memMgr); } }