Item::Ptr PromoteAnyURIResult::next(DynamicContext *context) { Item::Ptr item = parent_->next(context); if(item.notNull()) { assert(item->isAtomicValue()); const AnyAtomicType *atomic = (const AnyAtomicType *)item.get(); // 4. For each item of type xs:anyURI in the atomic sequence that can be promoted to the expected atomic // type using URI promotion as described in B.1 Type Promotion, the promotion is done. if(atomic->getPrimitiveTypeIndex() == AnyAtomicType::ANY_URI) { try { item = atomic->castAs(AnyAtomicType::STRING, context); } catch (XPath2TypeCastException &e) { XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"), X("AnyURI type promotion failed (for promotable type)")); } catch (const XMLException& e) { XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"), X("AnyURI type promotion failed (for promotable type)")); } } } else { parent_ = 0; } return item; }
Item::Ptr PromoteNumericResult::next(DynamicContext *context) { Item::Ptr item = parent_->next(context); if(item.notNull()) { assert(item->isAtomicValue()); const AnyAtomicType *atomic = (const AnyAtomicType *)item.get(); // 3. For each numeric item in the atomic sequence that can be promoted to the expected atomic type using // the promotion rules in B.1 Type Promotion, the promotion is done. if(atomic->isNumericValue()) { try { const Numeric::Ptr promotedType = ((const Numeric*)atomic)-> promoteTypeIfApplicable(typeIndex_, context); if(promotedType.notNull()) { item = promotedType; } } catch (XPath2TypeCastException &e) { XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"), X("Numeric type promotion failed (for promotable type)")); } catch (const XMLException& e) { XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"), X("Numeric type promotion failed (for promotable type)")); } } } else { parent_ = 0; } return item; }
Item::Ptr PromoteUntypedResult::next(DynamicContext *context) { Item::Ptr item = parent_->next(context); if(item.notNull()) { assert(item->isAtomicValue()); const AnyAtomicType *atomic = (const AnyAtomicType *)item.get(); // 2. Each item in the atomic sequence that is of type xdt:untypedAtomic is cast to the expected atomic // type. For built-in functions where the expected type is specified as numeric, arguments of type // xdt:untypedAtomic are cast to xs:double. if(atomic->getPrimitiveTypeIndex() == AnyAtomicType::UNTYPED_ATOMIC) { try { if(isPrimitive_) { item = atomic->castAs(typeIndex_, 0, 0, context); } else { item = atomic->castAs(typeIndex_, uri_, name_, context); } } catch(XPath2TypeCastException &e) { if(e.getXQueryLine() == 0) e.setXQueryPosition(this); throw; } } } else { parent_ = 0; } return item; }
Numeric::Ptr NumericFunction::getNumericParam(unsigned int number, DynamicContext *context, int flags) const { Result arg = XQFunction::getParamNumber(number, context, flags); Item::Ptr item = arg->next(context); if(item.isNull()) { return 0; } else if(item->isAtomicValue() && ((const AnyAtomicType *)item.get())->isNumericValue()) { return (const Numeric *)item.get(); } else { XQThrow(FunctionException,X("NumericFunction::getParamNumber"), X("Non-numeric argument in numeric function [err:XPTY0004]")); } }
bool SequenceType::ItemType::matches(const Item::Ptr &toBeTested, DynamicContext* context) const { if(toBeTested->isNode()) return matches((const Node::Ptr)toBeTested, context); switch(m_nTestType) { case TEST_ELEMENT: case TEST_ATTRIBUTE: case TEST_SCHEMA_ELEMENT: case TEST_SCHEMA_ATTRIBUTE: case TEST_NODE: case TEST_PI: case TEST_COMMENT: case TEST_TEXT: case TEST_DOCUMENT: case TEST_SCHEMA_DOCUMENT: { return false; } case TEST_ANYTHING: { return true; } case TEST_ATOMIC_TYPE: { if(!toBeTested->isAtomicValue()) return false; return matchesNameType(toBeTested, context); } case TEST_FUNCTION: { if(!toBeTested->isFunction()) return false; if(returnType_ == 0) return true; FunctionRef *func = (FunctionRef*)toBeTested.get(); if(func->getNumArgs() != argTypes_->size()) return false; return true; } } return true; }
bool SequenceType::ItemType::matchesNameType(const Item::Ptr &toBeTested, const DynamicContext* context) const { // Check name constraint if(m_pName) { if(toBeTested->isNode()) { ATQNameOrDerived::Ptr name = ((const Node*)(const Item*)toBeTested)->dmNodeName(context); if(name.isNull()) return false; // Match node name if(!(XPath2Utils::equals(m_pName->getName(), ((const ATQNameOrDerived*)name.get())->getName()))) return false; // Match node uri if(!(XPath2Utils::equals(m_NameURI, ((const ATQNameOrDerived*)name.get())->getURI()))) return false; } else return false; } //A named atomic type matches a value if the dynamic type of the //value is the same as the named atomic type or is derived from the //named atomic type by restriction. For example, the ItemType //xs:decimal matches the value 12.34 (a decimal literal); it also //matches a value whose dynamic type is shoesize, if shoesize is an //atomic type derived from xs:decimal. if(m_pType) { if(toBeTested->isAtomicValue()) { return ((AnyAtomicType*)toBeTested.get())->isInstanceOfType(m_TypeURI, m_pType->getName(), context); } else if (toBeTested->isNode()) { return ((Node*)toBeTested.get())->hasInstanceOfType(m_TypeURI, m_pType->getName(), context); } return false; } return true; }
/*static*/ bool Equals::equals(const Item::Ptr &arg1, const Item::Ptr &arg2, Collation* collation, DynamicContext* context, const LocationInfo *info) { assert(arg1->isAtomicValue() && arg2->isAtomicValue()); return equals((const AnyAtomicType::Ptr)arg1, (const AnyAtomicType::Ptr)arg2, collation, context, info); }