#include "../config/pathan_config.h" /* * Copyright (c) 2001, DecisionSoft Limited All rights reserved. * Please see LICENSE.TXT for more information. */ #include #include "TotalOrderComparison.hpp" #include #include #include "../utils/DateUtils.hpp" #include #include #include #include #include #include #include #include #include #include #include #include TotalOrderComparison::TotalOrderComparison(const VectorOfDataItems &args, bool greaterThan, XPath2MemoryManager* memMgr) : DataItemOperator(NULL, args, memMgr) { _greaterThan = greaterThan; } Sequence TotalOrderComparison::collapseTreeInternal(DynamicContext* context, int flags) const { Sequence newArgs = getComparisonOperatorArguments(context); const Item* arg1 = newArgs.first(); const Item* arg2 = newArgs.second(); assert(arg1->isAtomicValue() && arg2->isAtomicValue()); const AnyAtomicType* atom1 = (const AnyAtomicType*)arg1; const AnyAtomicType* atom2 = (const AnyAtomicType*)arg2; // take care of Numeric types first if(atom1->isNumericValue()) { if(atom2->isNumericValue()) { if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const Numeric*)atom1)->greaterThan((const Numeric*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const Numeric*)atom1)->lessThan((const Numeric*)atom2, context), context), context->getMemoryManager()); } } else { DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a numeric type to a non numeric type has occurred")); } } switch(atom1->getPrimitiveTypeIndex()) { case AnyAtomicType::DATE: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::DATE) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a date type to a non date type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATDateOrDerived*)atom1)->greaterThan((const ATDateOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATDateOrDerived*)atom1)->lessThan((const ATDateOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::TIME: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::TIME) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a time type to a non time type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATTimeOrDerived*)atom1)->greaterThan((const ATTimeOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATTimeOrDerived*)atom1)->lessThan((const ATTimeOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::DATE_TIME: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::DATE_TIME) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a dateTime type to a non dateTime type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATDateTimeOrDerived*)atom1)->greaterThan((const ATDateTimeOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATDateTimeOrDerived*)atom1)->lessThan((const ATDateTimeOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::DURATION: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::DURATION) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a duration type to a non duration type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATDurationOrDerived*)atom1)->greaterThan((const ATDurationOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATDurationOrDerived*)atom1)->lessThan((const ATDurationOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::G_DAY: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::G_DAY) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a gDay type to a non gDay type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGDayOrDerived*)atom1)->greaterThan((const ATGDayOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGDayOrDerived*)atom1)->lessThan((const ATGDayOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::G_MONTH: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::G_MONTH) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a gMonth type to a non gMonth type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGMonthOrDerived*)atom1)->greaterThan((const ATGMonthOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGMonthOrDerived*)atom1)->lessThan((const ATGMonthOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::G_MONTH_DAY: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::G_MONTH_DAY) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a gMonthDay type to a non gMonthDay type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGMonthDayOrDerived*)atom1)->greaterThan((const ATGMonthDayOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGMonthDayOrDerived*)atom1)->lessThan((const ATGMonthDayOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::G_YEAR: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::G_YEAR) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a GYear type to a non GYear type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGYearOrDerived*)atom1)->greaterThan((const ATGYearOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGYearOrDerived*)atom1)->lessThan((const ATGYearOrDerived*)atom2, context), context), context->getMemoryManager()); } } case AnyAtomicType::G_YEAR_MONTH: { if(atom2->getPrimitiveTypeIndex() != AnyAtomicType::G_YEAR_MONTH) DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("An attempt to compare a (const ATGYearMonthOrDerived*)atom type to a non gYearMonth type has occurred")); if (_greaterThan) { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGYearMonthOrDerived*)atom1)->greaterThan((const ATGYearMonthOrDerived*)atom2, context), context), context->getMemoryManager()); } else { return Sequence(DatatypeFactory::POD2AT::createBoolean(context->getMemoryManager(), ((const ATGYearMonthOrDerived*)atom1)->lessThan((const ATGYearMonthOrDerived*)atom2, context), context), context->getMemoryManager()); } } default: DSLthrow(XPath2ErrorException,X("TotalOrderComparison::collapseTreeInternal"), X("Total ordering is not defined for the provided arguments")); }// switch DSLthrow(XPath2ErrorException, X("TotalOrderComparison::collapseTreeInternal"), X("Total ordering is not defined for the provided arguments")); }