1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtNetwork 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 The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qurlinfo_p.h"
41 
42 #include "qurl.h"
43 #include "qdir.h"
44 #include <limits.h>
45 
46 QT_BEGIN_NAMESPACE
47 
48 class QUrlInfoPrivate
49 {
50 public:
QUrlInfoPrivate()51     QUrlInfoPrivate() :
52         permissions(0),
53         size(0),
54         isDir(false),
55         isFile(true),
56         isSymLink(false),
57         isWritable(true),
58         isReadable(true),
59         isExecutable(false)
60     {}
61 
62     QString name;
63     int permissions;
64     QString owner;
65     QString group;
66     qint64 size;
67 
68     QDateTime lastModified;
69     QDateTime lastRead;
70     bool isDir;
71     bool isFile;
72     bool isSymLink;
73     bool isWritable;
74     bool isReadable;
75     bool isExecutable;
76 };
77 
78 
79 /*!
80     \class QUrlInfo
81     \brief The QUrlInfo class stores information about URLs.
82 
83     \internal
84     \ingroup io
85     \ingroup network
86     \inmodule QtNetwork
87 
88     The information about a URL that can be retrieved includes name(),
89     permissions(), owner(), group(), size(), lastModified(),
90     lastRead(), isDir(), isFile(), isSymLink(), isWritable(),
91     isReadable() and isExecutable().
92 
93     You can create your own QUrlInfo objects passing in all the
94     relevant information in the constructor, and you can modify a
95     QUrlInfo; for each getter mentioned above there is an equivalent
96     setter. Note that setting values does not affect the underlying
97     resource that the QUrlInfo provides information about; for example
98     if you call setWritable(true) on a read-only resource the only
99     thing changed is the QUrlInfo object, not the resource.
100 
101     \sa QUrl, {FTP Example}
102 */
103 
104 /*!
105     \enum QUrlInfo::PermissionSpec
106 
107     This enum is used by the permissions() function to report the
108     permissions of a file.
109 
110     \value ReadOwner The file is readable by the owner of the file.
111     \value WriteOwner The file is writable by the owner of the file.
112     \value ExeOwner The file is executable by the owner of the file.
113     \value ReadGroup The file is readable by the group.
114     \value WriteGroup The file is writable by the group.
115     \value ExeGroup The file is executable by the group.
116     \value ReadOther The file is readable by anyone.
117     \value WriteOther The file is writable by anyone.
118     \value ExeOther The file is executable by anyone.
119 */
120 
121 /*!
122     Constructs an invalid QUrlInfo object with default values.
123 
124     \sa isValid()
125 */
126 
QUrlInfo()127 QUrlInfo::QUrlInfo()
128 {
129     d = nullptr;
130 }
131 
132 /*!
133     Copy constructor, copies \a ui to this URL info object.
134 */
135 
QUrlInfo(const QUrlInfo & ui)136 QUrlInfo::QUrlInfo(const QUrlInfo &ui)
137 {
138     if (ui.d) {
139         d = new QUrlInfoPrivate;
140         *d = *ui.d;
141     } else {
142         d = nullptr;
143     }
144 }
145 
146 /*!
147     Constructs a QUrlInfo object by specifying all the URL's
148     information.
149 
150     The information that is passed is the \a name, file \a
151     permissions, \a owner and \a group and the file's \a size. Also
152     passed is the \a lastModified date/time and the \a lastRead
153     date/time. Flags are also passed, specifically, \a isDir, \a
154     isFile, \a isSymLink, \a isWritable, \a isReadable and \a
155     isExecutable.
156 */
157 
QUrlInfo(const QString & name,int permissions,const QString & owner,const QString & group,qint64 size,const QDateTime & lastModified,const QDateTime & lastRead,bool isDir,bool isFile,bool isSymLink,bool isWritable,bool isReadable,bool isExecutable)158 QUrlInfo::QUrlInfo(const QString &name, int permissions, const QString &owner,
159                     const QString &group, qint64 size, const QDateTime &lastModified,
160                     const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
161                     bool isWritable, bool isReadable, bool isExecutable)
162 {
163     d = new QUrlInfoPrivate;
164     d->name = name;
165     d->permissions = permissions;
166     d->owner = owner;
167     d->group = group;
168     d->size = size;
169     d->lastModified = lastModified;
170     d->lastRead = lastRead;
171     d->isDir = isDir;
172     d->isFile = isFile;
173     d->isSymLink = isSymLink;
174     d->isWritable = isWritable;
175     d->isReadable = isReadable;
176     d->isExecutable = isExecutable;
177 }
178 
179 
180 /*!
181     Constructs a QUrlInfo object by specifying all the URL's
182     information.
183 
184     The information that is passed is the \a url, file \a
185     permissions, \a owner and \a group and the file's \a size. Also
186     passed is the \a lastModified date/time and the \a lastRead
187     date/time. Flags are also passed, specifically, \a isDir, \a
188     isFile, \a isSymLink, \a isWritable, \a isReadable and \a
189     isExecutable.
190 */
191 
QUrlInfo(const QUrl & url,int permissions,const QString & owner,const QString & group,qint64 size,const QDateTime & lastModified,const QDateTime & lastRead,bool isDir,bool isFile,bool isSymLink,bool isWritable,bool isReadable,bool isExecutable)192 QUrlInfo::QUrlInfo(const QUrl &url, int permissions, const QString &owner,
193                     const QString &group, qint64 size, const QDateTime &lastModified,
194                     const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
195                     bool isWritable, bool isReadable, bool isExecutable)
196 {
197     d = new QUrlInfoPrivate;
198     d->name = QFileInfo(url.path()).fileName();
199     d->permissions = permissions;
200     d->owner = owner;
201     d->group = group;
202     d->size = size;
203     d->lastModified = lastModified;
204     d->lastRead = lastRead;
205     d->isDir = isDir;
206     d->isFile = isFile;
207     d->isSymLink = isSymLink;
208     d->isWritable = isWritable;
209     d->isReadable = isReadable;
210     d->isExecutable = isExecutable;
211 }
212 
213 
214 /*!
215     Sets the name of the URL to \a name. The name is the full text,
216     for example, "http://qt-project.org/doc/qt-5.0/qtcore/qurl.html".
217 
218     If you call this function for an invalid URL info, this function
219     turns it into a valid one.
220 
221     \sa isValid()
222 */
223 
setName(const QString & name)224 void QUrlInfo::setName(const QString &name)
225 {
226     if (!d)
227         d = new QUrlInfoPrivate;
228     d->name = name;
229 }
230 
231 
232 /*!
233     If \a b is true then the URL is set to be a directory; if \a b is
234     false then the URL is set not to be a directory (which normally
235     means it is a file). (Note that a URL can refer to both a file and
236     a directory even though most file systems do not support this.)
237 
238     If you call this function for an invalid URL info, this function
239     turns it into a valid one.
240 
241     \sa isValid()
242 */
243 
setDir(bool b)244 void QUrlInfo::setDir(bool b)
245 {
246     if (!d)
247         d = new QUrlInfoPrivate;
248     d->isDir = b;
249 }
250 
251 
252 /*!
253     If \a b is true then the URL is set to be a file; if \b is false
254     then the URL is set not to be a file (which normally means it is a
255     directory). (Note that a URL can refer to both a file and a
256     directory even though most file systems do not support this.)
257 
258     If you call this function for an invalid URL info, this function
259     turns it into a valid one.
260 
261     \sa isValid()
262 */
263 
setFile(bool b)264 void QUrlInfo::setFile(bool b)
265 {
266     if (!d)
267         d = new QUrlInfoPrivate;
268     d->isFile = b;
269 }
270 
271 
272 /*!
273     Specifies that the URL refers to a symbolic link if \a b is true
274     and that it does not if \a b is false.
275 
276     If you call this function for an invalid URL info, this function
277     turns it into a valid one.
278 
279     \sa isValid()
280 */
281 
setSymLink(bool b)282 void QUrlInfo::setSymLink(bool b)
283 {
284     if (!d)
285         d = new QUrlInfoPrivate;
286     d->isSymLink = b;
287 }
288 
289 
290 /*!
291     Specifies that the URL is writable if \a b is true and not
292     writable if \a b is false.
293 
294     If you call this function for an invalid URL info, this function
295     turns it into a valid one.
296 
297     \sa isValid()
298 */
299 
setWritable(bool b)300 void QUrlInfo::setWritable(bool b)
301 {
302     if (!d)
303         d = new QUrlInfoPrivate;
304     d->isWritable = b;
305 }
306 
307 
308 /*!
309     Specifies that the URL is readable if \a b is true and not
310     readable if \a b is false.
311 
312     If you call this function for an invalid URL info, this function
313     turns it into a valid one.
314 
315     \sa isValid()
316 */
317 
setReadable(bool b)318 void QUrlInfo::setReadable(bool b)
319 {
320     if (!d)
321         d = new QUrlInfoPrivate;
322     d->isReadable = b;
323 }
324 
325 /*!
326     Specifies that the owner of the URL is called \a s.
327 
328     If you call this function for an invalid URL info, this function
329     turns it into a valid one.
330 
331     \sa isValid()
332 */
333 
setOwner(const QString & s)334 void QUrlInfo::setOwner(const QString &s)
335 {
336     if (!d)
337         d = new QUrlInfoPrivate;
338     d->owner = s;
339 }
340 
341 /*!
342     Specifies that the owning group of the URL is called \a s.
343 
344     If you call this function for an invalid URL info, this function
345     turns it into a valid one.
346 
347     \sa isValid()
348 */
349 
setGroup(const QString & s)350 void QUrlInfo::setGroup(const QString &s)
351 {
352     if (!d)
353         d = new QUrlInfoPrivate;
354     d->group = s;
355 }
356 
357 /*!
358     Specifies the \a size of the URL.
359 
360     If you call this function for an invalid URL info, this function
361     turns it into a valid one.
362 
363     \sa isValid()
364 */
365 
setSize(qint64 size)366 void QUrlInfo::setSize(qint64 size)
367 {
368     if (!d)
369         d = new QUrlInfoPrivate;
370     d->size = size;
371 }
372 
373 /*!
374     Specifies that the URL has access permissions \a p.
375 
376     If you call this function for an invalid URL info, this function
377     turns it into a valid one.
378 
379     \sa isValid()
380 */
381 
setPermissions(int p)382 void QUrlInfo::setPermissions(int p)
383 {
384     if (!d)
385         d = new QUrlInfoPrivate;
386     d->permissions = p;
387 }
388 
389 /*!
390     Specifies that the object the URL refers to was last modified at
391     \a dt.
392 
393     If you call this function for an invalid URL info, this function
394     turns it into a valid one.
395 
396     \sa isValid()
397 */
398 
setLastModified(const QDateTime & dt)399 void QUrlInfo::setLastModified(const QDateTime &dt)
400 {
401     if (!d)
402         d = new QUrlInfoPrivate;
403     d->lastModified = dt;
404 }
405 
406 /*!
407     \since 4.4
408 
409     Specifies that the object the URL refers to was last read at
410     \a dt.
411 
412     If you call this function for an invalid URL info, this function
413     turns it into a valid one.
414 
415     \sa isValid()
416 */
417 
setLastRead(const QDateTime & dt)418 void QUrlInfo::setLastRead(const QDateTime &dt)
419 {
420     if (!d)
421         d = new QUrlInfoPrivate;
422     d->lastRead = dt;
423 }
424 
425 /*!
426     Destroys the URL info object.
427 */
428 
~QUrlInfo()429 QUrlInfo::~QUrlInfo()
430 {
431     delete d;
432 }
433 
434 /*!
435     Assigns the values of \a ui to this QUrlInfo object.
436 */
437 
operator =(const QUrlInfo & ui)438 QUrlInfo &QUrlInfo::operator=(const QUrlInfo &ui)
439 {
440     if (ui.d) {
441         if (!d)
442             d= new QUrlInfoPrivate;
443         *d = *ui.d;
444     } else {
445         delete d;
446         d = nullptr;
447     }
448     return *this;
449 }
450 
451 /*!
452     Returns the file name of the URL.
453 
454     \sa isValid()
455 */
456 
name() const457 QString QUrlInfo::name() const
458 {
459     if (!d)
460         return QString();
461     return d->name;
462 }
463 
464 /*!
465     Returns the permissions of the URL. You can use the \c PermissionSpec flags
466     to test for certain permissions.
467 
468     \sa isValid()
469 */
470 
permissions() const471 int QUrlInfo::permissions() const
472 {
473     if (!d)
474         return 0;
475     return d->permissions;
476 }
477 
478 /*!
479     Returns the owner of the URL.
480 
481     \sa isValid()
482 */
483 
owner() const484 QString QUrlInfo::owner() const
485 {
486     if (!d)
487         return QString();
488     return d->owner;
489 }
490 
491 /*!
492     Returns the group of the URL.
493 
494     \sa isValid()
495 */
496 
group() const497 QString QUrlInfo::group() const
498 {
499     if (!d)
500         return QString();
501     return d->group;
502 }
503 
504 /*!
505     Returns the size of the URL.
506 
507     \sa isValid()
508 */
509 
size() const510 qint64 QUrlInfo::size() const
511 {
512     if (!d)
513         return 0;
514     return d->size;
515 }
516 
517 /*!
518     Returns the last modification date of the URL.
519 
520     \sa isValid()
521 */
522 
lastModified() const523 QDateTime QUrlInfo::lastModified() const
524 {
525     if (!d)
526         return QDateTime();
527     return d->lastModified;
528 }
529 
530 /*!
531     Returns the date when the URL was last read.
532 
533     \sa isValid()
534 */
535 
lastRead() const536 QDateTime QUrlInfo::lastRead() const
537 {
538     if (!d)
539         return QDateTime();
540     return d->lastRead;
541 }
542 
543 /*!
544     Returns \c true if the URL is a directory; otherwise returns \c false.
545 
546     \sa isValid()
547 */
548 
isDir() const549 bool QUrlInfo::isDir() const
550 {
551     if (!d)
552         return false;
553     return d->isDir;
554 }
555 
556 /*!
557     Returns \c true if the URL is a file; otherwise returns \c false.
558 
559     \sa isValid()
560 */
561 
isFile() const562 bool QUrlInfo::isFile() const
563 {
564     if (!d)
565         return false;
566     return d->isFile;
567 }
568 
569 /*!
570     Returns \c true if the URL is a symbolic link; otherwise returns \c false.
571 
572     \sa isValid()
573 */
574 
isSymLink() const575 bool QUrlInfo::isSymLink() const
576 {
577     if (!d)
578         return false;
579     return d->isSymLink;
580 }
581 
582 /*!
583     Returns \c true if the URL is writable; otherwise returns \c false.
584 
585     \sa isValid()
586 */
587 
isWritable() const588 bool QUrlInfo::isWritable() const
589 {
590     if (!d)
591         return false;
592     return d->isWritable;
593 }
594 
595 /*!
596     Returns \c true if the URL is readable; otherwise returns \c false.
597 
598     \sa isValid()
599 */
600 
isReadable() const601 bool QUrlInfo::isReadable() const
602 {
603     if (!d)
604         return false;
605     return d->isReadable;
606 }
607 
608 /*!
609     Returns \c true if the URL is executable; otherwise returns \c false.
610 
611     \sa isValid()
612 */
613 
isExecutable() const614 bool QUrlInfo::isExecutable() const
615 {
616     if (!d)
617         return false;
618     return d->isExecutable;
619 }
620 
621 /*!
622     Returns \c true if \a i1 is greater than \a i2; otherwise returns
623     false. The objects are compared by the value, which is specified
624     by \a sortBy. This must be one of QDir::Name, QDir::Time or
625     QDir::Size.
626 */
627 
greaterThan(const QUrlInfo & i1,const QUrlInfo & i2,int sortBy)628 bool QUrlInfo::greaterThan(const QUrlInfo &i1, const QUrlInfo &i2,
629                             int sortBy)
630 {
631     switch (sortBy) {
632     case QDir::Name:
633         return i1.name() > i2.name();
634     case QDir::Time:
635         return i1.lastModified() > i2.lastModified();
636     case QDir::Size:
637         return i1.size() > i2.size();
638     default:
639         return false;
640     }
641 }
642 
643 /*!
644     Returns \c true if \a i1 is less than \a i2; otherwise returns \c false.
645     The objects are compared by the value, which is specified by \a
646     sortBy. This must be one of QDir::Name, QDir::Time or QDir::Size.
647 */
648 
lessThan(const QUrlInfo & i1,const QUrlInfo & i2,int sortBy)649 bool QUrlInfo::lessThan(const QUrlInfo &i1, const QUrlInfo &i2,
650                          int sortBy)
651 {
652     return !greaterThan(i1, i2, sortBy);
653 }
654 
655 /*!
656     Returns \c true if \a i1 equals to \a i2; otherwise returns \c false.
657     The objects are compared by the value, which is specified by \a
658     sortBy. This must be one of QDir::Name, QDir::Time or QDir::Size.
659 */
660 
equal(const QUrlInfo & i1,const QUrlInfo & i2,int sortBy)661 bool QUrlInfo::equal(const QUrlInfo &i1, const QUrlInfo &i2,
662                       int sortBy)
663 {
664     switch (sortBy) {
665     case QDir::Name:
666         return i1.name() == i2.name();
667     case QDir::Time:
668         return i1.lastModified() == i2.lastModified();
669     case QDir::Size:
670         return i1.size() == i2.size();
671     default:
672         return false;
673     }
674 }
675 
676 /*!
677     Returns \c true if this QUrlInfo is equal to \a other; otherwise
678     returns \c false.
679 
680     \sa lessThan(), equal()
681 */
682 
operator ==(const QUrlInfo & other) const683 bool QUrlInfo::operator==(const QUrlInfo &other) const
684 {
685     if (!d)
686         return other.d == nullptr;
687     if (!other.d)
688         return false;
689 
690     return (d->name == other.d->name &&
691             d->permissions == other.d->permissions &&
692             d->owner == other.d->owner &&
693             d->group == other.d->group &&
694             d->size == other.d->size &&
695             d->lastModified == other.d->lastModified &&
696             d->lastRead == other.d->lastRead &&
697             d->isDir == other.d->isDir &&
698             d->isFile == other.d->isFile &&
699             d->isSymLink == other.d->isSymLink &&
700             d->isWritable == other.d->isWritable &&
701             d->isReadable == other.d->isReadable &&
702             d->isExecutable == other.d->isExecutable);
703 }
704 
705 /*!
706     \fn bool QUrlInfo::operator!=(const QUrlInfo &other) const
707     \since 4.2
708 
709     Returns \c true if this QUrlInfo is not equal to \a other; otherwise
710     returns \c false.
711 
712     \sa lessThan(), equal()
713 */
714 
715 /*!
716     Returns \c true if the URL info is valid; otherwise returns \c false.
717     Valid means that the QUrlInfo contains real information.
718 
719     You should always check if the URL info is valid before relying on
720     the values.
721 */
isValid() const722 bool QUrlInfo::isValid() const
723 {
724     return d != nullptr;
725 }
726 
727 QT_END_NAMESPACE
728