#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 const XMLCh FunctionSubsequence::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_s, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_u, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_b, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_s, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_q, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_u, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_n, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_c, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:subsequence($sourceSeq as item()*, $startingLoc as xs:double) as item()* * fn:subsequence($sourceSeq as item()*, $startingLoc as xs:double, $length as xs:double) as item()* **/ FunctionSubsequence::FunctionSubsequence(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : ConstantFoldingFunction(name,2, 3, "item()*, double, double", args, memMgr) { } Sequence FunctionSubsequence::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence sourceSeq = getParamNumber(1, context); if(sourceSeq.isEmpty()) return Sequence(memMgr); Sequence startingLoc=getParamNumber(2,context); const ATDecimalOrDerived* zero = DatatypeFactory::POD2AT::createInteger(memMgr, 0, context); const ATDecimalOrDerived* one = DatatypeFactory::POD2AT::createInteger(memMgr, 1, context); // The first character of a string is located at position 1 (not position 0). const Numeric* index = (const ATDoubleOrDerived*)startingLoc.first(); index = index->subtract(one, context); if(index->lessThan(zero, context)) { index = zero; } const Numeric* subSeqLength; const ATDecimalOrDerived* seqLength = DatatypeFactory::POD2AT::createDecimal(memMgr, (long)sourceSeq.getLength(), context); if(getNumArgs()>2) { Sequence length=getParamNumber(3,context); subSeqLength = (const ATDoubleOrDerived*)length.first(); } else { subSeqLength = seqLength->subtract(index, context); } const ATDecimalOrDerived* startIndex = (const ATDecimalOrDerived*)index->round(context)->castAs( XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgURI_SCHEMAFORSCHEMA, XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgDT_DECIMAL, context); const ATDecimalOrDerived* endIndex = (const ATDecimalOrDerived*)index->add(subSeqLength, context)->round(context)->castAs( XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgURI_SCHEMAFORSCHEMA, XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgDT_DECIMAL, context); // More specifically, returns the characters in $sourceSeq whose position $p obeys: // xf:round($startingLoc) <= $p < xf:round($startingLoc + $length) if(endIndex->greaterThan(seqLength, context)) { endIndex = seqLength; } if(startIndex->greaterThan(seqLength->subtract(one, context), context) || startIndex->greaterThan(endIndex->subtract(one, context), context) ) { return Sequence(memMgr); } Sequence resultSeq = Sequence(sourceSeq.getLength(), memMgr); for(const ATDecimalOrDerived* i = startIndex; i->lessThan(endIndex, context); i = (const ATDecimalOrDerived*)i->add(one, context)) { resultSeq.addItem(sourceSeq.item(i)); } return resultSeq; }