#include "../../config/pathan_config.h" /* * Copyright (c) 2001, DecisionSoft Limited All rights reserved. * Please see LICENSE.TXT for more information. */ #include "ATGMonthOrDerivedImpl.hpp" #include #include "../../exceptions/XPath2TypeCastException.hpp" #include #include #include #include #include // defines X() and XMLCh* #include #include #include #include "../../utils/DateUtils.hpp" #include #include #include ATGMonthOrDerivedImpl:: ATGMonthOrDerivedImpl(const XMLCh* typeURI, const XMLCh* typeName, const XMLCh* value, XPath2MemoryManager* memMgr, const DynamicContext* context): ATGMonthOrDerived(memMgr), _typeName(typeName), _typeURI(typeURI) { setGMonth(value, context); } /* Get the name of the primitive type (basic type) of this type * (ie "decimal" for xs:decimal) */ const XMLCh* ATGMonthOrDerivedImpl::getPrimitiveTypeName() const { return this->getPrimitiveName(); } const XMLCh* ATGMonthOrDerivedImpl::getPrimitiveName() { return XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgDT_MONTH; } /* Get the name of this type (ie "integer" for xs:integer) */ const XMLCh* ATGMonthOrDerivedImpl::getTypeName() const { return _typeName; } /* Get the namespace URI for this type */ const XMLCh* ATGMonthOrDerivedImpl::getTypeURI() const { return _typeURI; } AnyAtomicType::AtomicObjectType ATGMonthOrDerivedImpl::getTypeIndex() { return AnyAtomicType::G_MONTH; } /* returns the XMLCh* (canonical) representation of this type */ const XMLCh* ATGMonthOrDerivedImpl::asString(const DynamicContext* context) const { /* --MM-- format*/ XERCES_CPP_NAMESPACE_QUALIFIER XMLBuffer buffer(1023, context->getMemoryManager()); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); buffer.append(_gMonth->asString(2, context)); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); if ( _hasTimezone == true ) { buffer.append(_timezone->asString(context)); } return context->getMemoryManager()->getPooledString(buffer.getRawBuffer()); } /* returns true if the two objects * false otherwise */ bool ATGMonthOrDerivedImpl::equals(const AnyAtomicType* target, const DynamicContext* context) const { if(this->getPrimitiveTypeIndex() != target->getPrimitiveTypeIndex()) { DSLthrow(IllegalArgumentException,X("ATGMonthOrDerivedImpl::equals"), X("Equality operator for given types not supported")); } ATGMonthOrDerivedImpl* targetGMonth = (ATGMonthOrDerivedImpl*)target; if ( _hasTimezone == targetGMonth->_hasTimezone) { return ((!_hasTimezone || _timezone->equals(targetGMonth->_timezone)) && this->_gMonth->equals(targetGMonth->_gMonth, context) ); } else { return false; } } /** Returns true if this is greater than other. Ignores timezones. * Returns false otherwise. */ bool ATGMonthOrDerivedImpl::greaterThan(const ATGMonthOrDerived* other, const DynamicContext* context) const { const ATGMonthOrDerivedImpl* thisImpl = this; const ATGMonthOrDerivedImpl* otherImpl = (const ATGMonthOrDerivedImpl*)other; if (!thisImpl->hasTimezone()) thisImpl = (const ATGMonthOrDerivedImpl*)thisImpl->setTimezone(new (context->getMemoryManager()) Timezone(context->getImplicitTimezone(), context), context); if (!otherImpl->hasTimezone()) otherImpl = (const ATGMonthOrDerivedImpl*)otherImpl->setTimezone(new (context->getMemoryManager()) Timezone(context->getImplicitTimezone(), context), context); return (thisImpl->_gMonth->greaterThan(otherImpl->_gMonth, context) || (thisImpl->_gMonth->equals(otherImpl->_gMonth, context) && thisImpl->_timezone->greaterThan(otherImpl->_timezone))); } /** Returns true if this is less than other. Ignores timezones. * Returns false otherwise. */ bool ATGMonthOrDerivedImpl::lessThan(const ATGMonthOrDerived* other, const DynamicContext* context) const { const ATGMonthOrDerivedImpl* thisImpl = this; const ATGMonthOrDerivedImpl* otherImpl = (const ATGMonthOrDerivedImpl*)other; if (!thisImpl->hasTimezone()) thisImpl = (const ATGMonthOrDerivedImpl*)thisImpl->setTimezone(new (context->getMemoryManager()) Timezone(context->getImplicitTimezone(), context), context); if (!otherImpl->hasTimezone()) otherImpl = (const ATGMonthOrDerivedImpl*)otherImpl->setTimezone(new (context->getMemoryManager()) Timezone(context->getImplicitTimezone(), context), context); return (thisImpl->_gMonth->lessThan(otherImpl->_gMonth, context) || (thisImpl->_gMonth->equals(otherImpl->_gMonth, context) && thisImpl->_timezone->lessThan(otherImpl->_timezone))); } /** Returns true if a timezone is defined for this. False otherwise.*/ bool ATGMonthOrDerivedImpl::hasTimezone() const { return _hasTimezone; } /** Sets the timezone to the given timezone.*/ const ATGMonthOrDerived* ATGMonthOrDerivedImpl::setTimezone(const Timezone* timezone, const DynamicContext* context) const { bool hasTimezone = timezone == 0 ? false : true; XERCES_CPP_NAMESPACE_QUALIFIER XMLBuffer buffer(1023, context->getMemoryManager()); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); buffer.append(_gMonth->asString(2, context)); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); buffer.append(XERCES_CPP_NAMESPACE_QUALIFIER chDash); if (hasTimezone) buffer.append(timezone->asString(context)); const XMLCh* gMonth = context->getMemoryManager()->getPooledString(buffer.getRawBuffer()); return DatatypeFactory::STR2AT::createGMonthOrDerived(context->getMemoryManager(), this->getTypeURI(), this->getTypeName(), gMonth, context); } AnyAtomicType::AtomicObjectType ATGMonthOrDerivedImpl::getPrimitiveTypeIndex() const { return this->getTypeIndex(); } /** Releases the memory used by this Item */ void ATGMonthOrDerivedImpl::release() const { //TODO needs to check for ownership before releasing! getMemoryManager()->deallocate((void*)this); } /* parse the gMonth */ void ATGMonthOrDerivedImpl::setGMonth(const XMLCh* const value, const DynamicContext* context) { unsigned int length = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(value); if(value == NULL) { DSLthrow(XPath2TypeCastException,X("XSGMonthImpl::setGMonth"), X("Invalid representation of gMonth")); } // State variables etc. bool gotDigit = false; unsigned int pos = 0; long int tmpnum = 0; unsigned int numDigit = 0; // defaulting values MAPM MM = 0; _hasTimezone = false; bool zonepos = false; int zonehh = 0; int zonemm = 0; int state = 0 ; // 0 = year / 1 = month / 2 = day / 3 = hour // 4 = minutes / 5 = sec / 6 = timezonehour / 7 = timezonemin XMLCh tmpChar; bool wrongformat = false; if ( length < 6 || value[0] != L'-' || value[1] != L'-' || value[4] != L'-' || value[5] != L'-' ) { wrongformat = true; }else{ pos = 2; state = 1; } while ( ! wrongformat && pos < length) { tmpChar = value[pos]; pos++; switch(tmpChar) { case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034: case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: { tmpnum *= 10; tmpnum += static_cast(tmpChar - 0x0030); gotDigit = true; numDigit ++; break; } case L'-' : { if ( gotDigit && state == 1 && numDigit == 2) { MM = tmpnum; tmpnum = 0; gotDigit = false; state = 2; numDigit = 0; } else if ( !gotDigit && state == 2 ) { state = 5; } else if ( !gotDigit && state == 5 ) { state = 6; gotDigit = false; _hasTimezone = true; zonepos = false; } else { wrongformat = true; } break; } case L'+' : { if ( gotDigit && state == 1 && numDigit == 2) { MM = tmpnum; tmpnum = 0; gotDigit = false; state = 2; numDigit = 0; } else if ( !gotDigit && state == 2 ) { state = 5; } else if ( !gotDigit && state == 5 ) { state = 6; gotDigit = false; _hasTimezone = true; zonepos = true; } else { wrongformat = true; } break; } case L':' : { if (gotDigit && state == 6 && numDigit == 2) { zonehh = tmpnum; tmpnum = 0; gotDigit = false; state ++; numDigit = 0; }else { wrongformat = true; } break; } case L'Z' : { if ( !gotDigit && state == 5) { state = 8; // final state _hasTimezone = true; gotDigit = false; tmpnum = 0; numDigit = 0; } else { wrongformat = true; } break; } default: wrongformat = true; } } if (gotDigit) { if ( gotDigit && state == 7 && numDigit == 2) { zonemm = tmpnum; }else { wrongformat = true; } } // check time format if ( MM > 12 || zonehh > 24 || zonemm > 60 ) { wrongformat = true; } if ( wrongformat) { DSLthrow(XPath2TypeCastException,X("ATGMonthOrDerivedImpl::setGMonth"), X("Invalid representation of gMonth")); } // Create Timezone object, clean this up in future if (zonepos == false) { zonehh *= -1; zonemm *= -1; } _gMonth = DatatypeFactory::POD2AT::createNonNegativeInteger(context->getMemoryManager(), MM, context); _timezone = new Timezone(zonehh, zonemm); }