Remove Symbian support from src/corelib/io/.

Change-Id: I52c2a58396e03f29ca478de34c914535c7ae1012
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
bb10
Robin Burchell 2011-12-27 18:11:08 +01:00 committed by Qt by Nokia
parent 5a3b08e994
commit 467a000089
7 changed files with 7 additions and 2030 deletions

View File

@ -83,16 +83,12 @@ win32 {
SOURCES += io/qfilesystemiterator_win.cpp
SOURCES += io/qstandardpaths_win.cpp
} else:unix {
SOURCES += io/qfsfileengine_unix.cpp
symbian {
SOURCES += io/qfilesystemengine_symbian.cpp
SOURCES += io/qprocess_symbian.cpp
SOURCES += io/qfilesystemiterator_symbian.cpp
} else {
SOURCES += io/qfilesystemengine_unix.cpp
SOURCES += io/qprocess_unix.cpp
SOURCES += io/qfilesystemiterator_unix.cpp
}
SOURCES += \
io/qfsfileengine_unix.cpp \
io/qfilesystemengine_unix.cpp \
io/qprocess_unix.cpp \
io/qfilesystemiterator_unix.cpp \
!nacl:macx-*: {
HEADERS += io/qfilesystemwatcher_fsevents_p.h
SOURCES += io/qfilesystemengine_mac.cpp
@ -104,7 +100,7 @@ win32 {
SOURCES += io/qstandardpaths_unix.cpp
}
linux-*:!symbian {
linux-* {
SOURCES += \
io/qfilesystemwatcher_inotify.cpp \
io/qfilesystemwatcher_dnotify.cpp
@ -120,13 +116,6 @@ win32 {
HEADERS += io/qfilesystemwatcher_kqueue_p.h
}
}
symbian {
SOURCES += io/qfilesystemwatcher_symbian.cpp
HEADERS += io/qfilesystemwatcher_symbian_p.h
INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
LIBS += -lplatformenv -lesock
}
}
integrity {
SOURCES += io/qfsfileengine_unix.cpp \

View File

@ -1,406 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfilesystemengine_p.h"
#include "qfsfileengine.h"
#include <QtCore/private/qcore_symbian_p.h>
#include <QtCore/qcoreapplication.h>
#include <f32file.h>
#include <pathinfo.h>
#include <wchar.h>
QT_BEGIN_NAMESPACE
bool QFileSystemEngine::isCaseSensitive()
{
return false;
}
//TODO: resolve this with QDir::cleanPath, without breaking the behaviour of that
//function which is documented only by autotest
//input: a dirty absolute path, e.g. c:/../../foo/./
//output: a clean absolute path, e.g. c:/foo/
static QString symbianCleanAbsolutePath(const QString& path)
{
bool isDir = path.endsWith(QLatin1Char('/'));
//using SkipEmptyParts flag to eliminate duplicated slashes
QStringList components = path.split(QLatin1Char('/'), QString::SkipEmptyParts);
int cdups = 0;
for(int i=components.count() - 1; i>=0; --i) {
if(components.at(i) == QLatin1String("..")) {
components.removeAt(i);
cdups++;
}
else if(components.at(i) == QLatin1String(".")) {
components.removeAt(i);
}
else if(cdups && i > 0) {
--cdups;
components.removeAt(i);
}
}
QString result = components.join(QLatin1String("/"));
if ((isDir&& !result.endsWith(QLatin1Char('/')))
|| (result.length() == 2 && result.at(1).unicode() == ':'))
result.append(QLatin1Char('/'));
return result;
}
//static
QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data)
{
Q_UNUSED(data);
return link;
}
//static
QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
{
if (entry.isEmpty() || entry.isRoot())
return entry;
QFileSystemEntry result = absoluteName(entry);
if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute))
fillMetaData(result, data, QFileSystemMetaData::ExistsAttribute);
if (!data.exists()) {
// file doesn't exist
return QFileSystemEntry();
} else {
return result;
}
}
//static
QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
{
QString orig = entry.filePath();
const bool isAbsolute = entry.isAbsolute();
const bool isDirty = !entry.isClean();
if (isAbsolute && !isDirty)
return entry;
const bool isRelative = entry.isRelative();
const bool needsDrive = (!orig.isEmpty() && orig.at(0).unicode() == '/');
const bool isDriveLetter = !needsDrive && !isAbsolute && !isRelative && orig.length() == 2;
const bool isDriveRelative = !needsDrive && !isAbsolute && !isRelative && orig.length() > 2;
QString result;
if (needsDrive || isDriveLetter || isDriveRelative || !isAbsolute || orig.isEmpty()) {
QFileSystemEntry cur(currentPath());
if(needsDrive)
result = cur.filePath().left(2);
else if(isDriveRelative && cur.filePath().at(0) != orig.at(0))
result = orig.left(2); // for BC, see tst_QFileInfo::absolutePath(<not current drive>:my.dll)
else
result = cur.filePath();
if(isDriveLetter) {
result[0] = orig.at(0); //copy drive letter
orig.clear();
}
if(isDriveRelative) {
orig = orig.mid(2); //discard the drive specifier from orig
}
}
if (!orig.isEmpty() && !(orig.length() == 1 && orig.at(0).unicode() == '.')) {
if (!result.isEmpty() && !result.endsWith(QLatin1Char('/')))
result.append(QLatin1Char('/'));
result.append(orig);
}
return QFileSystemEntry(symbianCleanAbsolutePath(result), QFileSystemEntry::FromInternalPath());
}
void QFileSystemMetaData::fillFromTEntry(const TEntry& entry)
{
entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags);
knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags;
//Symbian doesn't have unix type file permissions
entryFlags |= QFileSystemMetaData::ReadPermissions;
if(!entry.IsReadOnly()) {
entryFlags |= QFileSystemMetaData::WritePermissions;
}
//set the type
if(entry.IsDir())
entryFlags |= (QFileSystemMetaData::DirectoryType | QFileSystemMetaData::ExecutePermissions);
else
entryFlags |= QFileSystemMetaData::FileType;
//set the attributes
entryFlags |= QFileSystemMetaData::ExistsAttribute;
if(entry.IsHidden())
entryFlags |= QFileSystemMetaData::HiddenAttribute;
#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
size_ = entry.FileSize();
#else
size_ = (TUint)(entry.iSize);
#endif
modificationTime_ = entry.iModified;
}
void QFileSystemMetaData::fillFromVolumeInfo(const TVolumeInfo& info)
{
entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags);
knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags;
entryFlags |= QFileSystemMetaData::ExistsAttribute;
entryFlags |= QFileSystemMetaData::Permissions;
if(info.iDrive.iDriveAtt & KDriveAttRom) {
entryFlags &= ~(QFileSystemMetaData::WritePermissions);
}
entryFlags |= QFileSystemMetaData::DirectoryType;
size_ = info.iSize;
modificationTime_ = qt_symbian_time_t_To_TTime(0);
}
//static
bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what)
{
if (what & QFileSystemMetaData::SymbianTEntryFlags) {
RFs& fs(qt_s60GetRFs());
TInt err;
QFileSystemEntry absentry(absoluteName(entry));
if (entry.isEmpty()) {
err = KErrNotFound;
} else if (absentry.isRoot()) {
//Root directories don't have an entry, and Entry() returns KErrBadName.
//Therefore get information about the volume instead.
TInt drive;
err = RFs::CharToDrive(TChar(absentry.nativeFilePath().at(0).unicode()), drive);
if (!err) {
TVolumeInfo info;
err = fs.Volume(info, drive);
if (!err)
data.fillFromVolumeInfo(info);
}
} else {
TEntry ent;
err = fs.Entry(qt_QString2TPtrC(absentry.nativeFilePath()), ent);
if (!err)
data.fillFromTEntry(ent);
}
if (err) {
data.size_ = 0;
data.modificationTime_ = TTime(0);
data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags);
}
//files in /sys/bin on any drive are executable, even though we don't normally have permission to check whether they exist or not
if(absentry.filePath().midRef(1,10).compare(QLatin1String(":/sys/bin/"), Qt::CaseInsensitive) == 0)
data.entryFlags |= QFileSystemMetaData::ExecutePermissions;
}
return data.hasFlags(what);
}
//static
bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents)
{
QString abspath = absoluteName(entry).nativeFilePath();
if (!abspath.endsWith(QLatin1Char('\\')))
abspath.append(QLatin1Char('\\'));
TInt r;
if (createParents)
r = qt_s60GetRFs().MkDirAll(qt_QString2TPtrC(abspath));
else
r = qt_s60GetRFs().MkDir(qt_QString2TPtrC(abspath));
if (createParents && r == KErrAlreadyExists)
return true; //# Qt5 - QDir::mkdir returns false for existing dir, QDir::mkpath returns true (should be made consistent in Qt 5)
return (r == KErrNone);
}
//static
bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents)
{
QString abspath = absoluteName(entry).nativeFilePath();
if (!abspath.endsWith(QLatin1Char('\\')))
abspath.append(QLatin1Char('\\'));
TPtrC dir(qt_QString2TPtrC(abspath));
RFs& fs = qt_s60GetRFs();
bool ok = false;
//behaviour of FS file engine:
//returns true if the directory could be removed
//success/failure of removing parent directories does not matter
while (KErrNone == fs.RmDir(dir)) {
ok = true;
if (!removeEmptyParents)
break;
//RFs::RmDir treats "c:\foo\bar" and "c:\foo\" the same, so it is sufficient to remove the last \ to the end
dir.Set(dir.Left(dir.LocateReverse(TChar('\\'))));
}
return ok;
}
//static
bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
Q_UNUSED(source)
Q_UNUSED(target)
error = QSystemError(KErrNotSupported, QSystemError::NativeError);
return false;
}
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
//CFileMan is allocated each time because it is not thread-safe
CFileMan *fm = 0;
TRAPD(err, fm = CFileMan::NewL(qt_s60GetRFs()));
if (err == KErrNone) {
err = fm->Copy(qt_QString2TPtrC(absoluteName(source).nativeFilePath()), qt_QString2TPtrC(absoluteName(target).nativeFilePath()), 0);
delete fm;
}
if (err == KErrNone)
return true;
error = QSystemError(err, QSystemError::NativeError);
return false;
}
//static
bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
QString sourcepath = absoluteName(source).nativeFilePath();
QString targetpath = absoluteName(target).nativeFilePath();
RFs& fs(qt_s60GetRFs());
TInt err = fs.Rename(qt_QString2TPtrC(sourcepath), qt_QString2TPtrC(targetpath));
if (err == KErrNone)
return true;
error = QSystemError(err, QSystemError::NativeError);
return false;
}
//static
bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error)
{
QString targetpath = absoluteName(entry).nativeFilePath();
RFs& fs(qt_s60GetRFs());
TInt err = fs.Delete(qt_QString2TPtrC(targetpath));
if (err == KErrNone)
return true;
error = QSystemError(err, QSystemError::NativeError);
return false;
}
//static
bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data)
{
QString targetpath = absoluteName(entry).nativeFilePath();
TUint setmask = 0;
TUint clearmask = 0;
RFs& fs(qt_s60GetRFs());
if (permissions & (QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther))
clearmask = KEntryAttReadOnly; //if anyone can write, it's not read-only
else
setmask = KEntryAttReadOnly;
TInt err = fs.SetAtt(qt_QString2TPtrC(targetpath), setmask, clearmask);
if (data && !err) {
data->entryFlags &= ~QFileSystemMetaData::Permissions;
data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions));
data->knownFlagsMask |= QFileSystemMetaData::Permissions;
}
if (err == KErrNone)
return true;
error = QSystemError(err, QSystemError::NativeError);
return false;
}
QString QFileSystemEngine::homePath()
{
QString home = QDir::fromNativeSeparators(qt_TDesC2QString(PathInfo::PhoneMemoryRootPath()));
if(home.endsWith(QLatin1Char('/')))
home.chop(1);
return home;
}
QString QFileSystemEngine::rootPath()
{
TChar drive;
TInt err = RFs::DriveToChar(RFs::GetSystemDrive(), drive); //RFs::GetSystemDriveChar not supported on S60 3.1
Q_ASSERT(err == KErrNone); //RFs::GetSystemDrive() shall always return a convertible drive number on a valid OS configuration
return QString(QChar(drive)).append(QLatin1String(":/"));
}
QString QFileSystemEngine::tempPath()
{
return rootPath().append(QLatin1String("system/temp"));
}
//static
bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
{
QFileSystemMetaData meta;
QFileSystemEntry absname = absoluteName(entry);
fillMetaData(absname, meta, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType);
if(!(meta.exists() && meta.isDirectory()))
return false;
RFs& fs = qt_s60GetRFs();
QString abspath = absname.nativeFilePath();
if(!abspath.endsWith(QLatin1Char('\\')))
abspath.append(QLatin1Char('\\'));
TInt r = fs.SetSessionPath(qt_QString2TPtrC(abspath));
//SetSessionPath succeeds for non existent directory, which is why it's checked above
if (r == KErrNone) {
__ASSERT_COMPILE(sizeof(wchar_t) == sizeof(unsigned short));
//attempt to set open C to the same path
r = ::wchdir(reinterpret_cast<const wchar_t *>(absname.filePath().utf16()));
if (r < 0)
qWarning("failed to sync path to open C");
return true;
}
return false;
}
//static
QFileSystemEntry QFileSystemEngine::currentPath()
{
TFileName fn;
QFileSystemEntry ret;
TInt r = qt_s60GetRFs().SessionPath(fn);
if(r == KErrNone) {
//remove terminating slash from non root paths (session path is clean, absolute and always ends in a \)
if(fn.Length() > 3 && fn[fn.Length() - 1] == '\\')
fn.SetLength(fn.Length() - 1);
ret = QFileSystemEntry(qt_TDesC2QString(fn), QFileSystemEntry::FromNativePath());
}
return ret;
}
QT_END_NAMESPACE

