Add the QStorageInfo class
Allows to retrieve information about mounted volumes such as label, total/available size, filesystem type and so on. Possible use cases are: - allows to do checks about filesystem before performing actual operation (such as available/maximum volume size) - allows to retrive information about volume that can be shown in file dialogs - allows to retrieve volume for specific path and check if two or more paths belong to the same volume or not [ChangeLog][QtCore] Added QStorageInfo class to retrive information about mounted volumes and drives Change-Id: Ibf9c2e6b53ef39c5605894a4422acdbbca4030c4 Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>bb10
parent
091653e9e7
commit
6c3c1a4cb8
|
|
@ -0,0 +1,70 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [0]
|
||||
QStorageInfo storage(qApp->applicationDirPath());
|
||||
if (storage.isValid() && storage.isReady()) {
|
||||
// ...
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) {
|
||||
if (storage.isValid() && storage.isReady()) {
|
||||
if (!storage.isReadOnly()) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
QStorageInfo storage = QStorageInfo::root();
|
||||
|
||||
qDebug() << storage.rootPath();
|
||||
if (storage.isReadOnly())
|
||||
qDebug() << "isReadOnly:" << storage.isReadOnly();
|
||||
|
||||
qDebug() << "name:" << storage.name();
|
||||
qDebug() << "fileSystemType:" << storage.fileSystemType();
|
||||
qDebug() << "size:" << storage.bytesTotal()/1000/1000 << "MB";
|
||||
qDebug() << "availableSize:" << storage.bytesAvailable()/1000/1000 << "MB";
|
||||
//! [2]
|
||||
|
|
@ -32,6 +32,8 @@ HEADERS += \
|
|||
io/qresource_iterator_p.h \
|
||||
io/qsavefile.h \
|
||||
io/qstandardpaths.h \
|
||||
io/qstorageinfo.h \
|
||||
io/qstorageinfo_p.h \
|
||||
io/qurl.h \
|
||||
io/qurl_p.h \
|
||||
io/qurlquery.h \
|
||||
|
|
@ -70,6 +72,7 @@ SOURCES += \
|
|||
io/qlockfile.cpp \
|
||||
io/qnoncontiguousbytedevice.cpp \
|
||||
io/qprocess.cpp \
|
||||
io/qstorageinfo.cpp \
|
||||
io/qtextstream.cpp \
|
||||
io/qtemporarydir.cpp \
|
||||
io/qtemporaryfile.cpp \
|
||||
|
|
@ -108,7 +111,8 @@ win32 {
|
|||
SOURCES += io/qstandardpaths_win.cpp
|
||||
|
||||
wince* {
|
||||
SOURCES += io/qprocess_wince.cpp
|
||||
SOURCES += io/qprocess_wince.cpp \
|
||||
io/qstorageinfo_stub.cpp
|
||||
} else {
|
||||
HEADERS += \
|
||||
io/qwinoverlappedionotifier_p.h \
|
||||
|
|
@ -116,12 +120,15 @@ win32 {
|
|||
SOURCES += \
|
||||
io/qprocess_win.cpp \
|
||||
io/qwinoverlappedionotifier.cpp \
|
||||
io/qwindowspipereader.cpp
|
||||
io/qwindowspipereader.cpp \
|
||||
io/qstorageinfo_win.cpp
|
||||
LIBS += -lmpr
|
||||
}
|
||||
} else {
|
||||
SOURCES += \
|
||||
io/qstandardpaths_winrt.cpp \
|
||||
io/qsettings_winrt.cpp
|
||||
io/qsettings_winrt.cpp \
|
||||
io/qstorageinfo_stub.cpp
|
||||
}
|
||||
} else:unix|integrity {
|
||||
SOURCES += \
|
||||
|
|
@ -141,18 +148,28 @@ win32 {
|
|||
HEADERS += io/qfilesystemwatcher_fsevents_p.h
|
||||
}
|
||||
macx {
|
||||
SOURCES += io/qstandardpaths_mac.cpp
|
||||
SOURCES += \
|
||||
io/qstorageinfo_mac.cpp \
|
||||
io/qstandardpaths_mac.cpp
|
||||
LIBS += -framework DiskArbitration -framework IOKit
|
||||
} else:ios {
|
||||
OBJECTIVE_SOURCES += io/qstandardpaths_ios.mm
|
||||
SOURCES += io/qstorageinfo_mac.cpp
|
||||
} else {
|
||||
SOURCES += io/qstandardpaths_unix.cpp
|
||||
}
|
||||
} else:blackberry {
|
||||
SOURCES += io/qstandardpaths_blackberry.cpp
|
||||
SOURCES += \
|
||||
io/qstandardpaths_blackberry.cpp \
|
||||
io/qstorageinfo_unix.cpp
|
||||
} else:android:!android-no-sdk {
|
||||
SOURCES += io/qstandardpaths_android.cpp
|
||||
SOURCES += \
|
||||
io/qstandardpaths_android.cpp \
|
||||
io/qstorageinfo_unix.cpp
|
||||
} else {
|
||||
SOURCES += io/qstandardpaths_unix.cpp
|
||||
SOURCES += \
|
||||
io/qstandardpaths_unix.cpp \
|
||||
io/qstorageinfo_unix.cpp
|
||||
}
|
||||
|
||||
linux|if(qnx:contains(QT_CONFIG, inotify)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,398 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qstorageinfo.h"
|
||||
#include "qstorageinfo_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QStorageInfo
|
||||
\inmodule QtCore
|
||||
\since 5.4
|
||||
\brief Provides information about currently mounted storages and drives.
|
||||
|
||||
\ingroup io
|
||||
\ingroup shared
|
||||
|
||||
Allows retrieving information about the volume's space, its mount point,
|
||||
label, filesystem name.
|
||||
|
||||
You can create an instance of QStorageInfo by passing the path to the
|
||||
volume's mount point as the constructor parameter, or you can set it using
|
||||
setPath() method. The static mountedVolumes() method can be used to get the
|
||||
list of all mounted filesystems.
|
||||
|
||||
QStorageInfo always caches the retrieved information but you can call
|
||||
refresh() to invalidate the cache.
|
||||
|
||||
The following example retrieves the most common information about the root
|
||||
volume of the system and prints information about it.
|
||||
|
||||
\snippet code/src_corelib_io_qstorageinfo.cpp 2
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an empty QStorageInfo object.
|
||||
|
||||
This object is not ready for use, invalid and all its parameters are empty.
|
||||
|
||||
\sa setPath(), isReady(), isValid()
|
||||
*/
|
||||
QStorageInfo::QStorageInfo()
|
||||
: d(new QStorageInfoPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new QStorageInfo that gives information about the volume
|
||||
mounted at \a path.
|
||||
|
||||
If you pass a directory or file, the QStorageInfo object will refer to the
|
||||
volume where this directory or file is located.
|
||||
You can check if the created object is correct using the isValid() method.
|
||||
|
||||
The following example shows how to get volume on which application is
|
||||
located. It is recommended to always check that volume is ready and valid.
|
||||
|
||||
\snippet code/src_corelib_io_qstorageinfo.cpp 0
|
||||
|
||||
\sa setPath()
|
||||
*/
|
||||
QStorageInfo::QStorageInfo(const QString &path)
|
||||
: d(new QStorageInfoPrivate)
|
||||
{
|
||||
setPath(path);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new QStorageInfo that gives information about the volume
|
||||
that contains the \a dir folder.
|
||||
*/
|
||||
QStorageInfo::QStorageInfo(const QDir &dir)
|
||||
: d(new QStorageInfoPrivate)
|
||||
{
|
||||
setPath(dir.absolutePath());
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new QStorageInfo that is a copy of the \a other QStorageInfo.
|
||||
*/
|
||||
QStorageInfo::QStorageInfo(const QStorageInfo &other)
|
||||
: d(other.d)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the QStorageInfo and frees its resources.
|
||||
*/
|
||||
QStorageInfo::~QStorageInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Makes a copy of \a other QStorageInfo and assigns it to this QStorageInfo.
|
||||
*/
|
||||
QStorageInfo &QStorageInfo::operator=(const QStorageInfo &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QStorageInfo &QStorageInfo::operator=(QStorageInfo &&other)
|
||||
|
||||
Move-assigns \a other to this QStorageInfo instance.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QStorageInfo::swap(QStorageInfo &other)
|
||||
|
||||
Swaps this volume info with the \a other. This function is very fast and
|
||||
never fails.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Sets QStorageInfo to the filesystem mounted where \a path is located.
|
||||
|
||||
Path can either be a root path of the filesystem, or a directory or a file
|
||||
within that filesystem.
|
||||
|
||||
\sa rootPath()
|
||||
*/
|
||||
void QStorageInfo::setPath(const QString &path)
|
||||
{
|
||||
if (d->rootPath == path)
|
||||
return;
|
||||
d.detach();
|
||||
d->rootPath = path;
|
||||
d->doStat();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the mount point of the filesystem this QStorageInfo object
|
||||
represents.
|
||||
|
||||
On Windows, returns the volume letter in case the volume is not mounted to
|
||||
a directory.
|
||||
|
||||
Note that the value returned by rootPath() is the real mount point of a
|
||||
volume and may not be equal to the value passed to constructor or setPath()
|
||||
method. For example, if you have only the root volume in the system and
|
||||
pass '/directory' to setPath(), then this method will return '/'.
|
||||
|
||||
\sa setPath(), device()
|
||||
*/
|
||||
QString QStorageInfo::rootPath() const
|
||||
{
|
||||
return d->rootPath;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the size (in bytes) available for the current user. If the user is
|
||||
the root user or a system administrator returns all available size.
|
||||
|
||||
This size can be less than or equal to the free size, returned by
|
||||
bytesFree() function.
|
||||
|
||||
\sa bytesTotal(), bytesFree()
|
||||
*/
|
||||
qint64 QStorageInfo::bytesAvailable() const
|
||||
{
|
||||
return d->bytesAvailable;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the number of free bytes on a volume. Note, that if there are some
|
||||
kind of quotas on the filesystem, this value can be bigger than
|
||||
bytesAvailable().
|
||||
|
||||
\sa bytesTotal(), bytesAvailable()
|
||||
*/
|
||||
qint64 QStorageInfo::bytesFree() const
|
||||
{
|
||||
return d->bytesFree;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns total volume size in bytes.
|
||||
|
||||
\sa bytesFree(), bytesAvailable()
|
||||
*/
|
||||
qint64 QStorageInfo::bytesTotal() const
|
||||
{
|
||||
return d->bytesTotal;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the type name of the filesystem.
|
||||
|
||||
This is a platform-dependent function, and filesystem names can vary
|
||||
between different operating systems. For example, on Windows filesystems
|
||||
can be named as 'NTFS' and on Linux as 'ntfs-3g' or 'fuseblk'.
|
||||
|
||||
\sa name()
|
||||
*/
|
||||
QByteArray QStorageInfo::fileSystemType() const
|
||||
{
|
||||
return d->fileSystemType;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the device for this volume.
|
||||
|
||||
For example, on Unix filesystems (including OS X), this returns the
|
||||
devpath like '/dev/sda0' for local storages. On Windows, returns the UNC
|
||||
path starting with \\\\?\\ for local storages (i.e. volume GUID).
|
||||
|
||||
\sa rootPath()
|
||||
*/
|
||||
QByteArray QStorageInfo::device() const
|
||||
{
|
||||
return d->device;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the human-readable name of a filesystem, usually called 'label'.
|
||||
|
||||
Not all filesystems support this feature, in this case value returned by
|
||||
this method could be empty. An empty string is returned if the file system
|
||||
does not support labels or no label is set.
|
||||
|
||||
On Linux, retrieving the volume's label requires udev to be present in the
|
||||
system.
|
||||
|
||||
\sa fileSystemType()
|
||||
*/
|
||||
QString QStorageInfo::name() const
|
||||
{
|
||||
return d->name;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the volume's name, if available, or the root path if not.
|
||||
*/
|
||||
QString QStorageInfo::displayName() const
|
||||
{
|
||||
if (!d->name.isEmpty())
|
||||
return d->name;
|
||||
return d->rootPath;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool QStorageInfo::isRoot() const
|
||||
|
||||
Returns true if this QStorageInfo represents the system root volume; false
|
||||
otherwise.
|
||||
|
||||
On Unix filesystems, the root volume is a volume mounted at "/", on Windows
|
||||
the root volume is the volume where OS is installed.
|
||||
|
||||
\sa root()
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns true if the current filesystem is protected from writing; false
|
||||
otherwise.
|
||||
*/
|
||||
bool QStorageInfo::isReadOnly() const
|
||||
{
|
||||
return d->readOnly;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if current filesystem is ready to work; false otherwise. For
|
||||
example, false is returned if CD volume is not inserted.
|
||||
|
||||
Note that fileSystemType(), name(), bytesTotal(), bytesFree(), and
|
||||
bytesAvailable() will return invalid data until the volume is ready.
|
||||
|
||||
\sa isValid()
|
||||
*/
|
||||
bool QStorageInfo::isReady() const
|
||||
{
|
||||
return d->ready;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the QStorageInfo specified by rootPath exists and is mounted
|
||||
correctly.
|
||||
|
||||
\sa isReady()
|
||||
*/
|
||||
bool QStorageInfo::isValid() const
|
||||
{
|
||||
return d->valid;
|
||||
}
|
||||
|
||||
/*!
|
||||
Resets QStorageInfo's internal cache.
|
||||
|
||||
QStorageInfo caches information about storages to speed up performance -
|
||||
QStorageInfo retrieves information during object construction and/or call
|
||||
to setPath() method. You have to manually reset the cache by calling this
|
||||
function to update storage information.
|
||||
*/
|
||||
void QStorageInfo::refresh()
|
||||
{
|
||||
d.detach();
|
||||
d->doStat();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns list of QStorageInfos that corresponds to the list of currently
|
||||
mounted filesystems.
|
||||
|
||||
On Windows, this returns drives presented in 'My Computer' folder. On Unix
|
||||
operating systems, returns list of all mounted filesystems (except for
|
||||
pseudo filesystems).
|
||||
|
||||
By default, returns all currently mounted filesystems.
|
||||
|
||||
The example shows how to retrieve all storages present in the system and
|
||||
skip read-only storages.
|
||||
|
||||
\snippet code/src_corelib_io_qstorageinfo.cpp 1
|
||||
|
||||
\sa root()
|
||||
*/
|
||||
QList<QStorageInfo> QStorageInfo::mountedVolumes()
|
||||
{
|
||||
return QStorageInfoPrivate::mountedVolumes();
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QStorageInfo, getRoot, (QStorageInfoPrivate::root()))
|
||||
|
||||
/*!
|
||||
Returns a QStorageInfo object that represents the system root volume.
|
||||
|
||||
On Unix systems this call returns '/' volume, on Windows the volume where
|
||||
operating system is installed is returned.
|
||||
|
||||
\sa isRoot()
|
||||
*/
|
||||
QStorageInfo QStorageInfo::root()
|
||||
{
|
||||
return *getRoot();
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn inline bool operator==(const QStorageInfo &first, const QStorageInfo &second)
|
||||
|
||||
\relates QStorageInfo
|
||||
|
||||
Returns true if \a first QStorageInfo object refers to the same drive or volume
|
||||
as the \a second; otherwise returns false.
|
||||
|
||||
Note that the result of comparing two invalid QStorageInfo objects is always
|
||||
positive.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn inline bool operator!=(const QStorageInfo &first, const QStorageInfo &second)
|
||||
|
||||
\relates QStorageInfo
|
||||
|
||||
Returns true if \a first QStorageInfo object refers to a different drive or
|
||||
volume than the one specified by \a second; otherwise returns false.
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSTORAGEINFO_H
|
||||
#define QSTORAGEINFO_H
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QStorageInfoPrivate;
|
||||
class Q_CORE_EXPORT QStorageInfo
|
||||
{
|
||||
public:
|
||||
QStorageInfo();
|
||||
explicit QStorageInfo(const QString &path);
|
||||
explicit QStorageInfo(const QDir &dir);
|
||||
QStorageInfo(const QStorageInfo &other);
|
||||
~QStorageInfo();
|
||||
|
||||
QStorageInfo &operator=(const QStorageInfo &other);
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
inline QStorageInfo &operator=(QStorageInfo &&other)
|
||||
{ qSwap(d, other.d); return *this; }
|
||||
#endif
|
||||
|
||||
inline void swap(QStorageInfo &other)
|
||||
{ qSwap(d, other.d); }
|
||||
|
||||
void setPath(const QString &path);
|
||||
|
||||
QString rootPath() const;
|
||||
QByteArray device() const;
|
||||
QByteArray fileSystemType() const;
|
||||
QString name() const;
|
||||
QString displayName() const;
|
||||
|
||||
qint64 bytesTotal() const;
|
||||
qint64 bytesFree() const;
|
||||
qint64 bytesAvailable() const;
|
||||
|
||||
inline bool isRoot() const;
|
||||
bool isReadOnly() const;
|
||||
bool isReady() const;
|
||||
bool isValid() const;
|
||||
|
||||
void refresh();
|
||||
|
||||
static QList<QStorageInfo> mountedVolumes();
|
||||
static QStorageInfo root();
|
||||
|
||||
private:
|
||||
friend class QStorageInfoPrivate;
|
||||
friend bool operator==(const QStorageInfo &first, const QStorageInfo &second);
|
||||
QExplicitlySharedDataPointer<QStorageInfoPrivate> d;
|
||||
};
|
||||
|
||||
inline bool operator==(const QStorageInfo &first, const QStorageInfo &second)
|
||||
{
|
||||
if (first.d == second.d)
|
||||
return true;
|
||||
return first.device() == second.device();
|
||||
}
|
||||
|
||||
inline bool operator!=(const QStorageInfo &first, const QStorageInfo &second)
|
||||
{
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
inline bool QStorageInfo::isRoot() const
|
||||
{ return *this == QStorageInfo::root(); }
|
||||
|
||||
Q_DECLARE_SHARED(QStorageInfo)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QStorageInfo)
|
||||
|
||||
#endif // QSTORAGEINFO_H
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qstorageinfo_p.h"
|
||||
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreFoundation/CFURLEnumerator.h>
|
||||
|
||||
#include <sys/mount.h>
|
||||
|
||||
#define QT_STATFSBUF struct statfs
|
||||
#define QT_STATFS ::statfs
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
void QStorageInfoPrivate::initRootPath()
|
||||
{
|
||||
rootPath = QFileInfo(rootPath).canonicalFilePath();
|
||||
|
||||
if (rootPath.isEmpty())
|
||||
return;
|
||||
|
||||
retrieveUrlProperties(true);
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::doStat()
|
||||
{
|
||||
initRootPath();
|
||||
|
||||
if (rootPath.isEmpty())
|
||||
return;
|
||||
|
||||
retrieveLabel();
|
||||
retrievePosixInfo();
|
||||
retrieveUrlProperties();
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::retrievePosixInfo()
|
||||
{
|
||||
QT_STATFSBUF statfs_buf;
|
||||
int result = QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf);
|
||||
if (result == 0) {
|
||||
device = QByteArray(statfs_buf.f_mntfromname);
|
||||
readOnly = (statfs_buf.f_flags & MNT_RDONLY) != 0;
|
||||
fileSystemType = QByteArray(statfs_buf.f_fstypename);
|
||||
}
|
||||
}
|
||||
|
||||
static inline qint64 CFDictionaryGetInt64(CFDictionaryRef dictionary, const void *key)
|
||||
{
|
||||
CFNumberRef cfNumber = (CFNumberRef)CFDictionaryGetValue(dictionary, key);
|
||||
if (!cfNumber)
|
||||
return -1;
|
||||
qint64 result;
|
||||
bool ok = CFNumberGetValue(cfNumber, kCFNumberSInt64Type, &result);
|
||||
if (!ok)
|
||||
return -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::retrieveUrlProperties(bool initRootPath)
|
||||
{
|
||||
static const void *rootPathKeys[] = { kCFURLVolumeURLKey };
|
||||
static const void *propertyKeys[] = {
|
||||
// kCFURLVolumeNameKey, // 10.7
|
||||
// kCFURLVolumeLocalizedNameKey, // 10.7
|
||||
kCFURLVolumeTotalCapacityKey,
|
||||
kCFURLVolumeAvailableCapacityKey,
|
||||
// kCFURLVolumeIsReadOnlyKey // 10.7
|
||||
};
|
||||
size_t size = (initRootPath ? sizeof(rootPathKeys) : sizeof(propertyKeys)) / sizeof(void*);
|
||||
QCFType<CFArrayRef> keys = CFArrayCreate(kCFAllocatorDefault,
|
||||
initRootPath ? rootPathKeys : propertyKeys,
|
||||
size,
|
||||
Q_NULLPTR);
|
||||
|
||||
if (!keys)
|
||||
return;
|
||||
|
||||
const QCFString cfPath = rootPath;
|
||||
if (initRootPath)
|
||||
rootPath.clear();
|
||||
|
||||
QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
|
||||
cfPath,
|
||||
kCFURLPOSIXPathStyle,
|
||||
true);
|
||||
if (!url)
|
||||
return;
|
||||
|
||||
CFErrorRef error;
|
||||
QCFType<CFDictionaryRef> map = CFURLCopyResourcePropertiesForKeys(url, keys, &error);
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
if (initRootPath) {
|
||||
const CFURLRef rootUrl = (CFURLRef)CFDictionaryGetValue(map, kCFURLVolumeURLKey);
|
||||
if (!rootUrl)
|
||||
return;
|
||||
|
||||
rootPath = QCFString(CFURLCopyFileSystemPath(rootUrl, kCFURLPOSIXPathStyle));
|
||||
valid = true;
|
||||
ready = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bytesTotal = CFDictionaryGetInt64(map, kCFURLVolumeTotalCapacityKey);
|
||||
bytesAvailable = CFDictionaryGetInt64(map, kCFURLVolumeAvailableCapacityKey);
|
||||
bytesFree = bytesAvailable;
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::retrieveLabel()
|
||||
{
|
||||
#if !defined(Q_OS_IOS)
|
||||
// deprecated since 10.8
|
||||
FSRef ref;
|
||||
FSPathMakeRef(reinterpret_cast<const UInt8*>(QFile::encodeName(rootPath).constData()),
|
||||
&ref,
|
||||
Q_NULLPTR);
|
||||
|
||||
// deprecated since 10.8
|
||||
FSCatalogInfo catalogInfo;
|
||||
OSErr error;
|
||||
error = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &catalogInfo, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
|
||||
if (error != noErr)
|
||||
return;
|
||||
|
||||
// deprecated (use CFURLCopyResourcePropertiesForKeys for 10.7 and higher)
|
||||
HFSUniStr255 volumeName;
|
||||
error = FSGetVolumeInfo(catalogInfo.volume,
|
||||
0,
|
||||
Q_NULLPTR,
|
||||
kFSVolInfoFSInfo,
|
||||
Q_NULLPTR,
|
||||
&volumeName,
|
||||
Q_NULLPTR);
|
||||
if (error == noErr)
|
||||
name = QCFString(FSCreateStringFromHFSUniStr(Q_NULLPTR, &volumeName));
|
||||
#endif
|
||||
}
|
||||
|
||||
QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
|
||||
{
|
||||
QList<QStorageInfo> volumes;
|
||||
|
||||
QCFType<CFURLEnumeratorRef> enumerator;
|
||||
enumerator = CFURLEnumeratorCreateForMountedVolumes(Q_NULLPTR,
|
||||
kCFURLEnumeratorSkipInvisibles,
|
||||
Q_NULLPTR);
|
||||
|
||||
CFURLEnumeratorResult result = kCFURLEnumeratorSuccess;
|
||||
do {
|
||||
CFURLRef url;
|
||||
CFErrorRef error;
|
||||
result = CFURLEnumeratorGetNextURL(enumerator, &url, &error);
|
||||
if (result == kCFURLEnumeratorSuccess) {
|
||||
const QCFString urlString = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
|
||||
volumes.append(QStorageInfo(urlString));
|
||||
}
|
||||
} while (result != kCFURLEnumeratorEnd);
|
||||
|
||||
return volumes;
|
||||
}
|
||||
|
||||
QStorageInfo QStorageInfoPrivate::root()
|
||||
{
|
||||
return QStorageInfo(QStringLiteral("/"));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSTORAGEINFO_P_H
|
||||
#define QSTORAGEINFO_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qstorageinfo.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QStorageInfoPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
inline QStorageInfoPrivate() : QSharedData(),
|
||||
bytesTotal(0), bytesFree(0), bytesAvailable(0),
|
||||
readOnly(false), ready(false), valid(false)
|
||||
{}
|
||||
|
||||
void initRootPath();
|
||||
void doStat();
|
||||
|
||||
static QList<QStorageInfo> mountedVolumes();
|
||||
static QStorageInfo root();
|
||||
|
||||
protected:
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
void retreiveVolumeInfo();
|
||||
void retreiveDiskFreeSpace();
|
||||
#elif defined(Q_OS_MAC)
|
||||
void retrievePosixInfo();
|
||||
void retrieveUrlProperties(bool initRootPath = false);
|
||||
void retrieveLabel();
|
||||
#elif defined(Q_OS_UNIX)
|
||||
void retreiveVolumeInfo();
|
||||
#endif
|
||||
|
||||
public:
|
||||
QString rootPath;
|
||||
QByteArray device;
|
||||
QByteArray fileSystemType;
|
||||
QString name;
|
||||
|
||||
qint64 bytesTotal;
|
||||
qint64 bytesFree;
|
||||
qint64 bytesAvailable;
|
||||
|
||||
bool readOnly;
|
||||
bool ready;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSTORAGEINFO_P_H
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qstorageinfo_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
void QStorageInfoPrivate::initRootPath()
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
rootPath = QString();
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::doStat()
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
return QList<QStorageInfo>();
|
||||
}
|
||||
|
||||
QStorageInfo QStorageInfoPrivate::root()
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
return QStorageInfo();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,454 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qstorageinfo_p.h"
|
||||
|
||||
#include <QtCore/qdiriterator.h>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/qtextstream.h>
|
||||
|
||||
#include <QtCore/private/qcore_unix_p.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(Q_OS_BSD4)
|
||||
# include <sys/mount.h>
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
# include <sys/mount.h>
|
||||
# include <sys/vfs.h>
|
||||
# include <mntent.h>
|
||||
#elif defined(Q_OS_QNX)
|
||||
# include <sys/statvfs.h>
|
||||
#elif defined(Q_OS_LINUX)
|
||||
# include <mntent.h>
|
||||
# include <sys/statvfs.h>
|
||||
#elif defined(Q_OS_SOLARIS)
|
||||
# include <sys/mnttab.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_BSD4)
|
||||
# define QT_STATFSBUF struct statvfs
|
||||
# define QT_STATFS ::statvfs
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
# define QT_STATFS ::statfs
|
||||
# define QT_STATFSBUF struct statfs
|
||||
# if !defined(ST_RDONLY)
|
||||
# define ST_RDONLY 1 // hack for missing define on Android
|
||||
# endif
|
||||
#else
|
||||
# if defined(QT_LARGEFILE_SUPPORT)
|
||||
# define QT_STATFSBUF struct statvfs64
|
||||
# define QT_STATFS ::statvfs64
|
||||
# else
|
||||
# define QT_STATFSBUF struct statvfs
|
||||
# define QT_STATFS ::statvfs
|
||||
# endif // QT_LARGEFILE_SUPPORT
|
||||
#endif // Q_OS_BSD4
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static bool isPseudoFs(const QString &mountDir, const QByteArray &type)
|
||||
{
|
||||
if (mountDir.startsWith(QStringLiteral("/dev"))
|
||||
|| mountDir.startsWith(QStringLiteral("/proc"))
|
||||
|| mountDir.startsWith(QStringLiteral("/run"))
|
||||
|| mountDir.startsWith(QStringLiteral("/sys"))
|
||||
|| mountDir.startsWith(QStringLiteral("/var/run"))
|
||||
|| mountDir.startsWith(QStringLiteral("/var/lock"))) {
|
||||
return true;
|
||||
}
|
||||
#if defined(Q_OS_LINUX)
|
||||
if (type == "rootfs")
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(type);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class QStorageIterator
|
||||
{
|
||||
public:
|
||||
QStorageIterator();
|
||||
~QStorageIterator();
|
||||
|
||||
inline bool isValid() const;
|
||||
inline bool next();
|
||||
inline QString rootPath() const;
|
||||
inline QByteArray fileSystemType() const;
|
||||
inline QByteArray device() const;
|
||||
private:
|
||||
#if defined(Q_OS_BSD4)
|
||||
statfs *stat_buf;
|
||||
int entryCount;
|
||||
int currentIndex;
|
||||
#elif defined(Q_OS_SOLARIS)
|
||||
FILE *fp;
|
||||
mnttab mnt;
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
QFile file;
|
||||
QByteArray m_rootPath;
|
||||
QByteArray m_fileSystemType;
|
||||
QByteArray m_device;
|
||||
#elif defined(Q_OS_LINUX)
|
||||
FILE *fp;
|
||||
mntent mnt;
|
||||
QByteArray buffer;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(Q_OS_BSD4)
|
||||
|
||||
inline QStorageIterator::QStorageIterator()
|
||||
: entryCount(::getmntinfo(&stat_buf, 0)),
|
||||
currentIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
inline QStorageIterator::~QStorageIterator()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::isValid() const
|
||||
{
|
||||
return entryCount != -1;
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::next()
|
||||
{
|
||||
return ++currentIndex < entryCount;
|
||||
}
|
||||
|
||||
inline QString QStorageIterator::rootPath() const
|
||||
{
|
||||
return QFile::decodeName(stat_buf[currentIndex].f_mntonname);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::fileSystemType() const
|
||||
{
|
||||
return QByteArray(stat_buf[currentIndex].f_fstypename);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::device() const
|
||||
{
|
||||
return QByteArray(stat_buf[currentIndex].f_mntfromname);
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_SOLARIS)
|
||||
|
||||
static const char pathMounted[] = "/etc/mnttab";
|
||||
|
||||
inline QStorageIterator::QStorageIterator()
|
||||
{
|
||||
const int fd = qt_safe_open(pathMounted, O_RDONLY);
|
||||
fp = ::fdopen(fd, "r");
|
||||
}
|
||||
|
||||
inline QStorageIterator::~QStorageIterator()
|
||||
{
|
||||
if (fp)
|
||||
::fclose(fp);
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::isValid() const
|
||||
{
|
||||
return fp != Q_NULLPTR;
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::next()
|
||||
{
|
||||
return ::getmntent(fp, &mnt) == Q_NULLPTR;
|
||||
}
|
||||
|
||||
inline QString QStorageIterator::rootPath() const
|
||||
{
|
||||
return QFile::decodeName(mnt->mnt_mountp);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::fileSystemType() const
|
||||
{
|
||||
return QByteArray(mnt->mnt_fstype);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::device() const
|
||||
{
|
||||
return QByteArray(mnt->mnt_mntopts);
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
|
||||
static const char pathMounted[] = "/proc/mounts";
|
||||
|
||||
inline QStorageIterator::QStorageIterator()
|
||||
{
|
||||
file.setFileName(pathMounted);
|
||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
}
|
||||
|
||||
inline QStorageIterator::~QStorageIterator()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::isValid() const
|
||||
{
|
||||
return file.isOpen();
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::next()
|
||||
{
|
||||
QList<QByteArray> data;
|
||||
do {
|
||||
const QByteArray line = file.readLine();
|
||||
data = line.split(' ');
|
||||
} while (data.count() < 3 && !file.atEnd());
|
||||
|
||||
if (file.atEnd())
|
||||
return false;
|
||||
m_device = data.at(0);
|
||||
m_rootPath = data.at(1);
|
||||
m_fileSystemType = data.at(2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline QString QStorageIterator::rootPath() const
|
||||
{
|
||||
return QFile::decodeName(m_rootPath);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::fileSystemType() const
|
||||
{
|
||||
return m_fileSystemType;
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::device() const
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_LINUX)
|
||||
|
||||
static const char pathMounted[] = "/etc/mtab";
|
||||
static const int bufferSize = 3*PATH_MAX; // 2 paths (mount point+device) and metainfo
|
||||
|
||||
inline QStorageIterator::QStorageIterator() :
|
||||
buffer(QByteArray(bufferSize, 0))
|
||||
{
|
||||
fp = ::setmntent(pathMounted, "r");
|
||||
}
|
||||
|
||||
inline QStorageIterator::~QStorageIterator()
|
||||
{
|
||||
if (fp)
|
||||
::endmntent(fp);
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::isValid() const
|
||||
{
|
||||
return fp != Q_NULLPTR;
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::next()
|
||||
{
|
||||
return ::getmntent_r(fp, &mnt, buffer.data(), buffer.size()) != Q_NULLPTR;
|
||||
}
|
||||
|
||||
inline QString QStorageIterator::rootPath() const
|
||||
{
|
||||
return QFile::decodeName(mnt.mnt_dir);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::fileSystemType() const
|
||||
{
|
||||
return QByteArray(mnt.mnt_type);
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::device() const
|
||||
{
|
||||
return QByteArray(mnt.mnt_fsname);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline QStorageIterator::QStorageIterator()
|
||||
{
|
||||
}
|
||||
|
||||
inline QStorageIterator::~QStorageIterator()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::isValid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool QStorageIterator::next()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline QString QStorageIterator::rootPath() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::fileSystemType() const
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
inline QByteArray QStorageIterator::device() const
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void QStorageInfoPrivate::initRootPath()
|
||||
{
|
||||
rootPath = QFileInfo(rootPath).canonicalFilePath();
|
||||
|
||||
if (rootPath.isEmpty())
|
||||
return;
|
||||
|
||||
QStorageIterator it;
|
||||
if (!it.isValid()) {
|
||||
rootPath = QStringLiteral("/");
|
||||
return;
|
||||
}
|
||||
|
||||
int maxLength = 0;
|
||||
const QString oldRootPath = rootPath;
|
||||
rootPath.clear();
|
||||
|
||||
while (it.next()) {
|
||||
const QString mountDir = it.rootPath();
|
||||
const QByteArray fsName = it.fileSystemType();
|
||||
if (isPseudoFs(mountDir, fsName))
|
||||
continue;
|
||||
// we try to find most suitable entry
|
||||
if (oldRootPath.startsWith(mountDir) && maxLength < mountDir.length()) {
|
||||
maxLength = mountDir.length();
|
||||
rootPath = mountDir;
|
||||
device = it.device();
|
||||
fileSystemType = fsName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline QString retrieveLabel(const QByteArray &device)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
static const char pathDiskByLabel[] = "/dev/disk/by-label";
|
||||
|
||||
QDirIterator it(QLatin1String(pathDiskByLabel), QDir::NoDotAndDotDot);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QFileInfo fileInfo(it.fileInfo());
|
||||
if (fileInfo.isSymLink() && fileInfo.symLinkTarget().toLocal8Bit() == device)
|
||||
return fileInfo.fileName();
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(device);
|
||||
#endif
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::doStat()
|
||||
{
|
||||
initRootPath();
|
||||
if (rootPath.isEmpty())
|
||||
return;
|
||||
|
||||
retreiveVolumeInfo();
|
||||
name = retrieveLabel(device);
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::retreiveVolumeInfo()
|
||||
{
|
||||
QT_STATFSBUF statfs_buf;
|
||||
int result;
|
||||
EINTR_LOOP(result, QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf));
|
||||
if (result == 0) {
|
||||
valid = true;
|
||||
ready = true;
|
||||
|
||||
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize;
|
||||
bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize;
|
||||
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize;
|
||||
#if defined(Q_OS_ANDROID)
|
||||
readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0;
|
||||
#else
|
||||
readOnly = (statfs_buf.f_flag & ST_RDONLY) != 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
|
||||
{
|
||||
QStorageIterator it;
|
||||
if (!it.isValid())
|
||||
return QList<QStorageInfo>() << root();
|
||||
|
||||
QList<QStorageInfo> volumes;
|
||||
|
||||
while (it.next()) {
|
||||
const QString mountDir = it.rootPath();
|
||||
const QByteArray fsName = it.fileSystemType();
|
||||
if (isPseudoFs(mountDir, fsName))
|
||||
continue;
|
||||
|
||||
volumes.append(QStorageInfo(mountDir));
|
||||
}
|
||||
|
||||
return volumes;
|
||||
}
|
||||
|
||||
QStorageInfo QStorageInfoPrivate::root()
|
||||
{
|
||||
return QStorageInfo(QStringLiteral("/"));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qstorageinfo_p.h"
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const int defaultBufferSize = MAX_PATH + 1;
|
||||
|
||||
void QStorageInfoPrivate::initRootPath()
|
||||
{
|
||||
rootPath = QFileInfo(rootPath).canonicalFilePath();
|
||||
|
||||
if (rootPath.isEmpty())
|
||||
return;
|
||||
|
||||
QString path = QDir::toNativeSeparators(rootPath);
|
||||
rootPath.clear();
|
||||
|
||||
if (path.startsWith(QStringLiteral("\\\\?\\")))
|
||||
path.remove(0, 4);
|
||||
if (path.length() < 2 || path.at(1) != QLatin1Char(':'))
|
||||
return;
|
||||
path[0] = path[0].toUpper();
|
||||
if (!(path.at(0).unicode() >= 'A' && path.at(0).unicode() <= 'Z'))
|
||||
return;
|
||||
if (!path.endsWith(QLatin1Char('\\')))
|
||||
path.append(QLatin1Char('\\'));
|
||||
|
||||
// ### test if disk mounted to folder on other disk
|
||||
wchar_t buffer[defaultBufferSize];
|
||||
if (::GetVolumePathName(reinterpret_cast<const wchar_t *>(path.utf16()), buffer, defaultBufferSize))
|
||||
rootPath = QDir::fromNativeSeparators(QString::fromWCharArray(buffer));
|
||||
}
|
||||
|
||||
static inline QByteArray getDevice(const QString &rootPath)
|
||||
{
|
||||
const QString path = QDir::toNativeSeparators(rootPath);
|
||||
const UINT type = ::GetDriveType(reinterpret_cast<const wchar_t *>(path.utf16()));
|
||||
if (type == DRIVE_REMOTE) {
|
||||
QVarLengthArray<char, 256> buffer(256);
|
||||
DWORD bufferLength = buffer.size();
|
||||
DWORD result;
|
||||
UNIVERSAL_NAME_INFO *remoteNameInfo;
|
||||
do {
|
||||
buffer.resize(bufferLength);
|
||||
remoteNameInfo = reinterpret_cast<UNIVERSAL_NAME_INFO *>(buffer.data());
|
||||
result = ::WNetGetUniversalName(reinterpret_cast<const wchar_t *>(path.utf16()),
|
||||
UNIVERSAL_NAME_INFO_LEVEL,
|
||||
remoteNameInfo,
|
||||
&bufferLength);
|
||||
} while (result == ERROR_MORE_DATA);
|
||||
if (result == NO_ERROR)
|
||||
return QString::fromWCharArray(remoteNameInfo->lpUniversalName).toUtf8();
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
wchar_t deviceBuffer[51];
|
||||
if (::GetVolumeNameForVolumeMountPoint(reinterpret_cast<const wchar_t *>(path.utf16()),
|
||||
deviceBuffer,
|
||||
sizeof(deviceBuffer) / sizeof(wchar_t))) {
|
||||
return QString::fromWCharArray(deviceBuffer).toLatin1();
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::doStat()
|
||||
{
|
||||
initRootPath();
|
||||
if (rootPath.isEmpty())
|
||||
return;
|
||||
|
||||
retreiveVolumeInfo();
|
||||
device = getDevice(rootPath);
|
||||
retreiveDiskFreeSpace();
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::retreiveVolumeInfo()
|
||||
{
|
||||
const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
const QString path = QDir::toNativeSeparators(rootPath);
|
||||
wchar_t nameBuffer[defaultBufferSize];
|
||||
wchar_t fileSystemTypeBuffer[defaultBufferSize];
|
||||
DWORD fileSystemFlags = 0;
|
||||
const bool result = ::GetVolumeInformation(reinterpret_cast<const wchar_t *>(path.utf16()),
|
||||
nameBuffer,
|
||||
defaultBufferSize,
|
||||
Q_NULLPTR,
|
||||
Q_NULLPTR,
|
||||
&fileSystemFlags,
|
||||
fileSystemTypeBuffer,
|
||||
defaultBufferSize);
|
||||
if (!result) {
|
||||
ready = false;
|
||||
valid = ::GetLastError() == ERROR_NOT_READY;
|
||||
} else {
|
||||
ready = true;
|
||||
valid = true;
|
||||
|
||||
fileSystemType = QString::fromWCharArray(fileSystemTypeBuffer).toLatin1();
|
||||
name = QString::fromWCharArray(nameBuffer);
|
||||
|
||||
readOnly = (fileSystemFlags & FILE_READ_ONLY_VOLUME) != 0;
|
||||
}
|
||||
|
||||
::SetErrorMode(oldmode);
|
||||
}
|
||||
|
||||
void QStorageInfoPrivate::retreiveDiskFreeSpace()
|
||||
{
|
||||
const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
const QString path = QDir::toNativeSeparators(rootPath);
|
||||
::GetDiskFreeSpaceEx(reinterpret_cast<const wchar_t *>(path.utf16()),
|
||||
PULARGE_INTEGER(&bytesAvailable),
|
||||
PULARGE_INTEGER(&bytesTotal),
|
||||
PULARGE_INTEGER(&bytesFree));
|
||||
|
||||
::SetErrorMode(oldmode);
|
||||
}
|
||||
|
||||
QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
|
||||
{
|
||||
QList<QStorageInfo> volumes;
|
||||
|
||||
QString driveName = QStringLiteral("A:/");
|
||||
const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
quint32 driveBits = quint32(::GetLogicalDrives()) & 0x3ffffff;
|
||||
::SetErrorMode(oldmode);
|
||||
while (driveBits) {
|
||||
if (driveBits & 1) {
|
||||
QStorageInfo drive(driveName);
|
||||
if (!drive.rootPath().isEmpty()) // drive exists, but not mounted
|
||||
volumes.append(drive);
|
||||
}
|
||||
driveName[0] = driveName[0].unicode() + 1;
|
||||
driveBits = driveBits >> 1;
|
||||
}
|
||||
|
||||
return volumes;
|
||||
}
|
||||
|
||||
QStorageInfo QStorageInfoPrivate::root()
|
||||
{
|
||||
return QStorageInfo(QDir::fromNativeSeparators(QFile::decodeName(qgetenv("SystemDrive"))));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -26,6 +26,7 @@ SUBDIRS=\
|
|||
qsettings \
|
||||
qsavefile \
|
||||
qstandardpaths \
|
||||
qstorageinfo \
|
||||
qtemporarydir \
|
||||
qtemporaryfile \
|
||||
qtextstream \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
CONFIG += testcase
|
||||
TARGET = tst_qstorageinfo
|
||||
QT = core-private testlib
|
||||
SOURCES = tst_qstorageinfo.cpp
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <QStorageInfo>
|
||||
|
||||
class tst_QStorageInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void defaultValues();
|
||||
void operatorEqual();
|
||||
#ifndef Q_OS_WINRT
|
||||
void operatorNotEqual();
|
||||
void root();
|
||||
void currentStorage();
|
||||
void storageList();
|
||||
void tempFile();
|
||||
void caching();
|
||||
#endif
|
||||
};
|
||||
|
||||
void tst_QStorageInfo::defaultValues()
|
||||
{
|
||||
QStorageInfo storage;
|
||||
|
||||
QVERIFY(!storage.isValid());
|
||||
QVERIFY(!storage.isReady());
|
||||
QVERIFY(storage.rootPath().isEmpty());
|
||||
QVERIFY(!storage.isRoot());
|
||||
QVERIFY(storage.device().isEmpty());
|
||||
QVERIFY(storage.fileSystemType().isEmpty());
|
||||
QVERIFY(storage.bytesTotal() == 0);
|
||||
QVERIFY(storage.bytesFree() == 0);
|
||||
QVERIFY(storage.bytesAvailable() == 0);
|
||||
}
|
||||
|
||||
void tst_QStorageInfo::operatorEqual()
|
||||
{
|
||||
{
|
||||
QStorageInfo storage1 = QStorageInfo::root();
|
||||
QStorageInfo storage2(QDir::rootPath());
|
||||
QVERIFY(storage1 == storage2);
|
||||
}
|
||||
|
||||
{
|
||||
QStorageInfo storage1(QCoreApplication::applicationDirPath());
|
||||
QStorageInfo storage2(QCoreApplication::applicationFilePath());
|
||||
QVERIFY(storage1 == storage2);
|
||||
}
|
||||
|
||||
{
|
||||
QStorageInfo storage1;
|
||||
QStorageInfo storage2;
|
||||
QVERIFY(storage1 == storage2);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WINRT
|
||||
void tst_QStorageInfo::operatorNotEqual()
|
||||
{
|
||||
QStorageInfo storage1 = QStorageInfo::root();
|
||||
QStorageInfo storage2;
|
||||
QVERIFY(storage1 != storage2);
|
||||
}
|
||||
|
||||
void tst_QStorageInfo::root()
|
||||
{
|
||||
QStorageInfo storage = QStorageInfo::root();
|
||||
|
||||
QVERIFY(storage.isValid());
|
||||
QVERIFY(storage.isReady());
|
||||
QCOMPARE(storage.rootPath(), QDir::rootPath());
|
||||
QVERIFY(storage.isRoot());
|
||||
QVERIFY(!storage.device().isEmpty());
|
||||
QVERIFY(!storage.fileSystemType().isEmpty());
|
||||
QVERIFY(storage.bytesTotal() > 0);
|
||||
QVERIFY(storage.bytesFree() > 0);
|
||||
QVERIFY(storage.bytesAvailable() > 0);
|
||||
}
|
||||
|
||||
void tst_QStorageInfo::currentStorage()
|
||||
{
|
||||
QString appPath = QCoreApplication::applicationFilePath();
|
||||
QStorageInfo storage(appPath);
|
||||
QVERIFY(storage.isValid());
|
||||
QVERIFY(storage.isReady());
|
||||
QVERIFY(appPath.startsWith(storage.rootPath(), Qt::CaseInsensitive));
|
||||
QVERIFY(!storage.device().isEmpty());
|
||||
QVERIFY(!storage.fileSystemType().isEmpty());
|
||||
QVERIFY(storage.bytesTotal() > 0);
|
||||
QVERIFY(storage.bytesFree() > 0);
|
||||
QVERIFY(storage.bytesAvailable() > 0);
|
||||
}
|
||||
|
||||
void tst_QStorageInfo::storageList()
|
||||
{
|
||||
QStorageInfo root = QStorageInfo::root();
|
||||
|
||||
QList<QStorageInfo> volumes = QStorageInfo::mountedVolumes();
|
||||
|
||||
// at least, root storage should be present
|
||||
QVERIFY(volumes.contains(root));
|
||||
volumes.removeOne(root);
|
||||
QVERIFY(!volumes.contains(root));
|
||||
|
||||
foreach (const QStorageInfo &storage, volumes) {
|
||||
if (!storage.isReady())
|
||||
continue;
|
||||
|
||||
QVERIFY(storage.isValid());
|
||||
QVERIFY(!storage.isRoot());
|
||||
#ifndef Q_OS_WIN
|
||||
QVERIFY(!storage.device().isEmpty());
|
||||
QVERIFY(!storage.fileSystemType().isEmpty());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QStorageInfo::tempFile()
|
||||
{
|
||||
QTemporaryFile file;
|
||||
QVERIFY(file.open());
|
||||
|
||||
QStorageInfo storage1(file.fileName());
|
||||
qint64 free = storage1.bytesFree();
|
||||
|
||||
file.write(QByteArray(1024*1024, '1'));
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
QStorageInfo storage2(file.fileName());
|
||||
QVERIFY(free != storage2.bytesFree());
|
||||
}
|
||||
|
||||
void tst_QStorageInfo::caching()
|
||||
{
|
||||
QTemporaryFile file;
|
||||
QVERIFY(file.open());
|
||||
|
||||
QStorageInfo storage1(file.fileName());
|
||||
qint64 free = storage1.bytesFree();
|
||||
QStorageInfo storage2(storage1);
|
||||
QVERIFY(free == storage2.bytesFree());
|
||||
|
||||
file.write(QByteArray(1024*1024, '\0'));
|
||||
file.flush();
|
||||
|
||||
QVERIFY(free == storage1.bytesFree());
|
||||
QVERIFY(free == storage2.bytesFree());
|
||||
storage2.refresh();
|
||||
QVERIFY(storage1 == storage2);
|
||||
QVERIFY(free != storage2.bytesFree());
|
||||
}
|
||||
#endif
|
||||
|
||||
QTEST_MAIN(tst_QStorageInfo)
|
||||
|
||||
#include "tst_qstorageinfo.moc"
|
||||
Loading…
Reference in New Issue