2
* atomicxmlfile.cpp - atomic saving of QDomDocuments in files
3
* Copyright (C) 2007 Michail Pishchagin
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include "atomicxmlfile.h"
23
#include <QDomDocument>
25
#include <QStringList>
26
#include <QTextStream>
29
* Creates new instance of AtomicXmlFile class that will be able to
30
* atomically save config file, so if application is terminated while
31
* saving config file, data is not lost.
33
AtomicXmlFile::AtomicXmlFile(QString fileName)
39
* Atomically save \a doc to specified name. Prior to saving, back up
40
* of old config data is created, and only then data is saved.
42
bool AtomicXmlFile::saveDocument(const QDomDocument& doc) const
44
if (!saveDocument(doc, tempFileName())) {
45
qWarning("AtomicXmlFile::saveDocument(): Unable to save '%s'. Possibly drive is full.",
46
qPrintable(tempFileName()));
50
if (QFile::exists(backupFileName()))
51
QFile::remove(backupFileName());
53
if (QFile::exists(fileName_)) {
54
if (!QFile::rename(fileName_, backupFileName())) {
55
qWarning("AtomicXmlFile::saveDocument(): Unable to rename '%s' to '%s'.",
56
qPrintable(fileName_), qPrintable(backupFileName()));
61
if (!QFile::rename(tempFileName(), fileName_)) {
62
qWarning("AtomicXmlFile::saveDocument(): Unable to rename '%s' to '%s'.",
63
qPrintable(tempFileName()), qPrintable(fileName_));
71
* Tries to load \a doc from config file, or if that fails, from a back up.
73
bool AtomicXmlFile::loadDocument(QDomDocument* doc) const
77
QStringList fileNames;
78
fileNames << fileName_
82
foreach(QString fileName, fileNames)
83
if (loadDocument(doc, fileName))
90
* Returns name of the file the config is first written to.
92
QString AtomicXmlFile::tempFileName() const
94
return fileName_ + ".temp";
98
* Returns name of the back up file.
100
QString AtomicXmlFile::backupFileName() const
102
return fileName_ + ".backup";
105
bool AtomicXmlFile::saveDocument(const QDomDocument& doc, QString fileName) const
109
QFile file(fileName);
110
if (!file.open(QIODevice::WriteOnly)) {
115
text.setDevice(&file);
116
text.setCodec("UTF-8");
117
text << doc.toString();
119
result = file.error() == QFile::NoError;
122
// QFile error checking should be enough, but to be completely sure that
123
// XML is well-formed we could try to parse data we just had written:
125
// QDomDocument temp;
126
// result = loadDocument(&temp, fileName);
132
bool AtomicXmlFile::loadDocument(QDomDocument* doc, QString fileName) const
134
QFile file(fileName);
135
if (!file.open(QIODevice::ReadOnly)) {
139
if (!doc->setContent(&file)) {