source: trunk/src/corelib/io/qabstractfileengine.cpp@ 651

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

trunk: Merged in qt 4.6.2 sources.

File size: 36.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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 "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
51QT_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 */
101Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, fileEngineHandlerMutex, (QReadWriteLock::Recursive))
102static bool qt_abstractfileenginehandlerlist_shutDown = false;
103class QAbstractFileEngineHandlerList : public QList<QAbstractFileEngineHandler *>
104{
105public:
106 ~QAbstractFileEngineHandlerList()
107 {
108 QWriteLocker locker(fileEngineHandlerMutex());
109 qt_abstractfileenginehandlerlist_shutDown = true;
110 }
111};
112Q_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 */
123QAbstractFileEngineHandler::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 */
133QAbstractFileEngineHandler::~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*/
167QAbstractFileEngine *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 */
339QAbstractFileEngine::QAbstractFileEngine() : d_ptr(new QAbstractFileEnginePrivate)
340{
341 d_ptr->q_ptr = this;
342}
343
344/*!
345 \internal
346
347 Constructs a QAbstractFileEngine.
348 */
349QAbstractFileEngine::QAbstractFileEngine(QAbstractFileEnginePrivate &dd) : d_ptr(&dd)
350{
351 d_ptr->q_ptr = this;
352}
353
354/*!
355 Destroys the QAbstractFileEngine.
356 */
357QAbstractFileEngine::~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*/
370bool 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*/
381bool 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*/
392bool QAbstractFileEngine::flush()
393{
394 return false;
395}
396
397/*!
398 Returns the size of the file.
399*/
400qint64 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*/
410qint64 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*/
426bool 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*/
439bool 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 */
452bool 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*/
461bool 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 */
476bool 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*/
488bool 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 */
506bool 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 */
526bool 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*/
543bool 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 */
555bool 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 */
568bool 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 */
586QStringList 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*/
612QAbstractFileEngine::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*/
629bool 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 */
647QString 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 */
662uint 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 */
678QString 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 */
696QDateTime 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 */
710void 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*/
720int 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*/
737bool 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
758uchar *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 */
782bool 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
858class QAbstractFileEngineIteratorPrivate
859{
860public:
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*/
871QAbstractFileEngineIterator::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*/
884QAbstractFileEngineIterator::~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*/
894QString 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*/
905void 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*/
915QStringList 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*/
925QDir::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*/
945QString 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*/
968QFileInfo 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*/
987QVariant 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*/
1027QAbstractFileEngine::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*/
1037QAbstractFileEngine::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*/
1049qint64 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*/
1060qint64 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*/
1072qint64 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*/
1157bool 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*/
1174bool 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 */
1187QFile::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 */
1200QString 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*/
1213void QAbstractFileEngine::setError(QFile::FileError error, const QString &errorString)
1214{
1215 Q_D(QAbstractFileEngine);
1216 d->fileError = error;
1217 d->errorString = errorString;
1218}
1219
1220QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.