Sequence FunctionRegexGroup::createSequence(DynamicContext *context, int flags) const { XPath2MemoryManager *mm = context->getMemoryManager(); const RegexGroupStore *store = context->getRegexGroupStore(); if(store == 0) return Sequence(context->getItemFactory()->createString(XMLUni::fgZeroLenString, context), mm); Numeric::Ptr indexItem = getParamNumber(1, context)->next(context); if(indexItem->isNegative()) return Sequence(context->getItemFactory()->createString(XMLUni::fgZeroLenString, context), mm); const XMLCh *indexStr = indexItem->asString(context); int index = 0; while(*indexStr != 0) { if(*indexStr >= '0' && *indexStr <= '9') { index *= 10; index += *indexStr - '0'; } ++indexStr; } const XMLCh *result = store->getGroup(index); if(result == 0) result = XMLUni::fgZeroLenString; return Sequence(context->getItemFactory()->createString(result, context), mm); }
/** Returns a Numeric object which is the quotient of this and other */ Numeric::Ptr ATFloatOrDerivedImpl::divide(const Numeric::Ptr &other, const DynamicContext* context) const { if(other->getPrimitiveTypeIndex() == AnyAtomicType::DECIMAL) { // if other is a decimal, promote it to xs:float return this->divide((const Numeric::Ptr )other->castAs(this->getPrimitiveTypeIndex(), context), context); } else if (other->getPrimitiveTypeIndex() == AnyAtomicType::DOUBLE) { // if other is a double, promote this to xs:double return ((const Numeric::Ptr )this->castAs(other->getPrimitiveTypeIndex(), context))->divide(other, context); } else if (other->getPrimitiveTypeIndex() == AnyAtomicType::FLOAT) { // same primitive type, can make comparison ATFloatOrDerivedImpl* otherImpl = (ATFloatOrDerivedImpl*)(const Numeric*)other; if(otherImpl->_state == NaN) return notANumber(context); switch (_state) { case NaN: return notANumber(context); case INF: { switch(otherImpl->_state) { case NaN: return notANumber(context); // case taken care of above case NEG_NUM: case NUM: return other->isPositive() ? infinity(context) : negInfinity(context); // INF / NUM = +/-INF case INF: return notANumber(context); // INF / INF = NaN case NEG_INF: return notANumber(context); // INF / (-INF) = NaN default: assert(false); return 0; // should never get here } // switch }// case case NEG_INF: { switch(otherImpl->_state) { case NaN: return notANumber(context); //case taken care of above case NEG_NUM: case NUM: return other->isPositive() ? negInfinity(context) : infinity(context); // -INF / NUM = -INF case INF: return notANumber(context); // -INF / INF = NaN case NEG_INF: return notANumber(context); // -INF / (-INF) = NaN default: assert(false); return 0; // should never get here } // switch } // case case NEG_NUM: case NUM: { switch(otherImpl->_state) { case NaN: return notANumber(context); // case taken care of above case INF: { // NUM / INF = +/-0 if(this->isNegative()) { return negZero(context); } else { return newFloat(0, context); } }// case case NEG_INF: { // NUM / -INF = +/-0 if(this->isPositive()) { return negZero(context); } else { return newFloat(0, context); } }// case case NEG_NUM: case NUM: { if(other->isZero()) { if(this->isZero()) return notANumber(context); if((this->isNegative() && other->isPositive()) || (this->isPositive() && other->isNegative())) { return negInfinity(context); // NUM / (-0) or (-NUM) / 0 = -INF } else { return infinity(context); // NUM / 0 or (-NUM) / (-0) = INF } } else if(this->isZero()) { if((this->isNegative() && other->isPositive()) || (this->isPositive() && other->isNegative())) { return negZero(context); // 0 / (-NUM) or (-0) / NUM = -0 } else { return newFloat(0, context); // 0 / NUM or (-0) / (-NUM) = 0 } } return newFloat(_float / otherImpl->_float, context); }// case default: assert(false); return 0; // should never get here }// switch }// case default: assert(false); return 0; // should never get here }// switch } else { assert(false); // should never get here, numeric types are xs:decimal, xs:float, xs:integer and xs:double return 0; } }