View File

@ -1,127 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfilesystemiterator_p.h"
#include "qfilesystemengine_p.h"
#include <QtCore/private/qcore_symbian_p.h>
QT_BEGIN_NAMESPACE
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Filters filters,
const QStringList &nameFilters, QDirIterator::IteratorFlags iteratorFlags)
: lastError(KErrNone), entryIndex(-1)
{
RFs& fs = qt_s60GetRFs();
nativePath = path.nativeFilePath();
if (!nativePath.endsWith(QLatin1Char('\\')))
nativePath.append(QLatin1Char('\\'));
QString absPath = QFileSystemEngine::absoluteName(path).nativeFilePath();
if (!absPath.endsWith(QLatin1Char('\\')))
absPath.append(QLatin1Char('\\'));
int pathLen = absPath.length();
if (pathLen > KMaxFileName) {
lastError = KErrBadName;
return;
}
//set up server side filtering to reduce IPCs
//RDir won't accept all valid name filters e.g. "*. bar"
if (nameFilters.count() == 1 && !(filters & QDir::AllDirs) && iteratorFlags
== QDirIterator::NoIteratorFlags && pathLen + nameFilters[0].length()
<= KMaxFileName) {
//server side supports one mask - skip this for recursive mode or if only files should be filtered
absPath.append(nameFilters[0]);
}
TUint symbianMask = 0;
if ((filters & QDir::Dirs) || (filters & QDir::AllDirs) || (iteratorFlags
& QDirIterator::Subdirectories))
symbianMask |= KEntryAttDir; //include directories
if (filters & QDir::Hidden)
symbianMask |= KEntryAttHidden;
if (filters & QDir::System)
symbianMask |= KEntryAttSystem;
if (((filters & QDir::Files) == 0) && symbianMask == KEntryAttDir)
symbianMask |= KEntryAttMatchExclusive; //exclude non-directories
else if (symbianMask == 0) {
if ((filters & QDir::PermissionMask) == QDir::Writable)
symbianMask = KEntryAttMatchExclude | KEntryAttReadOnly;
}
lastError = dirHandle.Open(fs, qt_QString2TPtrC(absPath), symbianMask);
}
QFileSystemIterator::~QFileSystemIterator()
{
dirHandle.Close();
}
bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData)
{
//1st time, lastError is result of dirHandle.Open(), entries.Count() is 0 and entryIndex is -1 so initial read is triggered
//subsequent times, read is triggered each time we reach the end of the entry list
//final time, lastError is KErrEof so we don't need to read anymore.
++entryIndex;
if (lastError == KErrNone && entryIndex >= entries.Count()) {
lastError = dirHandle.Read(entries);
entryIndex = 0;
}
//each call to advance() gets the next entry from the entry list.
//from the final (or only) read call, KErrEof is returned together with a full buffer so we still need to go through the list
if ((lastError == KErrNone || lastError == KErrEof) && entryIndex < entries.Count()) {
Q_ASSERT(entryIndex >= 0);
const TEntry &entry(entries[entryIndex]);
fileEntry = QFileSystemEntry(nativePath + qt_TDesC2QString(entry.iName), QFileSystemEntry::FromNativePath());
metaData.fillFromTEntry(entry);
return true;
}
//TODO: error reporting, to allow user to distinguish empty directory from error condition.
return false;
}
QT_END_NAMESPACE

