diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-11-06 11:27:37 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-11-06 11:27:37 (GMT) |
commit | 7515e36b6351e588b5324fe7be9bf4505b156793 (patch) | |
tree | a101d874ae1d3e0f219bac393fcbca3f956c8857 | |
parent | e219feca14eb96a39d38694edfcc810ed94539ff (diff) | |
parent | 5ab96eb2df98bf7f0c8e7d7e676e548f15c2f4a3 (diff) | |
download | Qt-7515e36b6351e588b5324fe7be9bf4505b156793.zip Qt-7515e36b6351e588b5324fe7be9bf4505b156793.tar.gz Qt-7515e36b6351e588b5324fe7be9bf4505b156793.tar.bz2 |
Merge commit 'upstream/4.6' into 4.6
63 files changed, 944 insertions, 166 deletions
diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index fe3d8b9..be2c89c 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -48,6 +48,9 @@ Third party components QtCore + - QObject + * [259514] fixed a possible dead-lock in the destructor + - QVariant * Many optimisations * Added QVariant::toFloat() and QVariant::toReal() @@ -76,7 +79,13 @@ QtCore QtGui -- QGraphicsItem + - QCompleter + * [246056] Fixed a possible assertion when setting the completer prefix + + - QFontDialog + * [256466] fixed the dialog not always returning the selected style. + + - QGraphicsItem * Fixed bug and improved accuracy of QGraphicsItem::childrenBoundingRect(). * Many optimizations. * Introduced QGraphicsItem::ItemHasNoContents @@ -88,10 +97,10 @@ QtGui * Introduced QGraphicsItem::stackBefore() * Cached items are now always invalidated when update() is called. -- QGraphicsObject + - QGraphicsObject * New class; inherits QGraphicsItem and adds notification signals and property declarations. -- QGraphicsProxyWidget + - QGraphicsProxyWidget * [251407] Fixed window flag handling. Now QGraphicsProxyWidget's flags win. * Fix Qt::ClickFocus policy @@ -104,24 +113,47 @@ QtGui * Introduced activation support. * Fixed bugs in initial focus support. -- QGraphicsTextItem + - QGraphicsTextItem * Now inherits from QGraphicsObject instead - QGraphicsTransform * New class; eases animation of transformations for QGraphicsItem. -- QGraphicsView + - QGraphicsView * Fix mapToScene(QRect) to avoid extra unnecessary adjustments. * Many optimizations. * Introduced QGraphicsView::isTransformed() * [QTBUG-4151] Items with parent that sets ItemClipsChildrenToShape were sometimes invisible. -- QGraphicsWidget + - QGraphicsWidget * Now inherits from QGraphicsObject instead + - QHeaderView + * [208320] Make sure the sort indicator s taken into account for the size hint + * [255574] Make sure the sizehint for the section depend on visible sections + + - QMainWindow + * [226060] Adding actions to a toolbar would always make the next toolbar move + + - QMenuBar + * [260873] Fix mouse interaction while undocking a widget from the main window + * dock areas don't get a splitter if their dock widgets are not resizable + + - QColumnView + * [246999] Fixed view not updating when the model is changed dynamically + + - QListView + * [243335] Fixed the visualRect to return correct values when the widget is not yet show + - QTreeView * [234930] Be able to use :has-children and :has-sibillings in a stylesheet * [252616] Set QStyleOptionViewItemV4::OnlyOne flag when painting spanning columns + * [245654] Fixed expandAll when deleting and recreating a mode for the tree + * [239271] Fixed missing update when adding a row when the first column is hidden + * [258225] Fixed scrollTo with center and bottom + + - QTreeWidget + * [253109] Shows the widget when calling setItemWidget - QTableView * [191545] Selections work more similarly to well-known spreadsheets @@ -130,6 +162,9 @@ QtGui speed-up, support for rows/columns insertion/removal, and better keyboard navigation + - QTableWidget + * [234641] Fixed takeItem to cause the view to be updated. + - QTabBar * [196326] Fixed having a stylesheet on a QTabBar resulted in some tab names to be slightly clipped. @@ -138,10 +173,10 @@ QtGui - QComboBox * [220195] Fixed keyboard search when current index is -1 -- QPixmap + - QPixmap * Optimized width(), height(), isNull() and depth(). -- QRegion + - QRegion * Minor optimizations. - QSpinBox @@ -192,7 +227,7 @@ QtGui - On Windows CE the link time code geration has been disabled by default to be consistent with win32-msvc200x. - + - Added QMAKE_LIBS_OPENGL_ES1, QMAKE_LIBS_OPENGL_ES1CL and QMAKE_LIBS_OPENGL_ES2 qmake variables for specifying OpenGL ES specific libraries. @@ -237,6 +272,12 @@ General changes on Mac OS X: Use the -arch flags to override. - Building for ppc64 is no longer supported by the gcc tool chain. - Building for ppc is still supported. + + - Phonon on Windows + * Now much more reliable when reading a file through a QIODevice. + * If Video Mixing Renderer 9 is not available, falls back to software + rendering. + * Fixed a flicker issue when switching source with a transition time of 0 **************************************************************************** * Tools * @@ -409,4 +450,14 @@ General changes on Mac OS X: - On Mac OS X, QDesktopServices::storageLocation(DataLocation) now includes QCoreApplication::organizationName() and QCoreApplication::applicationName() if those are set. This matches the behavior on the other platforms. + + - The Animation Framework + * currentTime() now returns the complete current time including previous loops + * currentLoopTime() returns the time inside the current loop + * stateChanged signal sends the new state as first parameter and old state as + the second + * QAnimationGroup::clearAnimations() has been renames to clear() + * QAnimationGroup::insertAnimationAt() has been renames to insertAnimation() + * QAnimationGroup::takeAnimationAt() has been renames to takeAnimation() + * QSequentialAnimationGroup::insertPauseAt() has been renames to insertPause() diff --git a/mkspecs/aix-g++-64/qplatformdefs.h b/mkspecs/aix-g++-64/qplatformdefs.h index 5a1cda8..25c86a2 100644 --- a/mkspecs/aix-g++-64/qplatformdefs.h +++ b/mkspecs/aix-g++-64/qplatformdefs.h @@ -109,6 +109,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -117,6 +118,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/aix-g++/qplatformdefs.h b/mkspecs/aix-g++/qplatformdefs.h index 5a1cda8..25c86a2 100644 --- a/mkspecs/aix-g++/qplatformdefs.h +++ b/mkspecs/aix-g++/qplatformdefs.h @@ -109,6 +109,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -117,6 +118,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/aix-xlc-64/qplatformdefs.h b/mkspecs/aix-xlc-64/qplatformdefs.h index 0a0d11f..a25ea42 100644 --- a/mkspecs/aix-xlc-64/qplatformdefs.h +++ b/mkspecs/aix-xlc-64/qplatformdefs.h @@ -105,6 +105,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -113,6 +114,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/aix-xlc/qplatformdefs.h b/mkspecs/aix-xlc/qplatformdefs.h index b162513..3856600 100644 --- a/mkspecs/aix-xlc/qplatformdefs.h +++ b/mkspecs/aix-xlc/qplatformdefs.h @@ -105,6 +105,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -113,6 +114,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/common/symbian/qplatformdefs.h b/mkspecs/common/symbian/qplatformdefs.h index 2d0e6e8..c0756b2 100644 --- a/mkspecs/common/symbian/qplatformdefs.h +++ b/mkspecs/common/symbian/qplatformdefs.h @@ -112,6 +112,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -120,6 +121,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif @@ -139,6 +141,7 @@ #define QT_CHDIR ::chdir #define QT_MKDIR ::mkdir #define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE 0 #define QT_OPEN_RDONLY O_RDONLY #define QT_OPEN_WRONLY O_WRONLY #define QT_OPEN_RDWR O_RDWR diff --git a/mkspecs/common/wince/qplatformdefs.h b/mkspecs/common/wince/qplatformdefs.h index f00ed71..52a34e9 100644 --- a/mkspecs/common/wince/qplatformdefs.h +++ b/mkspecs/common/wince/qplatformdefs.h @@ -97,6 +97,7 @@ #define QT_CHDIR ::_chdir #define QT_MKDIR ::qt_wince__mkdir #define QT_RMDIR ::qt_wince__rmdir +#define QT_OPEN_LARGEFILE 0 #define QT_OPEN_RDONLY _O_RDONLY #define QT_OPEN_WRONLY _O_WRONLY #define QT_OPEN_RDWR _O_RDWR @@ -111,6 +112,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long diff --git a/mkspecs/cygwin-g++/qplatformdefs.h b/mkspecs/cygwin-g++/qplatformdefs.h index 78f7398..6cf02f2 100644 --- a/mkspecs/cygwin-g++/qplatformdefs.h +++ b/mkspecs/cygwin-g++/qplatformdefs.h @@ -119,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long diff --git a/mkspecs/darwin-g++/qplatformdefs.h b/mkspecs/darwin-g++/qplatformdefs.h index 31e32f1..8ae5606 100644 --- a/mkspecs/darwin-g++/qplatformdefs.h +++ b/mkspecs/darwin-g++/qplatformdefs.h @@ -79,6 +79,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/freebsd-g++/qplatformdefs.h b/mkspecs/freebsd-g++/qplatformdefs.h index 470923a..8b07cdc 100644 --- a/mkspecs/freebsd-g++/qplatformdefs.h +++ b/mkspecs/freebsd-g++/qplatformdefs.h @@ -81,6 +81,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/hpux-acc-64/qplatformdefs.h b/mkspecs/hpux-acc-64/qplatformdefs.h index a8025d0..7ef3d51 100644 --- a/mkspecs/hpux-acc-64/qplatformdefs.h +++ b/mkspecs/hpux-acc-64/qplatformdefs.h @@ -104,6 +104,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -112,6 +113,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpux-acc-o64/qplatformdefs.h b/mkspecs/hpux-acc-o64/qplatformdefs.h index 4927cf9..e082d9d 100644 --- a/mkspecs/hpux-acc-o64/qplatformdefs.h +++ b/mkspecs/hpux-acc-o64/qplatformdefs.h @@ -105,6 +105,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -113,6 +114,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpux-acc/qplatformdefs.h b/mkspecs/hpux-acc/qplatformdefs.h index ec416cd..7b540a1 100644 --- a/mkspecs/hpux-acc/qplatformdefs.h +++ b/mkspecs/hpux-acc/qplatformdefs.h @@ -107,6 +107,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -115,6 +116,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpux-g++-64/qplatformdefs.h b/mkspecs/hpux-g++-64/qplatformdefs.h index 31aa7ff..a8d06d8 100644 --- a/mkspecs/hpux-g++-64/qplatformdefs.h +++ b/mkspecs/hpux-g++-64/qplatformdefs.h @@ -104,6 +104,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -112,6 +113,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpux-g++/qplatformdefs.h b/mkspecs/hpux-g++/qplatformdefs.h index 2c46b7d..d89a026 100644 --- a/mkspecs/hpux-g++/qplatformdefs.h +++ b/mkspecs/hpux-g++/qplatformdefs.h @@ -106,6 +106,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -114,6 +115,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpuxi-acc-32/qplatformdefs.h b/mkspecs/hpuxi-acc-32/qplatformdefs.h index f02de1f..466f27e 100644 --- a/mkspecs/hpuxi-acc-32/qplatformdefs.h +++ b/mkspecs/hpuxi-acc-32/qplatformdefs.h @@ -105,6 +105,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -113,6 +114,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpuxi-acc-64/qplatformdefs.h b/mkspecs/hpuxi-acc-64/qplatformdefs.h index f02de1f..466f27e 100644 --- a/mkspecs/hpuxi-acc-64/qplatformdefs.h +++ b/mkspecs/hpuxi-acc-64/qplatformdefs.h @@ -105,6 +105,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -113,6 +114,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hpuxi-g++-64/qplatformdefs.h b/mkspecs/hpuxi-g++-64/qplatformdefs.h index 546a7b5..d351af3 100644 --- a/mkspecs/hpuxi-g++-64/qplatformdefs.h +++ b/mkspecs/hpuxi-g++-64/qplatformdefs.h @@ -104,6 +104,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -112,6 +113,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/hurd-g++/qplatformdefs.h b/mkspecs/hurd-g++/qplatformdefs.h index d5aaf66..611252c 100644 --- a/mkspecs/hurd-g++/qplatformdefs.h +++ b/mkspecs/hurd-g++/qplatformdefs.h @@ -87,6 +87,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/irix-cc-64/qplatformdefs.h b/mkspecs/irix-cc-64/qplatformdefs.h index 6d436a1..bfb19ca 100644 --- a/mkspecs/irix-cc-64/qplatformdefs.h +++ b/mkspecs/irix-cc-64/qplatformdefs.h @@ -103,6 +103,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -111,6 +112,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/irix-cc/qplatformdefs.h b/mkspecs/irix-cc/qplatformdefs.h index 6d436a1..bfb19ca 100644 --- a/mkspecs/irix-cc/qplatformdefs.h +++ b/mkspecs/irix-cc/qplatformdefs.h @@ -103,6 +103,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -111,6 +112,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/irix-g++/qplatformdefs.h b/mkspecs/irix-g++/qplatformdefs.h index 8191c15..4e2fda2 100644 --- a/mkspecs/irix-g++/qplatformdefs.h +++ b/mkspecs/irix-g++/qplatformdefs.h @@ -103,6 +103,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -111,6 +112,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-cxx/qplatformdefs.h b/mkspecs/linux-cxx/qplatformdefs.h index 5bf9686..0c3a07e 100644 --- a/mkspecs/linux-cxx/qplatformdefs.h +++ b/mkspecs/linux-cxx/qplatformdefs.h @@ -110,6 +110,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -118,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-ecc-64/qplatformdefs.h b/mkspecs/linux-ecc-64/qplatformdefs.h index 5bf9686..0c3a07e 100644 --- a/mkspecs/linux-ecc-64/qplatformdefs.h +++ b/mkspecs/linux-ecc-64/qplatformdefs.h @@ -110,6 +110,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -118,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h b/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h index 1430916..ecfbc73 100644 --- a/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h +++ b/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h @@ -110,6 +110,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -118,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-g++/qplatformdefs.h b/mkspecs/linux-g++/qplatformdefs.h index 1430916..ecfbc73 100644 --- a/mkspecs/linux-g++/qplatformdefs.h +++ b/mkspecs/linux-g++/qplatformdefs.h @@ -110,6 +110,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -118,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-kcc/qplatformdefs.h b/mkspecs/linux-kcc/qplatformdefs.h index 48a289b..65278c8 100644 --- a/mkspecs/linux-kcc/qplatformdefs.h +++ b/mkspecs/linux-kcc/qplatformdefs.h @@ -113,6 +113,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -121,6 +122,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-llvm/qplatformdefs.h b/mkspecs/linux-llvm/qplatformdefs.h index 1430916..ecfbc73 100644 --- a/mkspecs/linux-llvm/qplatformdefs.h +++ b/mkspecs/linux-llvm/qplatformdefs.h @@ -110,6 +110,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -118,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-lsb-g++/qplatformdefs.h b/mkspecs/linux-lsb-g++/qplatformdefs.h index dc48a089..0928b71 100644 --- a/mkspecs/linux-lsb-g++/qplatformdefs.h +++ b/mkspecs/linux-lsb-g++/qplatformdefs.h @@ -114,6 +114,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -122,6 +123,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/linux-pgcc/qplatformdefs.h b/mkspecs/linux-pgcc/qplatformdefs.h index 5bf9686..0c3a07e 100644 --- a/mkspecs/linux-pgcc/qplatformdefs.h +++ b/mkspecs/linux-pgcc/qplatformdefs.h @@ -110,6 +110,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -118,6 +119,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/lynxos-g++/qplatformdefs.h b/mkspecs/lynxos-g++/qplatformdefs.h index e362676..96764a3 100644 --- a/mkspecs/lynxos-g++/qplatformdefs.h +++ b/mkspecs/lynxos-g++/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-g++/qplatformdefs.h b/mkspecs/macx-g++/qplatformdefs.h index 98e5eaf..3a9288b 100644 --- a/mkspecs/macx-g++/qplatformdefs.h +++ b/mkspecs/macx-g++/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-g++40/qplatformdefs.h b/mkspecs/macx-g++40/qplatformdefs.h index 98e5eaf..3a9288b 100644 --- a/mkspecs/macx-g++40/qplatformdefs.h +++ b/mkspecs/macx-g++40/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-g++42/qplatformdefs.h b/mkspecs/macx-g++42/qplatformdefs.h index 98e5eaf..3a9288b 100644 --- a/mkspecs/macx-g++42/qplatformdefs.h +++ b/mkspecs/macx-g++42/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-llvm/qplatformdefs.h b/mkspecs/macx-llvm/qplatformdefs.h index 98e5eaf..3a9288b 100644 --- a/mkspecs/macx-llvm/qplatformdefs.h +++ b/mkspecs/macx-llvm/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-pbuilder/qplatformdefs.h b/mkspecs/macx-pbuilder/qplatformdefs.h index 04aaab7..05ee441 100644 --- a/mkspecs/macx-pbuilder/qplatformdefs.h +++ b/mkspecs/macx-pbuilder/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-xcode/qplatformdefs.h b/mkspecs/macx-xcode/qplatformdefs.h index 98e5eaf..3a9288b 100644 --- a/mkspecs/macx-xcode/qplatformdefs.h +++ b/mkspecs/macx-xcode/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/macx-xlc/qplatformdefs.h b/mkspecs/macx-xlc/qplatformdefs.h index e701217..bc2cfb6 100644 --- a/mkspecs/macx-xlc/qplatformdefs.h +++ b/mkspecs/macx-xlc/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/netbsd-g++/qplatformdefs.h b/mkspecs/netbsd-g++/qplatformdefs.h index 6e0fee7..40f83a2 100644 --- a/mkspecs/netbsd-g++/qplatformdefs.h +++ b/mkspecs/netbsd-g++/qplatformdefs.h @@ -80,6 +80,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/openbsd-g++/qplatformdefs.h b/mkspecs/openbsd-g++/qplatformdefs.h index ef313aa..90e4c21 100644 --- a/mkspecs/openbsd-g++/qplatformdefs.h +++ b/mkspecs/openbsd-g++/qplatformdefs.h @@ -81,6 +81,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/sco-cc/qplatformdefs.h b/mkspecs/sco-cc/qplatformdefs.h index 4c53c18..41f4f0f 100644 --- a/mkspecs/sco-cc/qplatformdefs.h +++ b/mkspecs/sco-cc/qplatformdefs.h @@ -81,6 +81,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/sco-g++/qplatformdefs.h b/mkspecs/sco-g++/qplatformdefs.h index 3ecb86d..613f22e 100644 --- a/mkspecs/sco-g++/qplatformdefs.h +++ b/mkspecs/sco-g++/qplatformdefs.h @@ -85,6 +85,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/solaris-cc-64/qplatformdefs.h b/mkspecs/solaris-cc-64/qplatformdefs.h index 3d1ddeb..f344ffc 100644 --- a/mkspecs/solaris-cc-64/qplatformdefs.h +++ b/mkspecs/solaris-cc-64/qplatformdefs.h @@ -111,6 +111,7 @@ static inline int qt_socket_connect(int s, struct sockaddr *addr, QT_SOCKLEN_T a #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -119,6 +120,7 @@ static inline int qt_socket_connect(int s, struct sockaddr *addr, QT_SOCKLEN_T a #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/solaris-cc/qplatformdefs.h b/mkspecs/solaris-cc/qplatformdefs.h index 6c5fd5f..8b2104a 100644 --- a/mkspecs/solaris-cc/qplatformdefs.h +++ b/mkspecs/solaris-cc/qplatformdefs.h @@ -119,6 +119,7 @@ static inline int qt_socket_connect(int s, struct sockaddr *addr, QT_SOCKLEN_T a #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -127,6 +128,7 @@ static inline int qt_socket_connect(int s, struct sockaddr *addr, QT_SOCKLEN_T a #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/solaris-g++-64/qplatformdefs.h b/mkspecs/solaris-g++-64/qplatformdefs.h index 09aabfd..a6f9c8a 100644 --- a/mkspecs/solaris-g++-64/qplatformdefs.h +++ b/mkspecs/solaris-g++-64/qplatformdefs.h @@ -128,6 +128,7 @@ static inline int qt_socket_bind(int s, struct sockaddr *addr, QT_SOCKLEN_T addr #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -136,6 +137,7 @@ static inline int qt_socket_bind(int s, struct sockaddr *addr, QT_SOCKLEN_T addr #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/solaris-g++/qplatformdefs.h b/mkspecs/solaris-g++/qplatformdefs.h index 01b551d..c37b366 100644 --- a/mkspecs/solaris-g++/qplatformdefs.h +++ b/mkspecs/solaris-g++/qplatformdefs.h @@ -132,6 +132,7 @@ static inline int qt_socket_bind(int s, struct sockaddr *addr, QT_SOCKLEN_T addr #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -140,6 +141,7 @@ static inline int qt_socket_bind(int s, struct sockaddr *addr, QT_SOCKLEN_T addr #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/tru64-cxx/qplatformdefs.h b/mkspecs/tru64-cxx/qplatformdefs.h index 7c25fa0..aa3a909 100644 --- a/mkspecs/tru64-cxx/qplatformdefs.h +++ b/mkspecs/tru64-cxx/qplatformdefs.h @@ -83,6 +83,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/tru64-g++/qplatformdefs.h b/mkspecs/tru64-g++/qplatformdefs.h index 63eea44..0e8b345 100644 --- a/mkspecs/tru64-g++/qplatformdefs.h +++ b/mkspecs/tru64-g++/qplatformdefs.h @@ -83,6 +83,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/unixware-cc/qplatformdefs.h b/mkspecs/unixware-cc/qplatformdefs.h index ea523fb..3a6b314 100644 --- a/mkspecs/unixware-cc/qplatformdefs.h +++ b/mkspecs/unixware-cc/qplatformdefs.h @@ -81,6 +81,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/unixware-g++/qplatformdefs.h b/mkspecs/unixware-g++/qplatformdefs.h index ea523fb..3a6b314 100644 --- a/mkspecs/unixware-g++/qplatformdefs.h +++ b/mkspecs/unixware-g++/qplatformdefs.h @@ -81,6 +81,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t diff --git a/mkspecs/unsupported/qnx-g++/qplatformdefs.h b/mkspecs/unsupported/qnx-g++/qplatformdefs.h index 1bf9ffcb..f001eea 100644 --- a/mkspecs/unsupported/qnx-g++/qplatformdefs.h +++ b/mkspecs/unsupported/qnx-g++/qplatformdefs.h @@ -87,6 +87,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -95,6 +96,7 @@ #define QT_FTELL ::ftello #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T off_t #endif diff --git a/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h b/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h index 5cec788..d16fa8a 100644 --- a/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h +++ b/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h @@ -76,6 +76,7 @@ #define QT_FTELL ::ftello64 #define QT_FGETPOS ::fgetpos64 #define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 #define QT_FPOS_T fpos64_t #define QT_OFF_T off64_t #else @@ -84,6 +85,7 @@ #define QT_FTELL ::ftell #define QT_FGETPOS ::fgetpos #define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap #define QT_FPOS_T fpos_t #define QT_OFF_T long #endif diff --git a/mkspecs/win32-msvc.net/qplatformdefs.h b/mkspecs/win32-msvc.net/qplatformdefs.h index 19f9ba4..da092fa 100644 --- a/mkspecs/win32-msvc.net/qplatformdefs.h +++ b/mkspecs/win32-msvc.net/qplatformdefs.h @@ -115,8 +115,10 @@ #define QT_FOPEN ::fopen #ifdef QT_LARGEFILE_SUPPORT +// 64-bit versions of fseek/ftell not always available. E.g., when linking +// dynamically to CRT (/MT) #define QT_FSEEK ::fseek -#define QT_FTELL ::ftell +#define QT_FTELL (QT_OFF_T)::ftell #else #define QT_FSEEK ::fseek #define QT_FTELL ::ftell diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 134c4b8..c9b2603 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1020,14 +1020,15 @@ bool QFile::open(OpenMode mode) \bold{Warning:} \list 1 - \o If \a fh is \c stdin, \c stdout, or \c stderr, you may not be able - to seek(). See QIODevice::isSequential() for more information. + \o If \a fh does not refer to a regular file, e.g., it is \c stdin, + \c stdout, or \c stderr, you may not be able to seek(). size() + returns \c 0 in those cases. See QIODevice::isSequential() for + more information. \o Since this function opens the file without specifying the file name, you cannot use this QFile with a QFileInfo. \endlist - \note For Windows CE you may not be able to call seek() and resize(). - Also, size() is set to \c 0. + \note For Windows CE you may not be able to call resize(). \sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference} @@ -1064,7 +1065,7 @@ bool QFile::open(FILE *fh, OpenMode mode) if (mode & Append) { seek(size()); } else { - long pos = ftell(fh); + qint64 pos = (qint64)QT_FTELL(fh); if (pos != -1) seek(pos); } @@ -1081,7 +1082,7 @@ bool QFile::open(FILE *fh, OpenMode mode) /*! \overload - Opens the existing file descripter \a fd in the given \a mode. + Opens the existing file descriptor \a fd in the given \a mode. Returns true if successful; otherwise returns false. When a QFile is opened using this function, close() does not @@ -1092,12 +1093,13 @@ bool QFile::open(FILE *fh, OpenMode mode) are slow. If you run into performance issues, you should try to use one of the other open functions. - \warning If \a fd is 0 (\c stdin), 1 (\c stdout), or 2 (\c - stderr), you may not be able to seek(). size() is set to \c - LLONG_MAX (in \c <climits>). + \warning If \a fd is not a regular file, e.g, it is 0 (\c stdin), + 1 (\c stdout), or 2 (\c stderr), you may not be able to seek(). In + those cases, size() returns \c 0. See QIODevice::isSequential() + for more information. \warning For Windows CE you may not be able to call seek(), setSize(), - fileTime(). size() is set to \c 0. + fileTime(). size() returns \c 0. \warning Since this function opens the file without specifying the file name, you cannot use this QFile with a QFileInfo. @@ -1120,8 +1122,13 @@ bool QFile::open(int fd, OpenMode mode) } if(d->openExternalFile(mode, fd)) { QIODevice::open(mode); - if (mode & Append) + if (mode & Append) { seek(size()); + } else { + qint64 pos = (qint64)QT_LSEEK(fd, QT_OFF_T(0), SEEK_CUR); + if (pos != -1) + seek(pos); + } return true; } return false; diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index b69a5e5..d376dc7 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -132,11 +132,9 @@ void QFSFileEnginePrivate::init() #ifdef Q_OS_WIN fileAttrib = INVALID_FILE_ATTRIBUTES; fileHandle = INVALID_HANDLE_VALUE; + mapHandle = INVALID_HANDLE_VALUE; cachedFd = -1; #endif -#ifdef Q_USE_DEPRECATED_MAP_API - fileMapHandle = INVALID_HANDLE_VALUE; -#endif } /*! @@ -329,9 +327,9 @@ bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh) int ret; do { ret = QT_FSEEK(fh, 0, SEEK_END); - } while (ret == -1 && errno == EINTR); + } while (ret != 0 && errno == EINTR); - if (ret == -1) { + if (ret != 0) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); @@ -576,20 +574,23 @@ bool QFSFileEnginePrivate::seekFdFh(qint64 pos) if (lastIOCommand != QFSFileEnginePrivate::IOFlushCommand && !q->flush()) return false; + if (pos < 0 || pos != qint64(QT_OFF_T(pos))) + return false; + if (fh) { // Buffered stdlib mode. int ret; do { ret = QT_FSEEK(fh, QT_OFF_T(pos), SEEK_SET); - } while (ret == -1 && errno == EINTR); + } while (ret != 0 && errno == EINTR); - if (ret == -1) { + if (ret != 0) { q->setError(QFile::ReadError, qt_error_string(int(errno))); return false; } } else { // Unbuffered stdio mode. - if (QT_LSEEK(fd, pos, SEEK_SET) == -1) { + if (QT_LSEEK(fd, QT_OFF_T(pos), SEEK_SET) == -1) { qWarning() << "QFile::at: Cannot set file position" << pos; q->setError(QFile::PositionError, qt_error_string(errno)); return false; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 66e0219..87f0737 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -110,20 +110,16 @@ public: FILE *fh; #ifdef Q_WS_WIN HANDLE fileHandle; - QHash<uchar *, QPair<int /*offset*/, HANDLE /*handle*/> > maps; + HANDLE mapHandle; + QHash<uchar *, DWORD /* offset % AllocationGranularity */> maps; mutable int cachedFd; mutable DWORD fileAttrib; #else - QHash<uchar *, QPair<int /*offset*/, int /*handle|len*/> > maps; + QHash<uchar *, QPair<int /*offset % PageSize*/, size_t /*length + offset % PageSize*/> > maps; mutable QT_STATBUF st; #endif int fd; -#ifdef Q_USE_DEPRECATED_MAP_API - void mapHandleClose(); - HANDLE fileMapHandle; -#endif - enum LastIOCommand { IOFlushCommand, diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index b0cddaa..7824520 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1243,34 +1243,51 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla q->setError(QFile::PermissionsError, qt_error_string(int(EACCES))); return 0; } - if (offset < 0) { + + if (offset < 0 || offset != qint64(QT_OFF_T(offset)) + || size < 0 || size > (size_t)-1) { q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); return 0; } + + // If we know the mapping will extend beyond EOF, fail early to avoid + // undefined behavior. Otherwise, let mmap have its say. + if (doStat() + && (QT_OFF_T(size) > st.st_size - QT_OFF_T(offset))) + return 0; + int access = 0; if (openMode & QIODevice::ReadOnly) access |= PROT_READ; if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE; - int pagesSize = getpagesize(); - int realOffset = offset / pagesSize; - int extra = offset % pagesSize; + int pageSize = getpagesize(); + int extra = offset % pageSize; + + if (size + extra > (size_t)-1) { + q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); + return 0; + } + + size_t realSize = (size_t)size + extra; + QT_OFF_T realOffset = QT_OFF_T(offset); + realOffset &= ~(QT_OFF_T(pageSize - 1)); #ifdef Q_OS_SYMBIAN void *mapAddress; - TRAPD(err, mapAddress = mmap((void*)0, (size_t)size + extra, - access, MAP_SHARED, nativeHandle(), realOffset * pagesSize)); + TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, + access, MAP_SHARED, nativeHandle(), realOffset)); if (err != KErrNone) { qWarning("OpenC bug: leave from mmap %d", err); mapAddress = MAP_FAILED; errno = EINVAL; } #else - void *mapAddress = mmap((void*)0, (size_t)size + extra, - access, MAP_SHARED, nativeHandle(), realOffset * pagesSize); + void *mapAddress = QT_MMAP((void*)0, realSize, + access, MAP_SHARED, nativeHandle(), realOffset); #endif if (MAP_FAILED != mapAddress) { uchar *address = extra + static_cast<uchar*>(mapAddress); - maps[address] = QPair<int,int>(extra, size); + maps[address] = QPair<int,size_t>(extra, realSize); return address; } @@ -1300,7 +1317,7 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) } uchar *start = ptr - maps[ptr].first; - int len = maps[ptr].second; + size_t len = maps[ptr].second; if (-1 == munmap(start, len)) { q->setError(QFile::UnspecifiedError, qt_error_string(errno)); return false; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 898447c..a6cb5a9 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -455,17 +455,10 @@ bool QFSFileEnginePrivate::nativeClose() // Windows native mode. bool ok = true; - if ((fileHandle == INVALID_HANDLE_VALUE || !CloseHandle(fileHandle)) -#ifdef Q_USE_DEPRECATED_MAP_API - && (fileMapHandle == INVALID_HANDLE_VALUE || !CloseHandle(fileMapHandle)) -#endif - ) { + if ((fileHandle == INVALID_HANDLE_VALUE || !::CloseHandle(fileHandle))) { q->setError(QFile::UnspecifiedError, qt_error_string()); ok = false; } -#ifdef Q_USE_DEPRECATED_MAP_API - fileMapHandle = INVALID_HANDLE_VALUE; -#endif fileHandle = INVALID_HANDLE_VALUE; cachedFd = -1; // gets closed by CloseHandle above @@ -504,14 +497,30 @@ qint64 QFSFileEnginePrivate::nativeSize() const // ### Don't flush; for buffered files, we should get away with ftell. thatQ->flush(); +#if !defined(Q_OS_WINCE) + // stdlib/stdio mode. + if (fh || fd != -1) { + qint64 fileSize = _filelengthi64(fh ? QT_FILENO(fh) : fd); + if (fileSize == -1) { + fileSize = 0; + thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); + } + return fileSize; + } +#else // Q_OS_WINCE // Buffered stdlib mode. if (fh) { QT_OFF_T oldPos = QT_FTELL(fh); QT_FSEEK(fh, 0, SEEK_END); - QT_OFF_T fileSize = QT_FTELL(fh); + qint64 fileSize = (qint64)QT_FTELL(fh); QT_FSEEK(fh, oldPos, SEEK_SET); - return qint64(fileSize); + if (fileSize == -1) { + fileSize = 0; + thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); + } + return fileSize; } +#endif // Not-open mode, where the file name is known: We'll check the // file system directly. @@ -551,23 +560,13 @@ qint64 QFSFileEnginePrivate::nativeSize() const return 0; } - // Unbuffed stdio mode. - if(fd != -1) { -#if !defined(Q_OS_WINCE) - HANDLE handle = (HANDLE)_get_osfhandle(fd); - if (handle != INVALID_HANDLE_VALUE) { - BY_HANDLE_FILE_INFORMATION fileInfo; - if (GetFileInformationByHandle(handle, &fileInfo)) { - qint64 size = fileInfo.nFileSizeHigh; - size <<= 32; - size += fileInfo.nFileSizeLow; - return size; - } - } -#endif - thatQ->setError(QFile::UnspecifiedError, qt_error_string()); +#if defined(Q_OS_WINCE) + // Unbuffed stdio mode + if (fd != -1) { + thatQ->setError(QFile::UnspecifiedError, QLatin1String("Not implemented!")); return 0; } +#endif // Windows native mode. if (fileHandle == INVALID_HANDLE_VALUE) @@ -799,27 +798,18 @@ int QFSFileEnginePrivate::nativeHandle() const bool QFSFileEnginePrivate::nativeIsSequential() const { #if !defined(Q_OS_WINCE) - // stdlib / Windows native mode. - if (fh || fileHandle != INVALID_HANDLE_VALUE) { - if (fh == stdin || fh == stdout || fh == stderr) - return true; - - HANDLE handle = fileHandle; - if (fileHandle == INVALID_HANDLE_VALUE) { - // Rare case: using QFile::open(FILE*) to open a pipe. - handle = (HANDLE)_get_osfhandle(QT_FILENO(fh)); - return false; - } - - DWORD fileType = GetFileType(handle); - return fileType == FILE_TYPE_PIPE; - } + HANDLE handle = fileHandle; + if (fh || fd != -1) + handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd); + if (handle == INVALID_HANDLE_VALUE) + return false; - // stdio mode. - if (fd != -1) - return isSequentialFdFh(); -#endif + DWORD fileType = GetFileType(handle); + return (fileType == FILE_TYPE_CHAR) + || (fileType == FILE_TYPE_PIPE); +#else return false; +#endif } bool QFSFileEngine::remove() @@ -1931,42 +1921,42 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, return 0; } + if (mapHandle == INVALID_HANDLE_VALUE) { + // get handle to the file + HANDLE handle = fileHandle; - // get handle to the file - HANDLE handle = fileHandle; #ifndef Q_OS_WINCE - if (handle == INVALID_HANDLE_VALUE && fh) - handle = (HANDLE)_get_osfhandle(QT_FILENO(fh)); + if (handle == INVALID_HANDLE_VALUE && fh) + handle = (HANDLE)::_get_osfhandle(QT_FILENO(fh)); #endif #ifdef Q_USE_DEPRECATED_MAP_API - if (fileMapHandle == INVALID_HANDLE_VALUE) { nativeClose(); - fileMapHandle = CreateFileForMapping((const wchar_t*)nativeFilePath.constData(), + // handle automatically closed by kernel with mapHandle (below). + handle = ::CreateFileForMapping((const wchar_t*)nativeFilePath.constData(), GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0), 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } - handle = fileMapHandle; #endif - if (handle == INVALID_HANDLE_VALUE) { - q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); - return 0; - } + if (handle == INVALID_HANDLE_VALUE) { + q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); + return 0; + } - // first create the file mapping handle - DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY; - HANDLE mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0); - if (mapHandle == NULL) { - q->setError(QFile::PermissionsError, qt_error_string()); + // first create the file mapping handle + DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY; + mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0); + if (mapHandle == INVALID_HANDLE_VALUE) { + q->setError(QFile::PermissionsError, qt_error_string()); #ifdef Q_USE_DEPRECATED_MAP_API - mapHandleClose(); + ::CloseHandle(handle); #endif - return 0; + return 0; + } } // setup args to map @@ -1978,17 +1968,17 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, DWORD offsetLo = offset & Q_UINT64_C(0xffffffff); SYSTEM_INFO sysinfo; ::GetSystemInfo(&sysinfo); - int mask = sysinfo.dwAllocationGranularity - 1; - int extra = offset & mask; + DWORD mask = sysinfo.dwAllocationGranularity - 1; + DWORD extra = offset & mask; if (extra) offsetLo &= ~mask; // attempt to create the map - LPVOID mapAddress = MapViewOfFile(mapHandle, access, + LPVOID mapAddress = ::MapViewOfFile(mapHandle, access, offsetHi, offsetLo, size + extra); if (mapAddress) { uchar *address = extra + static_cast<uchar*>(mapAddress); - maps[address] = QPair<int, HANDLE>(extra, mapHandle); + maps[address] = extra; return address; } @@ -2001,10 +1991,8 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, default: q->setError(QFile::UnspecifiedError, qt_error_string()); } - CloseHandle(mapHandle); -#ifdef Q_USE_DEPRECATED_MAP_API - mapHandleClose(); -#endif + + ::CloseHandle(mapHandle); return 0; } @@ -2015,32 +2003,19 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); return false; } - uchar *start = ptr - maps[ptr].first; + uchar *start = ptr - maps[ptr]; if (!UnmapViewOfFile(start)) { q->setError(QFile::PermissionsError, qt_error_string()); return false; } - if (!CloseHandle((HANDLE)maps[ptr].second)) { - q->setError(QFile::UnspecifiedError, qt_error_string()); - return false; - } maps.remove(ptr); - -#ifdef Q_USE_DEPRECATED_MAP_API - mapHandleClose(); -#endif - return true; -} - -#ifdef Q_USE_DEPRECATED_MAP_API -void QFSFileEnginePrivate::mapHandleClose() -{ if (maps.isEmpty()) { - CloseHandle(fileMapHandle); - fileMapHandle = INVALID_HANDLE_VALUE; + ::CloseHandle(mapHandle); + mapHandle = INVALID_HANDLE_VALUE; } + + return true; } -#endif QT_END_NAMESPACE diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index dd6b0d3..c86af73 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -68,9 +68,11 @@ public: }; enum CompositionModeStatus { - PorterDuff_None = 0x0, - PorterDuff_SupportedBlits = 0x1, - PorterDuff_SupportedPrimitives = 0x2 + PorterDuff_None = 0x00, + PorterDuff_SupportedBlits = 0x01, + PorterDuff_SupportedPrimitives = 0x02, + PorterDuff_SupportedOpaquePrimitives = 0x04, + PorterDuff_Dirty = 0x10 }; enum ClipType { @@ -95,6 +97,7 @@ public: inline void unlock(); static inline void unlock(QDirectFBPaintDevice *device); + inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const; inline bool isSimpleBrush(const QBrush &brush) const; void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos); @@ -404,11 +407,11 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen) return; - if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) + if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip - || !d->isSimpleBrush(brush)) { + || !d->isSimpleBrush(brush) + || !d->testCompositionMode(&pen, &brush)) { RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); @@ -434,11 +437,11 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen) return; - if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) + if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip - || !d->isSimpleBrush(brush)) { + || !d->isSimpleBrush(brush) + || !d->testCompositionMode(&pen, &brush)) { RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); @@ -460,16 +463,16 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QDirectFBPaintEngine); - if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) - || !d->simplePen - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { + const QPen &pen = state()->pen; + if (!d->simplePen + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || !d->testCompositionMode(&pen, 0)) { RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); return; } - const QPen &pen = state()->pen; if (pen.style() != Qt::NoPen) { d->setDFBColor(pen.color()); CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface)); @@ -480,16 +483,16 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QDirectFBPaintEngine); - if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) - || !d->simplePen - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { + const QPen &pen = state()->pen; + if (!d->simplePen + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || !d->testCompositionMode(&pen, 0)) { RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); return; } - const QPen &pen = state()->pen; if (pen.style() != Qt::NoPen) { d->setDFBColor(pen.color()); CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface)); @@ -714,8 +717,8 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) { switch (brush.style()) { case Qt::SolidPattern: { - if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)) { + if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported + || !d->testCompositionMode(0, &brush)) { break; } const QColor color = brush.color(); @@ -753,9 +756,9 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) if (!color.isValid()) return; Q_D(QDirectFBPaintEngine); - if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { + if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || !d->testCompositionMode(0, 0, &color)) { RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); d->lock(); QRasterPaintEngine::fillRect(rect, color); @@ -815,6 +818,36 @@ bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); } +bool QDirectFBPaintEnginePrivate::testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color) const +{ + Q_ASSERT(!pen || pen->style() == Qt::NoPen || pen->style() == Qt::SolidLine); + Q_ASSERT(!brush || brush->style() == Qt::NoBrush || brush->style() == Qt::SolidPattern); + switch (compositionModeStatus & (QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives + |QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)) { + case QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives: + return true; + case QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives: + if (pen && pen->style() == Qt::SolidLine && pen->color().alpha() != 255) + return false; + if (brush) { + if (brush->style() == Qt::SolidPattern && brush->color().alpha() != 255) { + return false; + } + } else if (color && color->alpha() != 255) { + return false; + } + return true; + case QDirectFBPaintEnginePrivate::PorterDuff_None: + return false; + default: + // ### PorterDuff_SupportedOpaquePrimitives|PorterDuff_SupportedPrimitives can't be combined + break; + } + Q_ASSERT(0); + return false; +} + + void QDirectFBPaintEnginePrivate::lock() { // We will potentially get a new pointer to the buffer after a @@ -888,6 +921,7 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m break; case QPainter::CompositionMode_Source: surface->SetPorterDuff(surface, DSPD_SRC); + compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives; break; case QPainter::CompositionMode_SourceOver: compositionModeStatus |= PorterDuff_SupportedPrimitives; @@ -945,6 +979,9 @@ void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) } surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); surface->SetBlittingFlags(surface, blittingFlags); + if (compositionModeStatus & PorterDuff_Dirty) { + setCompositionMode(q->state()->composition_mode); + } } static inline uint ALPHA_MUL(uint x, uint a) @@ -962,6 +999,7 @@ void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha); surface->SetPorterDuff(surface, DSPD_NONE); surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND); + compositionModeStatus |= PorterDuff_Dirty; } IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release) diff --git a/tests/auto/qfile/largefile/largefile.pro b/tests/auto/qfile/largefile/largefile.pro new file mode 100644 index 0000000..0f96865 --- /dev/null +++ b/tests/auto/qfile/largefile/largefile.pro @@ -0,0 +1,4 @@ +load(qttest_p4) + +QT = core +SOURCES += tst_largefile.cpp diff --git a/tests/auto/qfile/largefile/tst_largefile.cpp b/tests/auto/qfile/largefile/tst_largefile.cpp new file mode 100644 index 0000000..8ab3275 --- /dev/null +++ b/tests/auto/qfile/largefile/tst_largefile.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTest> + +#include <QtAlgorithms> +#include <QFile> +#include <QFileInfo> +#include <qplatformdefs.h> + +#include <QDebug> + +#include <cstdlib> +#include <cstdio> + +#ifdef Q_OS_WIN + +#include <windows.h> +#include <io.h> + +#ifndef FSCTL_SET_SPARSE +// MinGW doesn't define this. +#define FSCTL_SET_SPARSE (0x900C4) +#endif + +#endif // Q_OS_WIN + +class tst_LargeFile + : public QObject +{ + Q_OBJECT + +public: + tst_LargeFile() + : blockSize(1 << 12) + , maxSizeBits() + , fd_(-1) + , stream_(0) + { + #if defined(QT_LARGEFILE_SUPPORT) && !defined(Q_OS_MAC) + maxSizeBits = 36; // 64 GiB + #elif defined(Q_OS_MAC) + // HFS+ does not support sparse files, so we limit file size for the test + // on Mac OS. + maxSizeBits = 32; // 4 GiB + #else + maxSizeBits = 24; // 16 MiB + #endif + } + +private: + void sparseFileData(); + QByteArray const &getDataBlock(int index, qint64 position); + +private slots: + // The LargeFile test case was designed to be run in order as a single unit + + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + // Create and fill large file + void createSparseFile(); + void fillFileSparsely(); + void closeSparseFile(); + + // Verify file was created + void fileCreated(); + + // Positioning in large files + void filePositioning(); + void fdPositioning(); + void streamPositioning(); + + // Read data from file + void openFileForReading(); + void readFile(); + + // Map/unmap large file + void mapFile(); + void mapOffsetOverflow(); + + void closeFile() { largeFile.close(); } + + // Test data + void fillFileSparsely_data() { sparseFileData(); } + void filePositioning_data() { sparseFileData(); } + void fdPositioning_data() { sparseFileData(); } + void streamPositioning_data() { sparseFileData(); } + void readFile_data() { sparseFileData(); } + void mapFile_data() { sparseFileData(); } + +private: + const int blockSize; + int maxSizeBits; + + QFile largeFile; + + QVector<QByteArray> generatedBlocks; + + int fd_; + FILE *stream_; +}; + +/* + Convenience function to hide reinterpret_cast when copying a POD directly + into a QByteArray. + */ +template <class T> +static inline void appendRaw(QByteArray &array, T data) +{ + array.append(reinterpret_cast<char *>(&data), sizeof(T)); +} + +/* + Pad array with filler up to size. On return, array.size() returns size. + */ +static inline void topUpWith(QByteArray &array, QByteArray filler, int size) +{ + Q_ASSERT(filler.size() > 0); + + for (int i = (size - array.size()) / filler.size(); i > 0; --i) + array.append(filler); + + if (array.size() < size) { + Q_ASSERT(size - array.size() < filler.size()); + array.append(filler.left(size - array.size())); + } +} + +/* + Generate a unique data block containing identifiable data. Unaligned, + overlapping and partial blocks should not compare equal. + */ +static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 userBits = -1) +{ + QByteArray block; + block.reserve(blockSize); + + // Use of counter and randomBits means content of block will be dependent + // on the generation order. For (file-)systems that do not support sparse + // files, these can be removed so the test file can be reused and doesn't + // have to be generated for every run. + + static qint64 counter = 0; + + qint64 randomBits = ((qint64)qrand() << 32) + | ((qint64)qrand() & 0x00000000ffffffff); + + appendRaw(block, randomBits); + appendRaw(block, userBits); + appendRaw(block, counter); + appendRaw(block, (qint32)0xdeadbeef); + appendRaw(block, blockSize); + + QByteArray userContent = text.toUtf8(); + appendRaw(block, userContent.size()); + block.append(userContent); + appendRaw(block, (qint64)0); + + // size, so far + appendRaw(block, block.size()); + + QByteArray filler("0123456789"); + block.append(filler.right(10 - block.size() % 10)); + topUpWith(block, filler, blockSize - 2 * sizeof(qint64)); + + appendRaw(block, counter); + appendRaw(block, userBits); + appendRaw(block, randomBits); + + Q_ASSERT( block.size() >= blockSize ); + block.resize(blockSize); + + ++counter; + return block; +} + +/* + Generates data blocks the first time they are requested. Keeps copies for reuse. + */ +QByteArray const &tst_LargeFile::getDataBlock(int index, qint64 position) +{ + if (index >= generatedBlocks.size()) + generatedBlocks.resize(index + 1); + + if (generatedBlocks[index].isNull()) { + QString text = QString("Current %1-byte block (index = %2) " + "starts %3 bytes into the file '%4'.") + .arg(blockSize) + .arg(index) + .arg(position) + .arg("qt_largefile.tmp"); + + generatedBlocks[index] = generateDataBlock(blockSize, text, (qint64)1 << index); + } + + return generatedBlocks[index]; +} + +void tst_LargeFile::initTestCase() +{ + QFile file("qt_largefile.tmp"); + QVERIFY( !file.exists() || file.remove() ); +} + +void tst_LargeFile::cleanupTestCase() +{ + if (largeFile.isOpen()) + largeFile.close(); + + QFile file("qt_largefile.tmp"); + QVERIFY( !file.exists() || file.remove() ); +} + +void tst_LargeFile::init() +{ + fd_ = -1; + stream_ = 0; +} + +void tst_LargeFile::cleanup() +{ + if (-1 != fd_) + QT_CLOSE(fd_); + if (stream_) + ::fclose(stream_); +} + +void tst_LargeFile::sparseFileData() +{ + QTest::addColumn<int>("index"); + QTest::addColumn<qint64>("position"); + QTest::addColumn<QByteArray>("block"); + + QTest::newRow(QString("block[%1] @%2)") + .arg(0).arg(0) + .toLocal8Bit().constData()) + << 0 << (qint64)0 << getDataBlock(0, 0); + + // While on Linux sparse files scale well, on Windows, testing at every + // power of 2 leads to very large files. i += 4 gives us a good coverage + // without taxing too much on resources. + for (int index = 12; index <= maxSizeBits; index += 4) { + qint64 position = (qint64)1 << index; + QByteArray block = getDataBlock(index, position); + + QTest::newRow( + QString("block[%1] @%2)") + .arg(index).arg(position) + .toLocal8Bit().constData()) + << index << position << block; + } +} + +void tst_LargeFile::createSparseFile() +{ +#if defined(Q_OS_WIN) + // On Windows platforms, we must explicitly set the file to be sparse, + // so disk space is not allocated for the full file when writing to it. + HANDLE handle = ::CreateFileA("qt_largefile.tmp", + GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + QVERIFY( INVALID_HANDLE_VALUE != handle ); + + DWORD bytes; + if (!::DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, + &bytes, NULL)) { + QWARN("Unable to set test file as sparse. " + "Limiting test file to 16MiB."); + maxSizeBits = 24; + } + + int fd = ::_open_osfhandle((intptr_t)handle, 0); + QVERIFY( -1 != fd ); + QVERIFY( largeFile.open(fd, QIODevice::WriteOnly | QIODevice::Unbuffered) ); +#else // !Q_OS_WIN + largeFile.setFileName("qt_largefile.tmp"); + QVERIFY( largeFile.open(QIODevice::WriteOnly | QIODevice::Unbuffered) ); +#endif +} + +void tst_LargeFile::closeSparseFile() +{ +#if defined(Q_OS_WIN) + int fd = largeFile.handle(); +#endif + + largeFile.close(); + +#if defined(Q_OS_WIN) + if (-1 != fd) + ::_close(fd); +#endif +} + +void tst_LargeFile::fillFileSparsely() +{ + QFETCH( qint64, position ); + QFETCH( QByteArray, block ); + QCOMPARE( block.size(), blockSize ); + + QVERIFY( largeFile.seek(position) ); + QCOMPARE( largeFile.pos(), position ); + + QCOMPARE( largeFile.write(block), (qint64)blockSize ); + QCOMPARE( largeFile.pos(), position + blockSize ); + QVERIFY( largeFile.flush() ); +} + +void tst_LargeFile::fileCreated() +{ + QFileInfo info("qt_largefile.tmp"); + + QVERIFY( info.exists() ); + QVERIFY( info.isFile() ); + QVERIFY( info.size() >= ((qint64)1 << maxSizeBits) + blockSize ); +} + +void tst_LargeFile::filePositioning() +{ + QFETCH( qint64, position ); + + QFile file("qt_largefile.tmp"); + QVERIFY( file.open(QIODevice::ReadOnly) ); + + QVERIFY( file.seek(position) ); + QCOMPARE( file.pos(), position ); +} + +void tst_LargeFile::fdPositioning() +{ + QFETCH( qint64, position ); + + fd_ = QT_OPEN("qt_largefile.tmp", + QT_OPEN_RDONLY | QT_OPEN_LARGEFILE); + QVERIFY( -1 != fd_ ); + + QFile file; + QVERIFY( file.open(fd_, QIODevice::ReadOnly) ); + QCOMPARE( file.pos(), (qint64)0 ); + QVERIFY( file.seek(position) ); + QCOMPARE( file.pos(), position ); + + file.close(); + + QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(0), SEEK_SET), QT_OFF_T(0) ); + QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(position), SEEK_SET), QT_OFF_T(position) ); + + QVERIFY( file.open(fd_, QIODevice::ReadOnly) ); + QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(0), SEEK_CUR), QT_OFF_T(position) ); + QCOMPARE( file.pos(), position ); + QVERIFY( file.seek(0) ); + QCOMPARE( file.pos(), (qint64)0 ); + + file.close(); + + QVERIFY( !QT_CLOSE(fd_) ); + fd_ = -1; +} + +void tst_LargeFile::streamPositioning() +{ + QFETCH( qint64, position ); + +#if defined(QT_LARGEFILE_SUPPORT) && defined(Q_CC_MSVC) && _MSC_VER < 1400 + if (position >= (qint64)1 << 31) + QSKIP("MSVC 2003 doesn't have 64 bit versions of fseek/ftell.", SkipSingle); +#endif + + stream_ = QT_FOPEN("qt_largefile.tmp", "rb"); + QVERIFY( 0 != stream_ ); + + QFile file; + QVERIFY( file.open(stream_, QIODevice::ReadOnly) ); + QCOMPARE( file.pos(), (qint64)0 ); + QVERIFY( file.seek(position) ); + QCOMPARE( file.pos(), position ); + + file.close(); + + QVERIFY( !QT_FSEEK(stream_, QT_OFF_T(0), SEEK_SET) ); + QCOMPARE( QT_FTELL(stream_), QT_OFF_T(0) ); + QVERIFY( !QT_FSEEK(stream_, QT_OFF_T(position), SEEK_SET) ); + QCOMPARE( QT_FTELL(stream_), QT_OFF_T(position) ); + + QVERIFY( file.open(stream_, QIODevice::ReadOnly) ); + QCOMPARE( QT_FTELL(stream_), QT_OFF_T(position) ); + QCOMPARE( file.pos(), position ); + QVERIFY( file.seek(0) ); + QCOMPARE( file.pos(), (qint64)0 ); + + file.close(); + + QVERIFY( !::fclose(stream_) ); + stream_ = 0; +} + +void tst_LargeFile::openFileForReading() +{ + largeFile.setFileName("qt_largefile.tmp"); + QVERIFY( largeFile.open(QIODevice::ReadOnly) ); +} + +void tst_LargeFile::readFile() +{ + QFETCH( qint64, position ); + QFETCH( QByteArray, block ); + QCOMPARE( block.size(), blockSize ); + + QVERIFY( largeFile.size() >= position + blockSize ); + + QVERIFY( largeFile.seek(position) ); + QCOMPARE( largeFile.pos(), position ); + + QCOMPARE( largeFile.read(blockSize), block ); + QCOMPARE( largeFile.pos(), position + blockSize ); +} + +void tst_LargeFile::mapFile() +{ + QFETCH( qint64, position ); + QFETCH( QByteArray, block ); + QCOMPARE( block.size(), blockSize ); + + // Keep full block mapped to facilitate OS and/or internal reuse by Qt. + uchar *baseAddress = largeFile.map(position, blockSize); + QVERIFY( baseAddress ); + QVERIFY( qEqual(block.begin(), block.end(), reinterpret_cast<char*>(baseAddress)) ); + + for (int offset = 1; offset < blockSize; ++offset) { + uchar *address = largeFile.map(position + offset, blockSize - offset); + + QVERIFY( address ); + if ( !qEqual(block.begin() + offset, block.end(), reinterpret_cast<char*>(address)) ) { + qDebug() << "Expected:" << block.toHex(); + qDebug() << "Actual :" << QByteArray(reinterpret_cast<char*>(address), blockSize).toHex(); + QVERIFY(false); + } + + QVERIFY( largeFile.unmap( address ) ); + } + + QVERIFY( largeFile.unmap( baseAddress ) ); +} + +void tst_LargeFile::mapOffsetOverflow() +{ + // Out-of-range mappings should fail, and not silently clip the offset + for (int i = 50; i < 63; ++i) { + uchar *address = 0; + + address = largeFile.map(((qint64)1 << i), blockSize); + QVERIFY( !address ); + + address = largeFile.map(((qint64)1 << i) + blockSize, blockSize); + QVERIFY( !address ); + } +} + +QTEST_APPLESS_MAIN(tst_LargeFile) +#include "tst_largefile.moc" + diff --git a/tests/auto/qfile/qfile.pro b/tests/auto/qfile/qfile.pro index eebfcda..f70f750 100644 --- a/tests/auto/qfile/qfile.pro +++ b/tests/auto/qfile/qfile.pro @@ -5,5 +5,5 @@ wince*:{ SUBDIRS = test stdinprocess } - +SUBDIRS += largefile diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 19fbecd..55cc286 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -79,6 +79,18 @@ # define SRCDIR "" #endif +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + Q_DECLARE_METATYPE(QFile::FileError) //TESTED_CLASS= @@ -105,6 +117,7 @@ private slots: void openUnbuffered(); void size_data(); void size(); + void sizeNoExist(); void seek(); void setSize(); void setSizeSeek(); @@ -187,6 +200,8 @@ private slots: void mapOpenMode_data(); void mapOpenMode(); + void openStandardStreams(); + // --- Task related tests below this line void task167217(); @@ -438,23 +453,57 @@ void tst_QFile::openUnbuffered() void tst_QFile::size_data() { QTest::addColumn<QString>("filename"); - QTest::addColumn<int>("size"); + QTest::addColumn<qint64>("size"); - QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << 245; - QTest::newRow( "nonexist01" ) << QString("foo.txt") << 0; + QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << (qint64)245; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) // Only test UNC on Windows./ - QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << 34; + QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << (qint64)34; #endif } void tst_QFile::size() { QFETCH( QString, filename ); - QFile f( filename ); - QTEST( (int)f.size(), "size" ); - if (f.open(QFile::ReadOnly)) - QTEST( (int)f.size(), "size" ); + QFETCH( qint64, size ); + + { + QFile f( filename ); + QCOMPARE( f.size(), size ); + + QVERIFY( f.open(QIODevice::ReadOnly) ); + QCOMPARE( f.size(), size ); + } + + { + QFile f; + int fd = QT_OPEN(filename.toLocal8Bit().constData(), QT_OPEN_RDONLY); + QVERIFY( fd != -1 ); + QVERIFY( f.open(fd, QIODevice::ReadOnly) ); + QCOMPARE( f.size(), size ); + + f.close(); + QT_CLOSE(fd); + } + + { + QFile f; + FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb"); + QVERIFY( stream ); + QVERIFY( f.open(stream, QIODevice::ReadOnly) ); + QCOMPARE( f.size(), size ); + + f.close(); + fclose(stream); + } +} + +void tst_QFile::sizeNoExist() +{ + QFile file("nonexist01"); + QVERIFY( !file.exists() ); + QCOMPARE( file.size(), (qint64)0 ); + QVERIFY( !file.open(QIODevice::ReadOnly) ); } void tst_QFile::seek() @@ -2634,5 +2683,58 @@ void tst_QFile::openDirectory() QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered)); } +void tst_QFile::openStandardStreams() +{ + // Using file descriptors + { + QFile in; + in.open(STDIN_FILENO, QIODevice::ReadOnly); + QCOMPARE( in.pos(), (qint64)0 ); + QCOMPARE( in.size(), (qint64)0 ); + QVERIFY( in.isSequential() ); + } + + { + QFile out; + out.open(STDOUT_FILENO, QIODevice::WriteOnly); + QCOMPARE( out.pos(), (qint64)0 ); + QCOMPARE( out.size(), (qint64)0 ); + QVERIFY( out.isSequential() ); + } + + { + QFile err; + err.open(STDERR_FILENO, QIODevice::WriteOnly); + QCOMPARE( err.pos(), (qint64)0 ); + QCOMPARE( err.size(), (qint64)0 ); + QVERIFY( err.isSequential() ); + } + + // Using streams + { + QFile in; + in.open(stdin, QIODevice::ReadOnly); + QCOMPARE( in.pos(), (qint64)0 ); + QCOMPARE( in.size(), (qint64)0 ); + QVERIFY( in.isSequential() ); + } + + { + QFile out; + out.open(stdout, QIODevice::WriteOnly); + QCOMPARE( out.pos(), (qint64)0 ); + QCOMPARE( out.size(), (qint64)0 ); + QVERIFY( out.isSequential() ); + } + + { + QFile err; + err.open(stderr, QIODevice::WriteOnly); + QCOMPARE( err.pos(), (qint64)0 ); + QCOMPARE( err.size(), (qint64)0 ); + QVERIFY( err.isSequential() ); + } +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" |