Qt 4.8
qabstractduration.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QStringList>
43 
44 #include "qbuiltintypes_p.h"
45 #include "qpatternistlocale_p.h"
46 #include "qvalidationerror_p.h"
47 
48 #include "qabstractduration_p.h"
49 
51 
52 using namespace QPatternist;
53 
54 AbstractDuration::AbstractDuration(const bool isPos) : m_isPositive(isPos)
55 {
56 }
57 
58 #define error(msg) return ValidationError::createError(msg);
59 #define getCapt(sym) ((captTable.sym == -1) ? QString() : capts.at(captTable.sym))
60 
62  const QString &lexical,
63  bool *isPositive,
71 {
72  /* We don't directly write into the arguments(eg @p years) but uses these
73  * because the arguments are intended for normalized values, and therefore
74  * can cause overflows. */
75  MonthCountProperty monthCount = 0;
76  MinuteCountProperty minCount = 0;
77  HourCountProperty hourCount = 0;
78  SecondCountProperty secCount = 0;
79 
80  Q_ASSERT(isPositive);
81  QRegExp myExp(captTable.regExp); /* Copy, in order to stay thread safe. */
82 
83  if(!myExp.exactMatch(lexical))
84  {
85  error(QString());
86  }
87 
88  const QStringList capts(myExp.capturedTexts());
89 
90 
91  if(days)
92  {
93  if(getCapt(tDelimiter).isEmpty())
94  {
95  if((years && getCapt(year).isEmpty() && getCapt(month).isEmpty() && getCapt(day).isEmpty())
96  ||
97  (!years && getCapt(day).isEmpty()))
98  {
99  error(QtXmlPatterns::tr("At least one component must be present."));
100  }
101  }
102  else if(getCapt(hour).isEmpty() &&
103  getCapt(minutes).isEmpty() &&
104  getCapt(seconds).isEmpty() &&
105  getCapt(mseconds).isEmpty())
106  {
107  error(QtXmlPatterns::tr("At least one time component must appear "
108  "after the %1-delimiter.")
109  .arg(formatKeyword("T")));
110  }
111  }
112  else if(getCapt(year).isEmpty() && getCapt(month).isEmpty()) /* This checks xs:yearMonthDuration. */
113  {
114  error(QtXmlPatterns::tr("At least one component must be present."));
115  }
116 
117  /* If we got no '-', we are positive. */
118  *isPositive = capts.at(1).isEmpty();
119 
120  if(days)
121  {
122  Q_ASSERT(hours);
123  Q_ASSERT(minutes);
124  Q_ASSERT(seconds);
125  Q_ASSERT(mseconds);
126 
127  *days = getCapt(day).toInt();
128  hourCount = getCapt(hour).toInt();
129  minCount = getCapt(minutes).toInt();
130  secCount = getCapt(seconds).toInt();
131 
132  const QString msecondsStr(getCapt(mseconds));
133  if(!msecondsStr.isEmpty())
134  *mseconds = msecondsStr.leftJustified(3, QLatin1Char('0')).toInt();
135  else
136  *mseconds = msecondsStr.toInt();
137 
138  if(secCount > 59)
139  {
140  minCount += secCount / 60;
141  *seconds = secCount % 60;
142  }
143  else
144  *seconds = secCount;
145 
146  if(minCount > 59)
147  {
148  hourCount += minCount / 60;
149  *minutes = minCount % 60;
150  }
151  else
152  *minutes = minCount;
153 
154  if(hourCount > 23)
155  {
156  *days += hourCount / 24;
157  *hours = hourCount % 24;
158  }
159  else
160  *hours = hourCount;
161  }
162 
163  if(!years)
164  return AtomicValue::Ptr();
165 
166  /* We're supposed to handle years/months. */
167  Q_ASSERT(months);
168 
169  *years = getCapt(year).toInt();
170  monthCount = getCapt(month).toInt();
171 
172  if(monthCount > 11)
173  {
174  *years += monthCount / 12;
175  *months = monthCount % 12;
176  }
177  else
178  *months = monthCount;
179 
180  return AtomicValue::Ptr();
181 }
182 #undef error
183 #undef getCapt
184 
186 {
187  if(years() == other.years()
188  && months() == other.months()
189  && days() == other.days()
190  && hours() == other.hours()
191  && minutes() == other.minutes()
192  && seconds() == other.seconds()
193  && mseconds() == other.mseconds())
194  {
195  if(isPositive() == other.isPositive())
196  return true;
197  else if(years() == 0
198  && months() == 0
199  && days() == 0
200  && hours() == 0
201  && minutes() == 0
202  && seconds () == 0
203  && mseconds() == 0)
204  {
205  return true; /* Signedness doesn't matter if all are zero. */
206  }
207  }
208 
209  return false;
210 }
211 
213 {
214  QString retval;
215  retval.append(QLatin1Char('.'));
216  int div = 100;
217  MSecondProperty msecs = mseconds;
218 
219  while(msecs > 0)
220  {
221  int d = msecs / div;
222  retval.append(QLatin1Char(d + '0'));
223  msecs = msecs % div;
224  div = div / 10;
225  }
226 
227  return retval;
228 }
229 
231 {
232  return m_isPositive;
233 }
234 
double d
Definition: qnumeric_p.h:62
qint32 DayCountProperty
QExplicitlySharedDataPointer< AtomicValue > Ptr
Definition: qitem_p.h:127
virtual SecondProperty seconds() const =0
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Base class for classes implementing durations.
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
QString formatKeyword(const QString &keyword)
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition: qstring.cpp:6090
qint32 MinuteCountProperty
virtual MinuteProperty minutes() const =0
#define error(msg)
QString leftJustified(int width, QChar fill=QLatin1Char(' '), bool trunc=false) const Q_REQUIRED_RESULT
Returns a string of size width that contains this string padded by the fill character.
Definition: qstring.cpp:5318
qint32 MonthCountProperty
qint8 MinuteProperty
qint32 SecondProperty
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define getCapt(sym)
virtual MonthProperty months() const =0
qint8 MonthProperty
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool isEmpty(const char *str)
virtual DayCountProperty days() const =0
QStringList capturedTexts() const
Returns a list of the captured text strings.
Definition: qregexp.cpp:4267
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
The namespace for the internal API of QtXmlPatterns.
virtual HourProperty hours() const =0
virtual YearProperty years() const =0
qint8 HourProperty
qint32 YearProperty
QString & append(QChar c)
Definition: qstring.cpp:1777
Contains functions used for formatting arguments, such as keywords and paths, in translated strings...
bool operator==(const AbstractDuration &other) const
bool exactMatch(const QString &str) const
Returns true if str is matched exactly by this regular expression; otherwise returns false...
Definition: qregexp.cpp:4094
static AtomicValue::Ptr create(const CaptureTable &captTable, const QString &lexical, bool *isPositive, YearProperty *years, MonthProperty *months, DayCountProperty *days, HourProperty *hours, MinuteProperty *minutes, SecondProperty *seconds, MSecondProperty *mseconds)
qint16 MSecondProperty
qint32 HourCountProperty
Acts as a mapping table for AbstractDuration::create() and describes where certain fields in a QRegEx...
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
qint32 SecondCountProperty
virtual MSecondProperty mseconds() const =0
static QString serializeMSeconds(const MSecondProperty mseconds)