#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 const XMLCh FunctionAvg::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_a, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_v, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_g, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:avg($arg as xdt:anyAtomicType*) as xdt:anyAtomicType? **/ FunctionAvg::FunctionAvg(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : AggregateFunction(name,1, 1, "anyAtomicType*", args, memMgr) { } Sequence FunctionAvg::collapseTreeInternal(DynamicContext* context, int flags) const { Sequence sequence(context->getMemoryManager()); try { sequence = validateSequence(getParamNumber(1,context), context); } catch (IllegalArgumentException &e) { DSLthrow(IllegalArgumentException, X("FunctionAvg::collapseTreeInternal()"), X("Invalid argument to fn:avg() function")); } if(sequence.isEmpty()) return Sequence(context->getMemoryManager()); // check for types that don't support addition and division by an integer 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("FunctionAvg::collapseTreeInternal()"), X("Invalid argument to fn:avg() function")); FunctionSum fnSum(_args, context->getMemoryManager()); Sequence sum(context->getMemoryManager()); try { sum = fnSum.collapseTree(context); } catch (IllegalArgumentException &e) { DSLthrow(IllegalArgumentException, X("FunctionAvg::collapseTreeInternal()"), X("Invalid argument to fn:avg() function")); } Sequence count(DatatypeFactory::POD2AT::createDecimal(context->getMemoryManager(), (long)sequence.getLength(), context), context->getMemoryManager()); VectorOfDataItems divArgs = VectorOfDataItems(PathanAllocator(context->getMemoryManager())); DataItemSequence seq1(sum, context->getMemoryManager()); divArgs.push_back(&seq1); DataItemSequence seq2(count, context->getMemoryManager()); divArgs.push_back(&seq2); Divide divide(divArgs, context->getMemoryManager()); Sequence avg(context->getMemoryManager()); try { avg = divide.collapseTree(context); } catch (XPath2ErrorException &e) { DSLthrow(IllegalArgumentException, X("FunctionAvg::collapseTreeInternal()"), X("Invalid argument to fn:avg() function")); } return avg; }