#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 #include #include #include #include #include #include #include const XMLCh FunctionSum::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_s, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_u, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_m, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:sum($arg as xdt:anyAtomicType*) as xdt:anyAtomicType * fn:sum($arg as xdt:anyAtomicType*, $zero as xdt:anyAtomicType?) as xdt:anyAtomicType? **/ FunctionSum::FunctionSum(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : AggregateFunction(name,1, 2, "anyAtomicType*,anyAtomicType?", args, memMgr) { } Sequence FunctionSum::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence sequence(memMgr); try { sequence = validateSequence(getParamNumber(1,context,DataItem::UNORDERED), context); } catch (IllegalArgumentException &e) { DSLthrow(IllegalArgumentException, X("FunctionSum::collapseTreeInternal"), X("Invalid argument to fn:sum() function")); } if(sequence.isEmpty()) if(getNumArgs() == 1) return Sequence(DatatypeFactory::POD2AT::createDouble(memMgr, 0.0, context), memMgr); else return getParamNumber(2,context); if(sequence.getLength()==1 && isNumericNaN(sequence.first())) return sequence; // check for types that don't support addition const AnyAtomicType* atom = (const AnyAtomicType*)sequence.first(); if (!atom->isNumericValue() && !context->isTypeOrDerivedFromType(atom->getTypeURI(), atom->getTypeName(), FunctionConstructor::XMLChXPath2DatatypesURI, ATDurationOrDerived::fgDT_DAYTIMEDURATION) && !context->isTypeOrDerivedFromType(atom->getTypeURI(), atom->getTypeName(), FunctionConstructor::XMLChXPath2DatatypesURI, ATDurationOrDerived::fgDT_YEARMONTHDURATION)) DSLthrow(IllegalArgumentException, X("FunctionSum::collapseTreeInternal"), X("Invalid argument to fn:sum() function")); Sequence::iterator i = sequence.begin(); Sequence sum(*i, memMgr); ++i; for(; i != sequence.end(); ++i) { VectorOfDataItems sumArgs = VectorOfDataItems(PathanAllocator(memMgr)); DataItemSequence seq1(Sequence(*i, memMgr), memMgr); sumArgs.push_back(&seq1); DataItemSequence seq2(sum, memMgr); sumArgs.push_back(&seq2); Plus plus(sumArgs, memMgr); try { sum = plus.collapseTree(context); } catch (IllegalArgumentException &e) { DSLthrow(IllegalArgumentException, X("FunctionSum::collapseTreeInternal"), X("Invalid argument to fn:sum() function")); } } return sum; }