Root/
Source at commit 1322 created 12 years 7 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /****************************************************************************␊ |
2 | ** ␊ |
3 | **␊ |
4 | ** Implementation of QFileInfo class␊ |
5 | **␊ |
6 | ** Created : 950628␊ |
7 | **␊ |
8 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.␊ |
9 | **␊ |
10 | ** This file is part of the tools module of the Qt GUI Toolkit.␊ |
11 | **␊ |
12 | ** This file may be distributed under the terms of the Q Public License␊ |
13 | ** as defined by Trolltech AS of Norway and appearing in the file␊ |
14 | ** LICENSE.QPL included in the packaging of this file.␊ |
15 | **␊ |
16 | ** This file may be distributed and/or modified under the terms of the␊ |
17 | ** GNU General Public License version 2 as published by the Free Software␊ |
18 | ** Foundation and appearing in the file LICENSE.GPL included in the␊ |
19 | ** packaging of this file.␊ |
20 | **␊ |
21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition␊ |
22 | ** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance␊ |
23 | ** with the Qt Commercial License Agreement provided with the Software.␊ |
24 | **␊ |
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE␊ |
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.␊ |
27 | **␊ |
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for␊ |
29 | ** information about Qt Commercial License Agreements.␊ |
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.␊ |
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.␊ |
32 | **␊ |
33 | ** Contact info@trolltech.com if any conditions of this licensing are␊ |
34 | ** not clear to you.␊ |
35 | **␊ |
36 | **********************************************************************/␊ |
37 | ␊ |
38 | #include "qglobal.h"␊ |
39 | ␊ |
40 | #if defined(_OS_SUN_)␊ |
41 | #define readlink _qt_hide_readlink␊ |
42 | #endif␊ |
43 | ␊ |
44 | #include <pwd.h>␊ |
45 | #include <grp.h>␊ |
46 | ␊ |
47 | #include "qfileinfo.h"␊ |
48 | #include "qfiledefs_p.h"␊ |
49 | #include "qdatetime.h"␊ |
50 | #include "qdir.h"␊ |
51 | ␊ |
52 | #if defined(_OS_SUN_)␊ |
53 | #undef readlink␊ |
54 | extern "C" int readlink( const char *, void *, uint );␊ |
55 | #endif␊ |
56 | ␊ |
57 | ␊ |
58 | void QFileInfo::slashify( QString& )␊ |
59 | {␊ |
60 | return;␊ |
61 | }␊ |
62 | ␊ |
63 | ␊ |
64 | void QFileInfo::makeAbs( QString & )␊ |
65 | {␊ |
66 | return;␊ |
67 | }␊ |
68 | ␊ |
69 | extern bool qt_file_access( const QString& fn, int t );␊ |
70 | ␊ |
71 | /*!␊ |
72 | Returns TRUE if we are pointing to a real file.␊ |
73 | \sa isDir(), isSymLink()␊ |
74 | */␊ |
75 | bool QFileInfo::isFile() const␊ |
76 | {␊ |
77 | if ( !fic || !cache )␊ |
78 | ␉doStat();␊ |
79 | return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;␊ |
80 | }␊ |
81 | ␊ |
82 | /*!␊ |
83 | Returns TRUE if we are pointing to a directory or a symbolic link to␊ |
84 | a directory.␊ |
85 | \sa isFile(), isSymLink()␊ |
86 | */␊ |
87 | ␊ |
88 | bool QFileInfo::isDir() const␊ |
89 | {␊ |
90 | if ( !fic || !cache )␊ |
91 | ␉doStat();␊ |
92 | return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;␊ |
93 | }␊ |
94 | ␊ |
95 | /*!␊ |
96 | Returns TRUE if we are pointing to a symbolic link.␊ |
97 | \sa isFile(), isDir(), readLink()␊ |
98 | */␊ |
99 | ␊ |
100 | bool QFileInfo::isSymLink() const␊ |
101 | {␊ |
102 | if ( !fic || !cache )␊ |
103 | ␉doStat();␊ |
104 | return fic ? fic->isSymLink : FALSE;␊ |
105 | }␊ |
106 | ␊ |
107 | ␊ |
108 | /*!␊ |
109 | Returns the name a symlink points to, or a null QString if the␊ |
110 | object does not refer to a symbolic link.␊ |
111 | ␊ |
112 | This name may not represent an existing file; it is only a string.␊ |
113 | QFileInfo::exists() returns TRUE if the symlink points to an␊ |
114 | existing file.␊ |
115 | ␊ |
116 | \sa exists(), isSymLink(), isDir(), isFile()␊ |
117 | */␊ |
118 | ␊ |
119 | QString QFileInfo::readLink() const␊ |
120 | {␊ |
121 | QString r;␊ |
122 | ␊ |
123 | #if defined(_OS_UNIX_) && !defined(_OS_OS2EMX_)␊ |
124 | char s[PATH_MAX+1];␊ |
125 | if ( !isSymLink() )␊ |
126 | ␉return QString();␊ |
127 | int len = readlink( QFile::encodeName(fn).data(), s, PATH_MAX );␊ |
128 | if ( len >= 0 ) {␊ |
129 | ␉s[len] = '\0';␊ |
130 | ␉r = QFile::decodeName(s);␊ |
131 | }␊ |
132 | #endif␊ |
133 | ␊ |
134 | return r;␊ |
135 | }␊ |
136 | ␊ |
137 | static const uint nobodyID = (uint) -2;␊ |
138 | ␊ |
139 | /*!␊ |
140 | Returns the owner of the file.␊ |
141 | ␊ |
142 | On systems where files do not have owners this function returns 0.␊ |
143 | ␊ |
144 | Note that this function can be time-consuming under UNIX. (in the order␊ |
145 | of milliseconds on a 486 DX2/66 running Linux).␊ |
146 | ␊ |
147 | \sa ownerId(), group(), groupId()␊ |
148 | */␊ |
149 | ␊ |
150 | QString QFileInfo::owner() const␊ |
151 | {␊ |
152 | passwd *pw = getpwuid( ownerId() );␊ |
153 | if ( pw )␊ |
154 | ␉return QFile::decodeName( pw->pw_name );␊ |
155 | return QString::null;␊ |
156 | }␊ |
157 | ␊ |
158 | /*!␊ |
159 | Returns the id of the owner of the file.␊ |
160 | ␊ |
161 | On systems where files do not have owners this function returns ((uint) -2).␊ |
162 | ␊ |
163 | \sa owner(), group(), groupId()␊ |
164 | */␊ |
165 | ␊ |
166 | uint QFileInfo::ownerId() const␊ |
167 | {␊ |
168 | if ( !fic || !cache )␊ |
169 | ␉doStat();␊ |
170 | if ( fic )␊ |
171 | ␉return fic->st.st_uid;␊ |
172 | return nobodyID;␊ |
173 | }␊ |
174 | ␊ |
175 | /*!␊ |
176 | Returns the group the file belongs to.␊ |
177 | ␊ |
178 | On systems where files do not have groups this function always␊ |
179 | returns 0.␊ |
180 | ␊ |
181 | Note that this function can be time-consuming under UNIX (in the order of␊ |
182 | milliseconds on a 486 DX2/66 running Linux).␊ |
183 | ␊ |
184 | \sa groupId(), owner(), ownerId()␊ |
185 | */␊ |
186 | ␊ |
187 | QString QFileInfo::group() const␊ |
188 | {␊ |
189 | struct group *gr = getgrgid( groupId() );␊ |
190 | if ( gr )␊ |
191 | ␉return QFile::decodeName( gr->gr_name );␊ |
192 | return QString::null;␊ |
193 | }␊ |
194 | ␊ |
195 | /*!␊ |
196 | Returns the id of the group the file belongs to.␊ |
197 | ␊ |
198 | On systems where files do not have groups this function always␊ |
199 | returns ((uind) -2).␊ |
200 | ␊ |
201 | \sa group(), owner(), ownerId()␊ |
202 | */␊ |
203 | ␊ |
204 | uint QFileInfo::groupId() const␊ |
205 | {␊ |
206 | if ( !fic || !cache )␊ |
207 | ␉doStat();␊ |
208 | if ( fic )␊ |
209 | ␉return fic->st.st_gid;␊ |
210 | return nobodyID;␊ |
211 | }␊ |
212 | ␊ |
213 | ␊ |
214 | /*!␊ |
215 | \fn bool QFileInfo::permission( int permissionSpec ) const␊ |
216 | ␊ |
217 | Tests for file permissions. The \e permissionSpec argument can be several␊ |
218 | flags of type PermissionSpec or'ed together to check for permission␊ |
219 | combinations.␊ |
220 | ␊ |
221 | On systems where files do not have permissions this function always␊ |
222 | returns TRUE.␊ |
223 | ␊ |
224 | Example:␊ |
225 | \code␊ |
226 | QFileInfo fi( "/tmp/tonsils" );␊ |
227 | if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )␊ |
228 | ␉qWarning( "Tonsils can be changed by me, and the group can read them.");␊ |
229 | if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )␊ |
230 | ␉qWarning( "Danger! Tonsils can be changed by the group or others!" );␊ |
231 | \endcode␊ |
232 | ␊ |
233 | \sa isReadable(), isWritable(), isExecutable()␊ |
234 | */␊ |
235 | ␊ |
236 | bool QFileInfo::permission( int permissionSpec ) const␊ |
237 | {␊ |
238 | if ( !fic || !cache )␊ |
239 | ␉doStat();␊ |
240 | if ( fic ) {␊ |
241 | ␉uint mask = 0;␊ |
242 | ␉if ( permissionSpec & ReadUser)␊ |
243 | ␉ mask |= S_IRUSR;␊ |
244 | ␉if ( permissionSpec & WriteUser)␊ |
245 | ␉ mask |= S_IWUSR;␊ |
246 | ␉if ( permissionSpec & ExeUser)␊ |
247 | ␉ mask |= S_IXUSR;␊ |
248 | ␉if ( permissionSpec & ReadGroup)␊ |
249 | ␉ mask |= S_IRGRP;␊ |
250 | ␉if ( permissionSpec & WriteGroup)␊ |
251 | ␉ mask |= S_IWGRP;␊ |
252 | ␉if ( permissionSpec & ExeGroup)␊ |
253 | ␉ mask |= S_IXGRP;␊ |
254 | ␉if ( permissionSpec & ReadOther)␊ |
255 | ␉ mask |= S_IROTH;␊ |
256 | ␉if ( permissionSpec & WriteOther)␊ |
257 | ␉ mask |= S_IWOTH;␊ |
258 | ␉if ( permissionSpec & ExeOther)␊ |
259 | ␉ mask |= S_IXOTH;␊ |
260 | ␉if ( mask ) {␊ |
261 | ␉ return (fic->st.st_mode & mask) == mask;␊ |
262 | ␉} else {␊ |
263 | #if defined(CHECK_NULL)␊ |
264 | ␉ qWarning( "QFileInfo::permission: permissionSpec is 0" );␊ |
265 | #endif␊ |
266 | ␉ return TRUE;␊ |
267 | ␉}␊ |
268 | } else {␊ |
269 | ␉return FALSE;␊ |
270 | }␊ |
271 | }␊ |
272 | ␊ |
273 | /*!␊ |
274 | Returns the file size in bytes, or 0 if the file does not exist if the size␊ |
275 | cannot be fetched.␊ |
276 | */␊ |
277 | ␊ |
278 | uint QFileInfo::size() const␊ |
279 | {␊ |
280 | if ( !fic || !cache )␊ |
281 | ␉doStat();␊ |
282 | if ( fic )␊ |
283 | ␉return (uint)fic->st.st_size;␊ |
284 | else␊ |
285 | ␉return 0;␊ |
286 | }␊ |
287 | ␊ |
288 | ␊ |
289 | /*!␊ |
290 | Returns the date and time when the file was last modified.␊ |
291 | \sa lastRead()␊ |
292 | */␊ |
293 | ␊ |
294 | QDateTime QFileInfo::lastModified() const␊ |
295 | {␊ |
296 | QDateTime dt;␊ |
297 | if ( !fic || !cache )␊ |
298 | ␉doStat();␊ |
299 | if ( fic )␊ |
300 | ␉dt.setTime_t( fic->st.st_mtime );␊ |
301 | return dt;␊ |
302 | }␊ |
303 | ␊ |
304 | /*!␊ |
305 | Returns the date and time when the file was last read (accessed).␊ |
306 | ␊ |
307 | On systems that do not support last read times, the modification time is␊ |
308 | returned.␊ |
309 | ␊ |
310 | \sa lastModified()␊ |
311 | */␊ |
312 | ␊ |
313 | QDateTime QFileInfo::lastRead() const␊ |
314 | {␊ |
315 | QDateTime dt;␊ |
316 | if ( !fic || !cache )␊ |
317 | ␉doStat();␊ |
318 | if ( fic )␊ |
319 | ␉dt.setTime_t( fic->st.st_atime );␊ |
320 | return dt;␊ |
321 | }␊ |
322 | ␊ |
323 | ␊ |
324 | void QFileInfo::doStat() const␊ |
325 | {␊ |
326 | QFileInfo *that = ((QFileInfo*)this);␉// mutable function␊ |
327 | if ( !that->fic )␊ |
328 | ␉that->fic = new QFileInfoCache;␊ |
329 | STATBUF *b = &that->fic->st;␊ |
330 | that->fic->isSymLink = FALSE;␊ |
331 | ␊ |
332 | #if defined(_OS_UNIX_) && defined(S_IFLNK)␊ |
333 | if ( ::lstat(QFile::encodeName(fn),b) == 0 ) {␊ |
334 | ␉if ( S_ISLNK( b->st_mode ) )␊ |
335 | ␉ that->fic->isSymLink = TRUE;␊ |
336 | ␉else␊ |
337 | ␉ return;␊ |
338 | }␊ |
339 | #endif␊ |
340 | int r;␊ |
341 | ␊ |
342 | r = STAT( QFile::encodeName(fn), b );␊ |
343 | ␊ |
344 | if ( r != 0 ) {␊ |
345 | ␉delete that->fic;␊ |
346 | ␉that->fic = 0;␊ |
347 | }␊ |
348 | }␊ |
349 | ␊ |
350 | /*!␊ |
351 | Returns the directory path of the file.␊ |
352 | ␊ |
353 | If \e absPath is TRUE an absolute path is always returned.␊ |
354 | ␊ |
355 | \sa dir(), filePath(), fileName(), isRelative()␊ |
356 | */␊ |
357 | #ifndef QT_NO_DIR␊ |
358 | QString QFileInfo::dirPath( bool absPath ) const␊ |
359 | {␊ |
360 | QString s;␊ |
361 | if ( absPath )␊ |
362 | ␉s = absFilePath();␊ |
363 | else␊ |
364 | ␉s = fn;␊ |
365 | int pos = s.findRev( '/' );␊ |
366 | if ( pos == -1 ) {␊ |
367 | ␉return QString::fromLatin1(".");␊ |
368 | } else {␊ |
369 | ␉if ( pos == 0 )␊ |
370 | ␉ return QString::fromLatin1( "/" );␊ |
371 | ␉return s.left( pos );␊ |
372 | }␊ |
373 | }␊ |
374 | #endif␊ |
375 | /*!␊ |
376 | Returns the name of the file, the file path is not included.␊ |
377 | ␊ |
378 | Example:␊ |
379 | \code␊ |
380 | QFileInfo fi( "/tmp/abdomen.lower" );␊ |
381 | QString name = fi.fileName();␉␉// name = "abdomen.lower"␊ |
382 | \endcode␊ |
383 | ␊ |
384 | \sa isRelative(), filePath(), baseName(), extension()␊ |
385 | */␊ |
386 | ␊ |
387 | QString QFileInfo::fileName() const␊ |
388 | {␊ |
389 | int p = fn.findRev( '/' );␊ |
390 | if ( p == -1 ) {␊ |
391 | ␉return fn;␊ |
392 | } else {␊ |
393 | ␉return fn.mid(p+1);␊ |
394 | }␊ |
395 | }␊ |
396 | ␊ |
397 | /*!␊ |
398 | Returns the absolute path name.␊ |
399 | ␊ |
400 | The absolute path name is the file name including the absolute path. If␊ |
401 | the QFileInfo is absolute (i.e. not relative) this function will return␊ |
402 | the same string as filePath().␊ |
403 | ␊ |
404 | Note that this function can be time-consuming under UNIX. (in the order␊ |
405 | of milliseconds on a 486 DX2/66 running Linux).␊ |
406 | ␊ |
407 | \sa isRelative(), filePath()␊ |
408 | */␊ |
409 | #ifndef QT_NO_DIR␊ |
410 | QString QFileInfo::absFilePath() const␊ |
411 | {␊ |
412 | if ( QDir::isRelativePath(fn) ) {␊ |
413 | ␉QString tmp = QDir::currentDirPath();␊ |
414 | ␉tmp += '/';␊ |
415 | ␉tmp += fn;␊ |
416 | ␉makeAbs( tmp );␊ |
417 | ␉return QDir::cleanDirPath( tmp );␊ |
418 | } else {␊ |
419 | ␉QString tmp = fn;␊ |
420 | ␉makeAbs( tmp );␊ |
421 | ␉return QDir::cleanDirPath( tmp );␊ |
422 | }␊ |
423 | ␊ |
424 | }␊ |
425 | #endif␊ |
426 |