View File

@ -62,8 +62,6 @@
# include "qfilesystemwatcher_fsevents_p.h"
# endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
# include "qfilesystemwatcher_kqueue_p.h"
#elif defined(Q_OS_SYMBIAN)
# include "qfilesystemwatcher_symbian_p.h"
#endif
QT_BEGIN_NAMESPACE
@ -260,8 +258,6 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine()
else
# endif
return QKqueueFileSystemWatcherEngine::create();
#elif defined(Q_OS_SYMBIAN)
return new QSymbianFileSystemWatcherEngine;
#else
return 0;
#endif

View File

@ -1,273 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfilesystemwatcher.h"
#include "qfilesystemwatcher_symbian_p.h"
#include "qfileinfo.h"
#include "qdebug.h"
#include "private/qcore_symbian_p.h"
#include <QDir>
#ifndef QT_NO_FILESYSTEMWATCHER
QT_BEGIN_NAMESPACE
QNotifyChangeEvent::QNotifyChangeEvent(RFs &fs, const TDesC &file,
QSymbianFileSystemWatcherEngine *e, bool aIsDir,
TInt aPriority) :
CActive(aPriority),
isDir(aIsDir),
fsSession(fs),
watchedPath(file),
engine(e),
failureCount(0)
{
if (isDir) {
fsSession.NotifyChange(ENotifyEntry, iStatus, file);
} else {
fsSession.NotifyChange(ENotifyAll, iStatus, file);
}
CActiveScheduler::Add(this);
SetActive();
}
QNotifyChangeEvent::~QNotifyChangeEvent()
{
Cancel();
}
void QNotifyChangeEvent::RunL()
{
if(iStatus.Int() == KErrNone) {
failureCount = 0;
} else {
qWarning("QNotifyChangeEvent::RunL() - Failed to order change notifications: %d", iStatus.Int());
failureCount++;
}
// Re-request failed notification once, but if it won't start working,
// we can't do much besides just not request any more notifications.
if (failureCount < 2) {
if (isDir) {
fsSession.NotifyChange(ENotifyEntry, iStatus, watchedPath);
} else {
fsSession.NotifyChange(ENotifyAll, iStatus, watchedPath);
}
SetActive();
if (!failureCount) {
int err;
QT_TRYCATCH_ERROR(err, engine->emitPathChanged(this));
if (err != KErrNone)
qWarning("QNotifyChangeEvent::RunL() - emitPathChanged threw exception (Converted error code: %d)", err);
}
}
}
void QNotifyChangeEvent::DoCancel()
{
fsSession.NotifyChangeCancel(iStatus);
}
QSymbianFileSystemWatcherEngine::QSymbianFileSystemWatcherEngine() :
watcherStarted(false)
{
moveToThread(this);
}
QSymbianFileSystemWatcherEngine::~QSymbianFileSystemWatcherEngine()
{
stop();
}
QStringList QSymbianFileSystemWatcherEngine::addPaths(const QStringList &paths, QStringList *files,
QStringList *directories)
{
QMutexLocker locker(&mutex);
QStringList p = paths;
startWatcher();
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
QString path = it.next();
QFileInfo fi(path);
if (!fi.exists())
continue;
bool isDir = fi.isDir();
if (isDir) {
if (directories->contains(path))
continue;
} else {
if (files->contains(path))
continue;
}
// Use absolute filepath as relative paths seem to have some issues.
QString filePath = fi.absoluteFilePath();
if (isDir && filePath.at(filePath.size() - 1) != QChar(L'/')) {
filePath += QChar(L'/');
}
currentAddEvent = NULL;
QMetaObject::invokeMethod(this,
"addNativeListener",
Qt::QueuedConnection,
Q_ARG(QString, filePath));
syncCondition.wait(&mutex);
if (currentAddEvent) {
currentAddEvent->isDir = isDir;
activeObjectToPath.insert(currentAddEvent, path);
it.remove();
if (isDir)
directories->append(path);
else
files->append(path);
}
}
return p;
}
QStringList QSymbianFileSystemWatcherEngine::removePaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
QMutexLocker locker(&mutex);
QStringList p = paths;
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
QString path = it.next();
currentRemoveEvent = activeObjectToPath.key(path);
if (!currentRemoveEvent)
continue;
activeObjectToPath.remove(currentRemoveEvent);
QMetaObject::invokeMethod(this,
"removeNativeListener",
Qt::QueuedConnection);
syncCondition.wait(&mutex);
it.remove();
files->removeAll(path);
directories->removeAll(path);
}
return p;
}
void QSymbianFileSystemWatcherEngine::emitPathChanged(QNotifyChangeEvent *e)
{
QMutexLocker locker(&mutex);
QString path = activeObjectToPath.value(e);
QFileInfo fi(path);
if (e->isDir)
emit directoryChanged(path, !fi.exists());
else
emit fileChanged(path, !fi.exists());
}
void QSymbianFileSystemWatcherEngine::stop()
{
quit();
wait();
}
// This method must be called inside mutex
void QSymbianFileSystemWatcherEngine::startWatcher()
{
if (!watcherStarted) {
setStackSize(0x5000);
start();
syncCondition.wait(&mutex);
watcherStarted = true;
}
}
void QSymbianFileSystemWatcherEngine::run()
{
mutex.lock();
syncCondition.wakeOne();
mutex.unlock();
exec();
foreach(QNotifyChangeEvent *e, activeObjectToPath.keys()) {
e->Cancel();
delete e;
}
activeObjectToPath.clear();
}
void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directoryPath)
{
QMutexLocker locker(&mutex);
QString nativeDir(QDir::toNativeSeparators(directoryPath));
TPtrC ptr(qt_QString2TPtrC(nativeDir));
currentAddEvent = new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/'), Qt::CaseSensitive));
syncCondition.wakeOne();
}
void QSymbianFileSystemWatcherEngine::removeNativeListener()
{
QMutexLocker locker(&mutex);
currentRemoveEvent->Cancel();
delete currentRemoveEvent;
currentRemoveEvent = NULL;
syncCondition.wakeOne();
}
QT_END_NAMESPACE
#endif // QT_NO_FILESYSTEMWATCHER

