~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/io/qtemporaryfile.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qplatformdefs.h"
 
30
 
 
31
#include "qtemporaryfile.h"
 
32
#include <qfileengine.h>
 
33
#include <private/qfile_p.h>
 
34
#include <private/qfileengine_p.h>
 
35
#include <private/qbufferedfsfileengine_p.h>
 
36
 
 
37
#include <stdlib.h>
 
38
#include <errno.h>
 
39
 
 
40
#ifndef Q_OS_WIN
 
41
# define HAS_MKSTEMP
 
42
#endif
 
43
 
 
44
//************* QTemporaryFileEngine
 
45
class QTemporaryFileEngine : public QFSFileEngine
 
46
{
 
47
    Q_DECLARE_PRIVATE(QFSFileEngine)
 
48
public:
 
49
    QTemporaryFileEngine(const QString &file) : QFSFileEngine(file) { }
 
50
    ~QTemporaryFileEngine();
 
51
 
 
52
    bool open(int flags);
 
53
};
 
54
 
 
55
QTemporaryFileEngine::~QTemporaryFileEngine()
 
56
{
 
57
}
 
58
 
 
59
bool QTemporaryFileEngine::open(int)
 
60
{
 
61
    Q_D(QFSFileEngine);
 
62
 
 
63
    QString qfilename = d->file;
 
64
    if(!qfilename.endsWith(QLatin1String("XXXXXX")))
 
65
        qfilename += QLatin1String(".XXXXXX");
 
66
    d->external_file = 0;
 
67
    char *filename = strdup(qfilename.toLocal8Bit());
 
68
#ifdef HAS_MKSTEMP
 
69
    d->fd = mkstemp(filename);
 
70
#else
 
71
#if defined(_MSC_VER) && _MSC_VER >= 1400
 
72
    int len = strnlen(filename, _MAX_FNAME) + 1;
 
73
    if(_mktemp_s(filename, len) == 0) {
 
74
#else
 
75
    if(mktemp(filename)) {
 
76
#endif
 
77
        int oflags = QT_OPEN_RDWR | QT_OPEN_CREAT;
 
78
#if defined(Q_OS_MSDOS) || defined(Q_OS_WIN32) || defined(Q_OS_OS2)
 
79
        oflags |= QT_OPEN_BINARY; // we handle all text translations our self.
 
80
#endif
 
81
        d->fd = d->sysOpen(filename, oflags);
 
82
    }
 
83
#endif
 
84
    if(d->fd != -1) {
 
85
        d->file = QString::fromLocal8Bit(filename); //changed now!
 
86
        free(filename);
 
87
        d->sequential = 0;
 
88
        return true;
 
89
    }
 
90
    free(filename);
 
91
    d->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, errno);
 
92
    return false;
 
93
}
 
94
 
 
95
 
 
96
//************* QTemporaryFilePrivate
 
97
class QTemporaryFilePrivate : public QFilePrivate
 
98
{
 
99
    Q_DECLARE_PUBLIC(QTemporaryFile)
 
100
 
 
101
protected:
 
102
    QTemporaryFilePrivate();
 
103
    ~QTemporaryFilePrivate();
 
104
 
 
105
    bool autoRemove;
 
106
    QString templateName;
 
107
    mutable QTemporaryFileEngine *fileEngine;
 
108
};
 
109
 
 
110
QTemporaryFilePrivate::QTemporaryFilePrivate() : autoRemove(true), fileEngine(0)
 
111
{
 
112
}
 
113
 
 
114
QTemporaryFilePrivate::~QTemporaryFilePrivate()
 
115
{
 
116
    delete fileEngine;
 
117
    fileEngine = 0;
 
118
}
 
119
 
 
120
//************* QTemporaryFile
 
121
 
 
122
/*!
 
123
    \class QTemporaryFile
 
124
    \reentrant
 
125
    \brief The QTemporaryFile class is an I/O device that operates on temporary files.
 
126
 
 
127
    \ingroup io
 
128
    \mainclass
 
129
 
 
130
    QTemporaryFile is an I/O device that will get its input/output
 
131
    from the local disk. The filename for the temporary file will be
 
132
    guaranteed to be unique once the file is opened and will
 
133
    subsequently be removed upon destruction of the QTemporaryFile
 
134
    object.
 
135
 
 
136
    A temporary file will have some static part of the name and some
 
137
    part that is calculated to be unique. The default filename qt_temp
 
138
    will be placed into the temporary path as returned by
 
139
    QDir::tempPath().
 
140
 
 
141
    \sa QDir::tempPath(), QFile
 
142
*/
 
