source: trunk/src/corelib/io/qfileinfo.cpp@ 595

Last change on this file since 595 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 37.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qplatformdefs.h"
43#include "qfileinfo.h"
44#include "qdatetime.h"
45#include "qabstractfileengine.h"
46#include "qfsfileengine_p.h"
47#include "qglobal.h"
48#include "qatomic.h"
49#include "qhash.h"
50#include "qdir.h"
51#include "qfileinfo_p.h"
52
53QT_BEGIN_NAMESPACE
54
55QFileInfoPrivate::QFileInfoPrivate(const QFileInfo *copy)
56{
57 if(copy) {
58 copy->d_func()->data->ref.ref();
59 data = copy->d_func()->data;
60 } else {
61 data = new QFileInfoPrivate::Data;
62 }
63}
64
65QFileInfoPrivate::~QFileInfoPrivate()
66{
67 if (!data->ref.deref())
68 delete data;
69 data = 0;
70}
71
72void QFileInfoPrivate::initFileEngine(const QString &file)
73{
74 detach();
75 delete data->fileEngine;
76 data->fileEngine = 0;
77 data->clear();
78 data->fileEngine = QAbstractFileEngine::create(file);
79 data->fileName = file;
80}
81
82bool QFileInfoPrivate::hasAccess(Access access) const
83{
84 if (!(getFileFlags(QAbstractFileEngine::FileInfoAll) & QAbstractFileEngine::LocalDiskFlag)) {
85 switch (access) {
86 case ReadAccess:
87 return getFileFlags(QAbstractFileEngine::ReadUserPerm);
88 case WriteAccess:
89 return getFileFlags(QAbstractFileEngine::WriteUserPerm);
90 case ExecuteAccess:
91 return getFileFlags(QAbstractFileEngine::ExeUserPerm);
92 default:
93 return false;
94 }
95 }
96
97 int mode = 0;
98 switch (access) {
99 case ReadAccess:
100 mode = R_OK;
101 break;
102 case WriteAccess:
103 mode = W_OK;
104 break;
105 case ExecuteAccess:
106 mode = X_OK;
107 break;
108 };
109#ifdef Q_OS_UNIX
110 return QT_ACCESS(QFile::encodeName(data->fileName).data(), mode) == 0;
111#endif
112#ifdef Q_OS_OS2
113 if ((access == ReadAccess && !getFileFlags(QAbstractFileEngine::ReadUserPerm))
114 || (access == WriteAccess && !getFileFlags(QAbstractFileEngine::WriteUserPerm))) {
115 return false;
116 }
117 if (access == ExecuteAccess)
118 return getFileFlags(QAbstractFileEngine::ExeUserPerm);
119
120 return QT_ACCESS(QFile::encodeName(data->fileName).data(), mode) == 0;
121#endif
122#ifdef Q_OS_WIN
123 if ((access == ReadAccess && !getFileFlags(QAbstractFileEngine::ReadUserPerm))
124 || (access == WriteAccess && !getFileFlags(QAbstractFileEngine::WriteUserPerm))) {
125 return false;
126 }
127 if (access == ExecuteAccess)
128 return getFileFlags(QAbstractFileEngine::ExeUserPerm);
129
130 return ::_waccess((wchar_t*)QFSFileEnginePrivate::longFileName(data->fileName).utf16(), mode) == 0;
131#endif
132 return false;
133}
134
135void QFileInfoPrivate::detach()
136{
137 qAtomicDetach(data);
138}
139
140QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
141{
142 if(data->cache_enabled && !data->fileNames[(int)name].isNull())
143 return data->fileNames[(int)name];
144 QString ret = data->fileEngine->fileName(name);
145 if(data->cache_enabled)
146 data->fileNames[(int)name] = ret;
147 return ret;
148}
149
150uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const
151{
152 // We split the testing into tests for for LinkType, BundleType and the rest.
153 // In order to determine if a file is a symlink or not, we have to lstat().
154 // If we're not interested in that information, we might as well avoid one
155 // extra syscall. Bundle detecton on Mac can be slow, expecially on network
156 // paths, so we separate out that as well.
157
158 QAbstractFileEngine::FileFlags flags;
159 if (!data->getCachedFlag(CachedFileFlags)) {
160 QAbstractFileEngine::FileFlags req = QAbstractFileEngine::FileInfoAll;
161 req &= (~QAbstractFileEngine::LinkType);
162 req &= (~QAbstractFileEngine::BundleType);
163
164 flags = data->fileEngine->fileFlags(req);
165 data->setCachedFlag(CachedFileFlags);
166 data->fileFlags |= uint(flags);
167 } else {
168 flags = QAbstractFileEngine::FileFlags(data->fileFlags & request);