1 /*
2 Actiona
3 Copyright (C) 2005 Jonathan Mercier-Ganady
4
5 Actiona is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Actiona is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 Contact : jmgr@jmgr.info
19 */
20
21 #include "version.h"
22
23 #if (QT_VERSION < 0x050600)
24 #include <QRegExp>
25 #include <QStringList>
26 #include <QDataStream>
27
28 namespace Tools
29 {
Version()30 Version::Version()
31 : d(new VersionData())
32 {
33 }
34
Version(const QString & str)35 Version::Version(const QString &str)
36 : d(new VersionData())
37 {
38 setFromString(str);
39 }
40
Version(const Version & other)41 Version::Version(const Version &other)
42 : d(other.d)
43 {
44 }
45
Version(int major,int minor,int micro,int nano)46 Version::Version(int major, int minor, int micro, int nano)
47 : d(new VersionData())
48 {
49 setMajor(major);
50 setMinor(minor);
51 setMicro(micro);
52 setNano(nano);
53
54 setNumberCount(4);
55 }
56
Version(int major,int minor,int micro)57 Version::Version(int major, int minor, int micro)
58 : d(new VersionData())
59 {
60 setMajor(major);
61 setMinor(minor);
62 setMicro(micro);
63
64 setNumberCount(3);
65 }
66
Version(int major,int minor)67 Version::Version(int major, int minor)
68 : d(new VersionData())
69 {
70 setMajor(major);
71 setMinor(minor);
72
73 setNumberCount(2);
74 }
75
Version(int major)76 Version::Version(int major)
77 : d(new VersionData())
78 {
79 setMajor(major);
80
81 setNumberCount(1);
82 }
83
toString() const84 QString Version::toString() const
85 {
86 switch(numberCount())
87 {
88 case 1:
89 return QString("%1").arg(d->major);
90 case 2:
91 return QString("%1.%2").arg(d->major).arg(d->minor);
92 case 3:
93 return QString("%1.%2.%3").arg(d->major).arg(d->minor).arg(d->micro);
94 case 4:
95 return QString("%1.%2.%3.%4").arg(d->major).arg(d->minor).arg(d->micro).arg(d->nano);
96 default:
97 return QString();
98 }
99 }
100
setFromString(const QString & str)101 bool Version::setFromString(const QString &str)
102 {
103 int newNumberCount = str.count('.') + 1;
104 if(newNumberCount < 1 || newNumberCount > 4)
105 {
106 d->major = d->minor = d->micro = d->nano = 0;
107 return false;
108 }
109
110 setNumberCount(newNumberCount);
111
112 QRegExp regExp(regExpForNumberCount(newNumberCount));
113
114 if(!regExp.exactMatch(str))
115 {
116 d->major = d->minor = d->micro = d->nano = 0;
117 return false;
118 }
119
120 const QStringList versionNumbers = regExp.capturedTexts();
121
122 if((versionNumbers.count() - 1) != newNumberCount)
123 {
124 d->major = d->minor = d->micro = d->nano = 0;
125 return false;
126 }
127
128 d->major = versionNumbers.at(1).toInt();
129 if(newNumberCount >= 2)
130 d->minor = versionNumbers.at(2).toInt();
131 if(newNumberCount >= 3)
132 d->micro = versionNumbers.at(3).toInt();
133 if(newNumberCount >= 4)
134 d->nano = versionNumbers.at(4).toInt();
135
136 return true;
137 }
138
swap(Version & other)139 void Version::swap(Version &other)
140 {
141 d.swap(other.d);
142 }
143
isValidVersion(const QString & str)144 bool Version::isValidVersion(const QString &str)
145 {
146 int newNumberCount = str.count('.') + 1;
147 if(newNumberCount < 1 || newNumberCount > 4)
148 return false;
149
150 QRegExp regExp(regExpForNumberCount(newNumberCount));
151
152 return regExp.exactMatch(str);
153 }
154
operator =(Version other)155 Version &Version::operator= (Version other)
156 {
157 swap(other);
158
159 return *this;
160 }
161
operator ==(const Version & other) const162 bool Version::operator== (const Version &other) const
163 {
164 if(d->numberCount != other.d->numberCount)
165 return false;
166
167 switch(numberCount())
168 {
169 case 1:
170 return (d->major == other.d->major);
171 case 2:
172 return (d->major == other.d->major && d->minor == other.d->minor);
173 case 3:
174 return (d->major == other.d->major && d->minor == other.d->minor && d->micro == other.d->micro);
175 case 4:
176 return (d->major == other.d->major && d->minor == other.d->minor && d->micro == other.d->micro && d->nano == other.d->nano);
177 default:
178 return false;
179 }
180 }
181
operator !=(const Version & other) const182 bool Version::operator!= (const Version &other) const
183 {
184 return !((*this) == other);
185 }
186
operator <(const Version & other) const187 bool Version::operator< (const Version &other) const
188 {
189 if(d->numberCount != other.d->numberCount)
190 return false;
191
192 switch(numberCount())
193 {
194 case 1:
195 if(d->major < other.d->major)
196 return true;
197
198 return false;
199 case 2:
200 if(d->major < other.d->major)
201 return true;
202 if(d->major > other.d->major)
203 return false;
204 if(d->minor < other.d->minor)
205 return true;
206 if(d->minor > other.d->minor)
207 return false;
208
209 return false;
210 case 3:
211 if(d->major < other.d->major)
212 return true;
213 if(d->major > other.d->major)
214 return false;
215 if(d->minor < other.d->minor)
216 return true;
217 if(d->minor > other.d->minor)
218 return false;
219 if(d->micro < other.d->micro)
220 return true;
221 if(d->micro > other.d->micro)
222 return false;
223
224 return false;
225 case 4:
226 if(d->major < other.d->major)
227 return true;
228 if(d->major > other.d->major)
229 return false;
230 if(d->minor < other.d->minor)
231 return true;
232 if(d->minor > other.d->minor)
233 return false;
234 if(d->micro < other.d->micro)
235 return true;
236 if(d->micro > other.d->micro)
237 return false;
238 if(d->nano < other.d->nano)
239 return true;
240 if(d->nano > other.d->nano)
241 return false;
242
243 return false;
244 default:
245 return false;
246 }
247 }
248
operator >(const Version & other) const249 bool Version::operator> (const Version &other) const
250 {
251 if(d->numberCount != other.d->numberCount)
252 return false;
253
254 switch(numberCount())
255 {
256 case 1:
257 if(d->major > other.d->major)
258 return true;
259
260 return false;
261 case 2:
262 if(d->major > other.d->major)
263 return true;
264 if(d->major < other.d->major)
265 return false;
266 if(d->minor > other.d->minor)
267 return true;
268 if(d->minor < other.d->minor)
269 return false;
270
271 return false;
272 case 3:
273 if(d->major > other.d->major)
274 return true;
275 if(d->major < other.d->major)
276 return false;
277 if(d->minor > other.d->minor)
278 return true;
279 if(d->minor < other.d->minor)
280 return false;
281 if(d->micro > other.d->micro)
282 return true;
283 if(d->micro < other.d->micro)
284 return false;
285
286 return false;
287 case 4:
288 if(d->major > other.d->major)
289 return true;
290 if(d->major < other.d->major)
291 return false;
292 if(d->minor > other.d->minor)
293 return true;
294 if(d->minor < other.d->minor)
295 return false;
296 if(d->micro > other.d->micro)
297 return true;
298 if(d->micro < other.d->micro)
299 return false;
300 if(d->nano > other.d->nano)
301 return true;
302 if(d->nano < other.d->nano)
303 return false;
304
305 return false;
306 default:
307 return false;
308 }
309 }
310
operator <=(const Version & other) const311 bool Version::operator<= (const Version &other) const
312 {
313 return ((*this) < other || (*this) == other);
314 }
315
operator >=(const Version & other) const316 bool Version::operator>= (const Version &other) const
317 {
318 return ((*this) > other || (*this) == other);
319 }
320
regExpForNumberCount(int numberCount)321 QString Version::regExpForNumberCount(int numberCount)
322 {
323 switch(numberCount)
324 {
325 case 1:
326 return "^([0-9]+)$";
327 case 2:
328 return "^([0-9]+)\\.([0-9]+)$";
329 case 3:
330 return "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$";
331 case 4:
332 return "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+)$";
333 default:
334 return QString();
335 }
336 }
337 }
338
operator <<(QDataStream & s,const Tools::Version & version)339 QDataStream &operator<<(QDataStream &s, const Tools::Version &version)
340 {
341 s << version.major();
342 s << version.minor();
343 s << version.micro();
344 s << version.nano();
345 s << version.numberCount();
346
347 return s;
348 }
349
operator >>(QDataStream & s,Tools::Version & version)350 QDataStream &operator>>(QDataStream &s, Tools::Version &version)
351 {
352 int major, minor, micro, nano, numberCount;
353
354 s >> major;
355 s >> minor;
356 s >> micro;
357 s >> nano;
358 s >> numberCount;
359
360 version.setMajor(major);
361 version.setMinor(minor);
362 version.setMicro(micro);
363 version.setNano(nano);
364 version.setNumberCount(numberCount);
365
366 return s;
367 }
368
operator <<(QDebug & dbg,const Tools::Version & version)369 QDebug &operator<<(QDebug &dbg, const Tools::Version &version)
370 {
371 dbg.nospace() << version.toString();
372
373 return dbg.maybeSpace();
374 }
375 #endif
376