diff options
Diffstat (limited to 'src/xmlpatterns/data/qabstractduration.cpp')
-rw-r--r-- | src/xmlpatterns/data/qabstractduration.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/xmlpatterns/data/qabstractduration.cpp b/src/xmlpatterns/data/qabstractduration.cpp new file mode 100644 index 0000000..4f34ff3 --- /dev/null +++ b/src/xmlpatterns/data/qabstractduration.cpp @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QStringList> + +#include "qbuiltintypes_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +#include "qabstractduration_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AbstractDuration::AbstractDuration(const bool isPos) : m_isPositive(isPos) +{ +} + +#define error(msg) return ValidationError::createError(msg); +#define getCapt(sym) ((captTable.sym == -1) ? QString() : capts.at(captTable.sym)) + +AtomicValue::Ptr AbstractDuration::create(const CaptureTable &captTable, + const QString &lexical, + bool *isPositive, + YearProperty *years, + MonthProperty *months, + DayCountProperty *days, + HourProperty *hours, + MinuteProperty *minutes, + SecondProperty *seconds, + MSecondProperty *mseconds) +{ + /* We don't directly write into the arguments(eg @p years) but uses these + * because the arguments are intended for normalized values, and therefore + * can cause overflows. */ + MonthCountProperty monthCount = 0; + MinuteCountProperty minCount = 0; + HourCountProperty hourCount = 0; + SecondCountProperty secCount = 0; + + Q_ASSERT(isPositive); + QRegExp myExp(captTable.regExp); /* Copy, in order to stay thread safe. */ + + if(!myExp.exactMatch(lexical)) + { + error(QString()); + } + + const QStringList capts(myExp.capturedTexts()); + + + if(days) + { + if(getCapt(tDelimiter).isEmpty()) + { + if((years && getCapt(year).isEmpty() && getCapt(month).isEmpty() && getCapt(day).isEmpty()) + || + (!years && getCapt(day).isEmpty())) + { + error(QtXmlPatterns::tr("At least one component must be present.")); + } + } + else if(getCapt(hour).isEmpty() && + getCapt(minutes).isEmpty() && + getCapt(seconds).isEmpty() && + getCapt(mseconds).isEmpty()) + { + error(QtXmlPatterns::tr("At least one time component must appear " + "after the %1-delimiter.") + .arg(formatKeyword("T"))); + } + } + else if(getCapt(year).isEmpty() && getCapt(month).isEmpty()) /* This checks xs:yearMonthDuration. */ + { + error(QtXmlPatterns::tr("At least one component must be present.")); + } + + /* If we got no '-', we are positive. */ + *isPositive = capts.at(1).isEmpty(); + + if(days) + { + Q_ASSERT(hours); + Q_ASSERT(minutes); + Q_ASSERT(seconds); + Q_ASSERT(mseconds); + + *days = getCapt(day).toInt(); + hourCount = getCapt(hour).toInt(); + minCount = getCapt(minutes).toInt(); + secCount = getCapt(seconds).toInt(); + + const QString msecondsStr(getCapt(mseconds)); + if(!msecondsStr.isEmpty()) + *mseconds = msecondsStr.leftJustified(3, QLatin1Char('0')).toInt(); + else + *mseconds = msecondsStr.toInt(); + + if(secCount > 59) + { + minCount += secCount / 60; + *seconds = secCount % 60; + } + else + *seconds = secCount; + + if(minCount > 59) + { + hourCount += minCount / 60; + *minutes = minCount % 60; + } + else + *minutes = minCount; + + if(hourCount > 23) + { + *days += hourCount / 24; + *hours = hourCount % 24; + } + else + *hours = hourCount; + } + + if(!years) + return AtomicValue::Ptr(); + + /* We're supposed to handle years/months. */ + Q_ASSERT(months); + + *years = getCapt(year).toInt(); + monthCount = getCapt(month).toInt(); + + if(monthCount > 11) + { + *years += monthCount / 12; + *months = monthCount % 12; + } + else + *months = monthCount; + + return AtomicValue::Ptr(); +} +#undef error +#undef getCapt + +bool AbstractDuration::operator==(const AbstractDuration &other) const +{ + if(years() == other.years() + && months() == other.months() + && days() == other.days() + && hours() == other.hours() + && minutes() == other.minutes() + && seconds() == other.seconds() + && mseconds() == other.mseconds()) + { + if(isPositive() == other.isPositive()) + return true; + else if(years() == 0 + && months() == 0 + && days() == 0 + && hours() == 0 + && minutes() == 0 + && seconds () == 0 + && mseconds() == 0) + { + return true; /* Signedness doesn't matter if all are zero. */ + } + } + + return false; +} + +QString AbstractDuration::serializeMSeconds(const MSecondProperty mseconds) +{ + QString retval; + retval.append(QLatin1Char('.')); + int div = 100; + MSecondProperty msecs = mseconds; + + while(msecs > 0) + { + int d = msecs / div; + retval.append(QLatin1Char(d + '0')); + msecs = msecs % div; + div = div / 10; + } + + return retval; +} + +bool AbstractDuration::isPositive() const +{ + return m_isPositive; +} + +QT_END_NAMESPACE |