View File

@ -1,130 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QFILESYSTEMWATCHER_SYMBIAN_P_H
#define QFILESYSTEMWATCHER_SYMBIAN_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 "qfilesystemwatcher_p.h"
#ifndef QT_NO_FILESYSTEMWATCHER
#include "qhash.h"
#include "qmutex.h"
#include "qwaitcondition.h"
#include <e32base.h>
#include <f32file.h>
QT_BEGIN_NAMESPACE
class QSymbianFileSystemWatcherEngine;
class QNotifyChangeEvent : public CActive
{
public:
QNotifyChangeEvent(RFs &fsSession, const TDesC &file, QSymbianFileSystemWatcherEngine *engine,
bool aIsDir, TInt aPriority = EPriorityStandard);
~QNotifyChangeEvent();
bool isDir;
private:
void RunL();
void DoCancel();
RFs &fsSession;
TPath watchedPath;
QSymbianFileSystemWatcherEngine *engine;
int failureCount;
};
class QSymbianFileSystemWatcherEngine : public QFileSystemWatcherEngine
{
Q_OBJECT
public:
QSymbianFileSystemWatcherEngine();
~QSymbianFileSystemWatcherEngine();
QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories);
QStringList removePaths(const QStringList &paths, QStringList *files,
QStringList *directories);
void stop();
protected:
void run();
public Q_SLOTS:
void addNativeListener(const QString &directoryPath);
void removeNativeListener();
private:
friend class QNotifyChangeEvent;
void emitPathChanged(QNotifyChangeEvent *e);
void startWatcher();
QHash<QNotifyChangeEvent*, QString> activeObjectToPath;
QMutex mutex;
QWaitCondition syncCondition;
bool watcherStarted;
QNotifyChangeEvent *currentAddEvent;
QNotifyChangeEvent *currentRemoveEvent;
};
#endif // QT_NO_FILESYSTEMWATCHER
QT_END_NAMESPACE
#endif // QFILESYSTEMWATCHER_WIN_P_H

File diff suppressed because it is too large Load Diff