kdelibs/kdecore/io/kautosavefile.cpp
Ivailo Monev 82fc15f54b generic: use CMake moc instead of automoc4 by default
for compatibilty reasons automoc4 support is not removed but it
shall be in the future. automoc4 has not been maintained for a
while (last commit is from 2011) and the stable release is from
2009.

CMake version >= 2.8.6 provides the functionality for mocking so
I see no reason to not make use of it.
2015-02-27 07:40:26 +00:00

229 lines
7 KiB
C++

/* This file is part of the KDE libraries
Copyright (c) 2006 Jacob R Rideout <kde@jacobrideout.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kautosavefile.h"
#include <stdio.h> // for FILENAME_MAX
#include <QtCore/QLatin1Char>
#include <QtCore/QCoreApplication>
#include "klockfile.h"
#include "krandom.h"
#include "kglobal.h"
#include "kstandarddirs.h"
class KAutoSaveFilePrivate
{
public:
KAutoSaveFilePrivate()
: lock(0),
managedFileNameChanged(false)
{}
QString tempFileName();
KUrl managedFile;
KLockFile::Ptr lock;
static const int padding;
bool managedFileNameChanged;
};
const int KAutoSaveFilePrivate::padding = 8;
QString KAutoSaveFilePrivate::tempFileName()
{
static const int maxNameLength = FILENAME_MAX;
// Note: we drop any query string and user/pass info
QString protocol(managedFile.protocol());
QString path(managedFile.directory());
QString name(managedFile.fileName());
// Remove any part of the path to the right if it is longer than the max file size and
// ensure that the max filesize takes into account the other parts of the tempFileName
// Subtract 1 for the _ char, 3 for the padding sepperator, 5 is for the .lock
path = path.left(maxNameLength - padding - name.size() - protocol.size() - 9);
QString junk = KRandom::randomString(padding);
// tempName = fileName + junk.trunicated + protocol + _ + path.trunicated + junk
// This is done so that the separation between the filename and path can be determined
name += junk.right(3) + protocol + QLatin1Char('_');
name += path + junk;
return QString::fromLatin1(KUrl::toPercentEncoding(name));
}
KAutoSaveFile::KAutoSaveFile(const KUrl &filename, QObject *parent)
: QFile(parent),
d(new KAutoSaveFilePrivate)
{
setManagedFile(filename);
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
}
KAutoSaveFile::KAutoSaveFile(QObject *parent)
: QFile(parent),
d(new KAutoSaveFilePrivate)
{
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
}
KAutoSaveFile::~KAutoSaveFile()
{
releaseLock();
delete d;
}
KUrl KAutoSaveFile::managedFile() const
{
return d->managedFile;
}
void KAutoSaveFile::setManagedFile(const KUrl &filename)
{
releaseLock();
d->managedFile = filename;
d->managedFileNameChanged = true;
}
void KAutoSaveFile::releaseLock()
{
if (d->lock && d->lock->isLocked()) {
d->lock.clear();
if (!fileName().isEmpty()) {
remove();
}
}
}
bool KAutoSaveFile::open(OpenMode openmode)
{
if (d->managedFile == KUrl()) {
return false;
}
QString tempFile;
if (d->managedFileNameChanged) {
tempFile = KStandardDirs::locateLocal("stale",
QCoreApplication::instance()->applicationName()
+ QChar::fromLatin1('/')
+ d->tempFileName()
);
} else {
tempFile = fileName();
}
d->managedFileNameChanged = false;
setFileName(tempFile);
if (QFile::open(openmode)) {
d->lock = new KLockFile(tempFile + QString::fromLatin1(".lock"));
d->lock->setStaleTime(60); // HARDCODE, 1 minute
if (d->lock->lock(KLockFile::ForceFlag|KLockFile::NoBlockFlag) == KLockFile::LockOK) {
return true;
} else {
close();
}
}
return false;
}
QList<KAutoSaveFile *> KAutoSaveFile::staleFiles(const KUrl &filename, const QString &applicationName)
{
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
QString appName(applicationName);
if (appName.isEmpty()) {
appName = QCoreApplication::instance()->applicationName();
}
QString url = filename.fileName();
if (url.isEmpty()) {
return QList<KAutoSaveFile *>();
}
// get stale files
const QStringList files = KGlobal::dirs()->findAllResources("stale",
appName + QChar::fromLatin1('/') +
url + QChar::fromLatin1('*'),
KStandardDirs::Recursive);
QList<KAutoSaveFile *> list;
KAutoSaveFile * asFile;
// contruct a KAutoSaveFile for each stale file
foreach(const QString &file, files) {
if (file.endsWith(QLatin1String(".lock")))
continue;
// sets managedFile
asFile = new KAutoSaveFile(filename);
asFile->setFileName(file);
// flags the name, so it isn't regenerated
asFile->d->managedFileNameChanged = false;
list.append(asFile);
}
return list;
}
QList<KAutoSaveFile *> KAutoSaveFile::allStaleFiles(const QString &applicationName)
{
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
QString appName(applicationName);
if (appName.isEmpty()) {
appName = QCoreApplication::instance()->applicationName();
}
// get stale files
const QStringList files = KGlobal::dirs()->findAllResources("stale", appName + QLatin1String("/*"));
QList<KAutoSaveFile *> list;
// contruct a KAutoSaveFile for each stale file
foreach(QString file, files) { // krazy:exclude=foreach (no const& because modified below)
if (file.endsWith(QLatin1String(".lock")))
continue;
const QString sep = file.right(3);
file.chop(KAutoSaveFilePrivate::padding);
int sepPos = file.indexOf(sep);
int pathPos = file.indexOf(QChar::fromLatin1('_'), sepPos);
KUrl name;
name.setProtocol(file.mid(sepPos + 3, pathPos - sep.size() - 3));
name.setPath(KUrl::fromPercentEncoding(file.right(pathPos - 1).toLatin1()));
name.addPath(KUrl::fromPercentEncoding(file.left(sepPos).toLatin1()));
// sets managedFile
KAutoSaveFile* asFile = new KAutoSaveFile(name);
asFile->setFileName(file);
// flags the name, so it isn't regenerated
asFile->d->managedFileNameChanged = false;
list.append(asFile);
}
return list;
}
#include "moc_kautosavefile.cpp"