io/qtemporaryfile.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qtemporaryfile.h" -
43 -
44#ifndef QT_NO_TEMPORARYFILE -
45 -
46#include "qplatformdefs.h" -
47#include "private/qfile_p.h" -
48#include "private/qfsfileengine_p.h" -
49#include "private/qsystemerror_p.h" -
50#include "private/qfilesystemengine_p.h" -
51 -
52#if !defined(Q_OS_WIN) -
53#include "private/qcore_unix_p.h" // overrides QT_OPEN -
54#include <errno.h> -
55#endif -
56 -
57#if defined(QT_BUILD_CORE_LIB) -
58#include "qcoreapplication.h" -
59#endif -
60 -
61QT_BEGIN_NAMESPACE -
62 -
63#if defined(Q_OS_WIN) -
64typedef ushort Char; -
65 -
66static inline Char Latin1Char(char ch) -
67{ -
68 return ushort(uchar(ch)); -
69} -
70 -
71typedef HANDLE NativeFileHandle; -
72 -
73#else // POSIX -
74typedef char Char; -
75typedef char Latin1Char; -
76typedef int NativeFileHandle; -
77#endif -
78 -
79/* -
80 * Copyright (c) 1987, 1993 -
81 * The Regents of the University of California. All rights reserved. -
82 * -
83 * Redistribution and use in source and binary forms, with or without -
84 * modification, are permitted provided that the following conditions -
85 * are met: -
86 * 1. Redistributions of source code must retain the above copyright -
87 * notice, this list of conditions and the following disclaimer. -
88 * 2. Redistributions in binary form must reproduce the above copyright -
89 * notice, this list of conditions and the following disclaimer in the -
90 * documentation and/or other materials provided with the distribution. -
91 * 3. Neither the name of the University nor the names of its contributors -
92 * may be used to endorse or promote products derived from this software -
93 * without specific prior written permission. -
94 * -
95 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -
96 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -
97 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -
98 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -
99 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -
100 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -
101 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -
102 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -
103 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -
104 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -
105 * SUCH DAMAGE. -
106 */ -
107 -
108/*! -
109 \internal -
110 -
111 Generates a unique file path and returns a native handle to the open file. -
112 \a path is used as a template when generating unique paths, \a pos -
113 identifies the position of the first character that will be replaced in the -
114 template and \a length the number of characters that may be substituted. -
115 -
116 Returns an open handle to the newly created file if successful, an invalid -
117 handle otherwise. In both cases, the string in \a path will be changed and -
118 contain the generated path name. -
119*/ -
120static bool createFileFromTemplate(NativeFileHandle &file, -
121 QFileSystemEntry::NativePath &path, size_t pos, size_t length, -
122 QSystemError &error) -
123{ -
124 Q_ASSERT(length != 0);
executed (the execution status of this line is deduced): qt_noop();
-
125 Q_ASSERT(pos < size_t(path.length()));
executed (the execution status of this line is deduced): qt_noop();
-
126 Q_ASSERT(length <= size_t(path.length()) - pos);
executed (the execution status of this line is deduced): qt_noop();
-
127 -
128 Char *const placeholderStart = (Char *)path.data() + pos;
executed (the execution status of this line is deduced): Char *const placeholderStart = (Char *)path.data() + pos;
-
129 Char *const placeholderEnd = placeholderStart + length;
executed (the execution status of this line is deduced): Char *const placeholderEnd = placeholderStart + length;
-
130 -
131 // Initialize placeholder with random chars + PID. -
132 { -
133 Char *rIter = placeholderEnd;
executed (the execution status of this line is deduced): Char *rIter = placeholderEnd;
-
134 -
135#if defined(QT_BUILD_CORE_LIB) -
136 quint64 pid = quint64(QCoreApplication::applicationPid());
executed (the execution status of this line is deduced): quint64 pid = quint64(QCoreApplication::applicationPid());
-
137 do { -
138 *--rIter = Latin1Char((pid % 10) + '0');
executed (the execution status of this line is deduced): *--rIter = Latin1Char((pid % 10) + '0');
-
139 pid /= 10;
executed (the execution status of this line is deduced): pid /= 10;
-
140 } while (rIter != placeholderStart && pid != 0);
executed: }
Execution Count:7264
partially evaluated: rIter != placeholderStart
TRUEFALSE
yes
Evaluation Count:7264
no
Evaluation Count:0
evaluated: pid != 0
TRUEFALSE
yes
Evaluation Count:5784
yes
Evaluation Count:1480
0-7264
141#endif -
142 -
143 while (rIter != placeholderStart) {
evaluated: rIter != placeholderStart
TRUEFALSE
yes
Evaluation Count:1658
yes
Evaluation Count:1480
1480-1658
144 char ch = char((qrand() & 0xffff) % (26 + 26));
executed (the execution status of this line is deduced): char ch = char((qrand() & 0xffff) % (26 + 26));
-
145 if (ch < 26)
evaluated: ch < 26
TRUEFALSE
yes
Evaluation Count:835
yes
Evaluation Count:823
823-835
146 *--rIter = Latin1Char(ch + 'A');
executed: *--rIter = Latin1Char(ch + 'A');
Execution Count:835
835
147 else -
148 *--rIter = Latin1Char(ch - 26 + 'a');
executed: *--rIter = Latin1Char(ch - 26 + 'a');
Execution Count:823
823
149 } -
150 } -
151 -
152 for (;;) {
executed (the execution status of this line is deduced): for (;;) {
-
153 // Atomically create file and obtain handle -
154#if defined(Q_OS_WIN) -
155 file = CreateFile((const wchar_t *)path.constData(), -
156 GENERIC_READ | GENERIC_WRITE, -
157 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, -
158 FILE_ATTRIBUTE_NORMAL, NULL); -
159 -
160 if (file != INVALID_HANDLE_VALUE) -
161 return true; -
162 -
163 DWORD err = GetLastError(); -
164 if (err != ERROR_FILE_EXISTS) { -
165 error = QSystemError(err, QSystemError::NativeError); -
166 return false; -
167 } -
168#else // POSIX -
169 file = QT_OPEN(path.constData(),
executed (the execution status of this line is deduced): file = qt_safe_open(path.constData(),
-
170 QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
executed (the execution status of this line is deduced): 0100 | 0200 | 02 | 0,
-
171 0600);
executed (the execution status of this line is deduced): 0600);
-
172 -
173 if (file != -1)
evaluated: file != -1
TRUEFALSE
yes
Evaluation Count:1472
yes
Evaluation Count:474537
1472-474537
174 return true;
executed: return true;
Execution Count:1472
1472
175 -
176 int err = errno;
executed (the execution status of this line is deduced): int err = (*__errno_location ());
-
177 if (err != EEXIST) {
evaluated: err != 17
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:474529
8-474529
178 error = QSystemError(err, QSystemError::NativeError);
executed (the execution status of this line is deduced): error = QSystemError(err, QSystemError::NativeError);
-
179 return false;
executed: return false;
Execution Count:8
8
180 } -
181#endif -
182 -
183 /* tricky little algorwwithm for backward compatibility */ -
184 for (Char *iter = placeholderStart;;) {
executed (the execution status of this line is deduced): for (Char *iter = placeholderStart;;) {
-
185 // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z' -
186 // String progression: "ZZaiC" => "aabiC" -
187 switch (char(*iter)) { -
188 case 'Z': -
189 // Rollover, advance next character -
190 *iter = Latin1Char('a');
executed (the execution status of this line is deduced): *iter = Latin1Char('a');
-
191 if (++iter == placeholderEnd) {
partially evaluated: ++iter == placeholderEnd
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:9120
0-9120
192 // Out of alternatives. Return file exists error, previously set. -
193 error = QSystemError(err, QSystemError::NativeError);
never executed (the execution status of this line is deduced): error = QSystemError(err, QSystemError::NativeError);
-
194 return false;
never executed: return false;
0
195 } -
196 -
197 continue;
executed: continue;
Execution Count:9120
9120
198 -
199 case '0': case '1': case '2': case '3': case '4': -
200 case '5': case '6': case '7': case '8': case '9': -
201 *iter = Latin1Char('a');
executed (the execution status of this line is deduced): *iter = Latin1Char('a');
-
202 break;
executed: break;
Execution Count:948
948
203 -
204 case 'z': -
205 // increment 'z' to 'A' -
206 *iter = Latin1Char('A');
executed (the execution status of this line is deduced): *iter = Latin1Char('A');
-
207 break;
executed: break;
Execution Count:9127
9127
208 -
209 default: -
210 ++*iter;
executed (the execution status of this line is deduced): ++*iter;
-
211 break;
executed: break;
Execution Count:464454
464454
212 } -
213 break;
executed: break;
Execution Count:474529
474529
214 } -
215 }
executed: }
Execution Count:474529
474529
216 -
217 Q_ASSERT(false);
never executed (the execution status of this line is deduced): qt_noop();
-
218}
never executed: }
0
219 -
220//************* QTemporaryFileEngine -
221class QTemporaryFileEngine : public QFSFileEngine -
222{ -
223 Q_DECLARE_PRIVATE(QFSFileEngine)
executed: return reinterpret_cast<QFSFileEnginePrivate *>(qGetPtrHelper(d_ptr));
Execution Count:3257
never executed: return reinterpret_cast<const QFSFileEnginePrivate *>(qGetPtrHelper(d_ptr));
0-3257
224public: -
225 QTemporaryFileEngine(const QString &file, bool fileIsTemplate = true) -
226 : QFSFileEngine(), filePathIsTemplate(fileIsTemplate), -
227 filePathWasTemplate(fileIsTemplate) -
228 { -
229 Q_D(QFSFileEngine);
executed (the execution status of this line is deduced): QFSFileEnginePrivate * const d = d_func();
-
230 d->fileEntry = QFileSystemEntry(file);
executed (the execution status of this line is deduced): d->fileEntry = QFileSystemEntry(file);
-
231 -
232 if (!filePathIsTemplate)
partially evaluated: !filePathIsTemplate
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1478
0-1478
233 QFSFileEngine::setFileName(file);
never executed: QFSFileEngine::setFileName(file);
0
234 }
executed: }
Execution Count:1478
1478
235 -
236 ~QTemporaryFileEngine(); -
237 -
238 bool isReallyOpen(); -
239 void setFileName(const QString &file); -
240 void setFileTemplate(const QString &fileTemplate); -
241 -
242 bool open(QIODevice::OpenMode flags); -
243 bool remove(); -
244 bool rename(const QString &newName); -
245 bool close(); -
246 -
247 bool filePathIsTemplate; -
248 bool filePathWasTemplate; -
249}; -
250 -
251QTemporaryFileEngine::~QTemporaryFileEngine() -
252{ -
253 QFSFileEngine::close();
executed (the execution status of this line is deduced): QFSFileEngine::close();
-
254}
executed: }
Execution Count:1477
1477
255 -
256bool QTemporaryFileEngine::isReallyOpen() -
257{ -
258 Q_D(QFSFileEngine);
executed (the execution status of this line is deduced): QFSFileEnginePrivate * const d = d_func();
-
259 -
260 if (!((0 == d->fh) && (-1 == d->fd)
partially evaluated: (0 == d->fh)
TRUEFALSE
yes
Evaluation Count:8
no
Evaluation Count:0
evaluated: (-1 == d->fd)
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:5
0-8
261#if defined Q_OS_WIN
executed (the execution status of this line is deduced):
-
262 && (INVALID_HANDLE_VALUE == d->fileHandle)
executed (the execution status of this line is deduced):
-
263#endif
executed (the execution status of this line is deduced):
-
264 ))
executed (the execution status of this line is deduced): ))
-
265 return true;
executed: return true;
Execution Count:5
5
266 -
267 return false;
executed: return false;
Execution Count:3
3
268 -
269} -
270 -
271void QTemporaryFileEngine::setFileName(const QString &file) -
272{ -
273 // Really close the file, so we don't leak -
274 QFSFileEngine::close();
executed (the execution status of this line is deduced): QFSFileEngine::close();
-
275 QFSFileEngine::setFileName(file);
executed (the execution status of this line is deduced): QFSFileEngine::setFileName(file);
-
276}
executed: }
Execution Count:184
184
277 -
278void QTemporaryFileEngine::setFileTemplate(const QString &fileTemplate) -
279{ -
280 Q_D(QFSFileEngine);
executed (the execution status of this line is deduced): QFSFileEnginePrivate * const d = d_func();
-
281 if (filePathIsTemplate)
evaluated: filePathIsTemplate
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
282 d->fileEntry = QFileSystemEntry(fileTemplate);
executed: d->fileEntry = QFileSystemEntry(fileTemplate);
Execution Count:1
1
283}
executed: }
Execution Count:2
2
284 -
285bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) -
286{ -
287 Q_D(QFSFileEngine);
executed (the execution status of this line is deduced): QFSFileEnginePrivate * const d = d_func();
-
288 Q_ASSERT(!isReallyOpen());
executed (the execution status of this line is deduced): qt_noop();
-
289 -
290 openMode |= QIODevice::ReadWrite;
executed (the execution status of this line is deduced): openMode |= QIODevice::ReadWrite;
-
291 -
292 if (!filePathIsTemplate)
evaluated: !filePathIsTemplate
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:1480
2-1480
293 return QFSFileEngine::open(openMode);
executed: return QFSFileEngine::open(openMode);
Execution Count:2
2
294 -
295 QString qfilename = d->fileEntry.filePath();
executed (the execution status of this line is deduced): QString qfilename = d->fileEntry.filePath();
-
296 -
297 // Ensure there is a placeholder mask -
298 uint phPos = qfilename.length();
executed (the execution status of this line is deduced): uint phPos = qfilename.length();
-
299 uint phLength = 0;
executed (the execution status of this line is deduced): uint phLength = 0;
-
300 -
301 while (phPos != 0) {
evaluated: phPos != 0
TRUEFALSE
yes
Evaluation Count:11622
yes
Evaluation Count:27
27-11622
302 --phPos;
executed (the execution status of this line is deduced): --phPos;
-
303 -
304 if (qfilename[phPos] == QLatin1Char('X')) {
evaluated: qfilename[phPos] == QLatin1Char('X')
TRUEFALSE
yes
Evaluation Count:8242
yes
Evaluation Count:3380
3380-8242
305 ++phLength;
executed (the execution status of this line is deduced): ++phLength;
-
306 continue;
executed: continue;
Execution Count:8242
8242
307 } -
308 -
309 if (phLength >= 6
evaluated: phLength >= 6
TRUEFALSE
yes
Evaluation Count:1344
yes
Evaluation Count:2036
1344-2036
310 || qfilename[phPos] == QLatin1Char('/')) {
evaluated: qfilename[phPos] == QLatin1Char('/')
TRUEFALSE
yes
Evaluation Count:109
yes
Evaluation Count:1927
109-1927
311 ++phPos;
executed (the execution status of this line is deduced): ++phPos;
-
312 break;
executed: break;
Execution Count:1453
1453
313 } -
314 -
315 // start over -
316 phLength = 0;
executed (the execution status of this line is deduced): phLength = 0;
-
317 }
executed: }
Execution Count:1927
1927
318 -
319 if (phLength < 6)
evaluated: phLength < 6
TRUEFALSE
yes
Evaluation Count:130
yes
Evaluation Count:1350
130-1350
320 qfilename.append(QLatin1String(".XXXXXX"));
executed: qfilename.append(QLatin1String(".XXXXXX"));
Execution Count:130
130
321 -
322 // "Nativify" :-) -
323 QFileSystemEntry::NativePath filename = QFileSystemEngine::absoluteName(
executed (the execution status of this line is deduced): QFileSystemEntry::NativePath filename = QFileSystemEngine::absoluteName(
-
324 QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath()))
executed (the execution status of this line is deduced): QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath()))
-
325 .nativeFilePath();
executed (the execution status of this line is deduced): .nativeFilePath();
-
326 -
327 // Find mask in native path -
328 phPos = filename.length();
executed (the execution status of this line is deduced): phPos = filename.length();
-
329 phLength = 0;
executed (the execution status of this line is deduced): phLength = 0;
-
330 while (phPos != 0) {
partially evaluated: phPos != 0
TRUEFALSE
yes
Evaluation Count:10682
no
Evaluation Count:0
0-10682
331 --phPos;
executed (the execution status of this line is deduced): --phPos;
-
332 -
333 if (filename[phPos] == Latin1Char('X')) {
evaluated: filename[phPos] == Latin1Char('X')
TRUEFALSE
yes
Evaluation Count:8941
yes
Evaluation Count:1741
1741-8941
334 ++phLength;
executed (the execution status of this line is deduced): ++phLength;
-
335 continue;
executed: continue;
Execution Count:8941
8941
336 } -
337 -
338 if (phLength >= 6) {
evaluated: phLength >= 6
TRUEFALSE
yes
Evaluation Count:1480
yes
Evaluation Count:261
261-1480
339 ++phPos;
executed (the execution status of this line is deduced): ++phPos;
-
340 break;
executed: break;
Execution Count:1480
1480
341 } -
342 -
343 // start over -
344 phLength = 0;
executed (the execution status of this line is deduced): phLength = 0;
-
345 }
executed: }
Execution Count:261
261
346 -
347 Q_ASSERT(phLength >= 6);
executed (the execution status of this line is deduced): qt_noop();
-
348 -
349 QSystemError error;
executed (the execution status of this line is deduced): QSystemError error;
-
350#if defined(Q_OS_WIN) -
351 NativeFileHandle &file = d->fileHandle; -
352#else // POSIX -
353 NativeFileHandle &file = d->fd;
executed (the execution status of this line is deduced): NativeFileHandle &file = d->fd;
-
354#endif -
355 -
356 if (!createFileFromTemplate(file, filename, phPos, phLength, error)) {
evaluated: !createFileFromTemplate(file, filename, phPos, phLength, error)
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:1472
8-1472
357 setError(QFile::OpenError, error.toString());
executed (the execution status of this line is deduced): setError(QFile::OpenError, error.toString());
-
358 return false;
executed: return false;
Execution Count:8
8
359 } -
360 -
361 d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
executed (the execution status of this line is deduced): d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
-
362 -
363#if !defined(Q_OS_WIN) -
364 d->closeFileHandle = true;
executed (the execution status of this line is deduced): d->closeFileHandle = true;
-
365#endif -
366 -
367 filePathIsTemplate = false;
executed (the execution status of this line is deduced): filePathIsTemplate = false;
-
368 -
369 d->openMode = openMode;
executed (the execution status of this line is deduced): d->openMode = openMode;
-
370 d->lastFlushFailed = false;
executed (the execution status of this line is deduced): d->lastFlushFailed = false;
-
371 d->tried_stat = 0;
executed (the execution status of this line is deduced): d->tried_stat = 0;
-
372 -
373 return true;
executed: return true;
Execution Count:1472
1472
374} -
375 -
376bool QTemporaryFileEngine::remove() -
377{ -
378 Q_D(QFSFileEngine);
executed (the execution status of this line is deduced): QFSFileEnginePrivate * const d = d_func();
-
379 // Since the QTemporaryFileEngine::close() does not really close the file, -
380 // we must explicitly call QFSFileEngine::close() before we remove it. -
381 QFSFileEngine::close();
executed (the execution status of this line is deduced): QFSFileEngine::close();
-
382 if (QFSFileEngine::remove()) {
evaluated: QFSFileEngine::remove()
TRUEFALSE
yes
Evaluation Count:286
yes
Evaluation Count:1
1-286
383 d->fileEntry.clear();
executed (the execution status of this line is deduced): d->fileEntry.clear();
-
384 // If a QTemporaryFile is constructed using a template file path, the path -
385 // is generated in QTemporaryFileEngine::open() and then filePathIsTemplate -
386 // is set to false. If remove() and then open() are called on the same -
387 // QTemporaryFile, the path is not regenerated. Here we ensure that if the -
388 // file path was generated, it will be generated again in the scenario above. -
389 filePathIsTemplate = filePathWasTemplate;
executed (the execution status of this line is deduced): filePathIsTemplate = filePathWasTemplate;
-
390 return true;
executed: return true;
Execution Count:286
286
391 } -
392 return false;
executed: return false;
Execution Count:1
1
393} -
394 -
395bool QTemporaryFileEngine::rename(const QString &newName) -
396{ -
397 QFSFileEngine::close();
executed (the execution status of this line is deduced): QFSFileEngine::close();
-
398 return QFSFileEngine::rename(newName);
executed: return QFSFileEngine::rename(newName);
Execution Count:185
185
399} -
400 -
401bool QTemporaryFileEngine::close() -
402{ -
403 // Don't close the file, just seek to the front. -
404 seek(0);
executed (the execution status of this line is deduced): seek(0);
-
405 setError(QFile::UnspecifiedError, QString());
executed (the execution status of this line is deduced): setError(QFile::UnspecifiedError, QString());
-
406 return true;
executed: return true;
Execution Count:1477
1477
407} -
408 -
409//************* QTemporaryFilePrivate -
410class QTemporaryFilePrivate : public QFilePrivate -
411{ -
412 Q_DECLARE_PUBLIC(QTemporaryFile) -
413 -
414protected: -
415 QTemporaryFilePrivate(); -
416 ~QTemporaryFilePrivate(); -
417 -
418 QAbstractFileEngine *engine() const; -
419 -
420 bool autoRemove; -
421 QString templateName; -
422}; -
423 -
424QTemporaryFilePrivate::QTemporaryFilePrivate() : autoRemove(true) -
425{ -
426}
executed: }
Execution Count:1485
1485
427 -
428QTemporaryFilePrivate::~QTemporaryFilePrivate() -
429{ -
430} -
431 -
432QAbstractFileEngine *QTemporaryFilePrivate::engine() const -
433{ -
434 if (!fileEngine) {
evaluated: !fileEngine
TRUEFALSE
yes
Evaluation Count:1478
yes
Evaluation Count:3091
1478-3091
435 if (fileName.isEmpty())
partially evaluated: fileName.isEmpty()
TRUEFALSE
yes
Evaluation Count:1478
no
Evaluation Count:0
0-1478
436 fileEngine = new QTemporaryFileEngine(templateName);
executed: fileEngine = new QTemporaryFileEngine(templateName);
Execution Count:1478
1478
437 else -
438 fileEngine = new QTemporaryFileEngine(fileName, false);
never executed: fileEngine = new QTemporaryFileEngine(fileName, false);
0
439 } -
440 return fileEngine;
executed: return fileEngine;
Execution Count:4569
4569
441} -
442 -
443static QString defaultTemplateName() -
444{ -
445 QString baseName;
executed (the execution status of this line is deduced): QString baseName;
-
446#if defined(QT_BUILD_CORE_LIB) -
447 baseName = QCoreApplication::applicationName();
executed (the execution status of this line is deduced): baseName = QCoreApplication::applicationName();
-
448 if (baseName.isEmpty())
partially evaluated: baseName.isEmpty()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1028
0-1028
449#endif -
450 baseName = QLatin1String("qt_temp");
never executed: baseName = QLatin1String("qt_temp");
0
451 -
452 return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String(".XXXXXX");
executed: return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String(".XXXXXX");
Execution Count:1028
1028
453} -
454 -
455//************* QTemporaryFile -
456 -
457/*! -
458 \class QTemporaryFile -
459 \inmodule QtCore -
460 \reentrant -
461 \brief The QTemporaryFile class is an I/O device that operates on temporary files. -
462 -
463 \ingroup io -
464 -
465 -
466 QTemporaryFile is used to create unique temporary files safely. -
467 The file itself is created by calling open(). The name of the -
468 temporary file is guaranteed to be unique (i.e., you are -
469 guaranteed to not overwrite an existing file), and the file will -
470 subsequently be removed upon destruction of the QTemporaryFile -
471 object. This is an important technique that avoids data -
472 corruption for applications that store data in temporary files. -
473 The file name is either auto-generated, or created based on a -
474 template, which is passed to QTemporaryFile's constructor. -
475 -
476 Example: -
477 -
478 \snippet code/src_corelib_io_qtemporaryfile.cpp 0 -
479 -
480 Reopening a QTemporaryFile after calling close() is safe. For as long as -
481 the QTemporaryFile object itself is not destroyed, the unique temporary -
482 file will exist and be kept open internally by QTemporaryFile. -
483 -
484 The file name of the temporary file can be found by calling fileName(). -
485 Note that this is only defined after the file is first opened; the function -
486 returns an empty string before this. -
487 -
488 A temporary file will have some static part of the name and some -
489 part that is calculated to be unique. The default filename will be -
490 determined from QCoreApplication::applicationName() (otherwise \c qt_temp) and will -
491 be placed into the temporary path as returned by QDir::tempPath(). -
492 If you specify your own filename, a relative file path will not be placed in the -
493 temporary directory by default, but be relative to the current working directory. -
494 -
495 Specified filenames can contain the following template \c XXXXXX -
496 (six upper case "X" characters), which will be replaced by the -
497 auto-generated portion of the filename. Note that the template is -
498 case sensitive. If the template is not present in the filename, -
499 QTemporaryFile appends the generated part to the filename given. -
500 -
501 \sa QDir::tempPath(), QFile -
502*/ -
503 -
504#ifdef QT_NO_QOBJECT -
505QTemporaryFile::QTemporaryFile() -
506 : QFile(*new QTemporaryFilePrivate) -
507{ -
508 Q_D(QTemporaryFile); -
509 d->templateName = defaultTemplateName(); -
510} -
511 -
512QTemporaryFile::QTemporaryFile(const QString &templateName) -
513 : QFile(*new QTemporaryFilePrivate) -
514{ -
515 Q_D(QTemporaryFile); -
516 d->templateName = templateName; -
517} -
518 -
519#else -
520/*! -
521 Constructs a QTemporaryFile using as file template -
522 the application name returned by QCoreApplication::applicationName() -
523 (otherwise \c qt_temp) followed by ".XXXXXX". -
524 The file is stored in the system's temporary directory, QDir::tempPath(). -
525 -
526 \sa setFileTemplate(), QDir::tempPath() -
527*/ -
528QTemporaryFile::QTemporaryFile() -
529 : QFile(*new QTemporaryFilePrivate, 0) -
530{ -
531 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
532 d->templateName = defaultTemplateName();
executed (the execution status of this line is deduced): d->templateName = defaultTemplateName();
-
533}
executed: }
Execution Count:1027
1027
534 -
535/*! -
536 Constructs a QTemporaryFile with a template filename of \a -
537 templateName. Upon opening the temporary file this will be used to create -
538 a unique filename. -
539 -
540 If the \a templateName does not contain XXXXXX it will automatically be -
541 appended and used as the dynamic portion of the filename. -
542 -
543 If \a templateName is a relative path, the path will be relative to the -
544 current working directory. You can use QDir::tempPath() to construct \a -
545 templateName if you want use the system's temporary directory. -
546 -
547 \sa open(), fileTemplate() -
548*/ -
549QTemporaryFile::QTemporaryFile(const QString &templateName) -
550 : QFile(*new QTemporaryFilePrivate, 0) -
551{ -
552 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
553 d->templateName = templateName;
executed (the execution status of this line is deduced): d->templateName = templateName;
-
554}
executed: }
Execution Count:371
371
555 -
556/*! -
557 Constructs a QTemporaryFile (with the given \a parent) -
558 using as file template the application name returned by QCoreApplication::applicationName() -
559 (otherwise \c qt_temp) followed by ".XXXXXX". -
560 The file is stored in the system's temporary directory, QDir::tempPath(). -
561 -
562 \sa setFileTemplate() -
563*/ -
564QTemporaryFile::QTemporaryFile(QObject *parent) -
565 : QFile(*new QTemporaryFilePrivate, parent) -
566{ -
567 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
568 d->templateName = defaultTemplateName();
executed (the execution status of this line is deduced): d->templateName = defaultTemplateName();
-
569}
executed: }
Execution Count:1
1
570 -
571/*! -
572 Constructs a QTemporaryFile with a template filename of \a -
573 templateName and the specified \a parent. -
574 Upon opening the temporary file this will be used to -
575 create a unique filename. -
576 -
577 If the \a templateName does not contain XXXXXX it will automatically be -
578 appended and used as the dynamic portion of the filename. -
579 -
580 If \a templateName is a relative path, the path will be relative to the -
581 current working directory. You can use QDir::tempPath() to construct \a -
582 templateName if you want use the system's temporary directory. -
583 -
584 \sa open(), fileTemplate() -
585*/ -
586QTemporaryFile::QTemporaryFile(const QString &templateName, QObject *parent) -
587 : QFile(*new QTemporaryFilePrivate, parent) -
588{ -
589 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
590 d->templateName = templateName;
executed (the execution status of this line is deduced): d->templateName = templateName;
-
591}
executed: }
Execution Count:86
86
592#endif -
593 -
594/*! -
595 Destroys the temporary file object, the file is automatically -
596 closed if necessary and if in auto remove mode it will -
597 automatically delete the file. -
598 -
599 \sa autoRemove() -
600*/ -
601QTemporaryFile::~QTemporaryFile() -
602{ -
603 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
604 close();
executed (the execution status of this line is deduced): close();
-
605 if (!d->fileName.isEmpty() && d->autoRemove)
evaluated: !d->fileName.isEmpty()
TRUEFALSE
yes
Evaluation Count:1470
yes
Evaluation Count:12
evaluated: d->autoRemove
TRUEFALSE
yes
Evaluation Count:286
yes
Evaluation Count:1184
12-1470
606 remove();
executed: remove();
Execution Count:286
286
607}
executed: }
Execution Count:1482
1482
608 -
609/*! -
610 \fn bool QTemporaryFile::open() -
611 -
612 A QTemporaryFile will always be opened in QIODevice::ReadWrite mode, -
613 this allows easy access to the data in the file. This function will -
614 return true upon success and will set the fileName() to the unique -
615 filename used. -
616 -
617 \sa fileName() -
618*/ -
619 -
620/*! -
621 Returns true if the QTemporaryFile is in auto remove -
622 mode. Auto-remove mode will automatically delete the filename from -
623 disk upon destruction. This makes it very easy to create your -
624 QTemporaryFile object on the stack, fill it with data, read from -
625 it, and finally on function return it will automatically clean up -
626 after itself. -
627 -
628 Auto-remove is on by default. -
629 -
630 \sa setAutoRemove(), remove() -
631*/ -
632bool QTemporaryFile::autoRemove() const -
633{ -
634 Q_D(const QTemporaryFile);
executed (the execution status of this line is deduced): const QTemporaryFilePrivate * const d = d_func();
-
635 return d->autoRemove;
executed: return d->autoRemove;
Execution Count:2
2
636} -
637 -
638/*! -
639 Sets the QTemporaryFile into auto-remove mode if \a b is true. -
640 -
641 Auto-remove is on by default. -
642 -
643 \sa autoRemove(), remove() -
644*/ -
645void QTemporaryFile::setAutoRemove(bool b) -
646{ -
647 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
648 d->autoRemove = b;
executed (the execution status of this line is deduced): d->autoRemove = b;
-
649}
executed: }
Execution Count:1206
1206
650 -
651/*! -
652 Returns the complete unique filename backing the QTemporaryFile -
653 object. This string is null before the QTemporaryFile is opened, -
654 afterwards it will contain the fileTemplate() plus -
655 additional characters to make it unique. -
656 -
657 \sa fileTemplate() -
658*/ -
659 -
660QString QTemporaryFile::fileName() const -
661{ -
662 Q_D(const QTemporaryFile);
executed (the execution status of this line is deduced): const QTemporaryFilePrivate * const d = d_func();
-
663 if(d->fileName.isEmpty())
evaluated: d->fileName.isEmpty()
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:2178
6-2178
664 return QString();
executed: return QString();
Execution Count:6
6
665 return d->engine()->fileName(QAbstractFileEngine::DefaultName);
executed: return d->engine()->fileName(QAbstractFileEngine::DefaultName);
Execution Count:2178
2178
666} -
667 -
668/*! -
669 Returns the set file template. The default file template will be -
670 called qcoreappname.XXXXXX and be placed in QDir::tempPath(). -
671 -
672 \sa setFileTemplate() -
673*/ -
674QString QTemporaryFile::fileTemplate() const -
675{ -
676 Q_D(const QTemporaryFile);
executed (the execution status of this line is deduced): const QTemporaryFilePrivate * const d = d_func();
-
677 return d->templateName;
executed: return d->templateName;
Execution Count:10
10
678} -
679 -
680/*! -
681 Sets the static portion of the file name to \a name. If the file -
682 template ends in XXXXXX that will automatically be replaced with -
683 the unique part of the filename, otherwise a filename will be -
684 determined automatically based on the static portion specified. -
685 -
686 If \a name contains a relative file path, the path will be relative to the -
687 current working directory. You can use QDir::tempPath() to construct \a -
688 name if you want use the system's temporary directory. -
689 -
690 \sa fileTemplate() -
691*/ -
692void QTemporaryFile::setFileTemplate(const QString &name) -
693{ -
694 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
695 d->templateName = name;
executed (the execution status of this line is deduced): d->templateName = name;
-
696 if (d->fileEngine)
evaluated: d->fileEngine
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:6
2-6
697 static_cast<QTemporaryFileEngine*>(d->fileEngine)->setFileTemplate(name);
executed: static_cast<QTemporaryFileEngine*>(d->fileEngine)->setFileTemplate(name);
Execution Count:2
2
698}
executed: }
Execution Count:8
8
699 -
700/*! -
701 \fn QTemporaryFile *QTemporaryFile::createLocalFile(const QString &fileName) -
702 \overload -
703 \obsolete -
704 -
705 Use QTemporaryFile::createNativeFile(const QString &fileName) instead. -
706*/ -
707 -
708/*! -
709 \fn QTemporaryFile *QTemporaryFile::createLocalFile(QFile &file) -
710 \obsolete -
711 -
712 Use QTemporaryFile::createNativeFile(QFile &file) instead. -
713*/ -
714 -
715/*! -
716 \fn QTemporaryFile *QTemporaryFile::createNativeFile(const QString &fileName) -
717 \overload -
718 -
719 Works on the given \a fileName rather than an existing QFile -
720 object. -
721*/ -
722 -
723 -
724/*! -
725 If \a file is not already a native file then a QTemporaryFile is created -
726 in the tempPath() and \a file is copied into the temporary file, then a -
727 pointer to the temporary file is returned. If \a file is already a native -
728 file, a QTemporaryFile is not created, no copy is made and 0 is returned. -
729 -
730 For example: -
731 -
732 QFile f(":/resources/file.txt"); -
733 QTemporaryFile::createNativeFile(f); // Returns a pointer to a temporary file -
734 -
735 QFile f("/users/qt/file.txt"); -
736 QTemporaryFile::createNativeFile(f); // Returns 0 -
737 -
738 \sa QFileInfo::isNativePath() -
739*/ -
740 -
741QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file) -
742{ -
743 if (QAbstractFileEngine *engine = file.d_func()->engine()) {
partially evaluated: QAbstractFileEngine *engine = file.d_func()->engine()
TRUEFALSE
yes
Evaluation Count:4
no
Evaluation Count:0
0-4
744 if(engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)
evaluated: engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:2
2
745 return 0; //native already
executed: return 0;
Execution Count:2
2
746 //cache -
747 bool wasOpen = file.isOpen();
executed (the execution status of this line is deduced): bool wasOpen = file.isOpen();
-
748 qint64 old_off = 0;
executed (the execution status of this line is deduced): qint64 old_off = 0;
-
749 if(wasOpen)
evaluated: wasOpen
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
750 old_off = file.pos();
executed: old_off = file.pos();
Execution Count:1
1
751 else -
752 file.open(QIODevice::ReadOnly);
executed: file.open(QIODevice::ReadOnly);
Execution Count:1
1
753 //dump data -
754 QTemporaryFile *ret = new QTemporaryFile;
executed (the execution status of this line is deduced): QTemporaryFile *ret = new QTemporaryFile;
-
755 ret->open();
executed (the execution status of this line is deduced): ret->open();
-
756 file.seek(0);
executed (the execution status of this line is deduced): file.seek(0);
-
757 char buffer[1024];
executed (the execution status of this line is deduced): char buffer[1024];
-
758 while(true) {
partially evaluated: true
TRUEFALSE
yes
Evaluation Count:4
no
Evaluation Count:0
0-4
759 qint64 len = file.read(buffer, 1024);
executed (the execution status of this line is deduced): qint64 len = file.read(buffer, 1024);
-
760 if(len < 1)
evaluated: len < 1
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:2
2
761 break;
executed: break;
Execution Count:2
2
762 ret->write(buffer, len);
executed (the execution status of this line is deduced): ret->write(buffer, len);
-
763 }
executed: }
Execution Count:2
2
764 ret->seek(0);
executed (the execution status of this line is deduced): ret->seek(0);
-
765 //restore -
766 if(wasOpen)
evaluated: wasOpen
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
767 file.seek(old_off);
executed: file.seek(old_off);
Execution Count:1
1
768 else -
769 file.close();
executed: file.close();
Execution Count:1
1
770 //done -
771 return ret;
executed: return ret;
Execution Count:2
2
772 } -
773 return 0;
never executed: return 0;
0
774} -
775 -
776/*! -
777 \reimp -
778 -
779 Creates a unique file name for the temporary file, and opens it. You can -
780 get the unique name later by calling fileName(). The file is guaranteed to -
781 have been created by this function (i.e., it has never existed before). -
782*/ -
783bool QTemporaryFile::open(OpenMode flags) -
784{ -
785 Q_D(QTemporaryFile);
executed (the execution status of this line is deduced): QTemporaryFilePrivate * const d = d_func();
-
786 if (!d->fileName.isEmpty()) {
evaluated: !d->fileName.isEmpty()
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:1479
8-1479
787 if (static_cast<QTemporaryFileEngine*>(d->engine())->isReallyOpen()) {
evaluated: static_cast<QTemporaryFileEngine*>(d->engine())->isReallyOpen()
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:3
3-5
788 setOpenMode(flags);
executed (the execution status of this line is deduced): setOpenMode(flags);
-
789 return true;
executed: return true;
Execution Count:5
5
790 } -
791 }
executed: }
Execution Count:3
3
792 -
793 if (QFile::open(flags)) {
evaluated: QFile::open(flags)
TRUEFALSE
yes
Evaluation Count:1474
yes
Evaluation Count:8
8-1474
794 d->fileName = d->fileEngine->fileName(QAbstractFileEngine::DefaultName);
executed (the execution status of this line is deduced): d->fileName = d->fileEngine->fileName(QAbstractFileEngine::DefaultName);
-
795 return true;
executed: return true;
Execution Count:1474
1474
796 } -
797 return false;
executed: return false;
Execution Count:8
8
798} -
799 -
800QT_END_NAMESPACE -
801 -
802#endif // QT_NO_TEMPORARYFILE -
803 -
804 -
805 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial