|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtCore module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
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 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qabstractfileengine.h" |
|
43 #include "private/qabstractfileengine_p.h" |
|
44 #include "qdatetime.h" |
|
45 #include "qreadwritelock.h" |
|
46 #include "qvariant.h" |
|
47 // built-in handlers |
|
48 #include "qfsfileengine.h" |
|
49 #include "qdiriterator.h" |
|
50 |
|
51 QT_BEGIN_NAMESPACE |
|
52 |
|
53 /*! |
|
54 \class QAbstractFileEngineHandler |
|
55 \reentrant |
|
56 |
|
57 \brief The QAbstractFileEngineHandler class provides a way to register |
|
58 custom file engines with your application. |
|
59 |
|
60 \ingroup io |
|
61 \since 4.1 |
|
62 |
|
63 QAbstractFileEngineHandler is a factory for creating QAbstractFileEngine |
|
64 objects (file engines), which are used internally by QFile, QFileInfo, and |
|
65 QDir when working with files and directories. |
|
66 |
|
67 When you open a file, Qt chooses a suitable file engine by passing the |
|
68 file name from QFile or QDir through an internal list of registered file |
|
69 engine handlers. The first handler to recognize the file name is used to |
|
70 create the engine. Qt provides internal file engines for working with |
|
71 regular files and resources, but you can also register your own |
|
72 QAbstractFileEngine subclasses. |
|
73 |
|
74 To install an application-specific file engine, you subclass |
|
75 QAbstractFileEngineHandler and reimplement create(). When you instantiate |
|
76 the handler (e.g. by creating an instance on the stack or on the heap), it |
|
77 will automatically register with Qt. (The latest registered handler takes |
|
78 precedence over existing handlers.) |
|
79 |
|
80 For example: |
|
81 |
|
82 \snippet doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp 0 |
|
83 |
|
84 When the handler is destroyed, it is automatically removed from Qt. |
|
85 |
|
86 The most common approach to registering a handler is to create an instance |
|
87 as part of the start-up phase of your application. It is also possible to |
|
88 limit the scope of the file engine handler to a particular area of |
|
89 interest (e.g. a special file dialog that needs a custom file engine). By |
|
90 creating the handler inside a local scope, you can precisely control the |
|
91 area in which your engine will be applied without disturbing file |
|
92 operations in other parts of your application. |
|
93 |
|
94 \sa QAbstractFileEngine, QAbstractFileEngine::create() |
|
95 */ |
|
96 |
|
97 /* |
|
98 All application-wide handlers are stored in this list. The mutex must be |
|
99 acquired to ensure thread safety. |
|
100 */ |
|
101 Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, fileEngineHandlerMutex, (QReadWriteLock::Recursive)) |
|
102 static bool qt_abstractfileenginehandlerlist_shutDown = false; |
|
103 class QAbstractFileEngineHandlerList : public QList<QAbstractFileEngineHandler *> |
|
104 { |
|
105 public: |
|
106 ~QAbstractFileEngineHandlerList() |
|
107 { |
|
108 QWriteLocker locker(fileEngineHandlerMutex()); |
|
109 qt_abstractfileenginehandlerlist_shutDown = true; |
|
110 } |
|
111 }; |
|
112 Q_GLOBAL_STATIC(QAbstractFileEngineHandlerList, fileEngineHandlers) |
|
113 |
|
114 /*! |
|
115 Constructs a file handler and registers it with Qt. Once created this |
|
116 handler's create() function will be called (along with all the other |
|
117 handlers) for any paths used. The most recently created handler that |
|
118 recognizes the given path (i.e. that returns a QAbstractFileEngine) is |
|
119 used for the new path. |
|
120 |
|
121 \sa create() |
|
122 */ |
|
123 QAbstractFileEngineHandler::QAbstractFileEngineHandler() |
|
124 { |
|
125 QWriteLocker locker(fileEngineHandlerMutex()); |
|
126 fileEngineHandlers()->prepend(this); |
|
127 } |
|
128 |
|
129 /*! |
|
130 Destroys the file handler. This will automatically unregister the handler |
|
131 from Qt. |
|
132 */ |
|
133 QAbstractFileEngineHandler::~QAbstractFileEngineHandler() |
|
134 { |
|
135 QWriteLocker locker(fileEngineHandlerMutex()); |
|
136 // Remove this handler from the handler list only if the list is valid. |
|
137 if (!qt_abstractfileenginehandlerlist_shutDown) |
|
138 fileEngineHandlers()->removeAll(this); |
|
139 } |
|
140 |
|
141 /*! |
|
142 \fn QAbstractFileEngine *QAbstractFileEngineHandler::create(const QString &fileName) const |
|
143 |
|
144 Creates a file engine for file \a fileName. Returns 0 if this |
|
145 file handler cannot handle \a fileName. |
|
146 |
|
147 Example: |
|
148 |
|
149 \snippet doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp 1 |
|
150 |
|
151 \sa QAbstractFileEngine::create() |
|
152 */ |
|
153 |
|
154 /*! |
|
155 Creates and returns a QAbstractFileEngine suitable for processing \a |
|
156 fileName. |
|
157 |
|
158 You should not need to call this function; use QFile, QFileInfo or |
|
159 QDir directly instead. |
|
160 |
|
161 If you reimplemnt this function, it should only return file |
|
162 engines that knows how to handle \a fileName; otherwise, it should |
|
163 return 0. |
|
164 |
|
165 \sa QAbstractFileEngineHandler |
|
166 */ |
|
167 QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName) |
|
168 { |
|
169 { |
|
170 QReadLocker locker(fileEngineHandlerMutex()); |
|
171 |
|
172 // check for registered handlers that can load the file |
|
173 for (int i = 0; i < fileEngineHandlers()->size(); i++) { |
|
174 if (QAbstractFileEngine *ret = fileEngineHandlers()->at(i)->create(fileName)) |
|
175 return ret; |
|
176 } |
|
177 } |
|
178 |
|
179 #ifdef QT_BUILD_CORE_LIB |
|
180 if (!fileName.startsWith(QLatin1Char('/'))) { |
|
181 int prefixSeparator = fileName.indexOf(QLatin1Char(':')); |
|
182 if (prefixSeparator > 1) { |
|
183 QString prefix = fileName.left(prefixSeparator); |
|
184 QString fileNameWithoutPrefix = fileName.mid(prefixSeparator + 1).prepend(QLatin1Char('/')); |
|
185 const QStringList &paths = QDir::searchPaths(prefix); |
|
186 for (int i = 0; i < paths.count(); i++) { |
|
187 QString path = paths.at(i); |
|
188 path.append(fileNameWithoutPrefix); |
|
189 QAbstractFileEngine *engine = create(path); |
|
190 if (engine && (engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag)) { |
|
191 return engine; |
|
192 } |
|
193 delete engine; |
|
194 } |
|
195 } |
|
196 } |
|
197 #endif |
|
198 |
|
199 #ifdef QT_NO_FSFILEENGINE |
|
200 return 0; |
|
201 #else |
|
202 // fall back to regular file engine |
|
203 return new QFSFileEngine(fileName); |
|
204 #endif |
|
205 } |
|
206 |
|
207 /*! |
|
208 \class QAbstractFileEngine |
|
209 \reentrant |
|
210 |
|
211 \brief The QAbstractFileEngine class provides an abstraction for accessing |
|
212 the filesystem. |
|
213 |
|
214 \ingroup io |
|
215 \since 4.1 |
|
216 |
|
217 The QDir, QFile, and QFileInfo classes all make use of a |
|
218 QAbstractFileEngine internally. If you create your own QAbstractFileEngine |
|
219 subclass (and register it with Qt by creating a QAbstractFileEngineHandler |
|
220 subclass), your file engine will be used when the path is one that your |
|
221 file engine handles. |
|
222 |
|
223 A QAbstractFileEngine refers to one file or one directory. If the referent |
|
224 is a file, the setFileName(), rename(), and remove() functions are |
|
225 applicable. If the referent is a directory the mkdir(), rmdir(), and |
|
226 entryList() functions are applicable. In all cases the caseSensitive(), |
|
227 isRelativePath(), fileFlags(), ownerId(), owner(), and fileTime() |
|
228 functions are applicable. |
|
229 |
|
230 A QAbstractFileEngine subclass can be created to do synchronous network I/O |
|
231 based file system operations, local file system operations, or to operate |
|
232 as a resource system to access file based resources. |
|
233 |
|
234 \sa QAbstractFileEngineHandler |
|
235 */ |
|
236 |
|
237 /*! |
|
238 \enum QAbstractFileEngine::FileName |
|
239 |
|
240 These values are used to request a file name in a particular |
|
241 format. |
|
242 |
|
243 \value DefaultName The same filename that was passed to the |
|
244 QAbstractFileEngine. |
|
245 \value BaseName The name of the file excluding the path. |
|
246 \value PathName The path to the file excluding the base name. |
|
247 \value AbsoluteName The absolute path to the file (including |
|
248 the base name). |
|
249 \value AbsolutePathName The absolute path to the file (excluding |
|
250 the base name). |
|
251 \value LinkName The full file name of the file that this file is a |
|
252 link to. (This will be empty if this file is not a link.) |
|
253 \value CanonicalName Often very similar to LinkName. Will return the true path to the file. |
|
254 \value CanonicalPathName Same as CanonicalName, excluding the base name. |
|
255 \value BundleName Returns the name of the bundle implies BundleType is set. |
|
256 |
|
257 \omitvalue NFileNames |
|
258 |
|
259 \sa fileName(), setFileName() |
|
260 */ |
|
261 |
|
262 /*! |
|
263 \enum QAbstractFileEngine::FileFlag |
|
264 |
|
265 The permissions and types of a file, suitable for OR'ing together. |
|
266 |
|
267 \value ReadOwnerPerm The owner of the file has permission to read |
|
268 it. |
|
269 \value WriteOwnerPerm The owner of the file has permission to |
|
270 write to it. |
|
271 \value ExeOwnerPerm The owner of the file has permission to |
|
272 execute it. |
|
273 \value ReadUserPerm The current user has permission to read the |
|
274 file. |
|
275 \value WriteUserPerm The current user has permission to write to |
|
276 the file. |
|
277 \value ExeUserPerm The current user has permission to execute the |
|
278 file. |
|
279 \value ReadGroupPerm Members of the current user's group have |
|
280 permission to read the file. |
|
281 \value WriteGroupPerm Members of the current user's group have |
|
282 permission to write to the file. |
|
283 \value ExeGroupPerm Members of the current user's group have |
|
284 permission to execute the file. |
|
285 \value ReadOtherPerm All users have permission to read the file. |
|
286 \value WriteOtherPerm All users have permission to write to the |
|
287 file. |
|
288 \value ExeOtherPerm All users have permission to execute the file. |
|
289 |
|
290 \value LinkType The file is a link to another file (or link) in |
|
291 the file system (i.e. not a file or directory). |
|
292 \value FileType The file is a regular file to the file system |
|
293 (i.e. not a link or directory) |
|
294 \value BundleType The file is a Mac OS X bundle implies DirectoryType |
|
295 \value DirectoryType The file is a directory in the file system |
|
296 (i.e. not a link or file). |
|
297 |
|
298 \value HiddenFlag The file is hidden. |
|
299 \value ExistsFlag The file actually exists in the file system. |
|
300 \value RootFlag The file or the file pointed to is the root of the filesystem. |
|
301 \value LocalDiskFlag The file resides on the local disk and can be passed to standard file functions. |
|
302 \value Refresh Passing this flag will force the file engine to refresh all flags. |
|
303 |
|
304 \omitvalue PermsMask |
|
305 \omitvalue TypesMask |
|
306 \omitvalue FlagsMask |
|
307 \omitvalue FileInfoAll |
|
308 |
|
309 \sa fileFlags(), setFileName() |
|
310 */ |
|
311 |
|
312 /*! |
|
313 \enum QAbstractFileEngine::FileTime |
|
314 |
|
315 These are used by the fileTime() function. |
|
316 |
|
317 \value CreationTime When the file was created. |
|
318 \value ModificationTime When the file was most recently modified. |
|
319 \value AccessTime When the file was most recently accessed (e.g. |
|
320 read or written to). |
|
321 |
|
322 \sa setFileName() |
|
323 */ |
|
324 |
|
325 /*! |
|
326 \enum QAbstractFileEngine::FileOwner |
|
327 |
|
328 \value OwnerUser The user who owns the file. |
|
329 \value OwnerGroup The group who owns the file. |
|
330 |
|
331 \sa owner(), ownerId(), setFileName() |
|
332 */ |
|
333 |
|
334 /*! |
|
335 Constructs a new QAbstractFileEngine that does not refer to any file or directory. |
|
336 |
|
337 \sa setFileName() |
|
338 */ |
|
339 QAbstractFileEngine::QAbstractFileEngine() : d_ptr(new QAbstractFileEnginePrivate) |
|
340 { |
|
341 d_ptr->q_ptr = this; |
|
342 } |
|
343 |
|
344 /*! |
|
345 \internal |
|
346 |
|
347 Constructs a QAbstractFileEngine. |
|
348 */ |
|
349 QAbstractFileEngine::QAbstractFileEngine(QAbstractFileEnginePrivate &dd) : d_ptr(&dd) |
|
350 { |
|
351 d_ptr->q_ptr = this; |
|
352 } |
|
353 |
|
354 /*! |
|
355 Destroys the QAbstractFileEngine. |
|
356 */ |
|
357 QAbstractFileEngine::~QAbstractFileEngine() |
|
358 { |
|
359 } |
|
360 |
|
361 /*! |
|
362 \fn bool QAbstractFileEngine::open(QIODevice::OpenMode mode) |
|
363 |
|
364 Opens the file in the specified \a mode. Returns true if the file |
|
365 was successfully opened; otherwise returns false. |
|
366 |
|
367 The \a mode is an OR combination of QIODevice::OpenMode and |
|
368 QIODevice::HandlingMode values. |
|
369 */ |
|
370 bool QAbstractFileEngine::open(QIODevice::OpenMode openMode) |
|
371 { |
|
372 Q_UNUSED(openMode); |
|
373 return false; |
|
374 } |
|
375 |
|
376 /*! |
|
377 Closes the file, returning true if successful; otherwise returns false. |
|
378 |
|
379 The default implementation always returns false. |
|
380 */ |
|
381 bool QAbstractFileEngine::close() |
|
382 { |
|
383 return false; |
|
384 } |
|
385 |
|
386 /*! |
|
387 Flushes the open file, returning true if successful; otherwise returns |
|
388 false. |
|
389 |
|
390 The default implementation always returns false. |
|
391 */ |
|
392 bool QAbstractFileEngine::flush() |
|
393 { |
|
394 return false; |
|
395 } |
|
396 |
|
397 /*! |
|
398 Returns the size of the file. |
|
399 */ |
|
400 qint64 QAbstractFileEngine::size() const |
|
401 { |
|
402 return 0; |
|
403 } |
|
404 |
|
405 /*! |
|
406 Returns the current file position. |
|
407 |
|
408 This is the position of the data read/write head of the file. |
|
409 */ |
|
410 qint64 QAbstractFileEngine::pos() const |
|
411 { |
|
412 return 0; |
|
413 } |
|
414 |
|
415 /*! |
|
416 \fn bool QAbstractFileEngine::seek(qint64 offset) |
|
417 |
|
418 Sets the file position to the given \a offset. Returns true if |
|
419 the position was successfully set; otherwise returns false. |
|
420 |
|
421 The offset is from the beginning of the file, unless the |
|
422 file is sequential. |
|
423 |
|
424 \sa isSequential() |
|
425 */ |
|
426 bool QAbstractFileEngine::seek(qint64 pos) |
|
427 { |
|
428 Q_UNUSED(pos); |
|
429 return false; |
|
430 } |
|
431 |
|
432 /*! |
|
433 Returns true if the file is a sequential access device; returns |
|
434 false if the file is a direct access device. |
|
435 |
|
436 Operations involving size() and seek(int) are not valid on |
|
437 sequential devices. |
|
438 */ |
|
439 bool QAbstractFileEngine::isSequential() const |
|
440 { |
|
441 return false; |
|
442 } |
|
443 |
|
444 /*! |
|
445 Requests that the file is deleted from the file system. If the |
|
446 operation succeeds return true; otherwise return false. |
|
447 |
|
448 This virtual function must be reimplemented by all subclasses. |
|
449 |
|
450 \sa setFileName() rmdir() |
|
451 */ |
|
452 bool QAbstractFileEngine::remove() |
|
453 { |
|
454 return false; |
|
455 } |
|
456 |
|
457 /*! |
|
458 Copies the contents of this file to a file with the name \a newName. |
|
459 Returns true on success; otherwise, false is returned. |
|
460 */ |
|
461 bool QAbstractFileEngine::copy(const QString &newName) |
|
462 { |
|
463 Q_UNUSED(newName); |
|
464 return false; |
|
465 } |
|
466 |
|
467 /*! |
|
468 Requests that the file be renamed to \a newName in the file |
|
469 system. If the operation succeeds return true; otherwise return |
|
470 false. |
|
471 |
|
472 This virtual function must be reimplemented by all subclasses. |
|
473 |
|
474 \sa setFileName() |
|
475 */ |
|
476 bool QAbstractFileEngine::rename(const QString &newName) |
|
477 { |
|
478 Q_UNUSED(newName); |
|
479 return false; |
|
480 } |
|
481 |
|
482 /*! |
|
483 Creates a link from the file currently specified by fileName() to |
|
484 \a newName. What a link is depends on the underlying filesystem |
|
485 (be it a shortcut on Windows or a symbolic link on Unix). Returns |
|
486 true if successful; otherwise returns false. |
|
487 */ |
|
488 bool QAbstractFileEngine::link(const QString &newName) |
|
489 { |
|
490 Q_UNUSED(newName); |
|
491 return false; |
|
492 } |
|
493 |
|
494 /*! |
|
495 Requests that the directory \a dirName be created. If |
|
496 \a createParentDirectories is true, then any sub-directories in \a dirName |
|
497 that don't exist must be created. If \a createParentDirectories is false then |
|
498 any sub-directories in \a dirName must already exist for the function to |
|
499 succeed. If the operation succeeds return true; otherwise return |
|
500 false. |
|
501 |
|
502 This virtual function must be reimplemented by all subclasses. |
|
503 |
|
504 \sa setFileName() rmdir() isRelativePath() |
|
505 */ |
|
506 bool QAbstractFileEngine::mkdir(const QString &dirName, bool createParentDirectories) const |
|
507 { |
|
508 Q_UNUSED(dirName); |
|
509 Q_UNUSED(createParentDirectories); |
|
510 return false; |
|
511 } |
|
512 |
|
513 /*! |
|
514 Requests that the directory \a dirName is deleted from the file |
|
515 system. When \a recurseParentDirectories is true, then any empty |
|
516 parent-directories in \a dirName must also be deleted. If |
|
517 \a recurseParentDirectories is false, only the \a dirName leaf-node |
|
518 should be deleted. In most file systems a directory cannot be deleted |
|
519 using this function if it is non-empty. If the operation succeeds |
|
520 return true; otherwise return false. |
|
521 |
|
522 This virtual function must be reimplemented by all subclasses. |
|
523 |
|
524 \sa setFileName() remove() mkdir() isRelativePath() |
|
525 */ |
|
526 bool QAbstractFileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const |
|
527 { |
|
528 Q_UNUSED(dirName); |
|
529 Q_UNUSED(recurseParentDirectories); |
|
530 return false; |
|
531 } |
|
532 |
|
533 /*! |
|
534 Requests that the file be set to size \a size. If \a size is larger |
|
535 than the current file then it is filled with 0's, if smaller it is |
|
536 simply truncated. If the operations succceeds return true; otherwise |
|
537 return false; |
|
538 |
|
539 This virtual function must be reimplemented by all subclasses. |
|
540 |
|
541 \sa size() |
|
542 */ |
|
543 bool QAbstractFileEngine::setSize(qint64 size) |
|
544 { |
|
545 Q_UNUSED(size); |
|
546 return false; |
|
547 } |
|
548 |
|
549 /*! |
|
550 Should return true if the underlying file system is case-sensitive; |
|
551 otherwise return false. |
|
552 |
|
553 This virtual function must be reimplemented by all subclasses. |
|
554 */ |
|
555 bool QAbstractFileEngine::caseSensitive() const |
|
556 { |
|
557 return false; |
|
558 } |
|
559 |
|
560 /*! |
|
561 Return true if the file referred to by this file engine has a |
|
562 relative path; otherwise return false. |
|
563 |
|
564 This virtual function must be reimplemented by all subclasses. |
|
565 |
|
566 \sa setFileName() |
|
567 */ |
|
568 bool QAbstractFileEngine::isRelativePath() const |
|
569 { |
|
570 return false; |
|
571 } |
|
572 |
|
573 /*! |
|
574 Requests that a list of all the files matching the \a filters |
|
575 list based on the \a filterNames in the file engine's directory |
|
576 are returned. |
|
577 |
|
578 Should return an empty list if the file engine refers to a file |
|
579 rather than a directory, or if the directory is unreadable or does |
|
580 not exist or if nothing matches the specifications. |
|
581 |
|
582 This virtual function must be reimplemented by all subclasses. |
|
583 |
|
584 \sa setFileName() |
|
585 */ |
|
586 QStringList QAbstractFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const |
|
587 { |
|
588 QStringList ret; |
|
589 QDirIterator it(fileName(), filterNames, filters); |
|
590 while (it.hasNext()) { |
|
591 it.next(); |
|
592 ret << it.fileName(); |
|
593 } |
|
594 return ret; |
|
595 } |
|
596 |
|
597 /*! |
|
598 This function should return the set of OR'd flags that are true |
|
599 for the file engine's file, and that are in the \a type's OR'd |
|
600 members. |
|
601 |
|
602 In your reimplementation you can use the \a type argument as an |
|
603 optimization hint and only return the OR'd set of members that are |
|
604 true and that match those in \a type; in other words you can |
|
605 ignore any members not mentioned in \a type, thus avoiding some |
|
606 potentially expensive lookups or system calls. |
|
607 |
|
608 This virtual function must be reimplemented by all subclasses. |
|
609 |
|
610 \sa setFileName() |
|
611 */ |
|
612 QAbstractFileEngine::FileFlags QAbstractFileEngine::fileFlags(FileFlags type) const |
|
613 { |
|
614 Q_UNUSED(type); |
|
615 return 0; |
|
616 } |
|
617 |
|
618 /*! |
|
619 Requests that the file's permissions be set to \a perms. The argument |
|
620 perms will be set to the OR-ed together combination of |
|
621 QAbstractFileEngine::FileInfo, with only the QAbstractFileEngine::PermsMask being |
|
622 honored. If the operations succceeds return true; otherwise return |
|
623 false; |
|
624 |
|
625 This virtual function must be reimplemented by all subclasses. |
|
626 |
|
627 \sa size() |
|
628 */ |
|
629 bool QAbstractFileEngine::setPermissions(uint perms) |
|
630 { |
|
631 Q_UNUSED(perms); |
|
632 return false; |
|
633 } |
|
634 |
|
635 /*! |
|
636 Return the file engine's current file name in the format |
|
637 specified by \a file. |
|
638 |
|
639 If you don't handle some \c FileName possibilities, return the |
|
640 file name set in setFileName() when an unhandled format is |
|
641 requested. |
|
642 |
|
643 This virtual function must be reimplemented by all subclasses. |
|
644 |
|
645 \sa setFileName(), FileName |
|
646 */ |
|
647 QString QAbstractFileEngine::fileName(FileName file) const |
|
648 { |
|
649 Q_UNUSED(file); |
|
650 return QString(); |
|
651 } |
|
652 |
|
653 /*! |
|
654 If \a owner is \c OwnerUser return the ID of the user who owns |
|
655 the file. If \a owner is \c OwnerGroup return the ID of the group |
|
656 that own the file. If you can't determine the owner return -2. |
|
657 |
|
658 This virtual function must be reimplemented by all subclasses. |
|
659 |
|
660 \sa owner() setFileName(), FileOwner |
|
661 */ |
|
662 uint QAbstractFileEngine::ownerId(FileOwner owner) const |
|
663 { |
|
664 Q_UNUSED(owner); |
|
665 return 0; |
|
666 } |
|
667 |
|
668 /*! |
|
669 If \a owner is \c OwnerUser return the name of the user who owns |
|
670 the file. If \a owner is \c OwnerGroup return the name of the group |
|
671 that own the file. If you can't determine the owner return |
|
672 QString(). |
|
673 |
|
674 This virtual function must be reimplemented by all subclasses. |
|
675 |
|
676 \sa ownerId() setFileName(), FileOwner |
|
677 */ |
|
678 QString QAbstractFileEngine::owner(FileOwner owner) const |
|
679 { |
|
680 Q_UNUSED(owner); |
|
681 return QString(); |
|
682 } |
|
683 |
|
684 /*! |
|
685 If \a time is \c CreationTime, return when the file was created. |
|
686 If \a time is \c ModificationTime, return when the file was most |
|
687 recently modified. If \a time is \c AccessTime, return when the |
|
688 file was most recently accessed (e.g. read or written). |
|
689 If the time cannot be determined return QDateTime() (an invalid |
|
690 date time). |
|
691 |
|
692 This virtual function must be reimplemented by all subclasses. |
|
693 |
|
694 \sa setFileName(), QDateTime, QDateTime::isValid(), FileTime |
|
695 */ |
|
696 QDateTime QAbstractFileEngine::fileTime(FileTime time) const |
|
697 { |
|
698 Q_UNUSED(time); |
|
699 return QDateTime(); |
|
700 } |
|
701 |
|
702 /*! |
|
703 Sets the file engine's file name to \a file. This file name is the |
|
704 file that the rest of the virtual functions will operate on. |
|
705 |
|
706 This virtual function must be reimplemented by all subclasses. |
|
707 |
|
708 \sa rename() |
|
709 */ |
|
710 void QAbstractFileEngine::setFileName(const QString &file) |
|
711 { |
|
712 Q_UNUSED(file); |
|
713 } |
|
714 |
|
715 /*! |
|
716 Returns the native file handle for this file engine. This handle must be |
|
717 used with care; its value and type are platform specific, and using it |
|
718 will most likely lead to non-portable code. |
|
719 */ |
|
720 int QAbstractFileEngine::handle() const |
|
721 { |
|
722 return -1; |
|
723 } |
|
724 |
|
725 /*! |
|
726 \since 4.3 |
|
727 |
|
728 Returns true if the current position is at the end of the file; otherwise, |
|
729 returns false. |
|
730 |
|
731 This function bases its behavior on calling extension() with |
|
732 AtEndExtension. If the engine does not support this extension, false is |
|
733 returned. |
|
734 |
|
735 \sa extension(), supportsExtension(), QFile::atEnd() |
|
736 */ |
|
737 bool QAbstractFileEngine::atEnd() const |
|
738 { |
|
739 return const_cast<QAbstractFileEngine *>(this)->extension(AtEndExtension); |
|
740 } |
|
741 |
|
742 /*! |
|
743 \since 4.4 |
|
744 |
|
745 Maps \a size bytes of the file into memory starting at \a offset. |
|
746 Returns a pointer to the memory if successful; otherwise returns false |
|
747 if, for example, an error occurs. |
|
748 |
|
749 This function bases its behavior on calling extension() with |
|
750 MapExtensionOption. If the engine does not support this extension, 0 is |
|
751 returned. |
|
752 |
|
753 \a flags is currently not used, but could be used in the future. |
|
754 |
|
755 \sa unmap(), supportsExtension() |
|
756 */ |
|
757 |
|
758 uchar *QAbstractFileEngine::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) |
|
759 { |
|
760 MapExtensionOption option; |
|
761 option.offset = offset; |
|
762 option.size = size; |
|
763 option.flags = flags; |
|
764 MapExtensionReturn r; |
|
765 if (!extension(MapExtension, &option, &r)) |
|
766 return 0; |
|
767 return r.address; |
|
768 } |
|
769 |
|
770 /*! |
|
771 \since 4.4 |
|
772 |
|
773 Unmaps the memory \a address. Returns true if the unmap succeeds; otherwise |
|
774 returns false. |
|
775 |
|
776 This function bases its behavior on calling extension() with |
|
777 UnMapExtensionOption. If the engine does not support this extension, false is |
|
778 returned. |
|
779 |
|
780 \sa map(), supportsExtension() |
|
781 */ |
|
782 bool QAbstractFileEngine::unmap(uchar *address) |
|
783 { |
|
784 UnMapExtensionOption options; |
|
785 options.address = address; |
|
786 return extension(UnMapExtension, &options); |
|
787 } |
|
788 |
|
789 /*! |
|
790 \since 4.3 |
|
791 \class QAbstractFileEngineIterator |
|
792 \brief The QAbstractFileEngineIterator class provides an iterator |
|
793 interface for custom file engines. |
|
794 |
|
795 If all you want is to iterate over entries in a directory, see |
|
796 QDirIterator instead. This class is only for custom file engine authors. |
|
797 |
|
798 QAbstractFileEngineIterator is a unidirectional single-use virtual |
|
799 iterator that plugs into QDirIterator, providing transparent proxy |
|
800 iteration for custom file engines. |
|
801 |
|
802 You can subclass QAbstractFileEngineIterator to provide an iterator when |
|
803 writing your own file engine. To plug the iterator into your file system, |
|
804 you simply return an instance of this subclass from a reimplementation of |
|
805 QAbstractFileEngine::beginEntryList(). |
|
806 |
|
807 Example: |
|
808 |
|
809 \snippet doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp 2 |
|
810 |
|
811 QAbstractFileEngineIterator is associated with a path, name filters, and |
|
812 entry filters. The path is the directory that the iterator lists entries |
|
813 in. The name filters and entry filters are provided for file engines that |
|
814 can optimize directory listing at the iterator level (e.g., network file |
|
815 systems that need to minimize network traffic), but they can also be |
|
816 ignored by the iterator subclass; QAbstractFileEngineIterator already |
|
817 provides the required filtering logics in the matchesFilters() function. |
|
818 You can call dirName() to get the directory name, nameFilters() to get a |
|
819 stringlist of name filters, and filters() to get the entry filters. |
|
820 |
|
821 The pure virual function hasNext() returns true if the current directory |
|
822 has at least one more entry (i.e., the directory name is valid and |
|
823 accessible, and we have not reached the end of the entry list), and false |
|
824 otherwise. Reimplement next() to seek to the next entry. |
|
825 |
|
826 The pure virtual function currentFileName() returns the name of the |
|
827 current entry without advancing the iterator. The currentFilePath() |
|
828 function is provided for convenience; it returns the full path of the |
|
829 current entry. |
|
830 |
|
831 Here is an example of how to implement an interator that returns each of |
|
832 three fixed entries in sequence. |
|
833 |
|
834 \snippet doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp 3 |
|
835 |
|
836 Note: QAbstractFileEngineIterator does not deal with QDir::IteratorFlags; |
|
837 it simply returns entries for a single directory. |
|
838 |
|
839 \sa QDirIterator |
|
840 */ |
|
841 |
|
842 /*! |
|
843 \enum QAbstractFileEngineIterator::EntryInfoType |
|
844 \internal |
|
845 |
|
846 This enum describes the different types of information that can be |
|
847 requested through the QAbstractFileEngineIterator::entryInfo() function. |
|
848 */ |
|
849 |
|
850 /*! |
|
851 \typedef QAbstractFileEngine::Iterator |
|
852 \since 4.3 |
|
853 \relates QAbstractFileEngine |
|
854 |
|
855 Synonym for QAbstractFileEngineIterator. |
|
856 */ |
|
857 |
|
858 class QAbstractFileEngineIteratorPrivate |
|
859 { |
|
860 public: |
|
861 QString path; |
|
862 QDir::Filters filters; |
|
863 QStringList nameFilters; |
|
864 QFileInfo fileInfo; |
|
865 }; |
|
866 |
|
867 /*! |
|
868 Constructs a QAbstractFileEngineIterator, using the entry filters \a |
|
869 filters, and wildcard name filters \a nameFilters. |
|
870 */ |
|
871 QAbstractFileEngineIterator::QAbstractFileEngineIterator(QDir::Filters filters, |
|
872 const QStringList &nameFilters) |
|
873 : d(new QAbstractFileEngineIteratorPrivate) |
|
874 { |
|
875 d->nameFilters = nameFilters; |
|
876 d->filters = filters; |
|
877 } |
|
878 |
|
879 /*! |
|
880 Destroys the QAbstractFileEngineIterator. |
|
881 |
|
882 \sa QDirIterator |
|
883 */ |
|
884 QAbstractFileEngineIterator::~QAbstractFileEngineIterator() |
|
885 { |
|
886 } |
|
887 |
|
888 /*! |
|
889 Returns the path for this iterator. QDirIterator is responsible for |
|
890 assigning this path; it cannot change during the iterator's lifetime. |
|
891 |
|
892 \sa nameFilters(), filters() |
|
893 */ |
|
894 QString QAbstractFileEngineIterator::path() const |
|
895 { |
|
896 return d->path; |
|
897 } |
|
898 |
|
899 /*! |
|
900 \internal |
|
901 |
|
902 Sets the iterator path to \a path. This function is called from within |
|
903 QDirIterator. |
|
904 */ |
|
905 void QAbstractFileEngineIterator::setPath(const QString &path) |
|
906 { |
|
907 d->path = path; |
|
908 } |
|
909 |
|
910 /*! |
|
911 Returns the name filters for this iterator. |
|
912 |
|
913 \sa QDir::nameFilters(), filters(), path() |
|
914 */ |
|
915 QStringList QAbstractFileEngineIterator::nameFilters() const |
|
916 { |
|
917 return d->nameFilters; |
|
918 } |
|
919 |
|
920 /*! |
|
921 Returns the entry filters for this iterator. |
|
922 |
|
923 \sa QDir::filter(), nameFilters(), path() |
|
924 */ |
|
925 QDir::Filters QAbstractFileEngineIterator::filters() const |
|
926 { |
|
927 return d->filters; |
|
928 } |
|
929 |
|
930 /*! |
|
931 \fn QString QAbstractFileEngineIterator::currentFileName() const = 0 |
|
932 |
|
933 This pure virtual function returns the name of the current directory |
|
934 entry, excluding the path. |
|
935 |
|
936 \sa currentFilePath() |
|
937 */ |
|
938 |
|
939 /*! |
|
940 Returns the path to the current directory entry. It's the same as |
|
941 prepending path() to the return value of currentFileName(). |
|
942 |
|
943 \sa currentFileName() |
|
944 */ |
|
945 QString QAbstractFileEngineIterator::currentFilePath() const |
|
946 { |
|
947 QString name = currentFileName(); |
|
948 if (!name.isNull()) { |
|
949 QString tmp = path(); |
|
950 if (!tmp.isEmpty()) { |
|
951 if (!tmp.endsWith(QLatin1Char('/'))) |
|
952 tmp.append(QLatin1Char('/')); |
|
953 name.prepend(tmp); |
|
954 } |
|
955 } |
|
956 return name; |
|
957 } |
|
958 |
|
959 /*! |
|
960 The virtual function returns a QFileInfo for the current directory |
|
961 entry. This function is provided for convenience. It can also be slightly |
|
962 faster that creating a QFileInfo object yourself, as the object returned |
|
963 by this function might contain cached information that QFileInfo otherwise |
|
964 would have to access through the file engine. |
|
965 |
|
966 \sa currentFileName() |
|
967 */ |
|
968 QFileInfo QAbstractFileEngineIterator::currentFileInfo() const |
|
969 { |
|
970 QString path = currentFilePath(); |
|
971 if (d->fileInfo.filePath() != path) |
|
972 d->fileInfo.setFile(path); |
|
973 |
|
974 // return a shallow copy |
|
975 return d->fileInfo; |
|
976 } |
|
977 |
|
978 /*! |
|
979 \internal |
|
980 |
|
981 Returns the entry info \a type for this iterator's current directory entry |
|
982 as a QVariant. If \a type is undefined for this entry, a null QVariant is |
|
983 returned. |
|
984 |
|
985 \sa QAbstractFileEngine::beginEntryList(), QDir::beginEntryList() |
|
986 */ |
|
987 QVariant QAbstractFileEngineIterator::entryInfo(EntryInfoType type) const |
|
988 { |
|
989 Q_UNUSED(type) |
|
990 return QVariant(); |
|
991 } |
|
992 |
|
993 /*! |
|
994 \fn virtual QString QAbstractFileEngineIterator::next() = 0 |
|
995 |
|
996 This pure virtual function advances the iterator to the next directory |
|
997 entry, and returns the file path to the current entry. |
|
998 |
|
999 This function can optionally make use of nameFilters() and filters() to |
|
1000 optimize its performance. |
|
1001 |
|
1002 Reimplement this function in a subclass to advance the iterator. |
|
1003 |
|
1004 \sa QDirIterator::next() |
|
1005 */ |
|
1006 |
|
1007 /*! |
|
1008 \fn virtual bool QAbstractFileEngineIterator::hasNext() const = 0 |
|
1009 |
|
1010 This pure virtual function returns true if there is at least one more |
|
1011 entry in the current directory (i.e., the iterator path is valid and |
|
1012 accessible, and the iterator has not reached the end of the entry list). |
|
1013 |
|
1014 \sa QDirIterator::hasNext() |
|
1015 */ |
|
1016 |
|
1017 /*! |
|
1018 Returns an instance of a QAbstractFileEngineIterator using \a filters for |
|
1019 entry filtering and \a filterNames for name filtering. This function is |
|
1020 called by QDirIterator to initiate directory iteration. |
|
1021 |
|
1022 QDirIterator takes ownership of the returned instance, and deletes it when |
|
1023 it's done. |
|
1024 |
|
1025 \sa QDirIterator |
|
1026 */ |
|
1027 QAbstractFileEngine::Iterator *QAbstractFileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames) |
|
1028 { |
|
1029 Q_UNUSED(filters); |
|
1030 Q_UNUSED(filterNames); |
|
1031 return 0; |
|
1032 } |
|
1033 |
|
1034 /*! |
|
1035 \internal |
|
1036 */ |
|
1037 QAbstractFileEngine::Iterator *QAbstractFileEngine::endEntryList() |
|
1038 { |
|
1039 return 0; |
|
1040 } |
|
1041 |
|
1042 /*! |
|
1043 Reads a number of characters from the file into \a data. At most |
|
1044 \a maxlen characters will be read. |
|
1045 |
|
1046 Returns -1 if a fatal error occurs, or 0 if there are no bytes to |
|
1047 read. |
|
1048 */ |
|
1049 qint64 QAbstractFileEngine::read(char *data, qint64 maxlen) |
|
1050 { |
|
1051 Q_UNUSED(data); |
|
1052 Q_UNUSED(maxlen); |
|
1053 return -1; |
|
1054 } |
|
1055 |
|
1056 /*! |
|
1057 Writes \a len bytes from \a data to the file. Returns the number |
|
1058 of characters written on success; otherwise returns -1. |
|
1059 */ |
|
1060 qint64 QAbstractFileEngine::write(const char *data, qint64 len) |
|
1061 { |
|
1062 Q_UNUSED(data); |
|
1063 Q_UNUSED(len); |
|
1064 return -1; |
|
1065 } |
|
1066 |
|
1067 /*! |
|
1068 This function reads one line, terminated by a '\n' character, from the |
|
1069 file info \a data. At most \a maxlen characters will be read. The |
|
1070 end-of-line character is included. |
|
1071 */ |
|
1072 qint64 QAbstractFileEngine::readLine(char *data, qint64 maxlen) |
|
1073 { |
|
1074 qint64 readSoFar = 0; |
|
1075 while (readSoFar < maxlen) { |
|
1076 char c; |
|
1077 qint64 readResult = read(&c, 1); |
|
1078 if (readResult <= 0) |
|
1079 return (readSoFar > 0) ? readSoFar : -1; |
|
1080 ++readSoFar; |
|
1081 *data++ = c; |
|
1082 if (c == '\n') |
|
1083 return readSoFar; |
|
1084 } |
|
1085 return readSoFar; |
|
1086 } |
|
1087 |
|
1088 /*! |
|
1089 \enum QAbstractFileEngine::Extension |
|
1090 \since 4.3 |
|
1091 |
|
1092 This enum describes the types of extensions that the file engine can |
|
1093 support. Before using these extensions, you must verify that the extension |
|
1094 is supported (i.e., call supportsExtension()). |
|
1095 |
|
1096 \value AtEndExtension Whether the current file position is at the end of |
|
1097 the file or not. This extension allows file engines that implement local |
|
1098 buffering to report end-of-file status without having to check the size of |
|
1099 the file. It is also useful for sequential files, where the size of the |
|
1100 file cannot be used to determine whether or not you have reached the end. |
|
1101 This extension returns true if the file is at the end; otherwise it returns |
|
1102 false. The input and output arguments to extension() are ignored. |
|
1103 |
|
1104 \value FastReadLineExtension Whether the file engine provides a |
|
1105 fast implementation for readLine() or not. If readLine() remains |
|
1106 unimplemented in the file engine, QAbstractFileEngine will provide |
|
1107 an implementation based on calling read() repeatedly. If |
|
1108 supportsExtension() returns false for this extension, however, |
|
1109 QIODevice can provide a faster implementation by making use of its |
|
1110 internal buffer. For engines that already provide a fast readLine() |
|
1111 implementation, returning false for this extension can avoid |
|
1112 unnnecessary double-buffering in QIODevice. |
|
1113 |
|
1114 \value MapExtension Whether the file engine provides the ability to map |
|
1115 a file to memory. |
|
1116 |
|
1117 \value UnMapExtension Whether the file engine provides the ability to |
|
1118 unmap memory that was previously mapped. |
|
1119 */ |
|
1120 |
|
1121 /*! |
|
1122 \class QAbstractFileEngine::ExtensionOption |
|
1123 \since 4.3 |
|
1124 \brief provides an extended input argument to QAbstractFileEngine's |
|
1125 extension support. |
|
1126 |
|
1127 \sa QAbstractFileEngine::extension() |
|
1128 */ |
|
1129 |
|
1130 /*! |
|
1131 \class QAbstractFileEngine::ExtensionReturn |
|
1132 \since 4.3 |
|
1133 \brief provides an extended output argument to QAbstractFileEngine's |
|
1134 extension support. |
|
1135 |
|
1136 \sa QAbstractFileEngine::extension() |
|
1137 */ |
|
1138 |
|
1139 /*! |
|
1140 \since 4.3 |
|
1141 |
|
1142 This virtual function can be reimplemented in a QAbstractFileEngine |
|
1143 subclass to provide support for extensions. The \a option argument is |
|
1144 provided as input to the extension, and this function can store output |
|
1145 results in \a output. |
|
1146 |
|
1147 The behavior of this function is determined by \a extension; see the |
|
1148 Extension documentation for details. |
|
1149 |
|
1150 You can call supportsExtension() to check if an extension is supported by |
|
1151 the file engine. |
|
1152 |
|
1153 By default, no extensions are supported, and this function returns false. |
|
1154 |
|
1155 \sa supportsExtension(), Extension |
|
1156 */ |
|
1157 bool QAbstractFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) |
|
1158 { |
|
1159 Q_UNUSED(extension); |
|
1160 Q_UNUSED(option); |
|
1161 Q_UNUSED(output); |
|
1162 return false; |
|
1163 } |
|
1164 |
|
1165 /*! |
|
1166 \since 4.3 |
|
1167 |
|
1168 This virtual function returns true if the file engine supports \a |
|
1169 extension; otherwise, false is returned. By default, no extensions are |
|
1170 supported. |
|
1171 |
|
1172 \sa extension() |
|
1173 */ |
|
1174 bool QAbstractFileEngine::supportsExtension(Extension extension) const |
|
1175 { |
|
1176 Q_UNUSED(extension); |
|
1177 return false; |
|
1178 } |
|
1179 |
|
1180 /*! |
|
1181 Returns the QFile::FileError that resulted from the last failed |
|
1182 operation. If QFile::UnspecifiedError is returned, QFile will |
|
1183 use its own idea of the error status. |
|
1184 |
|
1185 \sa QFile::FileError, errorString() |
|
1186 */ |
|
1187 QFile::FileError QAbstractFileEngine::error() const |
|
1188 { |
|
1189 Q_D(const QAbstractFileEngine); |
|
1190 return d->fileError; |
|
1191 } |
|
1192 |
|
1193 /*! |
|
1194 Returns the human-readable message appropriate to the current error |
|
1195 reported by error(). If no suitable string is available, an |
|
1196 empty string is returned. |
|
1197 |
|
1198 \sa error() |
|
1199 */ |
|
1200 QString QAbstractFileEngine::errorString() const |
|
1201 { |
|
1202 Q_D(const QAbstractFileEngine); |
|
1203 return d->errorString; |
|
1204 } |
|
1205 |
|
1206 /*! |
|
1207 Sets the error type to \a error, and the error string to \a errorString. |
|
1208 Call this function to set the error values returned by the higher-level |
|
1209 classes. |
|
1210 |
|
1211 \sa QFile::error(), QIODevice::errorString(), QIODevice::setErrorString() |
|
1212 */ |
|
1213 void QAbstractFileEngine::setError(QFile::FileError error, const QString &errorString) |
|
1214 { |
|
1215 Q_D(QAbstractFileEngine); |
|
1216 d->fileError = error; |
|
1217 d->errorString = errorString; |
|
1218 } |
|
1219 |
|
1220 QT_END_NAMESPACE |