#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 #include #include #include #include #include /*static*/ const XMLCh LessThan::name[]={ XERCES_CPP_NAMESPACE_QUALIFIER chLatin_l, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_t, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; LessThan::LessThan(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : DataItemOperator(name, args, memMgr) { } /*static*/ bool LessThan::less_than(const Item* arg1, const Item* arg2, DynamicContext* context) { const AnyAtomicType* atom1 = (const AnyAtomicType*)arg1; const AnyAtomicType* atom2 = (const AnyAtomicType*)arg2; // take care of Numeric types first if(atom1->isNumericValue()) { if(atom2->isNumericValue()) { return ((const Numeric*)atom1)->lessThan((const Numeric*)atom2, context); } else { DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a numeric type to a non numeric type has occurred")); } } switch(atom1->getPrimitiveTypeIndex()) { case AnyAtomicType::BOOLEAN: { // op:boolean-greater-than(A, B) if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::BOOLEAN) DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a boolean type to a non boolean type has occurred")); return ((const ATBooleanOrDerived*)atom1)->lessThan((const ATBooleanOrDerived*)atom2, context); } case AnyAtomicType::STRING: { // use function compare if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::STRING) DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a string type to a non string type has occurred")); Collation* collation=context->getDefaultCollation(); if(collation==NULL) collation=context->getCollation(CodepointCollation::getCodepointCollationName()); // if the function returns -1, then atom1 is less return collation->compare(arg1->asString(context),arg2->asString(context))<0; } case AnyAtomicType::DATE: { // op:date-greater-than(A, B) if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::DATE) DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a date type to a non date type has occurred")); return ((const ATDateOrDerived*)atom1)->lessThan((const ATDateOrDerived*)atom2, context); } case AnyAtomicType::TIME: { // op:time-greater-than(A, B) if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::TIME) DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a time type to a non time type has occurred")); return ((const ATTimeOrDerived*)atom1)->lessThan((const ATTimeOrDerived*)atom2, context); } case AnyAtomicType::DATE_TIME: { // op:datetime-greater-than(A, B) if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::DATE_TIME) DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a dateTime type to a non dateTime type has occurred")); return ((const ATDateTimeOrDerived*)atom1)->lessThan((const ATDateTimeOrDerived*)atom2, context); } case AnyAtomicType::DURATION: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::DURATION) DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("An attempt to compare a duration type to a non duration type has occurred")); return ((const ATDurationOrDerived*)atom1)->lessThan((const ATDurationOrDerived*)atom2, context); } default: DSLthrow(XPath2ErrorException,X("LessThan::less_than"), X("Unexpected data type in operator 'lt'")); }// switch DSLthrow(FunctionException,X("LessThan::less_than"), X("An equality operator is not defined for the provided arguments")); } Sequence LessThan::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence newArgs = getComparisonOperatorArguments(context); if(newArgs.getLength() < 2) return Sequence(memMgr); const Item* arg1 = newArgs.first(); const Item* arg2 = newArgs.second(); assert(arg1->isAtomicValue() && arg2->isAtomicValue()); bool result=less_than(arg1,arg2,context); return Sequence(DatatypeFactory::POD2AT::createBoolean(memMgr, result, context), memMgr); }