143
 
 
144
#ifdef QT_NO_QOBJECT
 
145
QTemporaryFile::QTemporaryFile()
 
146
    : QFile(*new QTemporaryFilePrivate)
 
147
{
 
148
    Q_D(QTemporaryFile);
 
149
    d->templateName = QDir::tempPath() + "/" + QLatin1String("qt_temp.XXXXXX");
 
150
}
 
151
 
 
152
QTemporaryFile::QTemporaryFile(const QString &templateName)
 
153
    : QFile(*new QTemporaryFilePrivate)
 
154
{
 
155
    Q_D(QTemporaryFile);
 
156
    d->templateName = templateName;
 
157
}
 
158
 
 
159
#else
 
160
/*!
 
161
    Constructs a QTemporaryFile with no name.
 
162
 
 
163
    \sa setFileTemplate()
 
164
*/
 
165
QTemporaryFile::QTemporaryFile()
 
166
    : QFile(*new QTemporaryFilePrivate, 0)
 
167
{
 
168
    Q_D(QTemporaryFile);
 
169
    d->templateName = QDir::tempPath() + QLatin1String("/qt_temp.XXXXXX");
 
170
}
 
171
 
 
172
/*!
 
173
    Constructs a QTemporaryFile with a template filename of \a
 
174
    templateName. Upon opening the temporary file this will be used to
 
175
    create a unique filename. If the \a templateName does end in
 
176
    XXXXXX it will automatically be appended and used as the dynamic
 
177
    portion of the filename.
 
178
 
 
179
    \sa open(), fileTemplate()
 
180
*/
 
181
QTemporaryFile::QTemporaryFile(const QString &templateName)
 
182
    : QFile(*new QTemporaryFilePrivate, 0)
 
183
{
 
184
    Q_D(QTemporaryFile);
 
185
    d->templateName = templateName;
 
186
}
 
187
 
 
188
/*!
 
189
    Constructs a QTemporaryFile with the given \a parent, but with no name.
 
190
 
 
191
    \sa setFileTemplate()
 
192
*/
 
193
QTemporaryFile::QTemporaryFile(QObject *parent)
 
194
    : QFile(*new QTemporaryFilePrivate, parent)
 
195
{
 
196
    Q_D(QTemporaryFile);
 
197
    d->templateName = QDir::tempPath() + QLatin1String("qt_temp.XXXXXX");
 
198
}
 
199
 
 
200
/*!
 
201
    Constructs a QTemporaryFile with a template filename of \a
 
202
    templateName and the specified \a parent.
 
203
    Upon opening the temporary file this will be used to
 
204
    create a unique filename. If the \a templateName does end in
 
205
    XXXXXX it will automatically be appended and used as the dynamic
 
206
    portion of the filename.
 
207
 
 
208
    \sa open(), fileTemplate()
 
209
*/
 
210
QTemporaryFile::QTemporaryFile(const QString &templateName, QObject *parent)
 
211
    : QFile(*new QTemporaryFilePrivate, parent)
 
212
{
 
213
    Q_D(QTemporaryFile);
 
214
    d->templateName = templateName;
 
215
}
 
216
#endif
 
217
 
 
218
/*!
 
219
    Destroys the temporary file object, the file is automatically
 
220
    closed if necessary and if in auto remove mode it will
 
221
    automatically delete the file.
 
222
 
 
223
    \sa autoRemove()
 
224
*/
 
225
QTemporaryFile::~QTemporaryFile()
 
226
{
 
227
    Q_D(QTemporaryFile);
 
228
    close();
 
229
    if (!d->fileName.isEmpty() && d->autoRemove)
 
230
        remove();
 
231
}
 
232
 
 
233
/*!
 
234
  \fn bool QTemporaryFile::open()
 
235
 
 
236
  A QTemporaryFile will always be opened in QIODevice::ReadWrite mode,
 
237
  this allows easy access to the data in the file. This function will
 
238
  return true upon success and will set the fileName() to the unique
 
239
  filename used.
 
240
 
 
241
  \sa fileName()
 
242
*/
 
243
 
 
244
/*!
 
245
   Returns true if the QTemporaryFile is in auto remove
 
246
   mode. Auto-remove mode will automatically delete the filename from
 
247
   disk upon destruction. This makes it very easy to create your
 
248
   QTemporaryFile object on the stack, fill it with data, read from
 
249
   it, and finally on function return it will automatically clean up
 
250
   after itself.
 
251
 
 
252
   \sa setAutoRemove(), remove()
 
253
*/
 
254
bool QTemporaryFile::autoRemove() const
 
255
{
 
256
    Q_D(const QTemporaryFile);
 
257
    return d->autoRemove;
 
258
}
 
259
 
 
260
/*!
 
261
    Sets the QTemporaryFile into auto-remove mode if \a b is true.
 
262
 
 
263
    \sa autoRemove(), remove()
 
264
*/
 
265
void QTemporaryFile::setAutoRemove(bool b)
 
266
{
 
267
    Q_D(QTemporaryFile);
 
268
    d->autoRemove = b;
 
269
}
 
270
 
 
271
/*!
 
272
   Returns the complete unique filename backing the QTemporaryFile
 
273
   object. This string is null before the QTemporaryFile is opened,
 
274
   afterwards it will contain the fileTemplate() plus
 
275
   additional characters to make it unique.
 
276
 
 
277
   \sa fileTemplate()
 
278
*/
 
279
 
 
280
QString QTemporaryFile::fileName() const
 
281
{
 
282
    if(!isOpen())
 
283
        return QString();
 
284
    return fileEngine()->fileName(QFileEngine::DefaultName);
 
285
}
 
286
 
 
287
/*!
 
288
  Returns the set file template. The default file template will be
 
289
  called qt_temp and be placed in QDir::tempPath().
 
290
 
 
291
  \sa setFileTemplate()
 
292
*/
 
293
QString QTemporaryFile::fileTemplate() const
 
294
{
 
295
    Q_D(const QTemporaryFile);
 
296
    return d->templateName;
 
297
}
 
298
 
 
299
/*!
 
300
   Sets the static portion of the file name to \a name. If the file
 
301
   template ends in XXXXXX that will automatically be replaced with
 
302
   the unique part of the filename, otherwise a filename will be
 
303
   determined automatically based on the static portion specified.
 
304
 
 
305
   \sa fileTemplate()
 
306
*/
 
307
void QTemporaryFile::setFileTemplate(const QString &name)
 
308
{
 
309
    Q_ASSERT(!isOpen());
 
310
    Q_D(QTemporaryFile);
 
311
    fileEngine()->setFileName(name);
 
312
    d->templateName = name;
 
313
}
 
314
 
 
315
/*!
 
316
    \fn QTemporaryFile *QTemporaryFile::createLocalFile(const QString &fileName)
 
317
 
 
318
    Works on the given \a fileName rather than an existing QFile
 
319
    object.
 
320
*/
 
321
 
 
322
 
 
323
/*!
 
324
    Creates and returns a local temporary file whose contents are a
 
325
    copy of the contens of the given \a file.
 
326
*/
 
327
QTemporaryFile *QTemporaryFile::createLocalFile(QFile &file)
 
328
{
 
329
    if(QFileEngine *engine = file.fileEngine()) {
 
330
        if(engine->fileFlags(QFileEngine::FlagsMask) & QFileEngine::LocalDiskFlag)
 
331
            return 0; //local already
 
332
        //cache
 
333
        bool wasOpen = file.isOpen();
 
334
        qint64 old_off = 0;
 
335
        if(wasOpen)
 
336
            old_off = file.pos();
 
337
        else
 
338
            file.open(QIODevice::ReadOnly);
 
339
        //dump data
 
340
        QTemporaryFile *ret = new QTemporaryFile;
 
341
        ret->open();
 
342
        file.seek(0);
 
343
        char buffer[1024];
 
344
        while(true) {
 
345
            qint64 len = file.read(buffer, 1024);
 
346
            if(len < 1)
 
347
                break;
 
348
            ret->write(buffer, len);
 
349
        }
 
350
        ret->seek(0);
 
351
        //restore
 
352
        if(wasOpen)
 
353
            file.seek(old_off);
 
354
        else
 
355
            file.close();
 
356
        //done
 
357
        return ret;
 
358
    }
 
359
    return 0;
 
360
}
 
361
 
 
362
/*!
 
363
   \internal
 
364
*/
 
365
 
 
366
QFileEngine *QTemporaryFile::fileEngine() const
 
367
{
 
368
    Q_D(const QTemporaryFile);
 
369
    if(!d->fileEngine)
 
370
        d->fileEngine = new QTemporaryFileEngine(d->templateName);
 
371
    return d->fileEngine;
 
372
}
 
373
 
 
374
/*!
 
375
   \reimp
 
376
*/
 
377
 
 
378
bool QTemporaryFile::open(OpenMode flags)
 
379
{
 
380
    Q_D(QTemporaryFile);
 
381
    if (QFile::open(flags)) {
 
382
        d->fileName = d->fileEngine->fileName(QFileEngine::DefaultName);
 
383
        return true;
 
384
    }
 
385
    return false;
 
386
}