Merge remote-tracking branch 'origin/api_changes'
Change-Id: I964b0a6f5c38351fdfafb8a2a128a349ff8c89d1
This commit is contained in:
commit
64255ef650
@ -1,3 +0,0 @@
|
||||
SOURCES = 3dnow.cpp
|
||||
CONFIG -= x11 qt
|
||||
mac:CONFIG -= app_bundle
|
@ -1,9 +1,9 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 Intel Corporation.
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the config.tests of the Qt Toolkit.
|
||||
** This file is part of the configuration of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
@ -39,13 +39,17 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <mm3dnow.h>
|
||||
#if defined(__GNUC__) && __GNUC__ < 4 && __GNUC_MINOR__ < 3
|
||||
#error GCC < 3.2 is known to create internal compiler errors with our MMX code
|
||||
#endif
|
||||
#include <immintrin.h>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
_m_femms();
|
||||
/* AVX */
|
||||
_mm256_zeroall();
|
||||
volatile __m256i a = _mm256_setzero_si256();
|
||||
|
||||
/* AVX2 */
|
||||
volatile __m256i b = _mm256_and_si256(a, a);
|
||||
volatile __m256i result = _mm256_add_epi8(a, b);
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
SOURCES = sse.cpp
|
||||
SOURCES = avx2.cpp
|
||||
CONFIG -= x11 qt
|
||||
mac:CONFIG -= app_bundle
|
@ -1,3 +0,0 @@
|
||||
SOURCES = mmx.cpp
|
||||
CONFIG -= x11 qt
|
||||
mac:CONFIG -= app_bundle
|
140
configure
vendored
140
configure
vendored
@ -718,20 +718,17 @@ CFG_GSTREAMER=auto
|
||||
CFG_QGTKSTYLE=auto
|
||||
CFG_LARGEFILE=auto
|
||||
CFG_OPENSSL=auto
|
||||
CFG_STL=auto
|
||||
CFG_PRECOMPILE=auto
|
||||
CFG_SEPARATE_DEBUG_INFO=no
|
||||
CFG_SEPARATE_DEBUG_INFO_NOCOPY=no
|
||||
CFG_REDUCE_EXPORTS=auto
|
||||
CFG_MMX=auto
|
||||
CFG_3DNOW=auto
|
||||
CFG_SSE=auto
|
||||
CFG_SSE2=auto
|
||||
CFG_SSE3=auto
|
||||
CFG_SSSE3=auto
|
||||
CFG_SSE4_1=auto
|
||||
CFG_SSE4_2=auto
|
||||
CFG_AVX=auto
|
||||
CFG_AVX2=auto
|
||||
CFG_REDUCE_RELOCATIONS=auto
|
||||
CFG_ACCESSIBILITY=auto
|
||||
CFG_IWMMXT=no
|
||||
@ -892,7 +889,7 @@ while [ "$#" -gt 0 ]; do
|
||||
VAL=no
|
||||
;;
|
||||
#Qt style yes options
|
||||
-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-eglfs|-directfb|-nis|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-debug-and-release|-exceptions|-harfbuzz|-prefix-install|-silent|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-phonon-backend|-audio-backend|-qml-debug|-javascript-jit|-rpath|-pkg-config|-force-pkg-config|-icu|-force-asserts|-testcocoon)
|
||||
-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-eglfs|-directfb|-nis|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-debug-and-release|-exceptions|-harfbuzz|-prefix-install|-silent|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-phonon-backend|-audio-backend|-qml-debug|-javascript-jit|-rpath|-pkg-config|-force-pkg-config|-icu|-force-asserts|-testcocoon)
|
||||
VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
|
||||
VAL=yes
|
||||
;;
|
||||
@ -1428,13 +1425,6 @@ while [ "$#" -gt 0 ]; do
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
stl)
|
||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||
CFG_STL="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
pch)
|
||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||
CFG_PRECOMPILE="$VAL"
|
||||
@ -1459,27 +1449,6 @@ while [ "$#" -gt 0 ]; do
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
mmx)
|
||||
if [ "$VAL" = "no" ]; then
|
||||
CFG_MMX="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
3dnow)
|
||||
if [ "$VAL" = "no" ]; then
|
||||
CFG_3DNOW="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
sse)
|
||||
if [ "$VAL" = "no" ]; then
|
||||
CFG_SSE="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
sse2)
|
||||
if [ "$VAL" = "no" ]; then
|
||||
CFG_SSE2="$VAL"
|
||||
@ -1522,6 +1491,13 @@ while [ "$#" -gt 0 ]; do
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
avx2)
|
||||
if [ "$VAL" = "no" ]; then
|
||||
CFG_AVX2="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
iwmmxt)
|
||||
CFG_IWMMXT="yes"
|
||||
;;
|
||||
@ -2816,13 +2792,6 @@ if [ "$OPT_HELP" = "yes" ]; then
|
||||
LFSY="*"
|
||||
LFSN=" "
|
||||
fi
|
||||
if [ "$CFG_STL" = "auto" ] || [ "$CFG_STL" = "yes" ]; then
|
||||
SHY="*"
|
||||
SHN=" "
|
||||
else
|
||||
SHY=" "
|
||||
SHN="*"
|
||||
fi
|
||||
if [ "$CFG_PRECOMPILE" = "auto" ] || [ "$CFG_PRECOMPILE" = "no" ]; then
|
||||
PHY=" "
|
||||
PHN="*"
|
||||
@ -2893,7 +2862,7 @@ Usage: $relconf [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir
|
||||
[-release] [-debug] [-debug-and-release]
|
||||
[-developer-build] [-shared] [-static] [-no-fast] [-fast] [-no-largefile]
|
||||
[-largefile] [-no-exceptions] [-exceptions] [-no-accessibility]
|
||||
[-accessibility] [-no-stl] [-stl] [-no-sql-<driver>] [-sql-<driver>]
|
||||
[-accessibility] [-no-sql-<driver>] [-sql-<driver>]
|
||||
[-plugin-sql-<driver>] [-system-sqlite]
|
||||
[-platform] [-D <string>] [-I <string>] [-L <string>] [-help]
|
||||
[-qt-zlib] [-system-zlib] [-no-gif] [-no-libpng] [-qt-libpng] [-system-libpng]
|
||||
@ -2901,7 +2870,7 @@ Usage: $relconf [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir
|
||||
[-nomake <part>] [-R <string>] [-l <string>] [-no-rpath] [-rpath] [-continue]
|
||||
[-verbose] [-v] [-silent] [-no-nis] [-nis] [-no-cups] [-cups] [-no-iconv]
|
||||
[-iconv] [-no-pch] [-pch] [-no-dbus] [-dbus] [-dbus-linked] [-no-gui]
|
||||
[-no-separate-debug-info] [-no-mmx] [-no-3dnow] [-no-sse] [-no-sse2]
|
||||
[-no-separate-debug-info] [-no-sse2]
|
||||
[-no-sse3] [-no-ssse3] [-no-sse4.1] [-no-sse4.2] [-no-avx] [-no-neon]
|
||||
[-qtnamespace <namespace>] [-qtlibinfix <infix>] [-separate-debug-info]
|
||||
[-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend]
|
||||
@ -3000,9 +2969,6 @@ Configure options:
|
||||
-no-accessibility .. Do not compile Accessibility support.
|
||||
* -accessibility ..... Compile Accessibility support.
|
||||
|
||||
$SHN -no-stl ............ Do not compile STL support.
|
||||
$SHY -stl ............... Compile STL support.
|
||||
|
||||
-no-sql-<driver> ... Disable SQL <driver> entirely.
|
||||
-qt-sql-<driver> ... Enable a SQL <driver> in the QtSql library, by default
|
||||
none are turned on.
|
||||
@ -3029,15 +2995,13 @@ Configure options:
|
||||
See the README file for a list of supported
|
||||
operating systems and compilers.
|
||||
|
||||
-no-mmx ............ Do not compile with use of MMX instructions.
|
||||
-no-3dnow .......... Do not compile with use of 3DNOW instructions.
|
||||
-no-sse ............ Do not compile with use of SSE instructions.
|
||||
-no-sse2 ........... Do not compile with use of SSE2 instructions.
|
||||
-no-sse3 ........... Do not compile with use of SSE3 instructions.
|
||||
-no-ssse3 .......... Do not compile with use of SSSE3 instructions.
|
||||
-no-sse4.1.......... Do not compile with use of SSE4.1 instructions.
|
||||
-no-sse4.2.......... Do not compile with use of SSE4.2 instructions.
|
||||
-no-avx ............ Do not compile with use of AVX instructions.
|
||||
-no-avx2 ........... Do not compile with use of AVX2 instructions.
|
||||
-no-neon ........... Do not compile with use of NEON instructions.
|
||||
-no-mips_dsp ....... Do not compile with use of MIPS DSP instructions.
|
||||
-no-mips_dspr2 ..... Do not compile with use of MIPS DSP rev2 instructions.
|
||||
@ -3733,33 +3697,6 @@ else
|
||||
CFG_USE_FLOATMATH=no
|
||||
fi
|
||||
|
||||
# detect mmx support
|
||||
if [ "${CFG_MMX}" = "auto" ]; then
|
||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/mmx "mmx" $L_FLAGS $I_FLAGS $l_FLAGS "-mmmx"; then
|
||||
CFG_MMX=yes
|
||||
else
|
||||
CFG_MMX=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# detect 3dnow support
|
||||
if [ "${CFG_3DNOW}" = "auto" ]; then
|
||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/3dnow "3dnow" $L_FLAGS $I_FLAGS $l_FLAGS "-m3dnow"; then
|
||||
CFG_3DNOW=yes
|
||||
else
|
||||
CFG_3DNOW=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# detect sse support
|
||||
if [ "${CFG_SSE}" = "auto" ]; then
|
||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/sse "sse" $L_FLAGS $I_FLAGS $l_FLAGS "-msse"; then
|
||||
CFG_SSE=yes
|
||||
else
|
||||
CFG_SSE=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# detect sse2 support
|
||||
if [ "${CFG_SSE2}" = "auto" ]; then
|
||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/sse2 "sse2" $L_FLAGS $I_FLAGS $l_FLAGS "-msse2"; then
|
||||
@ -3814,6 +3751,15 @@ if [ "${CFG_AVX}" = "auto" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# detect avx2 support
|
||||
if [ "${CFG_AVX2}" = "auto" ]; then
|
||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/avx2 "avx2" $L_FLAGS $I_FLAGS $l_FLAGS "-march=core-avx2"; then
|
||||
CFG_AVX2=yes
|
||||
else
|
||||
CFG_AVX2=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# check iWMMXt support
|
||||
if [ "$CFG_IWMMXT" = "yes" ]; then
|
||||
"$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/iwmmxt "iwmmxt" $L_FLAGS $I_FLAGS $l_FLAGS "-mcpu=iwmmxt"
|
||||
@ -4725,26 +4671,13 @@ if [ "$CFG_LIBFREETYPE" = "auto" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
HAVE_STL=no
|
||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then
|
||||
HAVE_STL=yes
|
||||
if ! "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS &&
|
||||
[ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
|
||||
echo "STL functionality check failed! Cannot build Qt with this STL library."
|
||||
echo " Turn on verbose messaging (-v) to $0 to see the final report."
|
||||
exit 101
|
||||
fi
|
||||
|
||||
if [ "$CFG_STL" != "no" ]; then
|
||||
if [ "$HAVE_STL" = "yes" ]; then
|
||||
CFG_STL=yes
|
||||
else
|
||||
if [ "$CFG_STL" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
|
||||
echo "STL support cannot be enabled due to functionality tests!"
|
||||
echo " Turn on verbose messaging (-v) to $0 to see the final report."
|
||||
echo " If you believe this message is in error you may use the continue"
|
||||
echo " switch (-continue) to $0 to continue."
|
||||
exit 101
|
||||
else
|
||||
CFG_STL=no
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# detect POSIX clock_gettime()
|
||||
if [ "$CFG_CLOCK_GETTIME" = "auto" ]; then
|
||||
@ -5086,11 +5019,6 @@ QMakeVar set UI_DIR ".uic/$QMAKE_OUTDIR"
|
||||
if [ "$CFG_LARGEFILE" = "yes" ] && [ "$XPLATFORM_MINGW" != "yes" ]; then
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG largefile"
|
||||
fi
|
||||
if [ "$CFG_STL" = "no" ]; then
|
||||
QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_STL"
|
||||
else
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG stl"
|
||||
fi
|
||||
if [ "$CFG_USE_GNUMAKE" = "yes" ]; then
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG GNUmake"
|
||||
fi
|
||||
@ -5105,15 +5033,13 @@ fi
|
||||
if [ "$CFG_SEPARATE_DEBUG_INFO_NOCOPY" = "yes" ] ; then
|
||||
QT_CONFIG="$QT_CONFIG separate_debug_info_nocopy"
|
||||
fi
|
||||
[ "$CFG_MMX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG mmx"
|
||||
[ "$CFG_3DNOW" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG 3dnow"
|
||||
[ "$CFG_SSE" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse"
|
||||
[ "$CFG_SSE2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse2"
|
||||
[ "$CFG_SSE3" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse3"
|
||||
[ "$CFG_SSSE3" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG ssse3"
|
||||
[ "$CFG_SSE4_1" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse4_1"
|
||||
[ "$CFG_SSE4_2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse4_2"
|
||||
[ "$CFG_AVX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx"
|
||||
[ "$CFG_AVX2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx2"
|
||||
[ "$CFG_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt"
|
||||
[ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon"
|
||||
if [ "$CFG_ARCH" = "mips" ]; then
|
||||
@ -5750,9 +5676,6 @@ elif [ "$CFG_DEBUG" = "no" ]; then
|
||||
fi
|
||||
QT_CONFIG="$QT_CONFIG release"
|
||||
fi
|
||||
if [ "$CFG_STL" = "yes" ]; then
|
||||
QTCONFIG_CONFIG="$QTCONFIG_CONFIG stl"
|
||||
fi
|
||||
if [ "$CFG_FRAMEWORK" = "no" ]; then
|
||||
QTCONFIG_CONFIG="$QTCONFIG_CONFIG qt_no_framework"
|
||||
else
|
||||
@ -6008,12 +5931,11 @@ else
|
||||
echo "JavaScriptCore JIT ..... $CFG_JAVASCRIPTCORE_JIT"
|
||||
fi
|
||||
echo "QML debugging .......... $CFG_QML_DEBUG"
|
||||
echo "STL support ............ $CFG_STL"
|
||||
echo "PCH support ............ $CFG_PRECOMPILE"
|
||||
if [ "$CFG_ARCH" = "i386" -o "$CFG_ARCH" = "x86_64" ]; then
|
||||
echo "MMX/3DNOW/SSE/SSE2/SSE3. ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}/${CFG_SSE3}"
|
||||
echo "SSSE3/SSE4.1/SSE4.2..... ${CFG_SSSE3}/${CFG_SSE4_1}/${CFG_SSE4_2}"
|
||||
echo "AVX..................... ${CFG_AVX}"
|
||||
echo "SSE2/SSE3/SSSE3......... ${CFG_SSE2}/${CFG_SSE3}/${CFG_SSSE3}"
|
||||
echo "SSE4.1/SSE4.2........... ${CFG_SSSE3}/${CFG_SSE4_1}/${CFG_SSE4_2}"
|
||||
echo "AVX/AVX2................ ${CFG_AVX}/${CFG_AVX2}"
|
||||
elif [ "$CFG_ARCH" = "arm" ]; then
|
||||
echo "iWMMXt support ......... ${CFG_IWMMXT}"
|
||||
echo "NEON support ........... ${CFG_NEON}"
|
||||
@ -6317,7 +6239,7 @@ for file in .projects .projects.3; do
|
||||
fi
|
||||
SPEC=$XQMAKESPEC ;;
|
||||
*/qmake/qmake.pro) continue ;;
|
||||
*tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*|*tools/qdoc*) SPEC=$QMAKESPEC ;;
|
||||
*tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*|*tools/qdoc*|*tools/qdbusxml2cpp*|*tools/qdbuscpp2xml*) SPEC=$QMAKESPEC ;;
|
||||
*) if [ "$CFG_NOPROCESS" = "yes" ]; then
|
||||
continue
|
||||
else
|
||||
|
62
dist/changes-5.0.0
vendored
62
dist/changes-5.0.0
vendored
@ -36,6 +36,13 @@ information about a particular change.
|
||||
- QCoreApplication::translate() will no longer return the source text when
|
||||
the translation is empty. Use lrelease -removeidentical for optimization.
|
||||
|
||||
- QString and QByteArray constructors that take a size argument will now treat
|
||||
negative sizes to indicate nul-terminated strings (a nul-terminated array of
|
||||
QChar, in the case of QString). In Qt 4, negative sizes were ignored and
|
||||
result in empty QString and QByteArray, respectively. The size argument to
|
||||
those constructors now has a default value of -1, thus replacing the separate
|
||||
constructors that did the same.
|
||||
|
||||
- Qt::escape() is deprecated (but can be enabled via
|
||||
QT_DISABLE_DEPRECATED_BEFORE), use QString::toHtmlEscaped() instead.
|
||||
|
||||
@ -51,6 +58,16 @@ information about a particular change.
|
||||
* QMetaType::construct() has been renamed to QMetaType::create().
|
||||
* QMetaType::unregisterType() has been removed.
|
||||
|
||||
- QMetaMethod:
|
||||
* QMetaMethod::signature() has been renamed to QMetaMethod::methodSignature(),
|
||||
and the return type has been changed to QByteArray. This was done to be able
|
||||
to generate the signature string on demand, rather than always storing it in
|
||||
the meta-data.
|
||||
* QMetaMethod::typeName() no longer returns an empty string when the return
|
||||
type is void; it returns "void". The recommended way of checking whether a
|
||||
method returns void is to compare the return value of QMetaMethod::returnType()
|
||||
to QMetaType::Void.
|
||||
|
||||
- QTestLib:
|
||||
* The plain-text, xml and lightxml test output formats have been changed to
|
||||
show a test result for every row of test data in data-driven tests. In
|
||||
@ -231,9 +248,17 @@ information about a particular change.
|
||||
|
||||
- QSqlQueryModel::indexInQuery() is now virtual. See note below under QtSql.
|
||||
|
||||
- QSqlDriver::subscribeToNotification, unsubscribeFromNotification,
|
||||
subscribedToNotifications, isIdentifierEscaped, and stripDelimiters
|
||||
are now virtual. See note below under QtSql.
|
||||
|
||||
- qMacVersion() has been removed. Use QSysInfo::macVersion() or
|
||||
QSysInfo::MacintoshVersion instead.
|
||||
|
||||
- QColorDialog::customColor() now returns a QColor value instead of QRgb.
|
||||
QColorDialog::setCustomColor() and QColorDialog::setStandardColor() now
|
||||
take a QColor value for their second parameter instead of QRgb.
|
||||
|
||||
****************************************************************************
|
||||
* General *
|
||||
****************************************************************************
|
||||
@ -325,6 +350,10 @@ QtCore
|
||||
* QEvent::AccessibilityPrepare, AccessibilityHelp and AccessibilityDescription removed:
|
||||
* The enum values simply didn't make sense in the first place and should simply be dropped.
|
||||
|
||||
* [QTBUG-23529] QHash is now more resilient to a family of denial of service
|
||||
attacks exploiting algorithmic complexity, by supporting two-arguments overloads
|
||||
of the qHash() hashing function.
|
||||
|
||||
QtGui
|
||||
-----
|
||||
* Accessibility has been refactored. The hierachy of accessible objects is implemented via
|
||||
@ -378,6 +407,11 @@ QtWidgets
|
||||
* ResizeMode resizeMode(int logicalindex) const -
|
||||
use sectionResizeMode(int logicalindex) instead.
|
||||
|
||||
* QDateEdit and QTimeEdit have re-gained a USER property. These were originally removed
|
||||
before Qt 4.7.0, and are re-added for 5.0. This means that the userProperty for
|
||||
those classes are now QDate and QTime respectively, not QDateTime as they have been
|
||||
for the 4.7 and 4.8 releases.
|
||||
|
||||
QtNetwork
|
||||
---------
|
||||
* QHostAddress::isLoopback() API added. Returns true if the address is
|
||||
@ -389,6 +423,14 @@ QtNetwork
|
||||
* The openssl network backend now reads the ssl configuration file allowing
|
||||
the use of openssl engines.
|
||||
|
||||
QtDBus
|
||||
------
|
||||
* QtDBus now generates property annotations for the Qt type names
|
||||
in the org.qtproject.QtDBus namespace. When parsing such annotations
|
||||
both the old and new namespaces are accepted.
|
||||
|
||||
* QtDBus error codes have been updated to be on the org.qtproject.QtDBus.Error
|
||||
namespace.
|
||||
|
||||
QtOpenGL
|
||||
--------
|
||||
@ -466,6 +508,12 @@ changes. insertRows() and insertRecord() also respect the edit strategy.
|
||||
|
||||
* QSqlTableModel::setData() and setRecord() in OnRowChange no longer have the
|
||||
side effect of submitting the cached row when invoked on a different row.
|
||||
|
||||
* QSqlDriver::subscribeToNotification, unsubscribeFromNotification,
|
||||
subscribedToNotifications, isIdentifierEscaped, and stripDelimiters
|
||||
are now virtual. Their xxxImplemenation counterparts have been removed
|
||||
now that QSqlDriver subclasses can reimplement these directly.
|
||||
|
||||
****************************************************************************
|
||||
* Database Drivers *
|
||||
****************************************************************************
|
||||
@ -580,6 +628,20 @@ Qt for Windows CE
|
||||
QMetaType::User, which means that it points to the first registered custom
|
||||
type, instead of a nonexistent type.
|
||||
|
||||
- QMetaType
|
||||
|
||||
* Interpretation of QMetaType::Void was changed. Before, in some cases
|
||||
it was returned as an invalid type id, but sometimes it was used as a valid
|
||||
type (C++ "void"). In Qt5, new QMetaType::UnknownType was introduced to
|
||||
distinguish between these two. QMetaType::UnknownType is an invalid type id
|
||||
signaling that a type is unknown to QMetaType, and QMetaType::Void
|
||||
is a valid type id of C++ void type. The difference will be visible for
|
||||
example in call to QMetaType::typeName(), this function will return null for
|
||||
QMetaType::UnknownType and a pointer to "void" string for
|
||||
QMetaType::Void.
|
||||
Please, notice that QMetaType::UnknownType has value 0, which previously was
|
||||
reserved for QMetaType::Void.
|
||||
|
||||
|
||||
- QMessageBox
|
||||
|
||||
|
@ -68,7 +68,7 @@ sock.connectToHost(url.host(), url.port(80));
|
||||
|
||||
|
||||
//! [4]
|
||||
http://www.example.com/cgi-bin/drawgraph.cgi?type-pie/color-green
|
||||
http://www.example.com/cgi-bin/drawgraph.cgi?type(pie)color(green)
|
||||
//! [4]
|
||||
|
||||
|
||||
|
@ -107,7 +107,7 @@ for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i)
|
||||
const QMetaObject* metaObject = obj->metaObject();
|
||||
QStringList methods;
|
||||
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
|
||||
methods << QString::fromLatin1(metaObject->method(i).signature());
|
||||
methods << QString::fromLatin1(metaObject->method(i).methodSignature());
|
||||
//! [methodCount]
|
||||
|
||||
//! [6]
|
||||
|
@ -73,7 +73,7 @@ MyStruct s2 = var.value<MyStruct>();
|
||||
|
||||
//! [3]
|
||||
int id = QMetaType::type("MyClass");
|
||||
if (id != 0) {
|
||||
if (id != QMetaType::UnknownType) {
|
||||
void *myClassPtr = QMetaType::create(id);
|
||||
...
|
||||
QMetaType::destroy(id, myClassPtr);
|
||||
|
@ -155,9 +155,9 @@ inline bool operator==(const Employee &e1, const Employee &e2)
|
||||
&& e1.dateOfBirth() == e2.dateOfBirth();
|
||||
}
|
||||
|
||||
inline uint qHash(const Employee &key)
|
||||
inline uint qHash(const Employee &key, uint seed)
|
||||
{
|
||||
return qHash(key.name()) ^ key.dateOfBirth().day();
|
||||
return qHash(key.name(), seed) ^ key.dateOfBirth().day();
|
||||
}
|
||||
|
||||
#endif // EMPLOYEE_H
|
||||
|
@ -1,48 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [0]
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
workspace = new QWorkspace;
|
||||
setCentralWidget(workspace);
|
||||
...
|
||||
}
|
||||
//! [0]
|
@ -314,6 +314,11 @@ void Widget::countFunction()
|
||||
QString str = "banana and panama";
|
||||
str.count(QRegExp("a[nm]a")); // returns 4
|
||||
//! [18]
|
||||
|
||||
//! [95]
|
||||
QString str = "banana and panama";
|
||||
str.count(QRegularExpression("a[nm]a")); // returns 4
|
||||
//! [95]
|
||||
}
|
||||
|
||||
void Widget::dataFunction()
|
||||
@ -384,6 +389,11 @@ void Widget::firstIndexOfFunction()
|
||||
QString str = "the minimum";
|
||||
str.indexOf(QRegExp("m[aeiou]"), 0); // returns 4
|
||||
//! [25]
|
||||
|
||||
//! [93]
|
||||
QString str = "the minimum";
|
||||
str.indexOf(QRegularExpression("m[aeiou]"), 0); // returns 4
|
||||
//! [93]
|
||||
}
|
||||
|
||||
void Widget::insertFunction()
|
||||
@ -429,6 +439,11 @@ void Widget::lastIndexOfFunction()
|
||||
QString str = "the minimum";
|
||||
str.lastIndexOf(QRegExp("m[aeiou]")); // returns 8
|
||||
//! [30]
|
||||
|
||||
//! [94]
|
||||
QString str = "the minimum";
|
||||
str.lastIndexOf(QRegularExpression("m[aeiou]")); // returns 8
|
||||
//! [94]
|
||||
}
|
||||
|
||||
void Widget::leftFunction()
|
||||
@ -499,6 +514,12 @@ void Widget::removeFunction()
|
||||
r.remove(QRegExp("[aeiou]."));
|
||||
// r == "The"
|
||||
//! [39]
|
||||
|
||||
//! [96]
|
||||
QString r = "Telephone";
|
||||
r.remove(QRegularExpression("[aeiou]."));
|
||||
// r == "The"
|
||||
//! [96]
|
||||
}
|
||||
|
||||
void Widget::replaceFunction()
|
||||
@ -533,6 +554,18 @@ void Widget::replaceFunction()
|
||||
equis.replace("xx", "x");
|
||||
// equis == "xxx"
|
||||
//! [86]
|
||||
|
||||
//! [87]
|
||||
QString s = "Banana";
|
||||
s.replace(QRegularExpression("a[mn]"), "ox");
|
||||
// s == "Boxoxa"
|
||||
//! [87]
|
||||
|
||||
//! [88]
|
||||
QString t = "A <i>bon mot</i>.";
|
||||
t.replace(QRegularExpression("<i>([^<]*)</i>"), "\\emph{\\1}");
|
||||
// t == "A \\emph{bon mot}."
|
||||
//! [88]
|
||||
}
|
||||
|
||||
void Widget::reserveFunction()
|
||||
@ -627,9 +660,16 @@ void Widget::sectionFunction()
|
||||
//! [55]
|
||||
QString line = "forename\tmiddlename surname \t \t phone";
|
||||
QRegExp sep("\\s+");
|
||||
str = line.section(sep, 2, 2); // s == "surname"
|
||||
str = line.section(sep, -3, -2); // s == "middlename surname"
|
||||
str = line.section(sep, 2, 2); // str == "surname"
|
||||
str = line.section(sep, -3, -2); // str == "middlename surname"
|
||||
//! [55]
|
||||
|
||||
//! [89]
|
||||
QString line = "forename\tmiddlename surname \t \t phone";
|
||||
QRegularExpression sep("\\s+");
|
||||
str = line.section(sep, 2, 2); // str == "surname"
|
||||
str = line.section(sep, -3, -2); // str == "middlename surname"
|
||||
//! [89]
|
||||
}
|
||||
|
||||
void Widget::setNumFunction()
|
||||
@ -682,6 +722,27 @@ void Widget::splitFunction()
|
||||
list = str.split(QRegExp("\\b"));
|
||||
// list: [ "", "Now", ": ", "this", " ", "sentence", " ", "fragment", "." ]
|
||||
//! [61]
|
||||
|
||||
//! [90]
|
||||
QString str;
|
||||
QStringList list;
|
||||
|
||||
str = "Some text\n\twith strange whitespace.";
|
||||
list = str.split(QRegularExpression("\\s+"));
|
||||
// list: [ "Some", "text", "with", "strange", "whitespace." ]
|
||||
//! [90]
|
||||
|
||||
//! [91]
|
||||
str = "This time, a normal English sentence.";
|
||||
list = str.split(QRegularExpression("\\W+"), QString::SkipEmptyParts);
|
||||
// list: [ "This", "time", "a", "normal", "English", "sentence" ]
|
||||
//! [91]
|
||||
|
||||
//! [92]
|
||||
str = "Now: this sentence fragment.";
|
||||
list = str.split(QRegularExpression("\\b"));
|
||||
// list: [ "", "Now", ": ", "this", " ", "sentence", " ", "fragment", "." ]
|
||||
//! [92]
|
||||
}
|
||||
|
||||
void Widget::splitCaseSensitiveFunction()
|
||||
|
@ -144,6 +144,21 @@ Widget::Widget(QWidget *parent)
|
||||
list.replaceInStrings(QRegExp("^(.*), (.*)$"), "\\2 \\1");
|
||||
// list == ["Bill Clinton", "Bill Murray"]
|
||||
//! [15]
|
||||
|
||||
list.clear();
|
||||
//! [16]
|
||||
list << "alpha" << "beta" << "gamma" << "epsilon";
|
||||
list.replaceInStrings(QRegularExpression("^a"), "o");
|
||||
// list == ["olpha", "beta", "gamma", "epsilon"]
|
||||
//! [16]
|
||||
|
||||
list.clear();
|
||||
//! [17]
|
||||
list << "Bill Clinton" << "Murray, Bill";
|
||||
list.replaceInStrings(QRegularExpression("^(.*), (.*)$"), "\\2 \\1");
|
||||
// list == ["Bill Clinton", "Bill Murray"]
|
||||
//! [17]
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -103,9 +103,9 @@ void Window::mouseMoveEvent(QMouseEvent *event)
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawLine(m_lastPos, event->pos());
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
scheduleRender();
|
||||
scheduleRender();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::mouseReleaseEvent(QMouseEvent *event)
|
||||
@ -115,9 +115,9 @@ void Window::mouseReleaseEvent(QMouseEvent *event)
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawLine(m_lastPos, event->pos());
|
||||
m_lastPos = QPoint(-1, -1);
|
||||
}
|
||||
|
||||
scheduleRender();
|
||||
scheduleRender();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::exposeEvent(QExposeEvent *)
|
||||
@ -139,8 +139,7 @@ void Window::resizeEvent(QResizeEvent *)
|
||||
QPainter p(&m_image);
|
||||
p.drawImage(0, 0, old);
|
||||
}
|
||||
|
||||
render();
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void Window::keyPressEvent(QKeyEvent *event)
|
||||
@ -168,7 +167,8 @@ void Window::scheduleRender()
|
||||
|
||||
void Window::timerEvent(QTimerEvent *)
|
||||
{
|
||||
render();
|
||||
if (isExposed())
|
||||
render();
|
||||
killTimer(m_renderTimer);
|
||||
m_renderTimer = 0;
|
||||
}
|
||||
|
@ -204,13 +204,11 @@ mac {
|
||||
}
|
||||
|
||||
#SIMD defines:
|
||||
mmx:DEFINES += QT_HAVE_MMX
|
||||
3dnow:DEFINES += QT_HAVE_3DNOW
|
||||
sse:DEFINES += QT_HAVE_SSE QT_HAVE_MMXEXT
|
||||
sse2:DEFINES += QT_HAVE_SSE2
|
||||
sse3:DEFINES += QT_HAVE_SSE3
|
||||
ssse3:DEFINES += QT_HAVE_SSSE3
|
||||
sse4_1:DEFINES += QT_HAVE_SSE4_1
|
||||
sse4_2:DEFINES += QT_HAVE_SSE4_2
|
||||
avx:DEFINES += QT_HAVE_AVX
|
||||
avx2:DEFINES += QT_HAVE_AVX2
|
||||
iwmmxt:DEFINES += QT_HAVE_IWMMXT
|
||||
|
@ -15,4 +15,4 @@ contains(QT_CONFIG, separate_debug_info_nocopy):CONFIG += separate_debug_info_no
|
||||
load(qt_targets)
|
||||
|
||||
wince*:LIBS += $$QMAKE_LIBS_GUI
|
||||
|
||||
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
|
||||
|
@ -16,14 +16,14 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \
|
||||
gbuild.o
|
||||
|
||||
#qt code
|
||||
QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
|
||||
qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \
|
||||
QOBJS=qtextcodec.o qutfcodec.o qstring.o qstringbuilder.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
|
||||
qarraydata.o qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \
|
||||
qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o qfilesystemiterator_unix.o \
|
||||
qfsfileengine_unix.o qfsfileengine.o \
|
||||
qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \
|
||||
qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \
|
||||
qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o qvariant.o qvsnprintf.o \
|
||||
qlocale.o qlocale_tools.o qlocale_unix.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o \
|
||||
qlocale.o qlocale_tools.o qlocale_unix.o qlinkedlist.o qnumeric.o qcryptographichash.o \
|
||||
qxmlstream.o qxmlutils.o qlogging.o \
|
||||
$(QTOBJS)
|
||||
|
||||
@ -39,10 +39,12 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
|
||||
generators/integrity/gbuild.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/global/qglobal.cpp $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp\
|
||||
$(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qdatastream.cpp $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qfilesystemengine_mac.cpp \
|
||||
@ -55,7 +57,8 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
|
||||
$(SOURCE_PATH)/src/corelib/io/qdir.cpp $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp $(SOURCE_PATH)/src/corelib/tools/qmap.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/global/qconfig.cpp $(SOURCE_PATH)/src/corelib/io/qurl.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/global/qconfig.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qlocale.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qlocale_unix.cpp \
|
||||
@ -78,7 +81,7 @@ CPPFLAGS = -g -I$(QMKSRC) -I$(QMKSRC)/generators -I$(QMKSRC)/generators/unix -I$
|
||||
-I$(BUILD_PATH)/src/corelib/global \
|
||||
-I$(SOURCE_PATH)/tools/shared \
|
||||
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT \
|
||||
-DQT_NO_COMPRESS -I$(QMAKESPEC) -DHAVE_QCONFIG_CPP -DQT_NO_THREAD -DQT_NO_QOBJECT \
|
||||
-DQT_NO_GEOM_VARIANT -DQT_NO_DEPRECATED $(OPENSOURCE_CXXFLAGS)
|
||||
|
||||
@ -197,6 +200,9 @@ qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
|
||||
qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
|
||||
|
||||
qarraydata.o: $(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp
|
||||
|
||||
qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
|
||||
|
||||
@ -212,9 +218,6 @@ qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
|
||||
qcore_mac.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp
|
||||
|
||||
qurl.o: $(SOURCE_PATH)/src/corelib/io/qurl.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qurl.cpp
|
||||
|
||||
qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
|
||||
|
||||
@ -224,6 +227,9 @@ qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
|
||||
qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
|
||||
|
||||
qstringbuilder.o: $(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp
|
||||
|
||||
qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
|
||||
|
||||
@ -245,6 +251,9 @@ qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
|
||||
qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
|
||||
|
||||
qfiledevice.o: $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp
|
||||
|
||||
qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
|
||||
|
||||
|
@ -38,7 +38,7 @@ CFLAGS_BARE = -c -Fo./ \
|
||||
-I$(BUILD_PATH)\src\corelib\global \
|
||||
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
|
||||
-I$(SOURCE_PATH)\tools\shared \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL \
|
||||
-DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \
|
||||
-DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_BOOTSTRAPPED
|
||||
CFLAGS = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS)
|
||||
@ -78,12 +78,14 @@ QTOBJS= \
|
||||
qfilesystemiterator_win.obj \
|
||||
qfsfileengine.obj \
|
||||
qfsfileengine_iterator.obj \
|
||||
qarraydata.obj \
|
||||
qbytearray.obj \
|
||||
qvsnprintf.obj \
|
||||
qbytearraymatcher.obj \
|
||||
qdatetime.obj \
|
||||
qdir.obj \
|
||||
qdiriterator.obj \
|
||||
qfiledevice.obj \
|
||||
qfile.obj \
|
||||
qtemporaryfile.obj \
|
||||
qabstractfileengine.obj \
|
||||
@ -105,6 +107,7 @@ QTOBJS= \
|
||||
qutfcodec.obj \
|
||||
qstring.obj \
|
||||
qstringlist.obj \
|
||||
qstringbuilder.obj \
|
||||
qsystemerror.obj \
|
||||
qtextstream.obj \
|
||||
qdatastream.obj \
|
||||
@ -113,7 +116,6 @@ QTOBJS= \
|
||||
qsettings.obj \
|
||||
qlibraryinfo.obj \
|
||||
qvariant.obj \
|
||||
qurl.obj \
|
||||
qsettings_win.obj \
|
||||
qmetatype.obj \
|
||||
qxmlstream.obj \
|
||||
|
@ -49,7 +49,7 @@ CFLAGS = -c -o$@ -O \
|
||||
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
|
||||
-I$(SOURCE_PATH)/tools/shared \
|
||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT \
|
||||
-DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \
|
||||
-DQT_NODLL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \
|
||||
-DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
|
||||
-DQT_BOOTSTRAPPED
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
@ -74,6 +74,7 @@ endif
|
||||
QTOBJS= \
|
||||
qbitarray.o \
|
||||
qbuffer.o \
|
||||
qarraydata.o \
|
||||
qbytearray.o \
|
||||
qcryptographichash.o \
|
||||
qvsnprintf.o \
|
||||
@ -82,6 +83,7 @@ QTOBJS= \
|
||||
qdatetime.o \
|
||||
qdir.o \
|
||||
qdiriterator.o \
|
||||
qfiledevice.o \
|
||||
qfile.o \
|
||||
qtemporaryfile.o \
|
||||
qfileinfo.o \
|
||||
@ -109,12 +111,12 @@ QTOBJS= \
|
||||
qutfcodec.o \
|
||||
qstring.o \
|
||||
qstringlist.o \
|
||||
qstringbuilder.o \
|
||||
qsystemerror.o \
|
||||
qsystemlibrary.o \
|
||||
qtextstream.o \
|
||||
quuid.o \
|
||||
qvector.o \
|
||||
qurl.o \
|
||||
qsettings.o \
|
||||
qsettings_win.o \
|
||||
qvariant.o \
|
||||
|
@ -1928,7 +1928,7 @@ ProjectBuilderMakefileGenerator::writeSettings(QString var, QStringList vals, in
|
||||
{
|
||||
QString ret;
|
||||
const QString quote = (flags & SettingsNoQuote) ? "" : "\"";
|
||||
const QString escape_quote = quote.isEmpty() ? "" : "\\" + quote;
|
||||
const QString escape_quote = quote.isEmpty() ? "" : QString("\\" + quote);
|
||||
QString newline = "\n";
|
||||
for(int i = 0; i < indent_level; ++i)
|
||||
newline += "\t";
|
||||
|
@ -1026,7 +1026,7 @@ QMakeProject::parse(const QString &t, QHash<QString, QStringList> &place, int nu
|
||||
debug_msg(1, "Project Parser: %s:%d : Entering block %d (%d). [%s]", parser.file.toLatin1().constData(),
|
||||
parser.line_no, scope_blocks.count(), scope_failed, s.toLatin1().constData());
|
||||
} else if(iterator) {
|
||||
iterator->parselist.append(var+s.mid(d_off));
|
||||
iterator->parselist.append(QString(var+s.mid(d_off)));
|
||||
bool ret = iterator->exec(this, place);
|
||||
delete iterator;
|
||||
return ret;
|
||||
|
@ -1,7 +1,7 @@
|
||||
CONFIG += depend_includepath
|
||||
|
||||
SKIP_DEPENDS += qconfig.h qmodules.h
|
||||
DEFINES += QT_NO_TEXTCODEC QT_NO_LIBRARY QT_NO_STL QT_NO_COMPRESS QT_NO_UNICODETABLES \
|
||||
DEFINES += QT_NO_TEXTCODEC QT_NO_LIBRARY QT_NO_COMPRESS QT_NO_UNICODETABLES \
|
||||
QT_NO_GEOM_VARIANT QT_NO_DATASTREAM
|
||||
|
||||
#qmake code
|
||||
@ -35,12 +35,14 @@ bootstrap { #Qt code
|
||||
SOURCES+= \
|
||||
qbitarray.cpp \
|
||||
qbuffer.cpp \
|
||||
qarraydata.cpp \
|
||||
qbytearray.cpp \
|
||||
qbytearraymatcher.cpp \
|
||||
qcryptographichash.cpp \
|
||||
qdatetime.cpp \
|
||||
qdir.cpp \
|
||||
qdiriterator.cpp \
|
||||
qfiledevice.cpp \
|
||||
qfile.cpp \
|
||||
qabstractfileengine.cpp \
|
||||
qfileinfo.cpp \
|
||||
@ -66,7 +68,6 @@ bootstrap { #Qt code
|
||||
qstringlist.cpp \
|
||||
qtemporaryfile.cpp \
|
||||
qtextstream.cpp \
|
||||
qurl.cpp \
|
||||
quuid.cpp \
|
||||
qsettings.cpp \
|
||||
qlibraryinfo.cpp \
|
||||
@ -81,7 +82,10 @@ bootstrap { #Qt code
|
||||
HEADERS+= \
|
||||
qbitarray.h \
|
||||
qbuffer.h \
|
||||
qarraydata.h \
|
||||
qbytearray.h \
|
||||
qarraydataops.h \
|
||||
qarraydatapointer.h \
|
||||
qbytearraymatcher.h \
|
||||
qchar.h \
|
||||
qcryptographichash.h \
|
||||
@ -113,7 +117,6 @@ bootstrap { #Qt code
|
||||
qsystemerror_p.h \
|
||||
qtemporaryfile.h \
|
||||
qtextstream.h \
|
||||
qurl.h \
|
||||
quuid.h \
|
||||
qvector.h \
|
||||
qxmlstream.h \
|
||||
|
@ -41,6 +41,11 @@
|
||||
|
||||
#ifndef QMAKE_PCH_H
|
||||
#define QMAKE_PCH_H
|
||||
// for rand_s, _CRT_RAND_S must be #defined before #including stdlib.h.
|
||||
// put it at the beginning so some indirect inclusion doesn't break it
|
||||
#ifndef _CRT_RAND_S
|
||||
#define _CRT_RAND_S
|
||||
#endif
|
||||
#include <qglobal.h>
|
||||
#ifdef Q_OS_WIN
|
||||
# define _POSIX_
|
||||
|
@ -50,9 +50,7 @@
|
||||
#include <QtConcurrent/qtconcurrentmedian.h>
|
||||
#include <QtConcurrent/qtconcurrentthreadengine.h>
|
||||
|
||||
#ifndef QT_NO_STL
|
||||
# include <iterator>
|
||||
#endif
|
||||
#include <iterator>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -62,15 +60,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtConcurrent {
|
||||
|
||||
#ifndef QT_NO_STL
|
||||
using std::advance;
|
||||
#else
|
||||
template <typename It, typename T>
|
||||
void advance(It &it, T value)
|
||||
{
|
||||
it+=value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
The BlockSizeManager class manages how many iterations a thread should
|
||||
@ -149,7 +139,6 @@ public:
|
||||
inline void * getPointer() { return 0; }
|
||||
};
|
||||
|
||||
#ifndef QT_NO_STL
|
||||
inline bool selectIteration(std::bidirectional_iterator_tag)
|
||||
{
|
||||
return false; // while
|
||||
@ -164,14 +153,6 @@ inline bool selectIteration(std::random_access_iterator_tag)
|
||||
{
|
||||
return true; // for
|
||||
}
|
||||
#else
|
||||
// no stl support, always use while iteration
|
||||
template <typename T>
|
||||
inline bool selectIteration(T)
|
||||
{
|
||||
return false; // while
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Iterator, typename T>
|
||||
class IterateKernel : public ThreadEngine<T>
|
||||
@ -180,20 +161,10 @@ public:
|
||||
typedef T ResultType;
|
||||
|
||||
IterateKernel(Iterator _begin, Iterator _end)
|
||||
#if defined (QT_NO_STL)
|
||||
: begin(_begin), end(_end), current(_begin), currentIndex(0),
|
||||
forIteration(false), progressReportingEnabled(true)
|
||||
#else
|
||||
: begin(_begin), end(_end), current(_begin), currentIndex(0),
|
||||
forIteration(selectIteration(typename std::iterator_traits<Iterator>::iterator_category())), progressReportingEnabled(true)
|
||||
#endif
|
||||
{
|
||||
#if defined (QT_NO_STL)
|
||||
iterationCount = 0;
|
||||
#else
|
||||
iterationCount = forIteration ? std::distance(_begin, _end) : 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~IterateKernel() { }
|
||||
|
@ -9,14 +9,13 @@ HEADERS += \
|
||||
arch/qatomic_armv7.h \
|
||||
arch/qatomic_bfin.h \
|
||||
arch/qatomic_bootstrap.h \
|
||||
arch/qatomic_i386.h \
|
||||
arch/qatomic_ia64.h \
|
||||
arch/qatomic_mips.h \
|
||||
arch/qatomic_power.h \
|
||||
arch/qatomic_s390.h \
|
||||
arch/qatomic_sh4a.h \
|
||||
arch/qatomic_sparc.h \
|
||||
arch/qatomic_x86_64.h \
|
||||
arch/qatomic_x86.h \
|
||||
arch/qatomic_gcc.h \
|
||||
arch/qatomic_cxx11.h
|
||||
|
||||
|
@ -1,358 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QATOMIC_I386_H
|
||||
#define QATOMIC_I386_H
|
||||
|
||||
#include <QtCore/qgenericatomic.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if 0
|
||||
// silence syncqt warnings
|
||||
QT_END_NAMESPACE
|
||||
QT_END_HEADER
|
||||
|
||||
#pragma qt_sync_stop_processing
|
||||
#endif
|
||||
|
||||
template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
|
||||
|
||||
#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT32_IS_SUPPORTED
|
||||
|
||||
#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
|
||||
|
||||
template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> >
|
||||
{
|
||||
static inline bool isReferenceCountingNative() { return true; }
|
||||
static inline bool isReferenceCountingWaitFree() { return true; }
|
||||
template <typename T> static bool ref(T &_q_value);
|
||||
template <typename T> static bool deref(T &_q_value);
|
||||
|
||||
static inline bool isTestAndSetNative() { return true; }
|
||||
static inline bool isTestAndSetWaitFree() { return true; }
|
||||
template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue);
|
||||
|
||||
static inline bool isFetchAndStoreNative() { return true; }
|
||||
static inline bool isFetchAndStoreWaitFree() { return true; }
|
||||
template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue);
|
||||
|
||||
static inline bool isFetchAndAddNative() { return true; }
|
||||
static inline bool isFetchAndAddWaitFree() { return true; }
|
||||
template <typename T> static
|
||||
T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd);
|
||||
};
|
||||
|
||||
template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)>
|
||||
{
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
#if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
|
||||
|
||||
template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
|
||||
|
||||
template<> template<typename T> inline
|
||||
bool QBasicAtomicOps<1>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incb %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template<typename T> inline
|
||||
bool QBasicAtomicOps<2>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incw %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template<typename T> inline
|
||||
bool QBasicAtomicOps<4>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incl %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
bool QBasicAtomicOps<1>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decb %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
bool QBasicAtomicOps<2>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decw %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
bool QBasicAtomicOps<4>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decl %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<int size> template <typename T> inline
|
||||
bool QBasicAtomicOps<size>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"cmpxchg %3,%2\n"
|
||||
"sete %1\n"
|
||||
: "=a" (newValue), "=qm" (ret), "+m" (_q_value)
|
||||
: "r" (newValue), "0" (expectedValue)
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"cmpxchg %3,%2\n"
|
||||
"sete %1\n"
|
||||
: "=a" (newValue), "=qm" (ret), "+m" (_q_value)
|
||||
: "q" (newValue), "0" (expectedValue)
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<int size> template <typename T> inline
|
||||
T QBasicAtomicOps<size>::fetchAndStoreRelaxed(T &_q_value, T newValue)
|
||||
{
|
||||
asm volatile("xchg %0,%1"
|
||||
: "=r" (newValue), "+m" (_q_value)
|
||||
: "0" (newValue)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue)
|
||||
{
|
||||
asm volatile("xchg %0,%1"
|
||||
: "=q" (newValue), "+m" (_q_value)
|
||||
: "0" (newValue)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
template<int size> template <typename T> inline
|
||||
T QBasicAtomicOps<size>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd)
|
||||
{
|
||||
T result;
|
||||
asm volatile("lock\n"
|
||||
"xadd %0,%1"
|
||||
: "=r" (result), "+m" (_q_value)
|
||||
: "0" (T(valueToAdd * QAtomicAdditiveType<T>::AddScale))
|
||||
: "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd)
|
||||
{
|
||||
T result;
|
||||
asm volatile("lock\n"
|
||||
"xadd %0,%1"
|
||||
: "=q" (result), "+m" (_q_value)
|
||||
: "0" (T(valueToAdd * QAtomicAdditiveType<T>::AddScale))
|
||||
: "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
#define Q_ATOMIC_INT8_IS_SUPPORTED
|
||||
|
||||
#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT8_TEST_AND_SET_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT16_IS_SUPPORTED
|
||||
|
||||
#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE
|
||||
|
||||
template <> struct QBasicAtomicOps<8>: QGenericAtomicOps<QBasicAtomicOps<8> >
|
||||
{
|
||||
static inline bool isTestAndSetNative() { return true; }
|
||||
static inline bool isTestAndSetWaitFree() { return true; }
|
||||
template <typename T> static inline
|
||||
bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue)
|
||||
{
|
||||
#ifdef __PIC__
|
||||
# define EBX_reg "r"
|
||||
# define EBX_load(reg) "xchg " reg ", %%ebx\n"
|
||||
#else
|
||||
# define EBX_reg "b"
|
||||
# define EBX_load(reg)
|
||||
#endif
|
||||
unsigned char ret;
|
||||
asm volatile(EBX_load("%3")
|
||||
"lock\n"
|
||||
"cmpxchg8b %0\n"
|
||||
EBX_load("%3")
|
||||
"sete %1\n"
|
||||
: "+m" (_q_value), "=qm" (ret),
|
||||
"+A" (expectedValue)
|
||||
: EBX_reg (quint32(newValue & 0xffffffff)), "c" (quint32(newValue >> 32))
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
#undef EBX_reg
|
||||
#undef EBX_load
|
||||
}
|
||||
};
|
||||
#define Q_ATOMIC_INT64_IS_SUPPORTED
|
||||
|
||||
#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NOT_NATIVE
|
||||
|
||||
#define Q_ATOMIC_INT64_TEST_AND_SET_IS_NOT_NATIVE
|
||||
#define Q_ATOMIC_INT64_TEST_AND_SET_IS_WAIT_FREE
|
||||
|
||||
#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NATIVE
|
||||
|
||||
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NOT_NATIVE
|
||||
|
||||
#else
|
||||
# error "This compiler for i386 is not supported"
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QATOMIC_I386_H
|
@ -40,8 +40,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QATOMIC_X86_64_H
|
||||
#define QATOMIC_X86_64_H
|
||||
#ifndef QATOMIC_X86_H
|
||||
#define QATOMIC_X86_H
|
||||
|
||||
#include <QtCore/qgenericatomic.h>
|
||||
|
||||
@ -121,7 +121,7 @@ template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)>
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
#if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
|
||||
#if defined(Q_CC_GNU)
|
||||
|
||||
template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; };
|
||||
@ -133,12 +133,40 @@ template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 };
|
||||
template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
|
||||
template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
|
||||
|
||||
/*
|
||||
* Guide for the inline assembly below:
|
||||
*
|
||||
* x86 instructions are in the form "{opcode}{length} {source}, {destination}",
|
||||
* where the length is one of the letters "b" (byte), "w" (word, 16-bit), "l"
|
||||
* (dword, 32-bit), "q" (qword, 64-bit).
|
||||
*
|
||||
* In most cases, we can omit the length because it's inferred from one of the
|
||||
* registers. For example, "xchg %0,%1" doesn't need the length suffix because
|
||||
* we can only exchange data of the same size and one of the operands must be a
|
||||
* register.
|
||||
*
|
||||
* The exception is the increment and decrement functions, where we add and
|
||||
* subtract an immediate value (1). For those, we need to specify the length.
|
||||
* GCC and ICC support the syntax "add%z0 $1, %0", where "%z0" expands to the
|
||||
* length of the operand. Unfortunately, clang as of 3.0 doesn't support that.
|
||||
* For that reason, the ref() and deref() functions are rolled out for all
|
||||
* sizes.
|
||||
*
|
||||
* The functions are also rolled out for the 1-byte operations since those
|
||||
* require a special register constraint "q" to force the compiler to schedule
|
||||
* one of the 8-bit registers. It's probably a compiler bug that it tries to
|
||||
* use a register that doesn't exist.
|
||||
*
|
||||
* Finally, 64-bit operations are supported via the cmpxchg8b instruction on
|
||||
* 32-bit processors, via specialisation below.
|
||||
*/
|
||||
|
||||
template<> template<typename T> inline
|
||||
bool QBasicAtomicOps<1>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incb %0\n"
|
||||
"addb $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
@ -164,20 +192,7 @@ bool QBasicAtomicOps<4>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incl %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template<typename T> inline
|
||||
bool QBasicAtomicOps<8>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incq %0\n"
|
||||
"addl $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
@ -190,7 +205,7 @@ bool QBasicAtomicOps<1>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decb %0\n"
|
||||
"subb $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
@ -215,20 +230,7 @@ bool QBasicAtomicOps<4>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decl %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
bool QBasicAtomicOps<8>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decq %0\n"
|
||||
"subl $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
@ -348,12 +350,73 @@ T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy
|
||||
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
|
||||
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE
|
||||
|
||||
#else // !Q_CC_INTEL && !Q_CC_GNU
|
||||
# error "This compiler for x86_64 is not supported"
|
||||
#endif // Q_CC_GNU || Q_CC_INTEL
|
||||
#ifdef Q_PROCESSOR_X86_64
|
||||
// native support for 64-bit types
|
||||
template<> template<typename T> inline
|
||||
bool QBasicAtomicOps<8>::ref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"addq $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
template<> template <typename T> inline
|
||||
bool QBasicAtomicOps<8>::deref(T &_q_value)
|
||||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"subq $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
}
|
||||
#else
|
||||
// i386 architecture, emulate 64-bit support via cmpxchg8b
|
||||
template <> struct QBasicAtomicOps<8>: QGenericAtomicOps<QBasicAtomicOps<8> >
|
||||
{
|
||||
static inline bool isTestAndSetNative() { return true; }
|
||||
static inline bool isTestAndSetWaitFree() { return true; }
|
||||
template <typename T> static inline
|
||||
bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue)
|
||||
{
|
||||
#ifdef __PIC__
|
||||
# define EBX_reg "r"
|
||||
# define EBX_load(reg) "xchg " reg ", %%ebx\n"
|
||||
#else
|
||||
# define EBX_reg "b"
|
||||
# define EBX_load(reg)
|
||||
#endif
|
||||
quint32 highExpectedValue = quint32(newValue >> 32); // ECX
|
||||
asm volatile(EBX_load("%3")
|
||||
"lock\n"
|
||||
"cmpxchg8b %0\n"
|
||||
EBX_load("%3")
|
||||
"sete %%cl\n"
|
||||
: "+m" (_q_value), "+c" (highExpectedValue), "+&A" (expectedValue)
|
||||
: EBX_reg (quint32(newValue & 0xffffffff))
|
||||
: "memory");
|
||||
// if the comparison failed, expectedValue here contains the current value
|
||||
return quint8(highExpectedValue) != 0;
|
||||
#undef EBX_reg
|
||||
#undef EBX_load
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#else
|
||||
# error "This compiler for x86 is not supported"
|
||||
#endif
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QATOMIC_X86_64_H
|
||||
#endif // QATOMIC_X86_H
|
@ -102,6 +102,10 @@
|
||||
# undef QT_HAVE_3DNOW
|
||||
# endif
|
||||
|
||||
# if defined(Q_CC_MSVC) && _MSC_VER >= 1400
|
||||
# define Q_COMPILER_VARIADIC_MACROS
|
||||
# endif
|
||||
|
||||
#if defined(Q_CC_MSVC) && _MSC_VER >= 1600
|
||||
# define Q_COMPILER_RVALUE_REFS
|
||||
# define Q_COMPILER_AUTO_TYPE
|
||||
|
@ -159,9 +159,6 @@
|
||||
#ifndef QT_NO_DATETIMEEDIT
|
||||
# define QT_NO_DATETIMEEDIT
|
||||
#endif
|
||||
#ifndef QT_NO_WORKSPACE
|
||||
# define QT_NO_WORKSPACE
|
||||
#endif
|
||||
#ifndef QT_NO_DIAL
|
||||
# define QT_NO_DIAL
|
||||
#endif
|
||||
|
@ -242,9 +242,6 @@
|
||||
#ifndef QT_NO_MENUBAR
|
||||
# define QT_NO_MENUBAR
|
||||
#endif
|
||||
#ifndef QT_NO_WORKSPACE
|
||||
# define QT_NO_WORKSPACE
|
||||
#endif
|
||||
#ifndef QT_NO_PROGRESSBAR
|
||||
# define QT_NO_PROGRESSBAR
|
||||
#endif
|
||||
|
@ -43,9 +43,6 @@
|
||||
#ifndef QT_NO_QUUID_STRING
|
||||
# define QT_NO_QUUID_STRING
|
||||
#endif
|
||||
#ifndef QT_NO_STL
|
||||
# define QT_NO_STL
|
||||
#endif
|
||||
#ifndef QT_NO_TEXTDATE
|
||||
# define QT_NO_TEXTDATE
|
||||
#endif
|
||||
@ -494,9 +491,6 @@
|
||||
#ifndef QT_NO_MENUBAR
|
||||
# define QT_NO_MENUBAR
|
||||
#endif
|
||||
#ifndef QT_NO_WORKSPACE
|
||||
# define QT_NO_WORKSPACE
|
||||
#endif
|
||||
#ifndef QT_NO_PROGRESSBAR
|
||||
# define QT_NO_PROGRESSBAR
|
||||
#endif
|
||||
|
@ -45,9 +45,6 @@
|
||||
#ifndef QT_NO_QUUID_STRING
|
||||
# define QT_NO_QUUID_STRING
|
||||
#endif
|
||||
#ifndef QT_NO_STL
|
||||
# define QT_NO_STL
|
||||
#endif
|
||||
#ifndef QT_NO_TEXTDATE
|
||||
# define QT_NO_TEXTDATE
|
||||
#endif
|
||||
|
@ -43,9 +43,6 @@
|
||||
#ifndef QT_NO_QUUID_STRING
|
||||
# define QT_NO_QUUID_STRING
|
||||
#endif
|
||||
#ifndef QT_NO_STL
|
||||
# define QT_NO_STL
|
||||
#endif
|
||||
|
||||
/* Dialogs */
|
||||
#ifndef QT_NO_COLORDIALOG
|
||||
@ -282,9 +279,6 @@
|
||||
#ifndef QT_NO_MENUBAR
|
||||
# define QT_NO_MENUBAR
|
||||
#endif
|
||||
#ifndef QT_NO_WORKSPACE
|
||||
# define QT_NO_WORKSPACE
|
||||
#endif
|
||||
#ifndef QT_NO_PROGRESSBAR
|
||||
# define QT_NO_PROGRESSBAR
|
||||
#endif
|
||||
|
@ -79,7 +79,7 @@ template <typename T> inline void qbswap(const T src, uchar *dest)
|
||||
// If you want to avoid the memcopy, you must write specializations for this function
|
||||
template <typename T> inline void qToUnaligned(const T src, uchar *dest)
|
||||
{
|
||||
qMemCopy(dest, &src, sizeof(T));
|
||||
memcpy(dest, &src, sizeof(T));
|
||||
}
|
||||
|
||||
/* T qFromLittleEndian(const uchar *src)
|
||||
@ -171,6 +171,11 @@ template <> inline qint16 qFromLittleEndian<qint16>(const uchar *src)
|
||||
{ return static_cast<qint16>(qFromLittleEndian<quint16>(src)); }
|
||||
#endif
|
||||
|
||||
template <> inline quint8 qFromLittleEndian<quint8>(const uchar *src)
|
||||
{ return static_cast<quint8>(src[0]); }
|
||||
template <> inline qint8 qFromLittleEndian<qint8>(const uchar *src)
|
||||
{ return static_cast<qint8>(src[0]); }
|
||||
|
||||
/* This function will read a big-endian (also known as network order) encoded value from \a src
|
||||
* and return the value in host-endian encoding.
|
||||
* There is no requirement that \a src must be aligned.
|
||||
@ -263,6 +268,12 @@ template <> inline qint32 qFromBigEndian<qint32>(const uchar *src)
|
||||
template <> inline qint16 qFromBigEndian<qint16>(const uchar *src)
|
||||
{ return static_cast<qint16>(qFromBigEndian<quint16>(src)); }
|
||||
#endif
|
||||
|
||||
template <> inline quint8 qFromBigEndian<quint8>(const uchar *src)
|
||||
{ return static_cast<quint8>(src[0]); }
|
||||
template <> inline qint8 qFromBigEndian<qint8>(const uchar *src)
|
||||
{ return static_cast<qint8>(src[0]); }
|
||||
|
||||
/*
|
||||
* T qbswap(T source).
|
||||
* Changes the byte order of a value from big endian to little endian or vice versa.
|
||||
@ -367,6 +378,11 @@ template <> inline quint8 qbswap<quint8>(quint8 source)
|
||||
return source;
|
||||
}
|
||||
|
||||
template <> inline qint8 qbswap<qint8>(qint8 source)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
@ -208,9 +208,6 @@
|
||||
// Status Tip
|
||||
//#define QT_NO_STATUSTIP
|
||||
|
||||
// Standard Template Library
|
||||
//#define QT_NO_STL
|
||||
|
||||
// QMotifStyle
|
||||
//#define QT_NO_STYLE_MOTIF
|
||||
|
||||
@ -487,11 +484,6 @@
|
||||
#define QT_NO_STYLE_STYLESHEET
|
||||
#endif
|
||||
|
||||
// Q3TabDialog
|
||||
#if !defined(QT_NO_TABDIALOG) && (defined(QT_NO_TABBAR))
|
||||
#define QT_NO_TABDIALOG
|
||||
#endif
|
||||
|
||||
// QColorDialog
|
||||
#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_SPINBOX))
|
||||
#define QT_NO_COLORDIALOG
|
||||
@ -662,11 +654,6 @@
|
||||
#define QT_NO_PRINTPREVIEWWIDGET
|
||||
#endif
|
||||
|
||||
// QWorkSpace
|
||||
#if !defined(QT_NO_WORKSPACE) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_MAINWINDOW) || defined(QT_NO_MENUBAR))
|
||||
#define QT_NO_WORKSPACE
|
||||
#endif
|
||||
|
||||
// QCalendarWidget
|
||||
#if !defined(QT_NO_CALENDARWIDGET) && (defined(QT_NO_TABLEVIEW) || defined(QT_NO_MENU) || defined(QT_NO_TEXTDATE) || defined(QT_NO_SPINBOX) || defined(QT_NO_TOOLBUTTON))
|
||||
#define QT_NO_CALENDARWIDGET
|
||||
|
@ -407,13 +407,6 @@ Requires: RUBBERBAND MAINWINDOW
|
||||
Name: QDockwidget
|
||||
SeeAlso: ???
|
||||
|
||||
Feature: WORKSPACE
|
||||
Description: Supports workspace windows, e.g. used in an MDI application.
|
||||
Section: Widgets
|
||||
Requires: SCROLLBAR MAINWINDOW MENUBAR
|
||||
Name: QWorkSpace
|
||||
SeeAlso: ???
|
||||
|
||||
Feature: MDIAREA
|
||||
Description: Provides an area in which MDI windows are displayed.
|
||||
Section: Widgets
|
||||
@ -644,13 +637,6 @@ Requires: COMBOBOX SPINBOX STACKEDWIDGET
|
||||
Name: QInputDialog
|
||||
SeeAlso: ???
|
||||
|
||||
Feature: TABDIALOG
|
||||
Description: Supports a stack of tabbed widgets.
|
||||
Section: Dialogs
|
||||
Requires: TABBAR
|
||||
Name: Q3TabDialog
|
||||
SeeAlso: ???
|
||||
|
||||
Feature: ERRORMESSAGE
|
||||
Description: Supports an error message display dialog.
|
||||
Section: Dialogs
|
||||
|
@ -1968,13 +1968,6 @@ Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n)
|
||||
return p;
|
||||
}
|
||||
|
||||
#if defined(qMemCopy)
|
||||
# undef qMemCopy
|
||||
#endif
|
||||
#if defined(qMemSet)
|
||||
# undef qMemSet
|
||||
#endif
|
||||
|
||||
void *qMemCopy(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); }
|
||||
void *qMemSet(void *dest, int c, size_t n) { return memset(dest, c, n); }
|
||||
|
||||
|
@ -69,9 +69,7 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifndef QT_NO_STL
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
#ifndef QT_NAMESPACE /* user namespace */
|
||||
|
||||
@ -254,6 +252,56 @@ typedef quint64 qulonglong;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
namespace QtPrivate {
|
||||
template <class T>
|
||||
struct AlignOfHelper
|
||||
{
|
||||
char c;
|
||||
T type;
|
||||
|
||||
AlignOfHelper();
|
||||
~AlignOfHelper();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct AlignOf_Default
|
||||
{
|
||||
enum { Value = sizeof(AlignOfHelper<T>) - sizeof(T) };
|
||||
};
|
||||
|
||||
template <class T> struct AlignOf : AlignOf_Default<T> { };
|
||||
template <class T> struct AlignOf<T &> : AlignOf<T> {};
|
||||
template <size_t N, class T> struct AlignOf<T[N]> : AlignOf<T> {};
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
template <class T> struct AlignOf<T &&> : AlignOf<T> {};
|
||||
#endif
|
||||
|
||||
#if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN)
|
||||
template <class T> struct AlignOf_WorkaroundForI386Abi { enum { Value = sizeof(T) }; };
|
||||
|
||||
// x86 ABI weirdness
|
||||
// Alignment of naked type is 8, but inside struct has alignment 4.
|
||||
template <> struct AlignOf<double> : AlignOf_WorkaroundForI386Abi<double> {};
|
||||
template <> struct AlignOf<qint64> : AlignOf_WorkaroundForI386Abi<qint64> {};
|
||||
template <> struct AlignOf<quint64> : AlignOf_WorkaroundForI386Abi<quint64> {};
|
||||
#ifdef Q_CC_CLANG
|
||||
// GCC and Clang seem to disagree wrt to alignment of arrays
|
||||
template <size_t N> struct AlignOf<double[N]> : AlignOf_Default<double> {};
|
||||
template <size_t N> struct AlignOf<qint64[N]> : AlignOf_Default<qint64> {};
|
||||
template <size_t N> struct AlignOf<quint64[N]> : AlignOf_Default<quint64> {};
|
||||
#endif
|
||||
#endif
|
||||
} // namespace QtPrivate
|
||||
|
||||
#define QT_EMULATED_ALIGNOF(T) \
|
||||
(size_t(QT_PREPEND_NAMESPACE(QtPrivate)::AlignOf<T>::Value))
|
||||
|
||||
#ifndef Q_ALIGNOF
|
||||
#define Q_ALIGNOF(T) QT_EMULATED_ALIGNOF(T)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
quintptr and qptrdiff is guaranteed to be the same size as a pointer, i.e.
|
||||
|
||||
@ -421,9 +469,15 @@ QT_END_INCLUDE_NAMESPACE
|
||||
#ifdef Q_COMPILER_EXPLICIT_OVERRIDES
|
||||
# define Q_DECL_OVERRIDE override
|
||||
# define Q_DECL_FINAL final
|
||||
# ifdef Q_COMPILER_DECLTYPE // required for class-level final to compile in qvariant_p.h
|
||||
# define Q_DECL_FINAL_CLASS final
|
||||
# else
|
||||
# define Q_DECL_FINAL_CLASS
|
||||
# endif
|
||||
#else
|
||||
# define Q_DECL_OVERRIDE
|
||||
# define Q_DECL_FINAL
|
||||
# define Q_DECL_FINAL_CLASS
|
||||
#endif
|
||||
|
||||
#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF)
|
||||
@ -1127,28 +1181,20 @@ static inline bool qIsNull(float f)
|
||||
template <typename T>
|
||||
inline void qSwap(T &value1, T &value2)
|
||||
{
|
||||
#ifdef QT_NO_STL
|
||||
const T t = value1;
|
||||
value1 = value2;
|
||||
value2 = t;
|
||||
#else
|
||||
using std::swap;
|
||||
swap(value1, value2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
These functions make it possible to use standard C++ functions with
|
||||
a similar name from Qt header files (especially template classes).
|
||||
*/
|
||||
Q_CORE_EXPORT void *qMalloc(size_t size) Q_ALLOC_SIZE(1);
|
||||
Q_CORE_EXPORT void qFree(void *ptr);
|
||||
Q_CORE_EXPORT void *qRealloc(void *ptr, size_t size) Q_ALLOC_SIZE(2);
|
||||
#if QT_DEPRECATED_SINCE(5, 0)
|
||||
Q_CORE_EXPORT QT_DEPRECATED void *qMalloc(size_t size) Q_ALLOC_SIZE(1);
|
||||
Q_CORE_EXPORT QT_DEPRECATED void qFree(void *ptr);
|
||||
Q_CORE_EXPORT QT_DEPRECATED void *qRealloc(void *ptr, size_t size) Q_ALLOC_SIZE(2);
|
||||
Q_CORE_EXPORT QT_DEPRECATED void *qMemCopy(void *dest, const void *src, size_t n);
|
||||
Q_CORE_EXPORT QT_DEPRECATED void *qMemSet(void *dest, int c, size_t n);
|
||||
#endif
|
||||
Q_CORE_EXPORT void *qMallocAligned(size_t size, size_t alignment) Q_ALLOC_SIZE(1);
|
||||
Q_CORE_EXPORT void *qReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment) Q_ALLOC_SIZE(2);
|
||||
Q_CORE_EXPORT void qFreeAligned(void *ptr);
|
||||
Q_CORE_EXPORT void *qMemCopy(void *dest, const void *src, size_t n);
|
||||
Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
|
||||
|
||||
|
||||
/*
|
||||
@ -1258,14 +1304,6 @@ inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* tell gcc to use its built-in methods for some common functions */
|
||||
#if defined(QT_NO_DEBUG) && defined(Q_CC_GNU)
|
||||
# define qMemCopy __builtin_memcpy
|
||||
# define qMemSet __builtin_memset
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
|
||||
template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }
|
||||
|
||||
|
@ -49,10 +49,16 @@
|
||||
# define Q_IS_ENUM(x) __is_enum(x)
|
||||
# elif defined(Q_CC_MSVC) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER >=140050215)
|
||||
# define Q_IS_ENUM(x) __is_enum(x)
|
||||
# else
|
||||
# include <QtCore/qtypetraits.h>
|
||||
# define Q_IS_ENUM(x) QtPrivate::is_enum<x>::value
|
||||
# elif defined(Q_CC_CLANG)
|
||||
# if __has_extension(is_enum)
|
||||
# define Q_IS_ENUM(x) __is_enum(x)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef Q_IS_ENUM
|
||||
# include <QtCore/qtypetraits.h>
|
||||
# define Q_IS_ENUM(x) QtPrivate::is_enum<x>::value
|
||||
#endif
|
||||
|
||||
#endif // QISENUM_H
|
||||
|
@ -342,7 +342,6 @@ public:
|
||||
WA_UpdatesDisabled = 10,
|
||||
WA_Mapped = 11,
|
||||
WA_MacNoClickThrough = 12, // Mac only
|
||||
WA_PaintOutsidePaintEvent = 13,
|
||||
WA_InputMethodEnabled = 14,
|
||||
WA_WState_Visible = 15,
|
||||
WA_WState_Hidden = 16,
|
||||
@ -1101,8 +1100,7 @@ public:
|
||||
enum TextFormat {
|
||||
PlainText,
|
||||
RichText,
|
||||
AutoText,
|
||||
LogText
|
||||
AutoText
|
||||
};
|
||||
|
||||
enum AspectRatioMode {
|
||||
@ -1111,12 +1109,6 @@ public:
|
||||
KeepAspectRatioByExpanding
|
||||
};
|
||||
|
||||
// This is for Q3TextEdit only, actually.
|
||||
enum AnchorAttribute {
|
||||
AnchorName,
|
||||
AnchorHref
|
||||
};
|
||||
|
||||
enum DockWidgetArea {
|
||||
LeftDockWidgetArea = 0x1,
|
||||
RightDockWidgetArea = 0x2,
|
||||
@ -1200,7 +1192,6 @@ public:
|
||||
AutoConnection,
|
||||
DirectConnection,
|
||||
QueuedConnection,
|
||||
AutoCompatConnection,
|
||||
BlockingQueuedConnection,
|
||||
UniqueConnection = 0x80
|
||||
};
|
||||
|
@ -537,13 +537,6 @@
|
||||
same pair of objects, then the connection will fail. This
|
||||
connection type was introduced in Qt 4.6.
|
||||
|
||||
\value AutoCompatConnection
|
||||
The default type when Qt 3 support is enabled. Same as
|
||||
AutoConnection but will also cause warnings to be output in
|
||||
certain situations. See \l{Porting to Qt 4#Compatibility
|
||||
Signals and Slots}{Compatibility Signals and Slots} for
|
||||
further information.
|
||||
|
||||
With queued connections, the parameters must be of types that are
|
||||
known to Qt's meta-object system, because Qt needs to copy the
|
||||
arguments to store them in an event behind the scenes. If you try
|
||||
@ -1000,11 +993,6 @@
|
||||
require native painting primitives, you need to reimplement
|
||||
QWidget::paintEngine() to return 0 and set this flag.
|
||||
|
||||
\value WA_PaintOutsidePaintEvent Makes it possible to use QPainter to
|
||||
paint on the widget outside \l{QWidget::paintEvent()}{paintEvent()}. This
|
||||
flag is not supported on Windows, Mac OS X or Embedded Linux. We recommend
|
||||
that you use it only when porting Qt 3 code to Qt 4.
|
||||
|
||||
\value WA_PaintUnclipped Makes all painters operating on this widget
|
||||
unclipped. Children of this widget or other widgets in front of it do not
|
||||
clip the area the painter can paint on. This flag is only supported for
|
||||
@ -2309,9 +2297,6 @@
|
||||
\value AutoText The text string is interpreted as for
|
||||
Qt::RichText if Qt::mightBeRichText() returns true, otherwise
|
||||
as Qt::PlainText.
|
||||
|
||||
\value LogText A special, limited text format which is only used
|
||||
by Q3TextEdit in an optimized mode.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -100,7 +100,7 @@ static inline double qt_inf()
|
||||
: qt_le_inf_bytes);
|
||||
|
||||
union { unsigned char c[8]; double d; } returnValue;
|
||||
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
|
||||
memcpy(returnValue.c, bytes, sizeof(returnValue.c));
|
||||
return returnValue.d;
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ static inline double qt_snan()
|
||||
: qt_le_snan_bytes);
|
||||
|
||||
union { unsigned char c[8]; double d; } returnValue;
|
||||
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
|
||||
memcpy(returnValue.c, bytes, sizeof(returnValue.c));
|
||||
return returnValue.d;
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ static inline double qt_qnan()
|
||||
: qt_le_qnan_bytes);
|
||||
|
||||
union { unsigned char c[8]; double d; } returnValue;
|
||||
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
|
||||
memcpy(returnValue.c, bytes, sizeof(returnValue.c));
|
||||
return returnValue.d;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,12 @@
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
// for rand_s, _CRT_RAND_S must be #defined before #including stdlib.h.
|
||||
// put it at the beginning so some indirect inclusion doesn't break it
|
||||
#ifndef _CRT_RAND_S
|
||||
#define _CRT_RAND_S
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <qglobal.h>
|
||||
#ifdef Q_OS_WIN
|
||||
# define _POSIX_
|
||||
@ -63,5 +69,4 @@
|
||||
#include <qstring.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextcodec.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
@ -172,9 +172,6 @@ Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
|
||||
types must declare a 'bool isDetached(void) const;' member for this
|
||||
to work.
|
||||
*/
|
||||
#ifdef QT_NO_STL
|
||||
#define Q_DECLARE_SHARED_STL(TYPE)
|
||||
#else
|
||||
#define Q_DECLARE_SHARED_STL(TYPE) \
|
||||
QT_END_NAMESPACE \
|
||||
namespace std { \
|
||||
@ -182,7 +179,6 @@ namespace std { \
|
||||
{ swap(value1.data_ptr(), value2.data_ptr()); } \
|
||||
} \
|
||||
QT_BEGIN_NAMESPACE
|
||||
#endif
|
||||
|
||||
#define Q_DECLARE_SHARED(TYPE) \
|
||||
template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \
|
||||
|
@ -11,8 +11,11 @@ HEADERS += \
|
||||
io/qdir_p.h \
|
||||
io/qdiriterator.h \
|
||||
io/qfile.h \
|
||||
io/qfiledevice.h \
|
||||
io/qfiledevice_p.h \
|
||||
io/qfileinfo.h \
|
||||
io/qfileinfo_p.h \
|
||||
io/qipaddress_p.h \
|
||||
io/qiodevice.h \
|
||||
io/qiodevice_p.h \
|
||||
io/qnoncontiguousbytedevice_p.h \
|
||||
@ -25,6 +28,8 @@ HEADERS += \
|
||||
io/qresource_iterator_p.h \
|
||||
io/qstandardpaths.h \
|
||||
io/qurl.h \
|
||||
io/qurl_p.h \
|
||||
io/qurlquery.h \
|
||||
io/qurltlds_p.h \
|
||||
io/qtldurl_p.h \
|
||||
io/qsettings.h \
|
||||
@ -49,7 +54,9 @@ SOURCES += \
|
||||
io/qdir.cpp \
|
||||
io/qdiriterator.cpp \
|
||||
io/qfile.cpp \
|
||||
io/qfiledevice.cpp \
|
||||
io/qfileinfo.cpp \
|
||||
io/qipaddress.cpp \
|
||||
io/qiodevice.cpp \
|
||||
io/qnoncontiguousbytedevice.cpp \
|
||||
io/qprocess.cpp \
|
||||
@ -60,6 +67,9 @@ SOURCES += \
|
||||
io/qresource_iterator.cpp \
|
||||
io/qstandardpaths.cpp \
|
||||
io/qurl.cpp \
|
||||
io/qurlidna.cpp \
|
||||
io/qurlquery.cpp \
|
||||
io/qurlrecode.cpp \
|
||||
io/qsettings.cpp \
|
||||
io/qfsfileengine.cpp \
|
||||
io/qfsfileengine_iterator.cpp \
|
||||
|
@ -114,7 +114,7 @@ public:
|
||||
explicit QDataStream(QIODevice *);
|
||||
QDataStream(QByteArray *, QIODevice::OpenMode flags);
|
||||
QDataStream(const QByteArray &);
|
||||
virtual ~QDataStream();
|
||||
~QDataStream();
|
||||
|
||||
QIODevice *device() const;
|
||||
void setDevice(QIODevice *);
|
||||
@ -385,7 +385,6 @@ Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap<aKey, aT> &ma
|
||||
in >> n;
|
||||
|
||||
map.detach();
|
||||
map.setInsertInOrder(true);
|
||||
for (quint32 i = 0; i < n; ++i) {
|
||||
if (in.status() != QDataStream::Ok)
|
||||
break;
|
||||
@ -395,7 +394,6 @@ Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap<aKey, aT> &ma
|
||||
in >> key >> value;
|
||||
map.insertMulti(key, value);
|
||||
}
|
||||
map.setInsertInOrder(false);
|
||||
if (in.status() != QDataStream::Ok)
|
||||
map.clear();
|
||||
if (oldStatus != QDataStream::Ok)
|
||||
|
@ -61,11 +61,8 @@ Q_CORE_EXPORT bool qDecodeDataUrl(const QUrl &uri, QString &mimeType, QByteArray
|
||||
// the following would have been the correct thing, but
|
||||
// reality often differs from the specification. People have
|
||||
// data: URIs with ? and #
|
||||
//QByteArray data = QByteArray::fromPercentEncoding(uri.encodedPath());
|
||||
QByteArray data = QByteArray::fromPercentEncoding(uri.toEncoded());
|
||||
|
||||
// remove the data: scheme
|
||||
data.remove(0, 5);
|
||||
//QByteArray data = QByteArray::fromPercentEncoding(uri.path(QUrl::PrettyDecoded).toLatin1());
|
||||
QByteArray data = QByteArray::fromPercentEncoding(uri.url(QUrl::PrettyDecoded | QUrl::RemoveScheme).toLatin1());
|
||||
|
||||
// parse it:
|
||||
int pos = data.indexOf(',');
|
||||
|
@ -52,6 +52,7 @@ QT_BEGIN_HEADER
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QDirIterator;
|
||||
class QDirPrivate;
|
||||
|
||||
class Q_CORE_EXPORT QDir
|
||||
@ -210,6 +211,7 @@ protected:
|
||||
QSharedDataPointer<QDirPrivate> d_ptr;
|
||||
|
||||
private:
|
||||
friend class QDirIterator;
|
||||
// Q_DECLARE_PRIVATE equivalent for shared data pointers
|
||||
QDirPrivate* d_func();
|
||||
inline const QDirPrivate* d_func() const
|
||||
|
@ -410,9 +410,7 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
|
||||
*/
|
||||
QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags)
|
||||
{
|
||||
// little trick to get hold of the QDirPrivate while there is no API on QDir to give it to us
|
||||
class MyQDir : public QDir { public: const QDirPrivate *priv() const { return d_ptr.constData(); } };
|
||||
const QDirPrivate *other = static_cast<const MyQDir*>(&dir)->priv();
|
||||
const QDirPrivate *other = dir.d_ptr.constData();
|
||||
d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull()));
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
QDir::Filters filters = QDir::NoFilter,
|
||||
IteratorFlags flags = NoIteratorFlags);
|
||||
|
||||
virtual ~QDirIterator();
|
||||
~QDirIterator();
|
||||
|
||||
QString next();
|
||||
bool hasNext() const;
|
||||
|
@ -59,8 +59,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const int QFILE_WRITEBUFFER_SIZE = 16384;
|
||||
|
||||
static QByteArray locale_encode(const QString &f)
|
||||
{
|
||||
#if defined(Q_OS_DARWIN)
|
||||
@ -86,16 +84,11 @@ QFile::EncoderFn QFilePrivate::encoder = locale_encode;
|
||||
QFile::DecoderFn QFilePrivate::decoder = locale_decode;
|
||||
|
||||
QFilePrivate::QFilePrivate()
|
||||
: fileEngine(0), lastWasWrite(false),
|
||||
writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
|
||||
cachedSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
QFilePrivate::~QFilePrivate()
|
||||
{
|
||||
delete fileEngine;
|
||||
fileEngine = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -137,39 +130,6 @@ QAbstractFileEngine *QFilePrivate::engine() const
|
||||
return fileEngine;
|
||||
}
|
||||
|
||||
inline bool QFilePrivate::ensureFlushed() const
|
||||
{
|
||||
// This function ensures that the write buffer has been flushed (const
|
||||
// because certain const functions need to call it.
|
||||
if (lastWasWrite) {
|
||||
const_cast<QFilePrivate *>(this)->lastWasWrite = false;
|
||||
if (!const_cast<QFile *>(q_func())->flush())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
QFilePrivate::setError(QFile::FileError err)
|
||||
{
|
||||
error = err;
|
||||
errorString.clear();
|
||||
}
|
||||
|
||||
void
|
||||
QFilePrivate::setError(QFile::FileError err, const QString &errStr)
|
||||
{
|
||||
error = err;
|
||||
errorString = errStr;
|
||||
}
|
||||
|
||||
void
|
||||
QFilePrivate::setError(QFile::FileError err, int errNum)
|
||||
{
|
||||
error = err;
|
||||
errorString = qt_error_string(errNum);
|
||||
}
|
||||
|
||||
//************* QFile
|
||||
|
||||
/*!
|
||||
@ -278,98 +238,18 @@ QFilePrivate::setError(QFile::FileError err, int errNum)
|
||||
\sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QFile::FileError
|
||||
|
||||
This enum describes the errors that may be returned by the error()
|
||||
function.
|
||||
|
||||
\value NoError No error occurred.
|
||||
\value ReadError An error occurred when reading from the file.
|
||||
\value WriteError An error occurred when writing to the file.
|
||||
\value FatalError A fatal error occurred.
|
||||
\value ResourceError
|
||||
\value OpenError The file could not be opened.
|
||||
\value AbortError The operation was aborted.
|
||||
\value TimeOutError A timeout occurred.
|
||||
\value UnspecifiedError An unspecified error occurred.
|
||||
\value RemoveError The file could not be removed.
|
||||
\value RenameError The file could not be renamed.
|
||||
\value PositionError The position in the file could not be changed.
|
||||
\value ResizeError The file could not be resized.
|
||||
\value PermissionsError The file could not be accessed.
|
||||
\value CopyError The file could not be copied.
|
||||
|
||||
\omitvalue ConnectError
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QFile::Permission
|
||||
|
||||
This enum is used by the permission() function to report the
|
||||
permissions and ownership of a file. The values may be OR-ed
|
||||
together to test multiple permissions and ownership values.
|
||||
|
||||
\value ReadOwner The file is readable by the owner of the file.
|
||||
\value WriteOwner The file is writable by the owner of the file.
|
||||
\value ExeOwner The file is executable by the owner of the file.
|
||||
\value ReadUser The file is readable by the user.
|
||||
\value WriteUser The file is writable by the user.
|
||||
\value ExeUser The file is executable by the user.
|
||||
\value ReadGroup The file is readable by the group.
|
||||
\value WriteGroup The file is writable by the group.
|
||||
\value ExeGroup The file is executable by the group.
|
||||
\value ReadOther The file is readable by anyone.
|
||||
\value WriteOther The file is writable by anyone.
|
||||
\value ExeOther The file is executable by anyone.
|
||||
|
||||
\warning Because of differences in the platforms supported by Qt,
|
||||
the semantics of ReadUser, WriteUser and ExeUser are
|
||||
platform-dependent: On Unix, the rights of the owner of the file
|
||||
are returned and on Windows the rights of the current user are
|
||||
returned. This behavior might change in a future Qt version.
|
||||
|
||||
Note that Qt does not by default check for permissions on NTFS
|
||||
file systems, as this may decrease the performance of file
|
||||
handling considerably. It is possible to force permission checking
|
||||
on NTFS by including the following code in your source:
|
||||
|
||||
\snippet doc/src/snippets/ntfsp.cpp 0
|
||||
|
||||
Permission checking is then turned on and off by incrementing and
|
||||
decrementing \c qt_ntfs_permission_lookup by 1.
|
||||
|
||||
\snippet doc/src/snippets/ntfsp.cpp 1
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QFile::FileHandleFlag
|
||||
|
||||
This enum is used when opening a file to specify additional
|
||||
options which only apply to files and not to a generic
|
||||
QIODevice.
|
||||
|
||||
\value AutoCloseHandle The file handle passed into open() should be
|
||||
closed by close(), the default behavior is that close just flushes
|
||||
the file and the application is responsible for closing the file handle.
|
||||
When opening a file by name, this flag is ignored as Qt always owns the
|
||||
file handle and must close it.
|
||||
\value DontCloseHandle If not explicitly closed, the underlying file
|
||||
handle is left open when the QFile object is destroyed.
|
||||
*/
|
||||
|
||||
#ifdef QT_NO_QOBJECT
|
||||
QFile::QFile()
|
||||
: QIODevice(*new QFilePrivate)
|
||||
: QFileDevice(*new QFilePrivate)
|
||||
{
|
||||
}
|
||||
QFile::QFile(const QString &name)
|
||||
: QIODevice(*new QFilePrivate)
|
||||
: QFileDevice(*new QFilePrivate)
|
||||
{
|
||||
d_func()->fileName = name;
|
||||
}
|
||||
QFile::QFile(QFilePrivate &dd)
|
||||
: QIODevice(dd)
|
||||
: QFileDevice(dd)
|
||||
{
|
||||
}
|
||||
#else
|
||||
@ -377,21 +257,21 @@ QFile::QFile(QFilePrivate &dd)
|
||||
\internal
|
||||
*/
|
||||
QFile::QFile()
|
||||
: QIODevice(*new QFilePrivate, 0)
|
||||
: QFileDevice(*new QFilePrivate, 0)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
Constructs a new file object with the given \a parent.
|
||||
*/
|
||||
QFile::QFile(QObject *parent)
|
||||
: QIODevice(*new QFilePrivate, parent)
|
||||
: QFileDevice(*new QFilePrivate, parent)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
Constructs a new file object to represent the file with the given \a name.
|
||||
*/
|
||||
QFile::QFile(const QString &name)
|
||||
: QIODevice(*new QFilePrivate, 0)
|
||||
: QFileDevice(*new QFilePrivate, 0)
|
||||
{
|
||||
Q_D(QFile);
|
||||
d->fileName = name;
|
||||
@ -401,7 +281,7 @@ QFile::QFile(const QString &name)
|
||||
file with the specified \a name.
|
||||
*/
|
||||
QFile::QFile(const QString &name, QObject *parent)
|
||||
: QIODevice(*new QFilePrivate, parent)
|
||||
: QFileDevice(*new QFilePrivate, parent)
|
||||
{
|
||||
Q_D(QFile);
|
||||
d->fileName = name;
|
||||
@ -410,7 +290,7 @@ QFile::QFile(const QString &name, QObject *parent)
|
||||
\internal
|
||||
*/
|
||||
QFile::QFile(QFilePrivate &dd, QObject *parent)
|
||||
: QIODevice(dd, parent)
|
||||
: QFileDevice(dd, parent)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@ -420,7 +300,6 @@ QFile::QFile(QFilePrivate &dd, QObject *parent)
|
||||
*/
|
||||
QFile::~QFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -966,20 +845,6 @@ QFile::copy(const QString &fileName, const QString &newName)
|
||||
return QFile(fileName).copy(newName);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the file can only be manipulated sequentially;
|
||||
otherwise returns false.
|
||||
|
||||
Most files support random-access, but some special files may not.
|
||||
|
||||
\sa QIODevice::isSequential()
|
||||
*/
|
||||
bool QFile::isSequential() const
|
||||
{
|
||||
Q_D(const QFile);
|
||||
return d->fileEngine && d->fileEngine->isSequential();
|
||||
}
|
||||
|
||||
/*!
|
||||
Opens the file using OpenMode \a mode, returning true if successful;
|
||||
otherwise false.
|
||||
@ -1154,119 +1019,11 @@ bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the file handle of the file.
|
||||
|
||||
This is a small positive integer, suitable for use with C library
|
||||
functions such as fdopen() and fcntl(). On systems that use file
|
||||
descriptors for sockets (i.e. Unix systems, but not Windows) the handle
|
||||
can be used with QSocketNotifier as well.
|
||||
|
||||
If the file is not open, or there is an error, handle() returns -1.
|
||||
|
||||
This function is not supported on Windows CE.
|
||||
|
||||
\sa QSocketNotifier
|
||||
\reimp
|
||||
*/
|
||||
|
||||
int
|
||||
QFile::handle() const
|
||||
bool QFile::resize(qint64 sz)
|
||||
{
|
||||
Q_D(const QFile);
|
||||
if (!isOpen() || !d->fileEngine)
|
||||
return -1;
|
||||
|
||||
return d->fileEngine->handle();
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QFile::MemoryMapFlags
|
||||
\since 4.4
|
||||
|
||||
This enum describes special options that may be used by the map()
|
||||
function.
|
||||
|
||||
\value NoOptions No options.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
Maps \a size bytes of the file into memory starting at \a offset. A file
|
||||
should be open for a map to succeed but the file does not need to stay
|
||||
open after the memory has been mapped. When the QFile is destroyed
|
||||
or a new file is opened with this object, any maps that have not been
|
||||
unmapped will automatically be unmapped.
|
||||
|
||||
Any mapping options can be passed through \a flags.
|
||||
|
||||
Returns a pointer to the memory or 0 if there is an error.
|
||||
|
||||
\note On Windows CE 5.0 the file will be closed before mapping occurs.
|
||||
|
||||
\sa unmap()
|
||||
*/
|
||||
uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (d->engine()
|
||||
&& d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
|
||||
unsetError();
|
||||
uchar *address = d->fileEngine->map(offset, size, flags);
|
||||
if (address == 0)
|
||||
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
|
||||
return address;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
Unmaps the memory \a address.
|
||||
|
||||
Returns true if the unmap succeeds; false otherwise.
|
||||
|
||||
\sa map()
|
||||
*/
|
||||
bool QFile::unmap(uchar *address)
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (d->engine()
|
||||
&& d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
|
||||
unsetError();
|
||||
bool success = d->fileEngine->unmap(address);
|
||||
if (!success)
|
||||
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
|
||||
return success;
|
||||
}
|
||||
d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the file size (in bytes) \a sz. Returns true if the file if the
|
||||
resize succeeds; false otherwise. If \a sz is larger than the file
|
||||
currently is the new bytes will be set to 0, if \a sz is smaller the
|
||||
file is simply truncated.
|
||||
|
||||
\sa size(), setFileName()
|
||||
*/
|
||||
|
||||
bool
|
||||
QFile::resize(qint64 sz)
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
d->engine();
|
||||
if (isOpen() && d->fileEngine->pos() > sz)
|
||||
seek(sz);
|
||||
if(d->fileEngine->setSize(sz)) {
|
||||
unsetError();
|
||||
d->cachedSize = sz;
|
||||
return true;
|
||||
}
|
||||
d->cachedSize = 0;
|
||||
d->setError(QFile::ResizeError, d->fileEngine->errorString());
|
||||
return false;
|
||||
return QFileDevice::resize(sz); // for now
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1287,18 +1044,11 @@ QFile::resize(const QString &fileName, qint64 sz)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the complete OR-ed together combination of
|
||||
QFile::Permission for the file.
|
||||
|
||||
\sa setPermissions(), setFileName()
|
||||
\reimp
|
||||
*/
|
||||
|
||||
QFile::Permissions
|
||||
QFile::permissions() const
|
||||
QFile::Permissions QFile::permissions() const
|
||||
{
|
||||
Q_D(const QFile);
|
||||
QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
|
||||
return QFile::Permissions((int)perms); //ewww
|
||||
return QFileDevice::permissions(); // for now
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1322,16 +1072,9 @@ QFile::permissions(const QString &fileName)
|
||||
\sa permissions(), setFileName()
|
||||
*/
|
||||
|
||||
bool
|
||||
QFile::setPermissions(Permissions permissions)
|
||||
bool QFile::setPermissions(Permissions permissions)
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (d->engine()->setPermissions(permissions)) {
|
||||
unsetError();
|
||||
return true;
|
||||
}
|
||||
d->setError(QFile::PermissionsError, d->fileEngine->errorString());
|
||||
return false;
|
||||
return QFileDevice::setPermissions(permissions); // for now
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1346,354 +1089,12 @@ QFile::setPermissions(const QString &fileName, Permissions permissions)
|
||||
return QFile(fileName).setPermissions(permissions);
|
||||
}
|
||||
|
||||
static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
|
||||
{
|
||||
qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
|
||||
if (ret > 0)
|
||||
buffer->free(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
Flushes any buffered data to the file. Returns true if successful;
|
||||
otherwise returns false.
|
||||
\reimp
|
||||
*/
|
||||
|
||||
bool
|
||||
QFile::flush()
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (!d->fileEngine) {
|
||||
qWarning("QFile::flush: No file engine. Is IODevice open?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->writeBuffer.isEmpty()) {
|
||||
qint64 size = d->writeBuffer.size();
|
||||
if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
|
||||
QFile::FileError err = d->fileEngine->error();
|
||||
if(err == QFile::UnspecifiedError)
|
||||
err = QFile::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->fileEngine->flush()) {
|
||||
QFile::FileError err = d->fileEngine->error();
|
||||
if(err == QFile::UnspecifiedError)
|
||||
err = QFile::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Calls QFile::flush() and closes the file. Errors from flush are ignored.
|
||||
|
||||
\sa QIODevice::close()
|
||||
*/
|
||||
void
|
||||
QFile::close()
|
||||
{
|
||||
Q_D(QFile);
|
||||
if(!isOpen())
|
||||
return;
|
||||
bool flushed = flush();
|
||||
QIODevice::close();
|
||||
|
||||
// reset write buffer
|
||||
d->lastWasWrite = false;
|
||||
d->writeBuffer.clear();
|
||||
|
||||
// keep earlier error from flush
|
||||
if (d->fileEngine->close() && flushed)
|
||||
unsetError();
|
||||
else if (flushed)
|
||||
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the size of the file.
|
||||
|
||||
For regular empty files on Unix (e.g. those in \c /proc), this function
|
||||
returns 0; the contents of such a file are generated on demand in response
|
||||
to you calling read().
|
||||
*/
|
||||
|
||||
qint64 QFile::size() const
|
||||
{
|
||||
Q_D(const QFile);
|
||||
if (!d->ensureFlushed())
|
||||
return 0;
|
||||
d->cachedSize = d->engine()->size();
|
||||
return d->cachedSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
|
||||
qint64 QFile::pos() const
|
||||
{
|
||||
return QIODevice::pos();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the end of the file has been reached; otherwise returns
|
||||
false.
|
||||
|
||||
For regular empty files on Unix (e.g. those in \c /proc), this function
|
||||
returns true, since the file system reports that the size of such a file is
|
||||
0. Therefore, you should not depend on atEnd() when reading data from such a
|
||||
file, but rather call read() until no more data can be read.
|
||||
*/
|
||||
|
||||
bool QFile::atEnd() const
|
||||
{
|
||||
Q_D(const QFile);
|
||||
|
||||
// If there's buffered data left, we're not at the end.
|
||||
if (!d->buffer.isEmpty())
|
||||
return false;
|
||||
|
||||
if (!isOpen())
|
||||
return true;
|
||||
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
|
||||
// If the file engine knows best, say what it says.
|
||||
if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
|
||||
// Check if the file engine supports AtEndExtension, and if it does,
|
||||
// check if the file engine claims to be at the end.
|
||||
return d->fileEngine->atEnd();
|
||||
}
|
||||
|
||||
// if it looks like we are at the end, or if size is not cached,
|
||||
// fall through to bytesAvailable() to make sure.
|
||||
if (pos() < d->cachedSize)
|
||||
return false;
|
||||
|
||||
// Fall back to checking how much is available (will stat files).
|
||||
return bytesAvailable() == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool QFile::seek(qint64 pos)
|
||||
|
||||
For random-access devices, this function sets the current position
|
||||
to \a pos, returning true on success, or false if an error occurred.
|
||||
For sequential devices, the default behavior is to do nothing and
|
||||
return false.
|
||||
|
||||
Seeking beyond the end of a file:
|
||||
If the position is beyond the end of a file, then seek() shall not
|
||||
immediately extend the file. If a write is performed at this position,
|
||||
then the file shall be extended. The content of the file between the
|
||||
previous end of file and the newly written data is UNDEFINED and
|
||||
varies between platforms and file systems.
|
||||
*/
|
||||
|
||||
bool QFile::seek(qint64 off)
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (!isOpen()) {
|
||||
qWarning("QFile::seek: IODevice is not open");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
|
||||
if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
|
||||
QFile::FileError err = d->fileEngine->error();
|
||||
if(err == QFile::UnspecifiedError)
|
||||
err = QFile::PositionError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
unsetError();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFile::readLineData(char *data, qint64 maxlen)
|
||||
{
|
||||
Q_D(QFile);
|
||||
if (!d->ensureFlushed())
|
||||
return -1;
|
||||
|
||||
qint64 read;
|
||||
if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
|
||||
read = d->fileEngine->readLine(data, maxlen);
|
||||
} else {
|
||||
// Fall back to QIODevice's readLine implementation if the engine
|
||||
// cannot do it faster.
|
||||
read = QIODevice::readLineData(data, maxlen);
|
||||
}
|
||||
|
||||
if (read < maxlen) {
|
||||
// failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
|
||||
d->cachedSize = 0;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
|
||||
qint64 QFile::readData(char *data, qint64 len)
|
||||
{
|
||||
Q_D(QFile);
|
||||
unsetError();
|
||||
if (!d->ensureFlushed())
|
||||
return -1;
|
||||
|
||||
qint64 read = d->fileEngine->read(data, len);
|
||||
if(read < 0) {
|
||||
QFile::FileError err = d->fileEngine->error();
|
||||
if(err == QFile::UnspecifiedError)
|
||||
err = QFile::ReadError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
}
|
||||
|
||||
if (read < len) {
|
||||
// failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
|
||||
d->cachedSize = 0;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
bool QFilePrivate::putCharHelper(char c)
|
||||
{
|
||||
#ifdef QT_NO_QOBJECT
|
||||
return QIODevicePrivate::putCharHelper(c);
|
||||
#else
|
||||
|
||||
// Cutoff for code that doesn't only touch the buffer.
|
||||
int writeBufferSize = writeBuffer.size();
|
||||
if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
|
||||
#ifdef Q_OS_WIN
|
||||
|| ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
|
||||
#endif
|
||||
) {
|
||||
return QIODevicePrivate::putCharHelper(c);
|
||||
}
|
||||
|
||||
if (!(openMode & QIODevice::WriteOnly)) {
|
||||
if (openMode == QIODevice::NotOpen)
|
||||
qWarning("QIODevice::putChar: Closed device");
|
||||
else
|
||||
qWarning("QIODevice::putChar: ReadOnly device");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the device is positioned correctly.
|
||||
const bool sequential = isSequential();
|
||||
if (pos != devicePos && !sequential && !q_func()->seek(pos))
|
||||
return false;
|
||||
|
||||
lastWasWrite = true;
|
||||
|
||||
int len = 1;
|
||||
#ifdef Q_OS_WIN
|
||||
if ((openMode & QIODevice::Text) && c == '\n') {
|
||||
++len;
|
||||
*writeBuffer.reserve(1) = '\r';
|
||||
}
|
||||
#endif
|
||||
|
||||
// Write to buffer.
|
||||
*writeBuffer.reserve(1) = c;
|
||||
|
||||
if (!sequential) {
|
||||
pos += len;
|
||||
devicePos += len;
|
||||
if (!buffer.isEmpty())
|
||||
buffer.skip(len);
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
|
||||
qint64
|
||||
QFile::writeData(const char *data, qint64 len)
|
||||
{
|
||||
Q_D(QFile);
|
||||
unsetError();
|
||||
d->lastWasWrite = true;
|
||||
bool buffered = !(d->openMode & Unbuffered);
|
||||
|
||||
// Flush buffered data if this read will overflow.
|
||||
if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
|
||||
if (!flush())
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write directly to the engine if the block size is larger than
|
||||
// the write buffer size.
|
||||
if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
|
||||
qint64 ret = d->fileEngine->write(data, len);
|
||||
if(ret < 0) {
|
||||
QFile::FileError err = d->fileEngine->error();
|
||||
if(err == QFile::UnspecifiedError)
|
||||
err = QFile::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Write to the buffer.
|
||||
char *writePointer = d->writeBuffer.reserve(len);
|
||||
if (len == 1)
|
||||
*writePointer = *data;
|
||||
else
|
||||
::memcpy(writePointer, data, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the file error status.
|
||||
|
||||
The I/O device status returns an error code. For example, if open()
|
||||
returns false, or a read/write operation returns -1, this function can
|
||||
be called to find out the reason why the operation failed.
|
||||
|
||||
\sa unsetError()
|
||||
*/
|
||||
|
||||
QFile::FileError
|
||||
QFile::error() const
|
||||
{
|
||||
Q_D(const QFile);
|
||||
return d->error;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the file's error to QFile::NoError.
|
||||
|
||||
\sa error()
|
||||
*/
|
||||
void
|
||||
QFile::unsetError()
|
||||
{
|
||||
Q_D(QFile);
|
||||
d->setError(QFile::NoError);
|
||||
return QFileDevice::size(); // for now
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -42,7 +42,7 @@
|
||||
#ifndef QFILE_H
|
||||
#define QFILE_H
|
||||
|
||||
#include <QtCore/qiodevice.h>
|
||||
#include <QtCore/qfiledevice.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QTemporaryFile;
|
||||
class QFilePrivate;
|
||||
|
||||
class Q_CORE_EXPORT QFile : public QIODevice
|
||||
class Q_CORE_EXPORT QFile : public QFileDevice
|
||||
{
|
||||
#ifndef QT_NO_QOBJECT
|
||||
Q_OBJECT
|
||||
@ -65,39 +65,6 @@ class Q_CORE_EXPORT QFile : public QIODevice
|
||||
Q_DECLARE_PRIVATE(QFile)
|
||||
|
||||
public:
|
||||
|
||||
enum FileError {
|
||||
NoError = 0,
|
||||
ReadError = 1,
|
||||
WriteError = 2,
|
||||
FatalError = 3,
|
||||
ResourceError = 4,
|
||||
OpenError = 5,
|
||||
AbortError = 6,
|
||||
TimeOutError = 7,
|
||||
UnspecifiedError = 8,
|
||||
RemoveError = 9,
|
||||
RenameError = 10,
|
||||
PositionError = 11,
|
||||
ResizeError = 12,
|
||||
PermissionsError = 13,
|
||||
CopyError = 14
|
||||
};
|
||||
|
||||
enum Permission {
|
||||
ReadOwner = 0x4000, WriteOwner = 0x2000, ExeOwner = 0x1000,
|
||||
ReadUser = 0x0400, WriteUser = 0x0200, ExeUser = 0x0100,
|
||||
ReadGroup = 0x0040, WriteGroup = 0x0020, ExeGroup = 0x0010,
|
||||
ReadOther = 0x0004, WriteOther = 0x0002, ExeOther = 0x0001
|
||||
};
|
||||
Q_DECLARE_FLAGS(Permissions, Permission)
|
||||
|
||||
enum FileHandleFlag {
|
||||
AutoCloseHandle = 0x0001,
|
||||
DontCloseHandle = 0
|
||||
};
|
||||
Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)
|
||||
|
||||
QFile();
|
||||
QFile(const QString &name);
|
||||
#ifndef QT_NO_QOBJECT
|
||||
@ -106,9 +73,6 @@ public:
|
||||
#endif
|
||||
~QFile();
|
||||
|
||||
FileError error() const;
|
||||
void unsetError();
|
||||
|
||||
QString fileName() const;
|
||||
void setFileName(const QString &name);
|
||||
|
||||
@ -141,18 +105,11 @@ public:
|
||||
bool copy(const QString &newName);
|
||||
static bool copy(const QString &fileName, const QString &newName);
|
||||
|
||||
bool isSequential() const;
|
||||
|
||||
bool open(OpenMode flags);
|
||||
bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
||||
bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
||||
virtual void close();
|
||||
|
||||
qint64 size() const;
|
||||
qint64 pos() const;
|
||||
bool seek(qint64 offset);
|
||||
bool atEnd() const;
|
||||
bool flush();
|
||||
|
||||
bool resize(qint64 sz);
|
||||
static bool resize(const QString &filename, qint64 sz);
|
||||
@ -162,15 +119,6 @@ public:
|
||||
bool setPermissions(Permissions permissionSpec);
|
||||
static bool setPermissions(const QString &filename, Permissions permissionSpec);
|
||||
|
||||
int handle() const;
|
||||
|
||||
enum MemoryMapFlags {
|
||||
NoOptions = 0
|
||||
};
|
||||
|
||||
uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
|
||||
bool unmap(uchar *address);
|
||||
|
||||
protected:
|
||||
#ifdef QT_NO_QOBJECT
|
||||
QFile(QFilePrivate &dd);
|
||||
@ -178,17 +126,11 @@ protected:
|
||||
QFile(QFilePrivate &dd, QObject *parent = 0);
|
||||
#endif
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
qint64 writeData(const char *data, qint64 len);
|
||||
qint64 readLineData(char *data, qint64 maxlen);
|
||||
|
||||
private:
|
||||
friend class QTemporaryFile;
|
||||
Q_DISABLE_COPY(QFile)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QFile::Permissions)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
@ -53,15 +53,13 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qabstractfileengine_p.h"
|
||||
#include "private/qiodevice_p.h"
|
||||
#include "private/qringbuffer_p.h"
|
||||
#include "private/qfiledevice_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTemporaryFile;
|
||||
|
||||
class QFilePrivate : public QIODevicePrivate
|
||||
class QFilePrivate : public QFileDevicePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QFile)
|
||||
friend class QTemporaryFile;
|
||||
@ -76,20 +74,6 @@ protected:
|
||||
virtual QAbstractFileEngine *engine() const;
|
||||
|
||||
QString fileName;
|
||||
mutable QAbstractFileEngine *fileEngine;
|
||||
|
||||
bool lastWasWrite;
|
||||
QRingBuffer writeBuffer;
|
||||
inline bool ensureFlushed() const;
|
||||
|
||||
bool putCharHelper(char c);
|
||||
|
||||
QFile::FileError error;
|
||||
void setError(QFile::FileError err);
|
||||
void setError(QFile::FileError err, const QString &errorString);
|
||||
void setError(QFile::FileError err, int errNum);
|
||||
|
||||
mutable qint64 cachedSize;
|
||||
|
||||
private:
|
||||
static QFile::EncoderFn encoder;
|
||||
|
736
src/corelib/io/qfiledevice.cpp
Normal file
736
src/corelib/io/qfiledevice.cpp
Normal file
@ -0,0 +1,736 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qplatformdefs.h"
|
||||
#include "qfiledevice.h"
|
||||
#include "qfiledevice_p.h"
|
||||
#include "qfsfileengine_p.h"
|
||||
|
||||
#ifdef QT_NO_QOBJECT
|
||||
#define tr(X) QString::fromLatin1(X)
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const int QFILE_WRITEBUFFER_SIZE = 16384;
|
||||
|
||||
QFileDevicePrivate::QFileDevicePrivate()
|
||||
: fileEngine(0), lastWasWrite(false),
|
||||
writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
|
||||
cachedSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
QFileDevicePrivate::~QFileDevicePrivate()
|
||||
{
|
||||
delete fileEngine;
|
||||
fileEngine = 0;
|
||||
}
|
||||
|
||||
QAbstractFileEngine * QFileDevicePrivate::engine() const
|
||||
{
|
||||
if (!fileEngine)
|
||||
fileEngine = new QFSFileEngine;
|
||||
return fileEngine;
|
||||
}
|
||||
|
||||
void QFileDevicePrivate::setError(QFileDevice::FileError err)
|
||||
{
|
||||
error = err;
|
||||
errorString.clear();
|
||||
}
|
||||
|
||||
void QFileDevicePrivate::setError(QFileDevice::FileError err, const QString &errStr)
|
||||
{
|
||||
error = err;
|
||||
errorString = errStr;
|
||||
}
|
||||
|
||||
void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
|
||||
{
|
||||
error = err;
|
||||
errorString = qt_error_string(errNum);
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::FileError
|
||||
|
||||
This enum describes the errors that may be returned by the error()
|
||||
function.
|
||||
|
||||
\value NoError No error occurred.
|
||||
\value ReadError An error occurred when reading from the file.
|
||||
\value WriteError An error occurred when writing to the file.
|
||||
\value FatalError A fatal error occurred.
|
||||
\value ResourceError
|
||||
\value OpenError The file could not be opened.
|
||||
\value AbortError The operation was aborted.
|
||||
\value TimeOutError A timeout occurred.
|
||||
\value UnspecifiedError An unspecified error occurred.
|
||||
\value RemoveError The file could not be removed.
|
||||
\value RenameError The file could not be renamed.
|
||||
\value PositionError The position in the file could not be changed.
|
||||
\value ResizeError The file could not be resized.
|
||||
\value PermissionsError The file could not be accessed.
|
||||
\value CopyError The file could not be copied.
|
||||
|
||||
\omitvalue ConnectError
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::Permission
|
||||
|
||||
This enum is used by the permission() function to report the
|
||||
permissions and ownership of a file. The values may be OR-ed
|
||||
together to test multiple permissions and ownership values.
|
||||
|
||||
\value ReadOwner The file is readable by the owner of the file.
|
||||
\value WriteOwner The file is writable by the owner of the file.
|
||||
\value ExeOwner The file is executable by the owner of the file.
|
||||
\value ReadUser The file is readable by the user.
|
||||
\value WriteUser The file is writable by the user.
|
||||
\value ExeUser The file is executable by the user.
|
||||
\value ReadGroup The file is readable by the group.
|
||||
\value WriteGroup The file is writable by the group.
|
||||
\value ExeGroup The file is executable by the group.
|
||||
\value ReadOther The file is readable by anyone.
|
||||
\value WriteOther The file is writable by anyone.
|
||||
\value ExeOther The file is executable by anyone.
|
||||
|
||||
\warning Because of differences in the platforms supported by Qt,
|
||||
the semantics of ReadUser, WriteUser and ExeUser are
|
||||
platform-dependent: On Unix, the rights of the owner of the file
|
||||
are returned and on Windows the rights of the current user are
|
||||
returned. This behavior might change in a future Qt version.
|
||||
|
||||
Note that Qt does not by default check for permissions on NTFS
|
||||
file systems, as this may decrease the performance of file
|
||||
handling considerably. It is possible to force permission checking
|
||||
on NTFS by including the following code in your source:
|
||||
|
||||
\snippet doc/src/snippets/ntfsp.cpp 0
|
||||
|
||||
Permission checking is then turned on and off by incrementing and
|
||||
decrementing \c qt_ntfs_permission_lookup by 1.
|
||||
|
||||
\snippet doc/src/snippets/ntfsp.cpp 1
|
||||
*/
|
||||
|
||||
//************* QFileDevice
|
||||
|
||||
/*!
|
||||
\class QFileDevice
|
||||
\since 5.0
|
||||
|
||||
\brief The QFileDevice class provides an interface for reading from and writing to open files.
|
||||
|
||||
\ingroup io
|
||||
|
||||
\reentrant
|
||||
|
||||
QFileDevice is the base class for I/O devices that can read and write text and binary files
|
||||
and \l{The Qt Resource System}{resources}. QFile offers the main functionality,
|
||||
QFileDevice serves as a base class for sharing functionality with other file devices such
|
||||
as QTemporaryFile, by providing all the operations that can be done on files that have
|
||||
been opened by QFile or QTemporaryFile.
|
||||
|
||||
\sa QFile, QTemporaryFile
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::FileHandleFlag
|
||||
|
||||
This enum is used when opening a file to specify additional
|
||||
options which only apply to files and not to a generic
|
||||
QIODevice.
|
||||
|
||||
\value AutoCloseHandle The file handle passed into open() should be
|
||||
closed by close(), the default behavior is that close just flushes
|
||||
the file and the application is responsible for closing the file handle.
|
||||
When opening a file by name, this flag is ignored as Qt always owns the
|
||||
file handle and must close it.
|
||||
\value DontCloseHandle If not explicitly closed, the underlying file
|
||||
handle is left open when the QFile object is destroyed.
|
||||
*/
|
||||
|
||||
#ifdef QT_NO_QOBJECT
|
||||
QFileDevice::QFileDevice()
|
||||
: QIODevice(*new QFileDevicePrivate)
|
||||
{
|
||||
}
|
||||
QFileDevice::QFileDevice(QFileDevicePrivate &dd)
|
||||
: QIODevice(dd)
|
||||
{
|
||||
}
|
||||
#else
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFileDevice::QFileDevice()
|
||||
: QIODevice(*new QFileDevicePrivate, 0)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFileDevice::QFileDevice(QObject *parent)
|
||||
: QIODevice(*new QFileDevicePrivate, parent)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFileDevice::QFileDevice(QFileDevicePrivate &dd, QObject *parent)
|
||||
: QIODevice(dd, parent)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Destroys the file device, closing it if necessary.
|
||||
*/
|
||||
QFileDevice::~QFileDevice()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the file can only be manipulated sequentially;
|
||||
otherwise returns false.
|
||||
|
||||
Most files support random-access, but some special files may not.
|
||||
|
||||
\sa QIODevice::isSequential()
|
||||
*/
|
||||
bool QFileDevice::isSequential() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
return d->fileEngine && d->fileEngine->isSequential();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the file handle of the file.
|
||||
|
||||
This is a small positive integer, suitable for use with C library
|
||||
functions such as fdopen() and fcntl(). On systems that use file
|
||||
descriptors for sockets (i.e. Unix systems, but not Windows) the handle
|
||||
can be used with QSocketNotifier as well.
|
||||
|
||||
If the file is not open, or there is an error, handle() returns -1.
|
||||
|
||||
This function is not supported on Windows CE.
|
||||
|
||||
\sa QSocketNotifier
|
||||
*/
|
||||
int QFileDevice::handle() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
if (!isOpen() || !d->fileEngine)
|
||||
return -1;
|
||||
|
||||
return d->fileEngine->handle();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the name of the file.
|
||||
The default implementation in QFileDevice returns QString().
|
||||
*/
|
||||
QString QFileDevice::fileName() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
|
||||
{
|
||||
qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
|
||||
if (ret > 0)
|
||||
buffer->free(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
Flushes any buffered data to the file. Returns true if successful;
|
||||
otherwise returns false.
|
||||
*/
|
||||
bool QFileDevice::flush()
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!d->fileEngine) {
|
||||
qWarning("QFileDevice::flush: No file engine. Is IODevice open?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->writeBuffer.isEmpty()) {
|
||||
qint64 size = d->writeBuffer.size();
|
||||
if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->fileEngine->flush()) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Calls QFileDevice::flush() and closes the file. Errors from flush are ignored.
|
||||
|
||||
\sa QIODevice::close()
|
||||
*/
|
||||
void QFileDevice::close()
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!isOpen())
|
||||
return;
|
||||
bool flushed = flush();
|
||||
QIODevice::close();
|
||||
|
||||
// reset write buffer
|
||||
d->lastWasWrite = false;
|
||||
d->writeBuffer.clear();
|
||||
|
||||
// keep earlier error from flush
|
||||
if (d->fileEngine->close() && flushed)
|
||||
unsetError();
|
||||
else if (flushed)
|
||||
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFileDevice::pos() const
|
||||
{
|
||||
return QIODevice::pos();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the end of the file has been reached; otherwise returns
|
||||
false.
|
||||
|
||||
For regular empty files on Unix (e.g. those in \c /proc), this function
|
||||
returns true, since the file system reports that the size of such a file is
|
||||
0. Therefore, you should not depend on atEnd() when reading data from such a
|
||||
file, but rather call read() until no more data can be read.
|
||||
*/
|
||||
bool QFileDevice::atEnd() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
|
||||
// If there's buffered data left, we're not at the end.
|
||||
if (!d->buffer.isEmpty())
|
||||
return false;
|
||||
|
||||
if (!isOpen())
|
||||
return true;
|
||||
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
|
||||
// If the file engine knows best, say what it says.
|
||||
if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
|
||||
// Check if the file engine supports AtEndExtension, and if it does,
|
||||
// check if the file engine claims to be at the end.
|
||||
return d->fileEngine->atEnd();
|
||||
}
|
||||
|
||||
// if it looks like we are at the end, or if size is not cached,
|
||||
// fall through to bytesAvailable() to make sure.
|
||||
if (pos() < d->cachedSize)
|
||||
return false;
|
||||
|
||||
// Fall back to checking how much is available (will stat files).
|
||||
return bytesAvailable() == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool QFileDevice::seek(qint64 pos)
|
||||
|
||||
For random-access devices, this function sets the current position
|
||||
to \a pos, returning true on success, or false if an error occurred.
|
||||
For sequential devices, the default behavior is to do nothing and
|
||||
return false.
|
||||
|
||||
Seeking beyond the end of a file:
|
||||
If the position is beyond the end of a file, then seek() shall not
|
||||
immediately extend the file. If a write is performed at this position,
|
||||
then the file shall be extended. The content of the file between the
|
||||
previous end of file and the newly written data is UNDEFINED and
|
||||
varies between platforms and file systems.
|
||||
*/
|
||||
bool QFileDevice::seek(qint64 off)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!isOpen()) {
|
||||
qWarning("QFileDevice::seek: IODevice is not open");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
|
||||
if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::PositionError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
unsetError();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFileDevice::readLineData(char *data, qint64 maxlen)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!d->ensureFlushed())
|
||||
return -1;
|
||||
|
||||
qint64 read;
|
||||
if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
|
||||
read = d->fileEngine->readLine(data, maxlen);
|
||||
} else {
|
||||
// Fall back to QIODevice's readLine implementation if the engine
|
||||
// cannot do it faster.
|
||||
read = QIODevice::readLineData(data, maxlen);
|
||||
}
|
||||
|
||||
if (read < maxlen) {
|
||||
// failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
|
||||
d->cachedSize = 0;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFileDevice::readData(char *data, qint64 len)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
unsetError();
|
||||
if (!d->ensureFlushed())
|
||||
return -1;
|
||||
|
||||
const qint64 read = d->fileEngine->read(data, len);
|
||||
if (read < 0) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::ReadError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
}
|
||||
|
||||
if (read < len) {
|
||||
// failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
|
||||
d->cachedSize = 0;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
bool QFileDevicePrivate::putCharHelper(char c)
|
||||
{
|
||||
#ifdef QT_NO_QOBJECT
|
||||
return QIODevicePrivate::putCharHelper(c);
|
||||
#else
|
||||
|
||||
// Cutoff for code that doesn't only touch the buffer.
|
||||
int writeBufferSize = writeBuffer.size();
|
||||
if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
|
||||
#ifdef Q_OS_WIN
|
||||
|| ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
|
||||
#endif
|
||||
) {
|
||||
return QIODevicePrivate::putCharHelper(c);
|
||||
}
|
||||
|
||||
if (!(openMode & QIODevice::WriteOnly)) {
|
||||
if (openMode == QIODevice::NotOpen)
|
||||
qWarning("QIODevice::putChar: Closed device");
|
||||
else
|
||||
qWarning("QIODevice::putChar: ReadOnly device");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the device is positioned correctly.
|
||||
const bool sequential = isSequential();
|
||||
if (pos != devicePos && !sequential && !q_func()->seek(pos))
|
||||
return false;
|
||||
|
||||
lastWasWrite = true;
|
||||
|
||||
int len = 1;
|
||||
#ifdef Q_OS_WIN
|
||||
if ((openMode & QIODevice::Text) && c == '\n') {
|
||||
++len;
|
||||
*writeBuffer.reserve(1) = '\r';
|
||||
}
|
||||
#endif
|
||||
|
||||
// Write to buffer.
|
||||
*writeBuffer.reserve(1) = c;
|
||||
|
||||
if (!sequential) {
|
||||
pos += len;
|
||||
devicePos += len;
|
||||
if (!buffer.isEmpty())
|
||||
buffer.skip(len);
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFileDevice::writeData(const char *data, qint64 len)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
unsetError();
|
||||
d->lastWasWrite = true;
|
||||
bool buffered = !(d->openMode & Unbuffered);
|
||||
|
||||
// Flush buffered data if this read will overflow.
|
||||
if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
|
||||
if (!flush())
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write directly to the engine if the block size is larger than
|
||||
// the write buffer size.
|
||||
if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
|
||||
const qint64 ret = d->fileEngine->write(data, len);
|
||||
if (ret < 0) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Write to the buffer.
|
||||
char *writePointer = d->writeBuffer.reserve(len);
|
||||
if (len == 1)
|
||||
*writePointer = *data;
|
||||
else
|
||||
::memcpy(writePointer, data, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the file error status.
|
||||
|
||||
The I/O device status returns an error code. For example, if open()
|
||||
returns false, or a read/write operation returns -1, this function can
|
||||
be called to find out the reason why the operation failed.
|
||||
|
||||
\sa unsetError()
|
||||
*/
|
||||
QFileDevice::FileError QFileDevice::error() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
return d->error;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the file's error to QFileDevice::NoError.
|
||||
|
||||
\sa error()
|
||||
*/
|
||||
void QFileDevice::unsetError()
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
d->setError(QFileDevice::NoError);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the size of the file.
|
||||
|
||||
For regular empty files on Unix (e.g. those in \c /proc), this function
|
||||
returns 0; the contents of such a file are generated on demand in response
|
||||
to you calling read().
|
||||
*/
|
||||
qint64 QFileDevice::size() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
if (!d->ensureFlushed())
|
||||
return 0;
|
||||
d->cachedSize = d->engine()->size();
|
||||
return d->cachedSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the file size (in bytes) \a sz. Returns true if the file if the
|
||||
resize succeeds; false otherwise. If \a sz is larger than the file
|
||||
currently is the new bytes will be set to 0, if \a sz is smaller the
|
||||
file is simply truncated.
|
||||
|
||||
\sa size()
|
||||
*/
|
||||
bool QFileDevice::resize(qint64 sz)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
d->engine();
|
||||
if (isOpen() && d->fileEngine->pos() > sz)
|
||||
seek(sz);
|
||||
if (d->fileEngine->setSize(sz)) {
|
||||
unsetError();
|
||||
d->cachedSize = sz;
|
||||
return true;
|
||||
}
|
||||
d->cachedSize = 0;
|
||||
d->setError(QFile::ResizeError, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the complete OR-ed together combination of
|
||||
QFile::Permission for the file.
|
||||
|
||||
\sa setPermissions()
|
||||
*/
|
||||
QFile::Permissions QFileDevice::permissions() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
|
||||
return QFile::Permissions((int)perms); //ewww
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the permissions for the file to the \a permissions specified.
|
||||
Returns true if successful, or false if the permissions cannot be
|
||||
modified.
|
||||
|
||||
\sa permissions()
|
||||
*/
|
||||
bool QFileDevice::setPermissions(Permissions permissions)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (d->engine()->setPermissions(permissions)) {
|
||||
unsetError();
|
||||
return true;
|
||||
}
|
||||
d->setError(QFile::PermissionsError, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::MemoryMapFlags
|
||||
\since 4.4
|
||||
|
||||
This enum describes special options that may be used by the map()
|
||||
function.
|
||||
|
||||
\value NoOptions No options.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Maps \a size bytes of the file into memory starting at \a offset. A file
|
||||
should be open for a map to succeed but the file does not need to stay
|
||||
open after the memory has been mapped. When the QFile is destroyed
|
||||
or a new file is opened with this object, any maps that have not been
|
||||
unmapped will automatically be unmapped.
|
||||
|
||||
Any mapping options can be passed through \a flags.
|
||||
|
||||
Returns a pointer to the memory or 0 if there is an error.
|
||||
|
||||
\note On Windows CE 5.0 the file will be closed before mapping occurs.
|
||||
|
||||
\sa unmap()
|
||||
*/
|
||||
uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (d->engine()
|
||||
&& d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
|
||||
unsetError();
|
||||
uchar *address = d->fileEngine->map(offset, size, flags);
|
||||
if (address == 0)
|
||||
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
|
||||
return address;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Unmaps the memory \a address.
|
||||
|
||||
Returns true if the unmap succeeds; false otherwise.
|
||||
|
||||
\sa map()
|
||||
*/
|
||||
bool QFileDevice::unmap(uchar *address)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (d->engine()
|
||||
&& d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
|
||||
unsetError();
|
||||
bool success = d->fileEngine->unmap(address);
|
||||
if (!success)
|
||||
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
|
||||
return success;
|
||||
}
|
||||
d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
147
src/corelib/io/qfiledevice.h
Normal file
147
src/corelib/io/qfiledevice.h
Normal file
@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QFILEDEVICE_H
|
||||
#define QFILEDEVICE_H
|
||||
|
||||
#include <QtCore/qiodevice.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFileDevicePrivate;
|
||||
|
||||
class Q_CORE_EXPORT QFileDevice : public QIODevice
|
||||
{
|
||||
#ifndef QT_NO_QOBJECT
|
||||
Q_OBJECT
|
||||
#endif
|
||||
Q_DECLARE_PRIVATE(QFileDevice)
|
||||
|
||||
public:
|
||||
enum FileError {
|
||||
NoError = 0,
|
||||
ReadError = 1,
|
||||
WriteError = 2,
|
||||
FatalError = 3,
|
||||
ResourceError = 4,
|
||||
OpenError = 5,
|
||||
AbortError = 6,
|
||||
TimeOutError = 7,
|
||||
UnspecifiedError = 8,
|
||||
RemoveError = 9,
|
||||
RenameError = 10,
|
||||
PositionError = 11,
|
||||
ResizeError = 12,
|
||||
PermissionsError = 13,
|
||||
CopyError = 14
|
||||
};
|
||||
|
||||
enum Permission {
|
||||
ReadOwner = 0x4000, WriteOwner = 0x2000, ExeOwner = 0x1000,
|
||||
ReadUser = 0x0400, WriteUser = 0x0200, ExeUser = 0x0100,
|
||||
ReadGroup = 0x0040, WriteGroup = 0x0020, ExeGroup = 0x0010,
|
||||
ReadOther = 0x0004, WriteOther = 0x0002, ExeOther = 0x0001
|
||||
};
|
||||
Q_DECLARE_FLAGS(Permissions, Permission)
|
||||
|
||||
enum FileHandleFlag {
|
||||
AutoCloseHandle = 0x0001,
|
||||
DontCloseHandle = 0
|
||||
};
|
||||
Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)
|
||||
|
||||
~QFileDevice();
|
||||
|
||||
FileError error() const;
|
||||
void unsetError();
|
||||
|
||||
virtual void close();
|
||||
|
||||
bool isSequential() const;
|
||||
|
||||
int handle() const;
|
||||
virtual QString fileName() const;
|
||||
|
||||
qint64 pos() const;
|
||||
bool seek(qint64 offset);
|
||||
bool atEnd() const;
|
||||
bool flush();
|
||||
|
||||
qint64 size() const;
|
||||
|
||||
virtual bool resize(qint64 sz);
|
||||
virtual Permissions permissions() const;
|
||||
virtual bool setPermissions(Permissions permissionSpec);
|
||||
|
||||
enum MemoryMapFlags {
|
||||
NoOptions = 0
|
||||
};
|
||||
|
||||
uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
|
||||
bool unmap(uchar *address);
|
||||
|
||||
protected:
|
||||
QFileDevice();
|
||||
#ifdef QT_NO_QOBJECT
|
||||
QFileDevice(QFileDevicePrivate &dd);
|
||||
#else
|
||||
explicit QFileDevice(QObject *parent);
|
||||
QFileDevice(QFileDevicePrivate &dd, QObject *parent = 0);
|
||||
#endif
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
qint64 writeData(const char *data, qint64 len);
|
||||
qint64 readLineData(char *data, qint64 maxlen);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QFileDevice)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QFileDevice::Permissions)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QFILEDEVICE_H
|
104
src/corelib/io/qfiledevice_p.h
Normal file
104
src/corelib/io/qfiledevice_p.h
Normal file
@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QFILEDEVICE_P_H
|
||||
#define QFILEDEVICE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qiodevice_p.h"
|
||||
#include "private/qringbuffer_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAbstractFileEngine;
|
||||
class QFSFileEngine;
|
||||
|
||||
class QFileDevicePrivate : public QIODevicePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QFileDevice)
|
||||
protected:
|
||||
QFileDevicePrivate();
|
||||
~QFileDevicePrivate();
|
||||
|
||||
virtual QAbstractFileEngine *engine() const;
|
||||
|
||||
QFileDevice::FileHandleFlags handleFlags;
|
||||
|
||||
mutable QAbstractFileEngine *fileEngine;
|
||||
bool lastWasWrite;
|
||||
QRingBuffer writeBuffer;
|
||||
inline bool ensureFlushed() const;
|
||||
|
||||
bool putCharHelper(char c);
|
||||
|
||||
QFileDevice::FileError error;
|
||||
void setError(QFileDevice::FileError err);
|
||||
void setError(QFileDevice::FileError err, const QString &errorString);
|
||||
void setError(QFileDevice::FileError err, int errNum);
|
||||
|
||||
mutable qint64 cachedSize;
|
||||
};
|
||||
|
||||
inline bool QFileDevicePrivate::ensureFlushed() const
|
||||
{
|
||||
// This function ensures that the write buffer has been flushed (const
|
||||
// because certain const functions need to call it.
|
||||
if (lastWasWrite) {
|
||||
const_cast<QFileDevicePrivate *>(this)->lastWasWrite = false;
|
||||
if (!const_cast<QFileDevice *>(q_func())->flush())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QFILEDEVICE_P_H
|
@ -41,7 +41,6 @@
|
||||
|
||||
#include "qfilesystemengine_p.h"
|
||||
|
||||
#define _POSIX_
|
||||
#include "qplatformdefs.h"
|
||||
#include "private/qabstractfileengine_p.h"
|
||||
#include "private/qfsfileengine_p.h"
|
||||
|
@ -39,7 +39,6 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#define _POSIX_
|
||||
#include "qplatformdefs.h"
|
||||
#include "private/qabstractfileengine_p.h"
|
||||
#include "private/qfsfileengine_p.h"
|
||||
@ -66,6 +65,7 @@
|
||||
#include <accctrl.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#define SECURITY_WIN32
|
||||
#include <security.h>
|
||||
|
||||
|
344
src/corelib/io/qipaddress.cpp
Normal file
344
src/corelib/io/qipaddress.cpp
Normal file
@ -0,0 +1,344 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Intel Corporation
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qipaddress_p.h"
|
||||
#include "private/qlocale_tools_p.h"
|
||||
#include "qvarlengtharray.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace QIPAddressUtils {
|
||||
|
||||
static QString number(quint8 val, int base = 10)
|
||||
{
|
||||
QChar zero(0x30);
|
||||
return val ? qulltoa(val, base, zero) : zero;
|
||||
}
|
||||
|
||||
typedef QVarLengthArray<char, 64> Buffer;
|
||||
static bool checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
|
||||
{
|
||||
const ushort *const ubegin = reinterpret_cast<const ushort *>(begin);
|
||||
const ushort *const uend = reinterpret_cast<const ushort *>(end);
|
||||
const ushort *src = ubegin;
|
||||
|
||||
buffer.resize(uend - ubegin + 1);
|
||||
char *dst = buffer.data();
|
||||
|
||||
while (src != uend) {
|
||||
if (*src >= 0x7f)
|
||||
return false;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero);
|
||||
bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end)
|
||||
{
|
||||
Q_ASSERT(begin != end);
|
||||
Buffer buffer;
|
||||
if (!checkedToAscii(buffer, begin, end))
|
||||
return false;
|
||||
|
||||
const char *ptr = buffer.data();
|
||||
return parseIp4Internal(address, ptr, true);
|
||||
}
|
||||
|
||||
static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero)
|
||||
{
|
||||
address = 0;
|
||||
int dotCount = 0;
|
||||
while (dotCount < 4) {
|
||||
if (!acceptLeadingZero && *ptr == '0' &&
|
||||
ptr[1] != '.' && ptr[1] != '\0')
|
||||
return false;
|
||||
|
||||
const char *endptr;
|
||||
bool ok;
|
||||
quint64 ll = qstrtoull(ptr, &endptr, 0, &ok);
|
||||
quint32 x = ll;
|
||||
if (!ok || endptr == ptr || ll != x)
|
||||
return false;
|
||||
|
||||
if (*endptr == '.' || dotCount == 3) {
|
||||
if (x & ~0xff)
|
||||
return false;
|
||||
address <<= 8;
|
||||
} else if (dotCount == 2) {
|
||||
if (x & ~0xffff)
|
||||
return false;
|
||||
address <<= 16;
|
||||
} else if (dotCount == 1) {
|
||||
if (x & ~0xffffff)
|
||||
return false;
|
||||
address <<= 24;
|
||||
}
|
||||
address |= x;
|
||||
|
||||
if (dotCount == 3 && *endptr != '\0')
|
||||
return false;
|
||||
else if (dotCount == 3 || *endptr == '\0')
|
||||
return true;
|
||||
++dotCount;
|
||||
ptr = endptr + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void toString(QString &appendTo, IPv4Address address)
|
||||
{
|
||||
// reconstructing is easy
|
||||
// use the fast operator% that pre-calculates the size
|
||||
appendTo += number(address >> 24)
|
||||
% QLatin1Char('.')
|
||||
% number(address >> 16)
|
||||
% QLatin1Char('.')
|
||||
% number(address >> 8)
|
||||
% QLatin1Char('.')
|
||||
% number(address);
|
||||
}
|
||||
|
||||
bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
|
||||
{
|
||||
Q_ASSERT(begin != end);
|
||||
Buffer buffer;
|
||||
if (!checkedToAscii(buffer, begin, end))
|
||||
return false;
|
||||
|
||||
const char *ptr = buffer.data();
|
||||
|
||||
// count the colons
|
||||
int colonCount = 0;
|
||||
int dotCount = 0;
|
||||
while (*ptr) {
|
||||
if (*ptr == ':')
|
||||
++colonCount;
|
||||
if (*ptr == '.')
|
||||
++dotCount;
|
||||
++ptr;
|
||||
}
|
||||
// IPv4-in-IPv6 addresses are stricter in what they accept
|
||||
if (dotCount != 0 && dotCount != 3)
|
||||
return false;
|
||||
|
||||
memset(address, 0, sizeof address);
|
||||
if (colonCount == 2 && end - begin == 2) // "::"
|
||||
return true;
|
||||
|
||||
// if there's a double colon ("::"), this is how many zeroes it means
|
||||
int zeroWordsToFill;
|
||||
ptr = buffer.data();
|
||||
|
||||
// there are two cases where 8 colons are allowed: at the ends
|
||||
// so test that before the colon-count test
|
||||
if ((ptr[0] == ':' && ptr[1] == ':') ||
|
||||
(ptr[end - begin - 2] == ':' && ptr[end - begin - 1] == ':')) {
|
||||
zeroWordsToFill = 9 - colonCount;
|
||||
} else if (colonCount < 2 || colonCount > 7) {
|
||||
return false;
|
||||
} else {
|
||||
zeroWordsToFill = 8 - colonCount;
|
||||
}
|
||||
if (dotCount)
|
||||
--zeroWordsToFill;
|
||||
|
||||
int pos = 0;
|
||||
while (pos < 15) {
|
||||
const char *endptr;
|
||||
bool ok;
|
||||
quint64 ll = qstrtoull(ptr, &endptr, 16, &ok);
|
||||
quint16 x = ll;
|
||||
|
||||
if (ptr == endptr) {
|
||||
// empty field, we hope it's "::"
|
||||
if (zeroWordsToFill < 1)
|
||||
return false;
|
||||
if (pos == 0 || pos == colonCount * 2) {
|
||||
if (ptr[0] == '\0' || ptr[1] != ':')
|
||||
return false;
|
||||
++ptr;
|
||||
}
|
||||
pos += zeroWordsToFill * 2;
|
||||
zeroWordsToFill = 0;
|
||||
++ptr;
|
||||
continue;
|
||||
}
|
||||
if (!ok || ll != x)
|
||||
return false;
|
||||
|
||||
if (*endptr == '.') {
|
||||
// this could be an IPv4 address
|
||||
// it's only valid in the last element
|
||||
if (pos != 12)
|
||||
return false;
|
||||
|
||||
IPv4Address ip4;
|
||||
if (!parseIp4Internal(ip4, ptr, false))
|
||||
return false;
|
||||
|
||||
address[12] = ip4 >> 24;
|
||||
address[13] = ip4 >> 16;
|
||||
address[14] = ip4 >> 8;
|
||||
address[15] = ip4;
|
||||
return true;
|
||||
}
|
||||
|
||||
address[pos++] = x >> 8;
|
||||
address[pos++] = x & 0xff;
|
||||
|
||||
if (*endptr == '\0')
|
||||
break;
|
||||
if (*endptr != ':')
|
||||
return false;
|
||||
ptr = endptr + 1;
|
||||
}
|
||||
return pos == 16;
|
||||
}
|
||||
|
||||
static inline QChar toHex(uchar c)
|
||||
{
|
||||
return ushort(c > 9 ? c + 'a' - 0xA : c + '0');
|
||||
}
|
||||
|
||||
void toString(QString &appendTo, IPv6Address address)
|
||||
{
|
||||
// the longest IPv6 address possible is:
|
||||
// "1111:2222:3333:4444:5555:6666:255.255.255.255"
|
||||
// however, this function never generates that. The longest it does
|
||||
// generate without an IPv4 address is:
|
||||
// "1111:2222:3333:4444:5555:6666:7777:8888"
|
||||
// and the longest with an IPv4 address is:
|
||||
// "::ffff:255.255.255.255"
|
||||
static const int Ip6AddressMaxLen = sizeof "1111:2222:3333:4444:5555:6666:7777:8888";
|
||||
static const int Ip6WithIp4AddressMaxLen = sizeof "::ffff:255.255.255.255";
|
||||
|
||||
// check for the special cases
|
||||
const quint64 zeroes[] = { 0, 0 };
|
||||
bool embeddedIp4 = false;
|
||||
|
||||
// we consider embedded IPv4 for:
|
||||
// ::ffff:x.x.x.x
|
||||
// ::x.x.x.y except if the x are 0 too
|
||||
if (memcmp(address, zeroes, 10) == 0) {
|
||||
if (address[10] == 0xff && address[11] == 0xff) {
|
||||
embeddedIp4 = true;
|
||||
} else if (address[10] == 0 && address[11] == 0) {
|
||||
if (address[12] != 0 || address[13] != 0 || address[14] != 0) {
|
||||
embeddedIp4 = true;
|
||||
} else if (address[15] == 0) {
|
||||
appendTo.append(QLatin1String("::"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// QString::reserve doesn't shrink, so it's fine to us
|
||||
appendTo.reserve(appendTo.size() +
|
||||
(embeddedIp4 ? Ip6WithIp4AddressMaxLen : Ip6AddressMaxLen));
|
||||
|
||||
// for finding where to place the "::"
|
||||
int zeroRunLength = 0; // in octets
|
||||
int zeroRunOffset = 0; // in octets
|
||||
for (int i = 0; i < 16; i += 2) {
|
||||
if (address[i] == 0 && address[i + 1] == 0) {
|
||||
// found a zero, scan forward to see how many more there are
|
||||
int j;
|
||||
for (j = i; j < 16; j += 2) {
|
||||
if (address[j] != 0 || address[j+1] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j - i > zeroRunLength) {
|
||||
zeroRunLength = j - i;
|
||||
zeroRunOffset = i;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QChar colon = ushort(':');
|
||||
if (zeroRunLength < 4)
|
||||
zeroRunOffset = -1;
|
||||
else if (zeroRunOffset == 0)
|
||||
appendTo.append(colon);
|
||||
|
||||
for (int i = 0; i < 16; i += 2) {
|
||||
if (i == zeroRunOffset) {
|
||||
appendTo.append(colon);
|
||||
i += zeroRunLength - 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == 12 && embeddedIp4) {
|
||||
IPv4Address ip4 = address[12] << 24 |
|
||||
address[13] << 16 |
|
||||
address[14] << 8 |
|
||||
address[15];
|
||||
toString(appendTo, ip4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (address[i]) {
|
||||
if (address[i] >> 4) {
|
||||
appendTo.append(toHex(address[i] >> 4));
|
||||
appendTo.append(toHex(address[i] & 0xf));
|
||||
appendTo.append(toHex(address[i + 1] >> 4));
|
||||
appendTo.append(toHex(address[i + 1] & 0xf));
|
||||
} else if (address[i] & 0xf) {
|
||||
appendTo.append(toHex(address[i] & 0xf));
|
||||
appendTo.append(toHex(address[i + 1] >> 4));
|
||||
appendTo.append(toHex(address[i + 1] & 0xf));
|
||||
}
|
||||
} else if (address[i + 1] >> 4) {
|
||||
appendTo.append(toHex(address[i + 1] >> 4));
|
||||
appendTo.append(toHex(address[i + 1] & 0xf));
|
||||
} else {
|
||||
appendTo.append(toHex(address[i + 1] & 0xf));
|
||||
}
|
||||
|
||||
if (i != 14)
|
||||
appendTo.append(colon);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
QT_END_NAMESPACE
|
@ -1,9 +1,9 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 Intel Corporation
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtTest module of the Qt Toolkit.
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
@ -39,31 +39,36 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef OLDNORMALIZEOBJECT_H
|
||||
#define OLDNORMALIZEOBJECT_H
|
||||
#ifndef QIPADDRESS_P_H
|
||||
#define QIPADDRESS_P_H
|
||||
|
||||
#include <QObject>
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience of
|
||||
// qurl*.cpp This header file may change from version to version without
|
||||
// notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
struct Struct;
|
||||
class Class;
|
||||
template <typename T> class Template;
|
||||
#include "qstring.h"
|
||||
|
||||
// An object with old moc output that incorrectly normalizes 'T<C> const &' in the function
|
||||
// signatures
|
||||
class OldNormalizeObject : public QObject
|
||||
{
|
||||
/* tmake ignore Q_OBJECT */
|
||||
Q_OBJECT
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
signals:
|
||||
void typeRefSignal(Template<Class &> &ref);
|
||||
void constTypeRefSignal(const Template<const Class &> &ref);
|
||||
void typeConstRefSignal(Template<Class const &> const &ref);
|
||||
namespace QIPAddressUtils {
|
||||
|
||||
public slots:
|
||||
void typeRefSlot(Template<Class &> &) {}
|
||||
void constTypeRefSlot(const Template<const Class &> &) {}
|
||||
void typeConstRefSlot(Template<Class const &> const &) {}
|
||||
};
|
||||
typedef quint32 IPv4Address;
|
||||
typedef quint8 IPv6Address[16];
|
||||
|
||||
#endif // OLDNORMALIZEOBJECT_H
|
||||
Q_CORE_EXPORT bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end);
|
||||
Q_CORE_EXPORT bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end);
|
||||
Q_CORE_EXPORT void toString(QString &appendTo, IPv4Address address);
|
||||
Q_CORE_EXPORT void toString(QString &appendTo, IPv6Address address);
|
||||
|
||||
} // namespace
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QIPADDRESS_P_H
|
@ -673,7 +673,7 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const
|
||||
qDebug() << " " << child+j << " :: " << name(child+j);
|
||||
}
|
||||
#endif
|
||||
const uint h = qHash(segment);
|
||||
const uint h = qt_hash(segment.toString());
|
||||
|
||||
//do the binary search for the hash
|
||||
int l = 0, r = child_count-1;
|
||||
|
@ -309,6 +309,27 @@ QString QStandardPaths::displayName(StandardLocation type)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\fn void QStandardPaths::enableTestMode(bool testMode)
|
||||
|
||||
Enables "test mode" in QStandardPaths, which changes writable locations
|
||||
to point to test directories, in order to prevent auto tests from reading from
|
||||
or writing to the current user's configuration.
|
||||
|
||||
This affects the locations into which test programs might write files:
|
||||
GenericDataLocation, DataLocation, ConfigLocation,
|
||||
GenericCacheLocation, CacheLocation.
|
||||
Other locations are not affected.
|
||||
|
||||
On Unix, XDG_DATA_HOME is set to ~/.qttest/share, XDG_CONFIG_HOME is
|
||||
set to ~/.qttest/config, and XDG_CACHE_HOME is set to ~/.qttest/cache.
|
||||
|
||||
On Mac, data goes to "~/.qttest/Application Support", cache goes to
|
||||
~/.qttest/Cache, and config goes to ~/.qttest/Preferences.
|
||||
|
||||
On Windows, everything goes to a "qttest" directory under Application Data.
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_STANDARDPATHS
|
||||
|
@ -91,6 +91,8 @@ public:
|
||||
|
||||
static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList());
|
||||
|
||||
static void enableTestMode(bool testMode);
|
||||
|
||||
private:
|
||||
// prevent construction
|
||||
QStandardPaths();
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QAtomicPointer>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#ifndef QT_NO_STANDARDPATHS
|
||||
|
||||
@ -62,6 +63,23 @@ public:
|
||||
|
||||
Q_GLOBAL_STATIC(QStandardPathsPrivate, configCache);
|
||||
|
||||
static bool qsp_testMode = false;
|
||||
|
||||
void QStandardPaths::enableTestMode(bool testMode)
|
||||
{
|
||||
qsp_testMode = testMode;
|
||||
}
|
||||
|
||||
static void appendOrganizationAndApp(QString &path)
|
||||
{
|
||||
const QString org = QCoreApplication::organizationName();
|
||||
if (!org.isEmpty())
|
||||
path += QLatin1Char('/') + org;
|
||||
const QString appName = QCoreApplication::applicationName();
|
||||
if (!appName.isEmpty())
|
||||
path += QLatin1Char('/') + appName;
|
||||
}
|
||||
|
||||
QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -73,6 +91,30 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (qsp_testMode) {
|
||||
const QString qttestDir = QDir::homePath() + QLatin1String("/.qttest");
|
||||
QString path;
|
||||
switch (type) {
|
||||
case GenericDataLocation:
|
||||
case DataLocation:
|
||||
path = qttestDir + QLatin1String("/share");
|
||||
if (type == DataLocation)
|
||||
appendOrganizationAndApp(path);
|
||||
return path;
|
||||
case GenericCacheLocation:
|
||||
case CacheLocation:
|
||||
path = qttestDir + QLatin1String("/cache");
|
||||
if (type == CacheLocation)
|
||||
appendOrganizationAndApp(path);
|
||||
return path;
|
||||
case ConfigLocation:
|
||||
return qttestDir + QLatin1String("/config");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QJsonObject * localConfigObject = configCache()->object.loadAcquire();
|
||||
if (localConfigObject == 0) {
|
||||
QString configHome = QFile::decodeName(qgetenv("PATH_CONFIG_HOME"));
|
||||
|
@ -90,6 +90,13 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
|
||||
}
|
||||
}
|
||||
|
||||
static bool qsp_testMode = false;
|
||||
|
||||
void QStandardPaths::enableTestMode(bool testMode)
|
||||
{
|
||||
qsp_testMode = testMode;
|
||||
}
|
||||
|
||||
/*
|
||||
Constructs a full unicode path from a FSRef.
|
||||
*/
|
||||
@ -101,6 +108,16 @@ static QString getFullPath(const FSRef &ref)
|
||||
return QString();
|
||||
}
|
||||
|
||||
static void appendOrganizationAndApp(QString &path)
|
||||
{
|
||||
const QString org = QCoreApplication::organizationName();
|
||||
if (!org.isEmpty())
|
||||
path += QLatin1Char('/') + org;
|
||||
const QString appName = QCoreApplication::applicationName();
|
||||
if (!appName.isEmpty())
|
||||
path += QLatin1Char('/') + appName;
|
||||
}
|
||||
|
||||
static QString macLocation(QStandardPaths::StandardLocation type, short domain)
|
||||
{
|
||||
// http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
|
||||
@ -111,17 +128,36 @@ static QString macLocation(QStandardPaths::StandardLocation type, short domain)
|
||||
|
||||
QString path = getFullPath(ref);
|
||||
|
||||
if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation) {
|
||||
if (!QCoreApplication::organizationName().isEmpty())
|
||||
path += QLatin1Char('/') + QCoreApplication::organizationName();
|
||||
if (!QCoreApplication::applicationName().isEmpty())
|
||||
path += QLatin1Char('/') + QCoreApplication::applicationName();
|
||||
}
|
||||
return path;
|
||||
if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation)
|
||||
appendOrganizationAndApp(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
{
|
||||
if (qsp_testMode) {
|
||||
const QString qttestDir = QDir::homePath() + QLatin1String("/.qttest");
|
||||
QString path;
|
||||
switch (type) {
|
||||
case GenericDataLocation:
|
||||
case DataLocation:
|
||||
path = qttestDir + QLatin1String("/Application Support");
|
||||
if (type == DataLocation)
|
||||
appendOrganizationAndApp(path);
|
||||
return path;
|
||||
case GenericCacheLocation:
|
||||
case CacheLocation:
|
||||
path = qttestDir + QLatin1String("/Cache");
|
||||
if (type == CacheLocation)
|
||||
appendOrganizationAndApp(path);
|
||||
return path;
|
||||
case ConfigLocation:
|
||||
return qttestDir + QLatin1String("/Preferences");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case HomeLocation:
|
||||
return QDir::homePath();
|
||||
|
@ -63,6 +63,13 @@ static void appendOrganizationAndApp(QString &path)
|
||||
path += QLatin1Char('/') + appName;
|
||||
}
|
||||
|
||||
static bool qsp_testMode = false;
|
||||
|
||||
void QStandardPaths::enableTestMode(bool testMode)
|
||||
{
|
||||
qsp_testMode = testMode;
|
||||
}
|
||||
|
||||
QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -75,6 +82,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
{
|
||||
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
|
||||
QString xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
|
||||
if (qsp_testMode)
|
||||
xdgCacheHome = QDir::homePath() + QLatin1String("/.qttest/cache");
|
||||
if (xdgCacheHome.isEmpty())
|
||||
xdgCacheHome = QDir::homePath() + QLatin1String("/.cache");
|
||||
if (type == QStandardPaths::CacheLocation)
|
||||
@ -85,6 +94,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
case GenericDataLocation:
|
||||
{
|
||||
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
|
||||
if (qsp_testMode)
|
||||
xdgDataHome = QDir::homePath() + QLatin1String("/.qttest/share");
|
||||
if (xdgDataHome.isEmpty())
|
||||
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
|
||||
if (type == QStandardPaths::DataLocation)
|
||||
@ -95,6 +106,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
{
|
||||
// http://standards.freedesktop.org/basedir-spec/latest/
|
||||
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
|
||||
if (qsp_testMode)
|
||||
xdgConfigHome = QDir::homePath() + QLatin1String("/.qttest/config");
|
||||
if (xdgConfigHome.isEmpty())
|
||||
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
|
||||
return xdgConfigHome;
|
||||
@ -140,7 +153,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
if (xdgConfigHome.isEmpty())
|
||||
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
|
||||
QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs"));
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
if (!qsp_testMode && file.open(QIODevice::ReadOnly)) {
|
||||
QHash<QString, QString> lines;
|
||||
QTextStream stream(&file);
|
||||
// Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop"
|
||||
|
@ -85,6 +85,13 @@ static QString convertCharArray(const wchar_t *path)
|
||||
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
|
||||
}
|
||||
|
||||
static bool qsp_testMode = false;
|
||||
|
||||
void QStandardPaths::enableTestMode(bool testMode)
|
||||
{
|
||||
qsp_testMode = testMode;
|
||||
}
|
||||
|
||||
QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
{
|
||||
QString result;
|
||||
@ -105,6 +112,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
|
||||
#endif
|
||||
result = convertCharArray(path);
|
||||
if (qsp_testMode)
|
||||
result += QLatin1String("/qttest");
|
||||
if (type != GenericDataLocation) {
|
||||
if (!QCoreApplication::organizationName().isEmpty())
|
||||
result += QLatin1Char('/') + QCoreApplication::organizationName();
|
||||
|
@ -696,7 +696,7 @@ void QTextStreamPrivate::flushWriteBuffer()
|
||||
|
||||
// flush the file
|
||||
#ifndef QT_NO_QOBJECT
|
||||
QFile *file = qobject_cast<QFile *>(device);
|
||||
QFileDevice *file = qobject_cast<QFileDevice *>(device);
|
||||
bool flushed = !file || file->flush();
|
||||
#else
|
||||
bool flushed = true;
|
||||
|
@ -44,12 +44,13 @@
|
||||
#include "private/qurltlds_p.h"
|
||||
#include "private/qtldurl_p.h"
|
||||
#include "QtCore/qstringlist.h"
|
||||
#include "QtCore/qhash.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static bool containsTLDEntry(const QString &entry)
|
||||
{
|
||||
int index = qHash(entry) % tldCount;
|
||||
int index = qt_hash(entry) % tldCount;
|
||||
int currentDomainIndex = tldIndices[index];
|
||||
while (currentDomainIndex < tldIndices[index+1]) {
|
||||
QString currentEntry = QString::fromUtf8(tldData + currentDomainIndex);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 Intel Corporation.
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -44,18 +45,74 @@
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QUrlQuery;
|
||||
class QUrlPrivate;
|
||||
class QDataStream;
|
||||
|
||||
template <typename E1, typename E2>
|
||||
class QUrlTwoFlags
|
||||
{
|
||||
int i;
|
||||
typedef int QUrlTwoFlags:: *Zero;
|
||||
public:
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags(E1 f) : i(f) {}
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags(E2 f) : i(f) {}
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags(QFlag f) : i(f) {}
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags(QFlags<E1> f) : i(f.operator int()) {}
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags(QFlags<E2> f) : i(f.operator int()) {}
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags(Zero = 0) : i(0) {}
|
||||
|
||||
inline QUrlTwoFlags &operator&=(int mask) { i &= mask; return *this; }
|
||||
inline QUrlTwoFlags &operator&=(uint mask) { i &= mask; return *this; }
|
||||
inline QUrlTwoFlags &operator|=(QUrlTwoFlags f) { i |= f.i; return *this; }
|
||||
inline QUrlTwoFlags &operator|=(E1 f) { i |= f; return *this; }
|
||||
inline QUrlTwoFlags &operator|=(E2 f) { i |= f; return *this; }
|
||||
inline QUrlTwoFlags &operator^=(QUrlTwoFlags f) { i ^= f.i; return *this; }
|
||||
inline QUrlTwoFlags &operator^=(E1 f) { i ^= f; return *this; }
|
||||
inline QUrlTwoFlags &operator^=(E2 f) { i ^= f; return *this; }
|
||||
|
||||
Q_DECL_CONSTEXPR inline operator QFlags<E1>() const { return E1(i); }
|
||||
Q_DECL_CONSTEXPR inline operator QFlags<E2>() const { return E2(i); }
|
||||
Q_DECL_CONSTEXPR inline operator int() const { return i; }
|
||||
Q_DECL_CONSTEXPR inline bool operator!() const { return !i; }
|
||||
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator|(QUrlTwoFlags f) const
|
||||
{ return QUrlTwoFlags(E1(i | f.i)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator|(E1 f) const
|
||||
{ return QUrlTwoFlags(E1(i | f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator|(E2 f) const
|
||||
{ return QUrlTwoFlags(E2(i | f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator^(QUrlTwoFlags f) const
|
||||
{ return QUrlTwoFlags(E1(i ^ f.i)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator^(E1 f) const
|
||||
{ return QUrlTwoFlags(E1(i ^ f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator^(E2 f) const
|
||||
{ return QUrlTwoFlags(E2(i ^ f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(int mask) const
|
||||
{ return QUrlTwoFlags(E1(i & mask)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(uint mask) const
|
||||
{ return QUrlTwoFlags(E1(i & mask)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(E1 f) const
|
||||
{ return QUrlTwoFlags(E1(i & f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(E2 f) const
|
||||
{ return QUrlTwoFlags(E2(i & f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator~() const
|
||||
{ return QUrlTwoFlags(E1(~i)); }
|
||||
|
||||
inline bool testFlag(E1 f) const { return (i & f) == f && (f != 0 || i == int(f)); }
|
||||
inline bool testFlag(E2 f) const { return (i & f) == f && (f != 0 || i == int(f)); }
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QUrl
|
||||
{
|
||||
public:
|
||||
@ -65,7 +122,7 @@ public:
|
||||
};
|
||||
|
||||
// encoding / toString values
|
||||
enum FormattingOption {
|
||||
enum UrlFormattingOption {
|
||||
None = 0x0,
|
||||
RemoveScheme = 0x1,
|
||||
RemovePassword = 0x2,
|
||||
@ -75,23 +132,41 @@ public:
|
||||
RemovePath = 0x20,
|
||||
RemoveQuery = 0x40,
|
||||
RemoveFragment = 0x80,
|
||||
// 0x100: private: normalized
|
||||
|
||||
StripTrailingSlash = 0x10000
|
||||
// 0x100 was a private code in Qt 4, keep unused for a while
|
||||
PreferLocalFile = 0x200,
|
||||
StripTrailingSlash = 0x400
|
||||
};
|
||||
Q_DECLARE_FLAGS(FormattingOptions, FormattingOption)
|
||||
|
||||
enum ComponentFormattingOption {
|
||||
PrettyDecoded = 0x000000,
|
||||
EncodeSpaces = 0x100000,
|
||||
EncodeUnicode = 0x200000,
|
||||
EncodeDelimiters = 0x400000 | 0x800000,
|
||||
EncodeReserved = 0x1000000,
|
||||
DecodeReserved = 0x2000000,
|
||||
|
||||
FullyEncoded = EncodeSpaces | EncodeUnicode | EncodeDelimiters | EncodeReserved,
|
||||
MostDecoded = PrettyDecoded | DecodeReserved
|
||||
};
|
||||
Q_DECLARE_FLAGS(ComponentFormattingOptions, ComponentFormattingOption)
|
||||
#ifdef qdoc
|
||||
Q_DECLARE_FLAGS(FormattingOptions, UrlFormattingOption)
|
||||
#else
|
||||
typedef QUrlTwoFlags<UrlFormattingOption, ComponentFormattingOption> FormattingOptions;
|
||||
#endif
|
||||
|
||||
QUrl();
|
||||
#ifdef QT_NO_URL_CAST_FROM_STRING
|
||||
explicit
|
||||
#endif
|
||||
QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||
QUrl(const QUrl ©);
|
||||
QUrl &operator =(const QUrl ©);
|
||||
#ifndef QT_NO_URL_CAST_FROM_STRING
|
||||
QUrl &operator =(const QString &url);
|
||||
#ifdef QT_NO_URL_CAST_FROM_STRING
|
||||
explicit QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||
#else
|
||||
QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||
QUrl &operator=(const QString &url);
|
||||
#endif
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
QUrl(QUrl &&other) : d(0)
|
||||
{ qSwap(d, other.d); }
|
||||
inline QUrl &operator=(QUrl &&other)
|
||||
{ qSwap(d, other.d); return *this; }
|
||||
#endif
|
||||
@ -100,96 +175,63 @@ public:
|
||||
inline void swap(QUrl &other) { qSwap(d, other.d); }
|
||||
|
||||
void setUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||
QString url(FormattingOptions options = None) const;
|
||||
QString toString(FormattingOptions options = None) const;
|
||||
QString toDisplayString(FormattingOptions options = None) const;
|
||||
QString url(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
|
||||
QString toString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
|
||||
QString toDisplayString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
|
||||
|
||||
QByteArray toEncoded(FormattingOptions options = FullyEncoded) const;
|
||||
static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode);
|
||||
|
||||
static QUrl fromUserInput(const QString &userInput);
|
||||
|
||||
bool isValid() const;
|
||||
QString errorString() const;
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
void clear();
|
||||
|
||||
void setScheme(const QString &scheme);
|
||||
QString scheme() const;
|
||||
|
||||
void setAuthority(const QString &authority);
|
||||
QString authority() const;
|
||||
QString authority(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||
|
||||
void setUserInfo(const QString &userInfo);
|
||||
QString userInfo() const;
|
||||
QString userInfo(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||
|
||||
void setUserName(const QString &userName);
|
||||
QString userName() const;
|
||||
void setEncodedUserName(const QByteArray &userName);
|
||||
QByteArray encodedUserName() const;
|
||||
QString userName(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||
|
||||
void setPassword(const QString &password);
|
||||
QString password() const;
|
||||
void setEncodedPassword(const QByteArray &password);
|
||||
QByteArray encodedPassword() const;
|
||||
QString password(ComponentFormattingOptions = PrettyDecoded) const;
|
||||
|
||||
void setHost(const QString &host);
|
||||
QString host() const;
|
||||
void setEncodedHost(const QByteArray &host);
|
||||
QByteArray encodedHost() const;
|
||||
QString host(ComponentFormattingOptions = PrettyDecoded) const;
|
||||
QString topLevelDomain(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||
|
||||
void setPort(int port);
|
||||
int port(int defaultPort = -1) const;
|
||||
|
||||
void setPath(const QString &path);
|
||||
QString path() const;
|
||||
void setEncodedPath(const QByteArray &path);
|
||||
QByteArray encodedPath() const;
|
||||
QString path(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||
|
||||
bool hasQuery() const;
|
||||
void setQuery(const QString &query);
|
||||
void setQuery(const QUrlQuery &query);
|
||||
QString query(ComponentFormattingOptions = PrettyDecoded) const;
|
||||
|
||||
void setEncodedQuery(const QByteArray &query);
|
||||
QByteArray encodedQuery() const;
|
||||
|
||||
void setQueryDelimiters(char valueDelimiter, char pairDelimiter);
|
||||
char queryValueDelimiter() const;
|
||||
char queryPairDelimiter() const;
|
||||
|
||||
void setQueryItems(const QList<QPair<QString, QString> > &query);
|
||||
void addQueryItem(const QString &key, const QString &value);
|
||||
QList<QPair<QString, QString> > queryItems() const;
|
||||
bool hasQueryItem(const QString &key) const;
|
||||
QString queryItemValue(const QString &key) const;
|
||||
QStringList allQueryItemValues(const QString &key) const;
|
||||
void removeQueryItem(const QString &key);
|
||||
void removeAllQueryItems(const QString &key);
|
||||
|
||||
void setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &query);
|
||||
void addEncodedQueryItem(const QByteArray &key, const QByteArray &value);
|
||||
QList<QPair<QByteArray, QByteArray> > encodedQueryItems() const;
|
||||
bool hasEncodedQueryItem(const QByteArray &key) const;
|
||||
QByteArray encodedQueryItemValue(const QByteArray &key) const;
|
||||
QList<QByteArray> allEncodedQueryItemValues(const QByteArray &key) const;
|
||||
void removeEncodedQueryItem(const QByteArray &key);
|
||||
void removeAllEncodedQueryItems(const QByteArray &key);
|
||||
|
||||
void setFragment(const QString &fragment);
|
||||
QString fragment() const;
|
||||
void setEncodedFragment(const QByteArray &fragment);
|
||||
QByteArray encodedFragment() const;
|
||||
bool hasFragment() const;
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
QString topLevelDomain() const;
|
||||
#endif
|
||||
QString fragment(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||
void setFragment(const QString &fragment);
|
||||
|
||||
QUrl resolved(const QUrl &relative) const;
|
||||
|
||||
bool isRelative() const;
|
||||
bool isParentOf(const QUrl &url) const;
|
||||
|
||||
bool isLocalFile() const;
|
||||
static QUrl fromLocalFile(const QString &localfile);
|
||||
QString toLocalFile() const;
|
||||
bool isLocalFile() const;
|
||||
|
||||
QByteArray toEncoded(FormattingOptions options = None) const;
|
||||
|
||||
static QUrl fromUserInput(const QString &userInput);
|
||||
|
||||
void detach();
|
||||
bool isDetached() const;
|
||||
@ -202,37 +244,121 @@ public:
|
||||
static QByteArray toPercentEncoding(const QString &,
|
||||
const QByteArray &exclude = QByteArray(),
|
||||
const QByteArray &include = QByteArray());
|
||||
static QString fromPunycode(const QByteArray &);
|
||||
static QByteArray toPunycode(const QString &);
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
QT_DEPRECATED static QString fromPunycode(const QByteArray &punycode)
|
||||
{ return fromAce(punycode); }
|
||||
QT_DEPRECATED static QByteArray toPunycode(const QString &string)
|
||||
{ return toAce(string); }
|
||||
|
||||
QT_DEPRECATED inline void setQueryItems(const QList<QPair<QString, QString> > &qry);
|
||||
QT_DEPRECATED inline void addQueryItem(const QString &key, const QString &value);
|
||||
QT_DEPRECATED inline QList<QPair<QString, QString> > queryItems() const;
|
||||
QT_DEPRECATED inline bool hasQueryItem(const QString &key) const;
|
||||
QT_DEPRECATED inline QString queryItemValue(const QString &key) const;
|
||||
QT_DEPRECATED inline QStringList allQueryItemValues(const QString &key) const;
|
||||
QT_DEPRECATED inline void removeQueryItem(const QString &key);
|
||||
QT_DEPRECATED inline void removeAllQueryItems(const QString &key);
|
||||
|
||||
QT_DEPRECATED inline void setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &query);
|
||||
QT_DEPRECATED inline void addEncodedQueryItem(const QByteArray &key, const QByteArray &value);
|
||||
QT_DEPRECATED inline QList<QPair<QByteArray, QByteArray> > encodedQueryItems() const;
|
||||
QT_DEPRECATED inline bool hasEncodedQueryItem(const QByteArray &key) const;
|
||||
QT_DEPRECATED inline QByteArray encodedQueryItemValue(const QByteArray &key) const;
|
||||
QT_DEPRECATED inline QList<QByteArray> allEncodedQueryItemValues(const QByteArray &key) const;
|
||||
QT_DEPRECATED inline void removeEncodedQueryItem(const QByteArray &key);
|
||||
QT_DEPRECATED inline void removeAllEncodedQueryItems(const QByteArray &key);
|
||||
|
||||
QT_DEPRECATED void setEncodedUrl(const QByteArray &u, ParsingMode mode = TolerantMode)
|
||||
{ setUrl(QString::fromUtf8(u.constData(), u.size()), mode); }
|
||||
|
||||
QT_DEPRECATED QByteArray encodedUserName() const
|
||||
{ return userName(FullyEncoded).toLatin1(); }
|
||||
QT_DEPRECATED void setEncodedUserName(const QByteArray &value)
|
||||
{ setUserName(QString::fromLatin1(value)); }
|
||||
|
||||
QT_DEPRECATED QByteArray encodedPassword() const
|
||||
{ return password(FullyEncoded).toLatin1(); }
|
||||
QT_DEPRECATED void setEncodedPassword(const QByteArray &value)
|
||||
{ setPassword(QString::fromLatin1(value)); }
|
||||
|
||||
QT_DEPRECATED QByteArray encodedHost() const
|
||||
{ return host(FullyEncoded).toLatin1(); }
|
||||
QT_DEPRECATED void setEncodedHost(const QByteArray &value)
|
||||
{ setHost(QString::fromLatin1(value)); }
|
||||
|
||||
QT_DEPRECATED QByteArray encodedPath() const
|
||||
{ return path(FullyEncoded).toLatin1(); }
|
||||
QT_DEPRECATED void setEncodedPath(const QByteArray &value)
|
||||
{ setPath(QString::fromLatin1(value)); }
|
||||
|
||||
QT_DEPRECATED QByteArray encodedQuery() const
|
||||
{ return toLatin1_helper(query(FullyEncoded)); }
|
||||
QT_DEPRECATED void setEncodedQuery(const QByteArray &value)
|
||||
{ setQuery(QString::fromLatin1(value)); }
|
||||
|
||||
QT_DEPRECATED QByteArray encodedFragment() const
|
||||
{ return toLatin1_helper(fragment(FullyEncoded)); }
|
||||
QT_DEPRECATED void setEncodedFragment(const QByteArray &value)
|
||||
{ setFragment(QString::fromLatin1(value)); }
|
||||
|
||||
private:
|
||||
// helper function for the encodedQuery and encodedFragment functions
|
||||
static QByteArray toLatin1_helper(const QString &string)
|
||||
{
|
||||
if (string.isEmpty())
|
||||
return string.isNull() ? QByteArray() : QByteArray("");
|
||||
return string.toLatin1();
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
static QString fromAce(const QByteArray &);
|
||||
static QByteArray toAce(const QString &);
|
||||
static QStringList idnWhitelist();
|
||||
static void setIdnWhitelist(const QStringList &);
|
||||
|
||||
QString errorString() const;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
QT_DEPRECATED void setEncodedUrl(const QByteArray &u, ParsingMode mode = TolerantMode)
|
||||
{ setUrl(QString::fromUtf8(u.constData(), u.size()), mode); }
|
||||
QT_DEPRECATED static QUrl fromEncoded(const QByteArray &u, ParsingMode mode = TolerantMode)
|
||||
{ return QUrl(QString::fromUtf8(u.constData(), u.size()), mode); }
|
||||
#endif
|
||||
friend Q_CORE_EXPORT uint qHash(const QUrl &url, uint seed = 0);
|
||||
|
||||
private:
|
||||
QUrlPrivate *d;
|
||||
friend class QUrlQuery;
|
||||
|
||||
public:
|
||||
typedef QUrlPrivate * DataPtr;
|
||||
inline DataPtr &data_ptr() { return d; }
|
||||
};
|
||||
|
||||
inline uint qHash(const QUrl &url)
|
||||
{
|
||||
return qHash(url.toEncoded(QUrl::FormattingOption(0x100)));
|
||||
}
|
||||
|
||||
Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);
|
||||
Q_DECLARE_SHARED(QUrl)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::FormattingOptions)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::ComponentFormattingOptions)
|
||||
//Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::FormattingOptions)
|
||||
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::UrlFormattingOption f1, QUrl::UrlFormattingOption f2)
|
||||
{ return QUrl::FormattingOptions(f1) | f2; }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::UrlFormattingOption f1, QUrl::FormattingOptions f2)
|
||||
{ return f2 | f1; }
|
||||
inline QIncompatibleFlag operator|(QUrl::UrlFormattingOption f1, int f2)
|
||||
{ return QIncompatibleFlag(int(f1) | f2); }
|
||||
|
||||
// add operators for OR'ing the two types of flags
|
||||
inline QUrl::FormattingOptions &operator|=(QUrl::FormattingOptions &i, QUrl::ComponentFormattingOptions f)
|
||||
{ i |= QUrl::UrlFormattingOption(int(f)); return i; }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::UrlFormattingOption i, QUrl::ComponentFormattingOption f)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::UrlFormattingOption i, QUrl::ComponentFormattingOptions f)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::ComponentFormattingOption f, QUrl::UrlFormattingOption i)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::ComponentFormattingOptions f, QUrl::UrlFormattingOption i)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::FormattingOptions i, QUrl::ComponentFormattingOptions f)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::ComponentFormattingOption f, QUrl::FormattingOptions i)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
Q_DECL_CONSTEXPR inline QUrl::FormattingOptions operator|(QUrl::ComponentFormattingOptions f, QUrl::FormattingOptions i)
|
||||
{ return i | QUrl::UrlFormattingOption(int(f)); }
|
||||
|
||||
//inline QUrl::UrlFormattingOption &operator=(const QUrl::UrlFormattingOption &i, QUrl::ComponentFormattingOptions f)
|
||||
//{ i = int(f); f; }
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QUrl &);
|
||||
@ -245,6 +371,10 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QUrl &);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
# include <QtCore/qurlquery.h>
|
||||
#endif
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QURL_H
|
||||
|
189
src/corelib/io/qurl_p.h
Normal file
189
src/corelib/io/qurl_p.h
Normal file
@ -0,0 +1,189 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012 Intel Corporation.
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QURL_P_H
|
||||
#define QURL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience of
|
||||
// qurl*.cpp This header file may change from version to version without
|
||||
// notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qurl.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QUrlPrivate
|
||||
{
|
||||
public:
|
||||
enum Section {
|
||||
Scheme = 0x01,
|
||||
UserName = 0x02,
|
||||
Password = 0x04,
|
||||
UserInfo = UserName | Password,
|
||||
Host = 0x08,
|
||||
Port = 0x10,
|
||||
Authority = UserInfo | Host | Port,
|
||||
Path = 0x20,
|
||||
Hierarchy = Authority | Path,
|
||||
Query = 0x40,
|
||||
Fragment = 0x80,
|
||||
FullUrl = 0xff
|
||||
};
|
||||
|
||||
enum ErrorCode {
|
||||
// the high byte of the error code matches the Section
|
||||
InvalidSchemeError = Scheme << 8,
|
||||
SchemeEmptyError,
|
||||
|
||||
InvalidUserNameError = UserName << 8,
|
||||
|
||||
InvalidPasswordError = Password << 8,
|
||||
|
||||
InvalidRegNameError = Host << 8,
|
||||
InvalidIPv4AddressError,
|
||||
InvalidIPv6AddressError,
|
||||
InvalidIPvFutureError,
|
||||
HostMissingEndBracket,
|
||||
|
||||
InvalidPortError = Port << 8,
|
||||
PortEmptyError,
|
||||
|
||||
InvalidPathError = Path << 8,
|
||||
PathContainsColonBeforeSlash,
|
||||
|
||||
InvalidQueryError = Query << 8,
|
||||
|
||||
InvalidFragmentError = Fragment << 8,
|
||||
|
||||
NoError = 0
|
||||
};
|
||||
|
||||
QUrlPrivate();
|
||||
QUrlPrivate(const QUrlPrivate ©);
|
||||
|
||||
void parse(const QString &url, QUrl::ParsingMode parsingMode);
|
||||
void clear();
|
||||
bool isEmpty() const
|
||||
{ return sectionIsPresent == 0 && port == -1 && path.isEmpty(); }
|
||||
|
||||
// no QString scheme() const;
|
||||
void appendAuthority(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
|
||||
void appendUserInfo(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
|
||||
void appendUserName(QString &appendTo, QUrl::FormattingOptions options) const;
|
||||
void appendPassword(QString &appendTo, QUrl::FormattingOptions options) const;
|
||||
void appendHost(QString &appendTo, QUrl::FormattingOptions options) const;
|
||||
void appendPath(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
|
||||
void appendQuery(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
|
||||
void appendFragment(QString &appendTo, QUrl::FormattingOptions options) const;
|
||||
|
||||
// the "end" parameters are like STL iterators: they point to one past the last valid element
|
||||
bool setScheme(const QString &value, int len, bool decoded = false);
|
||||
bool setAuthority(const QString &auth, int from, int end);
|
||||
void setUserInfo(const QString &userInfo, int from, int end);
|
||||
void setUserName(const QString &value, int from, int end);
|
||||
void setPassword(const QString &value, int from, int end);
|
||||
bool setHost(const QString &value, int from, int end, bool maybePercentEncoded = true);
|
||||
void setPath(const QString &value, int from, int end);
|
||||
void setQuery(const QString &value, int from, int end);
|
||||
void setFragment(const QString &value, int from, int end);
|
||||
|
||||
inline bool hasScheme() const { return sectionIsPresent & Scheme; }
|
||||
inline bool hasAuthority() const { return sectionIsPresent & Authority; }
|
||||
inline bool hasUserInfo() const { return sectionIsPresent & UserInfo; }
|
||||
inline bool hasUserName() const { return sectionIsPresent & UserName; }
|
||||
inline bool hasPassword() const { return sectionIsPresent & Password; }
|
||||
inline bool hasHost() const { return sectionIsPresent & Host; }
|
||||
inline bool hasPort() const { return port != -1; }
|
||||
inline bool hasPath() const { return !path.isEmpty(); }
|
||||
inline bool hasQuery() const { return sectionIsPresent & Query; }
|
||||
inline bool hasFragment() const { return sectionIsPresent & Fragment; }
|
||||
|
||||
QString mergePaths(const QString &relativePath) const;
|
||||
|
||||
QAtomicInt ref;
|
||||
int port;
|
||||
|
||||
QString scheme;
|
||||
QString userName;
|
||||
QString password;
|
||||
QString host;
|
||||
QString path;
|
||||
QString query;
|
||||
QString fragment;
|
||||
|
||||
ushort errorCode;
|
||||
ushort errorSupplement;
|
||||
|
||||
// not used for:
|
||||
// - Port (port == -1 means absence)
|
||||
// - Path (there's no path delimiter, so we optimize its use out of existence)
|
||||
// Schemes are never supposed to be empty, but we keep the flag anyway
|
||||
uchar sectionIsPresent;
|
||||
|
||||
// UserName, Password, Path, Query, and Fragment never contain errors in TolerantMode.
|
||||
// Those flags are set only by the strict parser.
|
||||
uchar sectionHasError;
|
||||
};
|
||||
|
||||
|
||||
// in qurlrecode.cpp
|
||||
extern Q_AUTOTEST_EXPORT int qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
|
||||
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications);
|
||||
|
||||
// in qurlidna.cpp
|
||||
enum AceOperation { ToAceOnly, NormalizeAce };
|
||||
extern QString qt_ACE_do(const QString &domain, AceOperation op);
|
||||
extern Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
|
||||
extern Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
|
||||
extern Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output);
|
||||
extern Q_AUTOTEST_EXPORT QString qt_punycodeDecoder(const QString &pc);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QURL_P_H
|
2592
src/corelib/io/qurlidna.cpp
Normal file
2592
src/corelib/io/qurlidna.cpp
Normal file
File diff suppressed because it is too large
Load Diff
729
src/corelib/io/qurlquery.cpp
Normal file
729
src/corelib/io/qurlquery.cpp
Normal file
@ -0,0 +1,729 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Intel Corporation.
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qurlquery.h"
|
||||
#include "qurl_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QUrlQuery
|
||||
|
||||
\brief The QUrlQuery class provides a way to manipulate a key-value pairs in
|
||||
a URL's query.
|
||||
|
||||
\reentrant
|
||||
\ingroup io
|
||||
\ingroup network
|
||||
\ingroup shared
|
||||
|
||||
It is used to parse the query strings found in URLs like the following:
|
||||
|
||||
\img qurl-querystring.png
|
||||
|
||||
Query strings like the above are used to transmit options in the URL and are
|
||||
usually decoded into multiple key-value pairs. The one above would contain
|
||||
two entries in its list, with keys "type" and "color". QUrlQuery can also be
|
||||
used to create a query string suitable for use in QUrl::setQuery() from the
|
||||
individual components of the query.
|
||||
|
||||
The most common way of parsing a query string is to initialize it in the
|
||||
constructor by passing it the query string. Otherwise, the setQuery() method
|
||||
can be used to set the query to be parsed. That method can also be used to
|
||||
parse a query with non-standard delimiters, after having set them using the
|
||||
setQueryDelimiters() function.
|
||||
|
||||
The encoded query string can be obtained again using query(). This will take
|
||||
all the internally-stored items and encode the string using the delimiters.
|
||||
|
||||
\section1 Encoding
|
||||
|
||||
All of the getter methods in QUrlQuery support an optional parameter of type
|
||||
QUrl::ComponentFormattingOptions, including query(), which dictate how to
|
||||
encode the data in question. Regardless of the mode, the returned value must
|
||||
still be considered a percent-encoded string, as there are certain values
|
||||
which cannot be expressed in decoded form (like control characters, byte
|
||||
sequences not decodable to UTF-8). For that reason, the percent character is
|
||||
always represented by the string "%25".
|
||||
|
||||
\section2 Handling of spaces and plus ("+")
|
||||
|
||||
Web browsers usually encode spaces found in HTML FORM elements to a plus sign
|
||||
("+") and plus signs to its percent-encoded form (%2B). However, the Internet
|
||||
specifications governing URLs do not consider spaces and the plus character
|
||||
equivalent.
|
||||
|
||||
For that reason, QUrlQuery never encodes the space character to "+" and will
|
||||
never decode "+" to a space character. Instead, space characters will be
|
||||
rendered "%20" in encoded form.
|
||||
|
||||
To support encoding like that of HTML forms, QUrlQuery also never decodes the
|
||||
"%2B" sequence to a plus sign nor encode a plus sign. In fact, any "%2B" or
|
||||
"+" sequences found in the keys, values, or query string are left exactly
|
||||
like written (except for the uppercasing of "%2b" to "%2B").
|
||||
|
||||
\section1 Non-standard delimiters
|
||||
|
||||
By default, QUrlQuery uses an equal sign ("=") to separate a key from its
|
||||
value, and an ampersand ("&") to separate key-value pairs from each other. It
|
||||
is possible to change the delimiters that QUrlQuery uses for parsing and for
|
||||
reconstructing the query by calling setQueryDelimiters().
|
||||
|
||||
Non-standard delimiters should be chosen from among what RFC 3986 calls
|
||||
"sub-delimiters". They are:
|
||||
|
||||
\code
|
||||
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
/ "*" / "+" / "," / ";" / "="
|
||||
\endcode
|
||||
|
||||
Use of other characters is not supported and may result in unexpected
|
||||
behaviour. QUrlQuery does not verify that you passed a valid delimiter.
|
||||
|
||||
\sa QUrl
|
||||
*/
|
||||
|
||||
typedef QList<QPair<QString, QString> > Map;
|
||||
|
||||
class QUrlQueryPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QUrlQueryPrivate(const QString &query = QString())
|
||||
: valueDelimiter(QUrlQuery::defaultQueryValueDelimiter()),
|
||||
pairDelimiter(QUrlQuery::defaultQueryPairDelimiter())
|
||||
{ if (!query.isEmpty()) setQuery(query); }
|
||||
|
||||
QString recodeFromUser(const QString &input) const;
|
||||
QString recodeToUser(const QString &input, QUrl::ComponentFormattingOptions encoding) const;
|
||||
|
||||
void setQuery(const QString &query);
|
||||
|
||||
void addQueryItem(const QString &key, const QString &value)
|
||||
{ itemList.append(qMakePair(recodeFromUser(key), recodeFromUser(value))); }
|
||||
int findRecodedKey(const QString &key, int from = 0) const
|
||||
{
|
||||
for (int i = from; i < itemList.size(); ++i)
|
||||
if (itemList.at(i).first == key)
|
||||
return i;
|
||||
return itemList.size();
|
||||
}
|
||||
Map::const_iterator findKey(const QString &key) const
|
||||
{ return itemList.constBegin() + findRecodedKey(recodeFromUser(key)); }
|
||||
Map::iterator findKey(const QString &key)
|
||||
{ return itemList.begin() + findRecodedKey(recodeFromUser(key)); }
|
||||
|
||||
// use QMap so we end up sorting the items by key
|
||||
Map itemList;
|
||||
QChar valueDelimiter;
|
||||
QChar pairDelimiter;
|
||||
};
|
||||
|
||||
template<> void QSharedDataPointer<QUrlQueryPrivate>::detach()
|
||||
{
|
||||
if (d && d->ref.load() == 1)
|
||||
return;
|
||||
QUrlQueryPrivate *x = (d ? new QUrlQueryPrivate(*d)
|
||||
: new QUrlQueryPrivate);
|
||||
x->ref.ref();
|
||||
if (d && !d->ref.deref())
|
||||
delete d;
|
||||
d = x;
|
||||
}
|
||||
|
||||
// Here's how we do the encoding in QUrlQuery
|
||||
// The RFC says these are the delimiters:
|
||||
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
// / "*" / "+" / "," / ";" / "="
|
||||
// And the definition of query is:
|
||||
// query = *( pchar / "/" / "?" )
|
||||
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
//
|
||||
// The strict definition of query says that it can have unencoded any
|
||||
// unreserved, sub-delim, ":", "@", "/" and "?". Or, by exclusion, excluded
|
||||
// delimiters are "#", "[" and "]" -- if those are present, they must be
|
||||
// percent-encoded. The fact that "[" and "]" should be encoded is probably a
|
||||
// mistake in the spec, so we ignore it and leave the decoded.
|
||||
//
|
||||
// The internal storage in the Map is equivalent to PrettyDecoded. That means
|
||||
// the getter methods, when called with the default encoding value, will not
|
||||
// have to recode anything (except for toString()).
|
||||
//
|
||||
// The "+" sub-delimiter is always left untouched. We never encode "+" to "%2B"
|
||||
// nor do we decode "%2B" to "+", no matter what the user asks.
|
||||
//
|
||||
// The rest of the delimiters are kept in their decoded forms and that's
|
||||
// considered non-ambiguous. That includes the pair and value delimiters
|
||||
// themselves.
|
||||
//
|
||||
// But when recreating the query string, in toString(), we must take care of
|
||||
// the special delimiters: the pair and value delimiters, as well as the "#"
|
||||
// character if unambiguous decoding is requested.
|
||||
|
||||
#define decode(x) ushort(x)
|
||||
#define leave(x) ushort(0x100 | (x))
|
||||
#define encode(x) ushort(0x200 | (x))
|
||||
static const ushort prettyDecodedActions[] = { leave('+'), 0 };
|
||||
|
||||
inline QString QUrlQueryPrivate::recodeFromUser(const QString &input) const
|
||||
{
|
||||
// note: duplicated in setQuery()
|
||||
QString output;
|
||||
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
|
||||
QUrl::MostDecoded,
|
||||
prettyDecodedActions))
|
||||
return output;
|
||||
return input;
|
||||
}
|
||||
|
||||
inline bool idempotentRecodeToUser(QUrl::ComponentFormattingOptions encoding)
|
||||
{
|
||||
return encoding == QUrl::PrettyDecoded;
|
||||
}
|
||||
|
||||
inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::ComponentFormattingOptions encoding) const
|
||||
{
|
||||
// our internal formats are stored in "PrettyDecoded" form
|
||||
// and there are no ambiguous characters
|
||||
if (idempotentRecodeToUser(encoding))
|
||||
return input;
|
||||
|
||||
if (!(encoding & QUrl::EncodeDelimiters)) {
|
||||
QString output;
|
||||
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
|
||||
encoding, prettyDecodedActions))
|
||||
return output;
|
||||
return input;
|
||||
}
|
||||
|
||||
// re-encode the "#" character and the query delimiter pair
|
||||
ushort actions[] = { encode(pairDelimiter.unicode()), encode(valueDelimiter.unicode()),
|
||||
encode('#'), 0 };
|
||||
QString output;
|
||||
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(), encoding, actions))
|
||||
return output;
|
||||
return input;
|
||||
}
|
||||
|
||||
void QUrlQueryPrivate::setQuery(const QString &query)
|
||||
{
|
||||
itemList.clear();
|
||||
const QChar *pos = query.constData();
|
||||
const QChar *const end = pos + query.size();
|
||||
while (pos != end) {
|
||||
const QChar *begin = pos;
|
||||
const QChar *delimiter = 0;
|
||||
while (pos != end) {
|
||||
// scan for the component parts of this pair
|
||||
if (!delimiter && pos->unicode() == valueDelimiter)
|
||||
delimiter = pos;
|
||||
if (pos->unicode() == pairDelimiter)
|
||||
break;
|
||||
++pos;
|
||||
}
|
||||
if (!delimiter)
|
||||
delimiter = pos;
|
||||
|
||||
// pos is the end of this pair (the end of the string or the pair delimiter)
|
||||
// delimiter points to the value delimiter or to the end of this pair
|
||||
|
||||
QString key;
|
||||
if (!qt_urlRecode(key, begin, delimiter,
|
||||
QUrl::MostDecoded,
|
||||
prettyDecodedActions))
|
||||
key = QString(begin, delimiter - begin);
|
||||
|
||||
if (delimiter == pos) {
|
||||
// the value delimiter wasn't found, store a null value
|
||||
itemList.append(qMakePair(key, QString()));
|
||||
} else if (delimiter + 1 == pos) {
|
||||
// if the delimiter was found but the value is empty, store empty-but-not-null
|
||||
itemList.append(qMakePair(key, QString(0, Qt::Uninitialized)));
|
||||
} else {
|
||||
QString value;
|
||||
if (!qt_urlRecode(value, delimiter + 1, pos,
|
||||
QUrl::MostDecoded,
|
||||
prettyDecodedActions))
|
||||
value = QString(delimiter + 1, pos - delimiter - 1);
|
||||
itemList.append(qMakePair(key, value));
|
||||
}
|
||||
|
||||
if (pos != end)
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
// allow QUrlQueryPrivate to detach from null
|
||||
template <> inline QUrlQueryPrivate *
|
||||
QSharedDataPointer<QUrlQueryPrivate>::clone()
|
||||
{
|
||||
return d ? new QUrlQueryPrivate(*d) : new QUrlQueryPrivate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs an empty QUrlQuery object. A query can be set afterwards by
|
||||
calling setQuery() or items can be added by using addQueryItem().
|
||||
|
||||
\sa setQuery(), addQueryItem()
|
||||
*/
|
||||
QUrlQuery::QUrlQuery()
|
||||
: d(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a QUrlQuery object and parses the \a queryString query string,
|
||||
using the default query delimiters. To parse a query string using other
|
||||
delimiters, you should first set them using setQueryDelimiters() and then
|
||||
set the query with setQuery().
|
||||
*/
|
||||
QUrlQuery::QUrlQuery(const QString &queryString)
|
||||
: d(queryString.isEmpty() ? 0 : new QUrlQueryPrivate(queryString))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a QUrlQuery object and parses the query string found in the \a
|
||||
url URL, using the default query delimiters. To parse a query string using
|
||||
other delimiters, you should first set them using setQueryDelimiters() and
|
||||
then set the query with setQuery().
|
||||
|
||||
\sa QUrl::query()
|
||||
*/
|
||||
QUrlQuery::QUrlQuery(const QUrl &url)
|
||||
: d(0)
|
||||
{
|
||||
// use internals to avoid unnecessary recoding
|
||||
// ### FIXME: actually do it
|
||||
if (url.hasQuery())
|
||||
d = new QUrlQueryPrivate(url.query());
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies the contents of the \a other QUrlQuery object, including the query
|
||||
delimiters.
|
||||
*/
|
||||
QUrlQuery::QUrlQuery(const QUrlQuery &other)
|
||||
: d(other.d)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies the contents of the \a other QUrlQuery object, including the query
|
||||
delimiters.
|
||||
*/
|
||||
QUrlQuery &QUrlQuery::operator =(const QUrlQuery &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys this QUrlQuery object.
|
||||
*/
|
||||
QUrlQuery::~QUrlQuery()
|
||||
{
|
||||
// d auto-deletes
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this object and the \a other object contain the same
|
||||
contents, in the same order, and use the same query delimiters.
|
||||
*/
|
||||
bool QUrlQuery::operator ==(const QUrlQuery &other) const
|
||||
{
|
||||
if (d == other.d)
|
||||
return true;
|
||||
if (d && other.d)
|
||||
return d->valueDelimiter == other.d->valueDelimiter &&
|
||||
d->pairDelimiter == other.d->pairDelimiter &&
|
||||
d->itemList == other.d->itemList;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if this QUrlQUery object contains no key-value pairs, such as
|
||||
after being default-constructed or after parsing an empty query string.
|
||||
|
||||
\sa setQuery(), clear()
|
||||
*/
|
||||
bool QUrlQuery::isEmpty() const
|
||||
{
|
||||
return d ? d->itemList.isEmpty() : true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
bool QUrlQuery::isDetached() const
|
||||
{
|
||||
return d && d->ref.load() == 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Clears this QUrlQuery object by removing all of the key-value pairs
|
||||
currently stored. If the query delimiters have been changed, this function
|
||||
will leave them with their changed values.
|
||||
|
||||
\sa isEmpty(), setQueryDelimiters()
|
||||
*/
|
||||
void QUrlQuery::clear()
|
||||
{
|
||||
if (d.constData())
|
||||
d->itemList.clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
Parses the query string in \a queryString and sets the internal items to
|
||||
the values found there. If any delimiters have been specified with
|
||||
setQueryDelimiters(), this function will use them instead of the default
|
||||
delimiters to parse the string.
|
||||
*/
|
||||
void QUrlQuery::setQuery(const QString &queryString)
|
||||
{
|
||||
d->setQuery(queryString);
|
||||
}
|
||||
|
||||
static void recodeAndAppend(QString &to, const QString &input,
|
||||
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications)
|
||||
{
|
||||
if (!qt_urlRecode(to, input.constData(), input.constData() + input.length(), encoding, tableModifications))
|
||||
to += input;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the reconstructed query string, formed from the key-value pairs
|
||||
currently stored in this QUrlQuery object and separated by the query
|
||||
delimiters chosen for this object. The keys and values are encoded using
|
||||
the options given by the \a encoding paramter.
|
||||
|
||||
For this function, the only ambiguous delimiter is the hash ("#"), as in
|
||||
URLs it is used to separate the query string from the fragment that may
|
||||
follow.
|
||||
|
||||
The order of the key-value pairs in the returned string is exactly the same
|
||||
as in the original query.
|
||||
|
||||
\sa setQuery(), QUrl::setQuery(), QUrl::fragment(), \l{#Encoding}{Encoding}
|
||||
*/
|
||||
QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const
|
||||
{
|
||||
if (!d)
|
||||
return QString();
|
||||
|
||||
// unlike the component encoding, for the whole query we need to modify a little:
|
||||
// - the "#" character is ambiguous, so we decode it only in DecodeAllDelimiters mode
|
||||
// - the query delimiter pair must always be encoded
|
||||
// - the non-delimiters vary on DecodeUnambiguousDelimiters
|
||||
// so:
|
||||
// - full encoding: encode the non-delimiters, the pair, "#", "[" and "]"
|
||||
// - pretty decode: decode the non-delimiters, "[" and "]"; encode the pair and "#"
|
||||
// - decode all: decode the non-delimiters, "[", "]", "#"; encode the pair
|
||||
|
||||
// start with what's always encoded
|
||||
ushort tableActions[] = {
|
||||
leave('+'), // 0
|
||||
encode(d->pairDelimiter.unicode()), // 1
|
||||
encode(d->valueDelimiter.unicode()), // 2
|
||||
decode('#'), // 3
|
||||
0
|
||||
};
|
||||
if (encoding & QUrl::EncodeDelimiters) {
|
||||
tableActions[3] = encode('#');
|
||||
}
|
||||
|
||||
QString result;
|
||||
Map::const_iterator it = d->itemList.constBegin();
|
||||
Map::const_iterator end = d->itemList.constEnd();
|
||||
|
||||
{
|
||||
int size = 0;
|
||||
for ( ; it != end; ++it)
|
||||
size += it->first.length() + 1 + it->second.length() + 1;
|
||||
result.reserve(size + size / 4);
|
||||
}
|
||||
|
||||
for (it = d->itemList.constBegin(); it != end; ++it) {
|
||||
if (!result.isEmpty())
|
||||
result += QChar(d->pairDelimiter);
|
||||
recodeAndAppend(result, it->first, encoding, tableActions);
|
||||
if (!it->second.isNull()) {
|
||||
result += QChar(d->valueDelimiter);
|
||||
recodeAndAppend(result, it->second, encoding, tableActions);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the characters used for delimiting between keys and values,
|
||||
and between key-value pairs in the URL's query string. The default
|
||||
value delimiter is '=' and the default pair delimiter is '&'.
|
||||
|
||||
\img qurl-querystring.png
|
||||
|
||||
\a valueDelimiter will be used for separating keys from values,
|
||||
and \a pairDelimiter will be used to separate key-value pairs.
|
||||
Any occurrences of these delimiting characters in the encoded
|
||||
representation of the keys and values of the query string are
|
||||
percent encoded when returned in query().
|
||||
|
||||
If \a valueDelimiter is set to '(' and \a pairDelimiter is ')',
|
||||
the above query string would instead be represented like this:
|
||||
|
||||
\snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 4
|
||||
|
||||
\note Non-standard delimiters should be chosen from among what RFC 3986 calls
|
||||
"sub-delimiters". They are:
|
||||
|
||||
\code
|
||||
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
/ "*" / "+" / "," / ";" / "="
|
||||
\endcode
|
||||
|
||||
Use of other characters is not supported and may result in unexpected
|
||||
behaviour. This method does not verify that you passed a valid delimiter.
|
||||
|
||||
\sa queryValueDelimiter(), queryPairDelimiter()
|
||||
*/
|
||||
void QUrlQuery::setQueryDelimiters(QChar valueDelimiter, QChar pairDelimiter)
|
||||
{
|
||||
d->valueDelimiter = valueDelimiter.unicode();
|
||||
d->pairDelimiter = pairDelimiter.unicode();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the character used to delimit between keys and values when
|
||||
reconstructing the query string in query() or when parsing in setQuery().
|
||||
|
||||
\sa setQueryDelimiters(), queryPairDelimiter()
|
||||
*/
|
||||
QChar QUrlQuery::queryValueDelimiter() const
|
||||
{
|
||||
return d ? d->valueDelimiter : defaultQueryValueDelimiter();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the character used to delimit between keys-value pairs when
|
||||
reconstructing the query string in query() or when parsing in setQuery().
|
||||
|
||||
\sa setQueryDelimiters(), queryValueDelimiter()
|
||||
*/
|
||||
QChar QUrlQuery::queryPairDelimiter() const
|
||||
{
|
||||
return d ? d->pairDelimiter : defaultQueryPairDelimiter();
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the items in this QUrlQuery object to \a query. The order of the
|
||||
elements in \a query is preserved.
|
||||
|
||||
\note This method does not treat spaces (ASCII 0x20) and plus ("+") signs
|
||||
as the same, like HTML forms do. If you need spaces to be represented as
|
||||
plus signs, use actual plus signs.
|
||||
|
||||
\sa queryItems(), isEmpty()
|
||||
*/
|
||||
void QUrlQuery::setQueryItems(const QList<QPair<QString, QString> > &query)
|
||||
{
|
||||
clear();
|
||||
if (query.isEmpty())
|
||||
return;
|
||||
|
||||
QUrlQueryPrivate *dd = d;
|
||||
QList<QPair<QString, QString> >::const_iterator it = query.constBegin(),
|
||||
end = query.constEnd();
|
||||
for ( ; it != end; ++it)
|
||||
dd->addQueryItem(it->first, it->second);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the query string of the URL, as a map of keys and values, using the
|
||||
options specified in \a encoding to encode the items. The order of the
|
||||
elements is the same as the one found in the query string or set with
|
||||
setQueryItems().
|
||||
|
||||
\sa setQueryItems(), \l{#Encoding}{Encoding}
|
||||
*/
|
||||
QList<QPair<QString, QString> > QUrlQuery::queryItems(QUrl::ComponentFormattingOptions encoding) const
|
||||
{
|
||||
if (!d)
|
||||
return QList<QPair<QString, QString> >();
|
||||
if (idempotentRecodeToUser(encoding))
|
||||
return d->itemList;
|
||||
|
||||
QList<QPair<QString, QString> > result;
|
||||
Map::const_iterator it = d->itemList.constBegin();
|
||||
Map::const_iterator end = d->itemList.constEnd();
|
||||
for ( ; it != end; ++it)
|
||||
result << qMakePair(d->recodeToUser(it->first, encoding),
|
||||
d->recodeToUser(it->second, encoding));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if there is a query string pair whose key is equal
|
||||
to \a key from the URL.
|
||||
|
||||
\sa addQueryItem(), queryItemValue()
|
||||
*/
|
||||
bool QUrlQuery::hasQueryItem(const QString &key) const
|
||||
{
|
||||
if (!d)
|
||||
return false;
|
||||
return d->findKey(key) != d->itemList.constEnd();
|
||||
}
|
||||
|
||||
/*!
|
||||
Appends the pair \a key = \a value to the end of the query string of the
|
||||
URL. This method does not overwrite existing items that might exist with
|
||||
the same key.
|
||||
|
||||
\note This method does not treat spaces (ASCII 0x20) and plus ("+") signs
|
||||
as the same, like HTML forms do. If you need spaces to be represented as
|
||||
plus signs, use actual plus signs.
|
||||
|
||||
\sa hasQueryItem(), queryItemValue()
|
||||
*/
|
||||
void QUrlQuery::addQueryItem(const QString &key, const QString &value)
|
||||
{
|
||||
d->addQueryItem(key, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the query value associated with key \a key from the URL, using the
|
||||
options specified in \a encoding to encode the return value. If the key \a
|
||||
key is not found, this function returns an empty string. If you need to
|
||||
distinguish between an empty value and a non-existent key, you should check
|
||||
for the key's presence first using hasQueryItem().
|
||||
|
||||
If the key \a key is multiply defined, this function will return the first
|
||||
one found, in the order they were present in the query string or added
|
||||
using addQueryItem().
|
||||
|
||||
\sa addQueryItem(), allQueryItemValues(), \l{#Encoding}{Encoding}
|
||||
*/
|
||||
QString QUrlQuery::queryItemValue(const QString &key, QUrl::ComponentFormattingOptions encoding) const
|
||||
{
|
||||
QString result;
|
||||
if (d) {
|
||||
Map::const_iterator it = d->findKey(key);
|
||||
if (it != d->itemList.constEnd())
|
||||
result = d->recodeToUser(it->second, encoding);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the a list of query string values whose key is equal to \a key from
|
||||
the URL, using the options specified in \a encoding to encode the return
|
||||
value. If the key \a key is not found, this function returns an empty list.
|
||||
|
||||
\sa queryItemValue(), addQueryItem()
|
||||
*/
|
||||
QStringList QUrlQuery::allQueryItemValues(const QString &key, QUrl::ComponentFormattingOptions encoding) const
|
||||
{
|
||||
QStringList result;
|
||||
if (d) {
|
||||
QString encodedKey = d->recodeFromUser(key);
|
||||
int idx = d->findRecodedKey(encodedKey);
|
||||
while (idx < d->itemList.size()) {
|
||||
result << d->recodeToUser(d->itemList.at(idx).second, encoding);
|
||||
idx = d->findRecodedKey(encodedKey, idx + 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes the query string pair whose key is equal to \a key from the URL. If
|
||||
there are multiple items with a key equal to \a key, it removes the first
|
||||
item in the order they were present in the query string or added with
|
||||
addQueryItem().
|
||||
|
||||
\sa removeAllQueryItems()
|
||||
*/
|
||||
void QUrlQuery::removeQueryItem(const QString &key)
|
||||
{
|
||||
if (d) {
|
||||
Map::iterator it = d->findKey(key);
|
||||
if (it != d->itemList.end())
|
||||
d->itemList.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes all the query string pairs whose key is equal to \a key
|
||||
from the URL.
|
||||
|
||||
\sa removeQueryItem()
|
||||
*/
|
||||
void QUrlQuery::removeAllQueryItems(const QString &key)
|
||||
{
|
||||
if (d.constData()) {
|
||||
QString encodedKey = d->recodeFromUser(key);
|
||||
Map::iterator it = d->itemList.begin();
|
||||
while (it != d->itemList.end()) {
|
||||
if (it->first == encodedKey)
|
||||
it = d->itemList.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QChar QUrlQuery::defaultQueryValueDelimiter()
|
||||
Returns the default character for separating keys from values in the query,
|
||||
an equal sign ("=").
|
||||
|
||||
\sa setQueryDelimiters(), queryValueDelimiter(), defaultQueryPairDelimiter()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QChar QUrlQuery::defaultQueryPairDelimiter()
|
||||
Returns the default character for separating keys-value pairs from each
|
||||
other, an ampersand ("&").
|
||||
|
||||
\sa setQueryDelimiters(), queryPairDelimiter(), defaultQueryValueDelimiter()
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
179
src/corelib/io/qurlquery.h
Normal file
179
src/corelib/io/qurlquery.h
Normal file
@ -0,0 +1,179 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Intel Corporation.
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QURLQUERY_H
|
||||
#define QURLQUERY_H
|
||||
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
#include <QtCore/qstringlist.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QUrlQueryPrivate;
|
||||
class Q_CORE_EXPORT QUrlQuery
|
||||
{
|
||||
public:
|
||||
QUrlQuery();
|
||||
explicit QUrlQuery(const QUrl &url);
|
||||
explicit QUrlQuery(const QString &queryString);
|
||||
QUrlQuery(const QUrlQuery &other);
|
||||
QUrlQuery &operator=(const QUrlQuery &other);
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
QUrlQuery &operator=(QUrlQuery &&other)
|
||||
{ qSwap(d, other.d); return *this; }
|
||||
#endif
|
||||
~QUrlQuery();
|
||||
|
||||
bool operator==(const QUrlQuery &other) const;
|
||||
bool operator!=(const QUrlQuery &other) const
|
||||
{ return !(*this == other); }
|
||||
|
||||
void swap(QUrlQuery &other) { qSwap(d, other.d); }
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isDetached() const;
|
||||
void clear();
|
||||
|
||||
QString query(QUrl::ComponentFormattingOptions encoding = QUrl::PrettyDecoded) const;
|
||||
void setQuery(const QString &queryString);
|
||||
QString toString(QUrl::ComponentFormattingOptions encoding = QUrl::PrettyDecoded) const
|
||||
{ return query(encoding); }
|
||||
|
||||
void setQueryDelimiters(QChar valueDelimiter, QChar pairDelimiter);
|
||||
QChar queryValueDelimiter() const;
|
||||
QChar queryPairDelimiter() const;
|
||||
|
||||
void setQueryItems(const QList<QPair<QString, QString> > &query);
|
||||
QList<QPair<QString, QString> > queryItems(QUrl::ComponentFormattingOptions encoding = QUrl::PrettyDecoded) const;
|
||||
|
||||
bool hasQueryItem(const QString &key) const;
|
||||
void addQueryItem(const QString &key, const QString &value);
|
||||
void removeQueryItem(const QString &key);
|
||||
QString queryItemValue(const QString &key, QUrl::ComponentFormattingOptions encoding = QUrl::PrettyDecoded) const;
|
||||
QStringList allQueryItemValues(const QString &key, QUrl::ComponentFormattingOptions encoding = QUrl::PrettyDecoded) const;
|
||||
void removeAllQueryItems(const QString &key);
|
||||
|
||||
static QChar defaultQueryValueDelimiter()
|
||||
{ return QChar(ushort('=')); }
|
||||
static QChar defaultQueryPairDelimiter()
|
||||
{ return QChar(ushort('&')); }
|
||||
|
||||
private:
|
||||
friend class QUrl;
|
||||
QSharedDataPointer<QUrlQueryPrivate> d;
|
||||
public:
|
||||
typedef QSharedDataPointer<QUrlQueryPrivate> DataPtr;
|
||||
inline DataPtr &data_ptr() { return d; }
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QUrlQuery, Q_MOVABLE_TYPE);
|
||||
Q_DECLARE_SHARED(QUrlQuery)
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
inline void QUrl::setQueryItems(const QList<QPair<QString, QString> > &qry)
|
||||
{ QUrlQuery q(*this); q.setQueryItems(qry); setQuery(q); }
|
||||
inline void QUrl::addQueryItem(const QString &key, const QString &value)
|
||||
{ QUrlQuery q(*this); q.addQueryItem(key, value); setQuery(q); }
|
||||
inline QList<QPair<QString, QString> > QUrl::queryItems() const
|
||||
{ return QUrlQuery(*this).queryItems(); }
|
||||
inline bool QUrl::hasQueryItem(const QString &key) const
|
||||
{ return QUrlQuery(*this).hasQueryItem(key); }
|
||||
inline QString QUrl::queryItemValue(const QString &key) const
|
||||
{ return QUrlQuery(*this).queryItemValue(key); }
|
||||
inline QStringList QUrl::allQueryItemValues(const QString &key) const
|
||||
{ return QUrlQuery(*this).allQueryItemValues(key); }
|
||||
inline void QUrl::removeQueryItem(const QString &key)
|
||||
{ QUrlQuery q(*this); q.removeQueryItem(key); setQuery(q); }
|
||||
inline void QUrl::removeAllQueryItems(const QString &key)
|
||||
{ QUrlQuery q(*this); q.removeAllQueryItems(key); }
|
||||
|
||||
inline void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value)
|
||||
{ QUrlQuery q(*this); q.addQueryItem(QString::fromUtf8(key), QString::fromUtf8(value)); setQuery(q); }
|
||||
inline bool QUrl::hasEncodedQueryItem(const QByteArray &key) const
|
||||
{ return QUrlQuery(*this).hasQueryItem(QString::fromUtf8(key)); }
|
||||
inline QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const
|
||||
{ return QUrlQuery(*this).queryItemValue(QString::fromUtf8(key), QUrl::FullyEncoded).toLatin1(); }
|
||||
inline void QUrl::removeEncodedQueryItem(const QByteArray &key)
|
||||
{ QUrlQuery q(*this); q.removeQueryItem(QString::fromUtf8(key)); setQuery(q); }
|
||||
inline void QUrl::removeAllEncodedQueryItems(const QByteArray &key)
|
||||
{ QUrlQuery q(*this); q.removeAllQueryItems(QString::fromUtf8(key)); }
|
||||
|
||||
inline void QUrl::setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &qry)
|
||||
{
|
||||
QUrlQuery q(*this);
|
||||
QList<QPair<QByteArray, QByteArray> >::ConstIterator it = qry.constBegin();
|
||||
for ( ; it != qry.constEnd(); ++it)
|
||||
q.addQueryItem(QString::fromUtf8(it->first), QString::fromUtf8(it->second));
|
||||
setQuery(q);
|
||||
}
|
||||
inline QList<QPair<QByteArray, QByteArray> > QUrl::encodedQueryItems() const
|
||||
{
|
||||
QList<QPair<QString, QString> > items = QUrlQuery(*this).queryItems(QUrl::FullyEncoded);
|
||||
QList<QPair<QString, QString> >::ConstIterator it = items.constBegin();
|
||||
QList<QPair<QByteArray, QByteArray> > result;
|
||||
result.reserve(items.size());
|
||||
for ( ; it != items.constEnd(); ++it)
|
||||
result << qMakePair(it->first.toLatin1(), it->second.toLatin1());
|
||||
return result;
|
||||
}
|
||||
inline QList<QByteArray> QUrl::allEncodedQueryItemValues(const QByteArray &key) const
|
||||
{
|
||||
QStringList items = QUrlQuery(*this).allQueryItemValues(QString::fromUtf8(key), QUrl::FullyEncoded);
|
||||
QList<QByteArray> result;
|
||||
result.reserve(items.size());
|
||||
Q_FOREACH (const QString &item, items)
|
||||
result << item.toLatin1();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QURLQUERY_H
|
644
src/corelib/io/qurlrecode.cpp
Normal file
644
src/corelib/io/qurlrecode.cpp
Normal file
@ -0,0 +1,644 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Intel Corporation
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qurl.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// ### move to qurl_p.h
|
||||
enum EncodingAction {
|
||||
DecodeCharacter = 0,
|
||||
LeaveCharacter = 1,
|
||||
EncodeCharacter = 2
|
||||
};
|
||||
|
||||
// From RFC 3896, Appendix A Collected ABNF for URI
|
||||
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
// reserved = gen-delims / sub-delims
|
||||
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
// / "*" / "+" / "," / ";" / "="
|
||||
static const uchar defaultActionTable[96] = {
|
||||
2, // space
|
||||
1, // '!' (sub-delim)
|
||||
2, // '"'
|
||||
1, // '#' (gen-delim)
|
||||
1, // '$' (gen-delim)
|
||||
2, // '%' (percent)
|
||||
1, // '&' (gen-delim)
|
||||
1, // "'" (sub-delim)
|
||||
1, // '(' (sub-delim)
|
||||
1, // ')' (sub-delim)
|
||||
1, // '*' (sub-delim)
|
||||
1, // '+' (sub-delim)
|
||||
1, // ',' (sub-delim)
|
||||
0, // '-' (unreserved)
|
||||
0, // '.' (unreserved)
|
||||
1, // '/' (gen-delim)
|
||||
|
||||
0, 0, 0, 0, 0, // '0' to '4' (unreserved)
|
||||
0, 0, 0, 0, 0, // '5' to '9' (unreserved)
|
||||
1, // ':' (gen-delim)
|
||||
1, // ';' (sub-delim)
|
||||
2, // '<'
|
||||
1, // '=' (sub-delim)
|
||||
2, // '>'
|
||||
1, // '?' (gen-delim)
|
||||
|
||||
1, // '@' (gen-delim)
|
||||
0, 0, 0, 0, 0, // 'A' to 'E' (unreserved)
|
||||
0, 0, 0, 0, 0, // 'F' to 'J' (unreserved)
|
||||
0, 0, 0, 0, 0, // 'K' to 'O' (unreserved)
|
||||
0, 0, 0, 0, 0, // 'P' to 'T' (unreserved)
|
||||
0, 0, 0, 0, 0, 0, // 'U' to 'Z' (unreserved)
|
||||
1, // '[' (gen-delim)
|
||||
2, // '\'
|
||||
1, // ']' (gen-delim)
|
||||
2, // '^'
|
||||
0, // '_' (unreserved)
|
||||
|
||||
2, // '`'
|
||||
0, 0, 0, 0, 0, // 'a' to 'e' (unreserved)
|
||||
0, 0, 0, 0, 0, // 'f' to 'j' (unreserved)
|
||||
0, 0, 0, 0, 0, // 'k' to 'o' (unreserved)
|
||||
0, 0, 0, 0, 0, // 'p' to 't' (unreserved)
|
||||
0, 0, 0, 0, 0, 0, // 'u' to 'z' (unreserved)
|
||||
2, // '{'
|
||||
2, // '|'
|
||||
2, // '}'
|
||||
0, // '~' (unreserved)
|
||||
|
||||
2 // BSKP
|
||||
};
|
||||
|
||||
// mask tables, in negative polarity
|
||||
// 0x00 if it belongs to this category
|
||||
// 0xff if it doesn't
|
||||
|
||||
static const uchar delimsMask[96] = {
|
||||
0xff, // space
|
||||
0x00, // '!' (sub-delim)
|
||||
0xff, // '"'
|
||||
0x00, // '#' (gen-delim)
|
||||
0x00, // '$' (gen-delim)
|
||||
0xff, // '%' (percent)
|
||||
0x00, // '&' (gen-delim)
|
||||
0x00, // "'" (sub-delim)
|
||||
0x00, // '(' (sub-delim)
|
||||
0x00, // ')' (sub-delim)
|
||||
0x00, // '*' (sub-delim)
|
||||
0x00, // '+' (sub-delim)
|
||||
0x00, // ',' (sub-delim)
|
||||
0xff, // '-' (unreserved)
|
||||
0xff, // '.' (unreserved)
|
||||
0x00, // '/' (gen-delim)
|
||||
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved)
|
||||
0x00, // ':' (gen-delim)
|
||||
0x00, // ';' (sub-delim)
|
||||
0xff, // '<'
|
||||
0x00, // '=' (sub-delim)
|
||||
0xff, // '>'
|
||||
0x00, // '?' (gen-delim)
|
||||
|
||||
0x00, // '@' (gen-delim)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved)
|
||||
0x00, // '[' (gen-delim)
|
||||
0xff, // '\'
|
||||
0x00, // ']' (gen-delim)
|
||||
0xff, // '^'
|
||||
0xff, // '_' (unreserved)
|
||||
|
||||
0xff, // '`'
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved)
|
||||
0xff, // '{'
|
||||
0xff, // '|'
|
||||
0xff, // '}'
|
||||
0xff, // '~' (unreserved)
|
||||
|
||||
0xff // BSKP
|
||||
};
|
||||
|
||||
static const uchar reservedMask[96] = {
|
||||
0xff, // space
|
||||
0xff, // '!' (sub-delim)
|
||||
0x00, // '"'
|
||||
0xff, // '#' (gen-delim)
|
||||
0xff, // '$' (gen-delim)
|
||||
0xff, // '%' (percent)
|
||||
0xff, // '&' (gen-delim)
|
||||
0xff, // "'" (sub-delim)
|
||||
0xff, // '(' (sub-delim)
|
||||
0xff, // ')' (sub-delim)
|
||||
0xff, // '*' (sub-delim)
|
||||
0xff, // '+' (sub-delim)
|
||||
0xff, // ',' (sub-delim)
|
||||
0xff, // '-' (unreserved)
|
||||
0xff, // '.' (unreserved)
|
||||
0xff, // '/' (gen-delim)
|
||||
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved)
|
||||
0xff, // ':' (gen-delim)
|
||||
0xff, // ';' (sub-delim)
|
||||
0x00, // '<'
|
||||
0xff, // '=' (sub-delim)
|
||||
0x00, // '>'
|
||||
0xff, // '?' (gen-delim)
|
||||
|
||||
0xff, // '@' (gen-delim)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved)
|
||||
0xff, // '[' (gen-delim)
|
||||
0x00, // '\'
|
||||
0xff, // ']' (gen-delim)
|
||||
0x00, // '^'
|
||||
0xff, // '_' (unreserved)
|
||||
|
||||
0x00, // '`'
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved)
|
||||
0x00, // '{'
|
||||
0x00, // '|'
|
||||
0x00, // '}'
|
||||
0xff, // '~' (unreserved)
|
||||
|
||||
0xff // BSKP
|
||||
};
|
||||
|
||||
static inline bool isHex(ushort c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
static inline bool isUpperHex(ushort c)
|
||||
{
|
||||
// undefined behaviour if c isn't an hex char!
|
||||
return c < 0x60;
|
||||
}
|
||||
|
||||
static inline ushort toUpperHex(ushort c)
|
||||
{
|
||||
return isUpperHex(c) ? c : c - 0x20;
|
||||
}
|
||||
|
||||
static inline ushort decodeNibble(ushort c)
|
||||
{
|
||||
return c >= 'a' ? c - 'a' + 0xA :
|
||||
c >= 'A' ? c - 'A' + 0xA : c - '0';
|
||||
}
|
||||
|
||||
// if the sequence at input is 2*HEXDIG, returns its decoding
|
||||
// returns -1 if it isn't.
|
||||
// assumes that the range has been checked already
|
||||
static inline ushort decodePercentEncoding(const ushort *input)
|
||||
{
|
||||
ushort c1 = input[1];
|
||||
ushort c2 = input[2];
|
||||
if (!isHex(c1) || !isHex(c2))
|
||||
return ushort(-1);
|
||||
return decodeNibble(c1) << 4 | decodeNibble(c2);
|
||||
}
|
||||
|
||||
static inline ushort encodeNibble(ushort c)
|
||||
{
|
||||
static const uchar hexnumbers[] = "0123456789ABCDEF";
|
||||
return hexnumbers[c & 0xf];
|
||||
}
|
||||
|
||||
static void ensureDetached(QString &result, ushort *&output, const ushort *begin, const ushort *input, const ushort *end,
|
||||
int add = 0)
|
||||
{
|
||||
if (!output) {
|
||||
// now detach
|
||||
// create enough space if the rest of the string needed to be percent-encoded
|
||||
int charsProcessed = input - begin;
|
||||
int charsRemaining = end - input;
|
||||
int spaceNeeded = end - begin + 2 * charsRemaining + add;
|
||||
int origSize = result.size();
|
||||
result.resize(origSize + spaceNeeded);
|
||||
|
||||
// we know that resize() above detached, so we bypass the reference count check
|
||||
output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData()))
|
||||
+ origSize;
|
||||
|
||||
// copy the chars we've already processed
|
||||
int i;
|
||||
for (i = 0; i < charsProcessed; ++i)
|
||||
output[i] = begin[i];
|
||||
output += i;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isUnicodeNonCharacter(uint ucs4)
|
||||
{
|
||||
// Unicode has a couple of "non-characters" that one can use internally,
|
||||
// but are not allowed to be used for text interchange.
|
||||
//
|
||||
// Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
|
||||
// U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
|
||||
// U+FDEF (inclusive)
|
||||
|
||||
return (ucs4 & 0xfffe) == 0xfffe
|
||||
|| (ucs4 - 0xfdd0U) < 16;
|
||||
}
|
||||
|
||||
// returns true if we performed an UTF-8 decoding
|
||||
static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input,
|
||||
const ushort *end, ushort decoded)
|
||||
{
|
||||
int charsNeeded;
|
||||
uint min_uc;
|
||||
uint uc;
|
||||
|
||||
if (decoded <= 0xC1) {
|
||||
// an UTF-8 first character must be at least 0xC0
|
||||
// however, all 0xC0 and 0xC1 first bytes can only produce overlong sequences
|
||||
return false;
|
||||
} else if (decoded < 0xe0) {
|
||||
charsNeeded = 2;
|
||||
min_uc = 0x80;
|
||||
uc = decoded & 0x1f;
|
||||
} else if (decoded < 0xf0) {
|
||||
charsNeeded = 3;
|
||||
min_uc = 0x800;
|
||||
uc = decoded & 0x0f;
|
||||
} else if (decoded < 0xf5) {
|
||||
charsNeeded = 4;
|
||||
min_uc = 0x10000;
|
||||
uc = decoded & 0x07;
|
||||
} else {
|
||||
// the last Unicode character is U+10FFFF
|
||||
// it's encoded in UTF-8 as "\xF4\x8F\xBF\xBF"
|
||||
// therefore, a byte higher than 0xF4 is not the UTF-8 first byte
|
||||
return false;
|
||||
}
|
||||
|
||||
// are there enough remaining?
|
||||
if (end - input < 3*charsNeeded)
|
||||
return false;
|
||||
|
||||
if (input[3] != '%')
|
||||
return false;
|
||||
|
||||
// first continuation character
|
||||
decoded = decodePercentEncoding(input + 3);
|
||||
if ((decoded & 0xc0) != 0x80)
|
||||
return false;
|
||||
uc <<= 6;
|
||||
uc |= decoded & 0x3f;
|
||||
|
||||
if (charsNeeded > 2) {
|
||||
if (input[6] != '%')
|
||||
return false;
|
||||
|
||||
// second continuation character
|
||||
decoded = decodePercentEncoding(input + 6);
|
||||
if ((decoded & 0xc0) != 0x80)
|
||||
return false;
|
||||
uc <<= 6;
|
||||
uc |= decoded & 0x3f;
|
||||
|
||||
if (charsNeeded > 3) {
|
||||
if (input[9] != '%')
|
||||
return false;
|
||||
|
||||
// third continuation character
|
||||
decoded = decodePercentEncoding(input + 9);
|
||||
if ((decoded & 0xc0) != 0x80)
|
||||
return false;
|
||||
uc <<= 6;
|
||||
uc |= decoded & 0x3f;
|
||||
}
|
||||
}
|
||||
|
||||
// we've decoded something; safety-check it
|
||||
if (uc < min_uc)
|
||||
return false;
|
||||
if (isUnicodeNonCharacter(uc) || (uc >= 0xD800 && uc <= 0xDFFF) || uc >= 0x110000)
|
||||
return false;
|
||||
|
||||
if (!QChar::requiresSurrogates(uc)) {
|
||||
// UTF-8 decoded and no surrogates are required
|
||||
// detach if necessary
|
||||
ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 1);
|
||||
*output++ = uc;
|
||||
} else {
|
||||
// UTF-8 decoded to something that requires a surrogate pair
|
||||
ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 2);
|
||||
*output++ = QChar::highSurrogate(uc);
|
||||
*output++ = QChar::lowSurrogate(uc);
|
||||
}
|
||||
input += charsNeeded * 3 - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort *begin,
|
||||
const ushort *&input, const ushort *end, ushort decoded)
|
||||
{
|
||||
uint uc = decoded;
|
||||
if (QChar::isHighSurrogate(uc)) {
|
||||
if (input < end && QChar::isLowSurrogate(input[1]))
|
||||
uc = QChar::surrogateToUcs4(uc, input[1]);
|
||||
}
|
||||
|
||||
// note: we will encode bad UTF-16 to UTF-8
|
||||
// but they don't get decoded back
|
||||
|
||||
// calculate the utf8 length
|
||||
int utf8len = uc >= 0x10000 ? 4 : uc >= 0x800 ? 3 : 2;
|
||||
|
||||
// detach
|
||||
if (!output) {
|
||||
// we need 3 * utf8len for the encoded UTF-8 sequence
|
||||
// but ensureDetached already adds 3 for the char we're processing
|
||||
ensureDetached(result, output, begin, input, end, 3*utf8len - 3);
|
||||
} else {
|
||||
// verify that there's enough space or expand
|
||||
int charsRemaining = end - input - 1; // not including this one
|
||||
int pos = output - reinterpret_cast<const ushort *>(result.constData());
|
||||
int spaceRemaining = result.size() - pos;
|
||||
if (spaceRemaining < 3*charsRemaining + 3*utf8len) {
|
||||
// must resize
|
||||
result.resize(result.size() + 3*utf8len);
|
||||
|
||||
// we know that resize() above detached, so we bypass the reference count check
|
||||
output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData()));
|
||||
output += pos;
|
||||
}
|
||||
}
|
||||
|
||||
// write the sequence
|
||||
if (uc < 0x800) {
|
||||
// first of two bytes
|
||||
uchar c = 0xc0 | uchar(uc >> 6);
|
||||
*output++ = '%';
|
||||
*output++ = encodeNibble(c >> 4);
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
} else {
|
||||
uchar c;
|
||||
if (uc > 0xFFFF) {
|
||||
// first two of four bytes
|
||||
c = 0xf0 | uchar(uc >> 18);
|
||||
*output++ = '%';
|
||||
*output++ = 'F';
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
|
||||
// continuation byte
|
||||
c = 0x80 | (uchar(uc >> 12) & 0x3f);
|
||||
*output++ = '%';
|
||||
*output++ = encodeNibble(c >> 4);
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
|
||||
// this was a surrogate pair
|
||||
++input;
|
||||
} else {
|
||||
// first of three bytes
|
||||
c = 0xe0 | uchar(uc >> 12);
|
||||
*output++ = '%';
|
||||
*output++ = 'E';
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
}
|
||||
|
||||
// continuation byte
|
||||
c = 0x80 | (uchar(uc >> 6) & 0x3f);
|
||||
*output++ = '%';
|
||||
*output++ = encodeNibble(c >> 4);
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
}
|
||||
|
||||
// continuation byte
|
||||
uchar c = 0x80 | (uc & 0x3f);
|
||||
*output++ = '%';
|
||||
*output++ = encodeNibble(c >> 4);
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
}
|
||||
|
||||
static int recode(QString &result, const ushort *begin, const ushort *end, QUrl::ComponentFormattingOptions encoding,
|
||||
const uchar *actionTable, bool retryBadEncoding)
|
||||
{
|
||||
const int origSize = result.size();
|
||||
const ushort *input = begin;
|
||||
ushort *output = 0;
|
||||
|
||||
for ( ; input != end; ++input) {
|
||||
register ushort c;
|
||||
EncodingAction action;
|
||||
|
||||
// try a run where no change is necessary
|
||||
for ( ; input != end; ++input) {
|
||||
c = *input;
|
||||
if (c < 0x20U || c >= 0x80U) // also: (c - 0x20 < 0x60U)
|
||||
goto non_trivial;
|
||||
action = EncodingAction(actionTable[c - ' ']);
|
||||
if (action == EncodeCharacter)
|
||||
goto non_trivial;
|
||||
if (output)
|
||||
*output++ = c;
|
||||
}
|
||||
break;
|
||||
|
||||
non_trivial:
|
||||
register uint decoded;
|
||||
if (c == '%' && retryBadEncoding) {
|
||||
// always write "%25"
|
||||
ensureDetached(result, output, begin, input, end);
|
||||
*output++ = '%';
|
||||
*output++ = '2';
|
||||
*output++ = '5';
|
||||
continue;
|
||||
} else if (c == '%') {
|
||||
// check if the input is valid
|
||||
if (input + 2 >= end || (decoded = decodePercentEncoding(input)) == ushort(-1)) {
|
||||
// not valid, retry
|
||||
result.resize(origSize);
|
||||
return recode(result, begin, end, encoding, actionTable, true);
|
||||
}
|
||||
|
||||
if (decoded >= 0x80) {
|
||||
// decode the UTF-8 sequence
|
||||
if (!(encoding & QUrl::EncodeUnicode) &&
|
||||
encodedUtf8ToUtf16(result, output, begin, input, end, decoded))
|
||||
continue;
|
||||
|
||||
// decoding the encoded UTF-8 failed
|
||||
action = LeaveCharacter;
|
||||
} else if (decoded >= 0x20) {
|
||||
action = EncodingAction(actionTable[decoded - ' ']);
|
||||
}
|
||||
} else {
|
||||
decoded = c;
|
||||
if (decoded >= 0x80 && encoding & QUrl::EncodeUnicode) {
|
||||
// encode the UTF-8 sequence
|
||||
unicodeToEncodedUtf8(result, output, begin, input, end, decoded);
|
||||
continue;
|
||||
} else if (decoded >= 0x80) {
|
||||
if (output)
|
||||
*output++ = c;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (decoded < 0x20)
|
||||
action = EncodeCharacter;
|
||||
|
||||
// there are six possibilities:
|
||||
// current \ action | DecodeCharacter | LeaveCharacter | EncodeCharacter
|
||||
// decoded | 1:leave | 2:leave | 3:encode
|
||||
// encoded | 4:decode | 5:leave | 6:leave
|
||||
// cases 1 and 2 were handled before this section
|
||||
|
||||
if (c == '%' && action != DecodeCharacter) {
|
||||
// cases 5 and 6: it's encoded and we're leaving it as it is
|
||||
// except we're pedantic and we'll uppercase the hex
|
||||
if (output || !isUpperHex(input[1]) || !isUpperHex(input[2])) {
|
||||
ensureDetached(result, output, begin, input, end);
|
||||
*output++ = '%';
|
||||
*output++ = toUpperHex(*++input);
|
||||
*output++ = toUpperHex(*++input);
|
||||
}
|
||||
} else if (c == '%' && action == DecodeCharacter) {
|
||||
// case 4: we need to decode
|
||||
ensureDetached(result, output, begin, input, end);
|
||||
*output++ = decoded;
|
||||
input += 2;
|
||||
} else {
|
||||
// must be case 3: we need to encode
|
||||
ensureDetached(result, output, begin, input, end);
|
||||
*output++ = '%';
|
||||
*output++ = encodeNibble(c >> 4);
|
||||
*output++ = encodeNibble(c & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
if (output) {
|
||||
int len = output - reinterpret_cast<const ushort *>(result.constData());
|
||||
result.truncate(len);
|
||||
return len - origSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static void maskTable(uchar (&table)[N], const uchar (&mask)[N])
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
table[i] &= mask[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Recodes the string from \a begin to \a end. If any transformations are
|
||||
done, append them to \a appendTo and return the number of characters added.
|
||||
If no transformations were required, return 0.
|
||||
|
||||
The \a encoding option modifies the default behaviour:
|
||||
\list
|
||||
\li QUrl::EncodeDelimiters: if set, delimiters will be left untransformed (note: not encoded!);
|
||||
if unset, delimiters will be decoded
|
||||
\li QUrl::DecodeReserved: if set, reserved characters will be decoded;
|
||||
if unset, reserved characters will be encoded
|
||||
\li QUrl::EncodeSpaces: if set, spaces will be encoded to "%20"; if unset, they will be " "
|
||||
\li QUrl::EncodeUnicode: if set, characters above U+0080 will be encoded to their UTF-8
|
||||
percent-encoded form; if unset, they will be decoded to UTF-16
|
||||
\endlist
|
||||
|
||||
Other flags are ignored (including QUrl::EncodeReserved).
|
||||
|
||||
The \a tableModifications argument can be used to supply extra
|
||||
modifications to the tables, to be applied after the flags above are
|
||||
handled. It consists of a sequence of 16-bit values, where the low 8 bits
|
||||
indicate the character in question and the high 8 bits are either \c
|
||||
EncodeCharacter, \c LeaveCharacter or \c DecodeCharacter.
|
||||
*/
|
||||
|
||||
Q_AUTOTEST_EXPORT int
|
||||
qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
|
||||
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications)
|
||||
{
|
||||
uchar actionTable[sizeof defaultActionTable];
|
||||
if (!(encoding & QUrl::EncodeDelimiters) && encoding & QUrl::DecodeReserved) {
|
||||
// reset the table
|
||||
memset(actionTable, DecodeCharacter, sizeof actionTable);
|
||||
if (encoding & QUrl::EncodeSpaces)
|
||||
actionTable[0] = EncodeCharacter;
|
||||
|
||||
// these are always encoded
|
||||
actionTable['%' - ' '] = EncodeCharacter;
|
||||
actionTable[0x7F - ' '] = EncodeCharacter;
|
||||
} else {
|
||||
memcpy(actionTable, defaultActionTable, sizeof actionTable);
|
||||
if (!(encoding & QUrl::EncodeDelimiters))
|
||||
maskTable(actionTable, delimsMask);
|
||||
if (encoding & QUrl::DecodeReserved)
|
||||
maskTable(actionTable, reservedMask);
|
||||
if (!(encoding & QUrl::EncodeSpaces))
|
||||
actionTable[0] = DecodeCharacter; // decode
|
||||
}
|
||||
|
||||
if (tableModifications) {
|
||||
for (const ushort *p = tableModifications; *p; ++p)
|
||||
actionTable[uchar(*p) - ' '] = *p >> 8;
|
||||
}
|
||||
|
||||
return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end),
|
||||
encoding, actionTable, false);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -2096,7 +2096,9 @@ QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const
|
||||
Returns a list of indexes for the items in the column of the \a start index
|
||||
where data stored under the given \a role matches the specified \a value.
|
||||
The way the search is performed is defined by the \a flags given. The list
|
||||
that is returned may be empty.
|
||||
that is returned may be empty. Note also that the order of results in the
|
||||
list may not correspond to the order in the model, if for example a proxy
|
||||
model is used. The order of the results can not be relied upon.
|
||||
|
||||
The search begins from the \a start index, and continues until the number
|
||||
of matching data items equals \a hits, the search reaches the last row, or
|
||||
|
@ -59,7 +59,7 @@ class Q_CORE_EXPORT QAbstractProxyModel : public QAbstractItemModel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QAbstractProxyModel(QObject *parent = 0);
|
||||
explicit QAbstractProxyModel(QObject *parent = 0);
|
||||
~QAbstractProxyModel();
|
||||
|
||||
virtual void setSourceModel(QAbstractItemModel *sourceModel);
|
||||
|
@ -235,7 +235,7 @@ bool QItemSelectionRange::intersects(const QItemSelectionRange &other) const
|
||||
both the selection range and the \a other selection range.
|
||||
*/
|
||||
|
||||
QItemSelectionRange QItemSelectionRange::intersect(const QItemSelectionRange &other) const
|
||||
QItemSelectionRange QItemSelectionRange::intersected(const QItemSelectionRange &other) const
|
||||
{
|
||||
if (model() == other.model() && parent() == other.parent()) {
|
||||
QModelIndex topLeft = model()->index(qMax(top(), other.top()),
|
||||
|
@ -92,9 +92,12 @@ public:
|
||||
}
|
||||
|
||||
bool intersects(const QItemSelectionRange &other) const;
|
||||
QItemSelectionRange intersect(const QItemSelectionRange &other) const; // ### Qt 5: make QT4_SUPPORT
|
||||
inline QItemSelectionRange intersected(const QItemSelectionRange &other) const
|
||||
{ return intersect(other); }
|
||||
#if QT_DEPRECATED_SINCE(5, 0)
|
||||
inline QItemSelectionRange intersect(const QItemSelectionRange &other) const
|
||||
{ return intersected(other); }
|
||||
#endif
|
||||
QItemSelectionRange intersected(const QItemSelectionRange &other) const;
|
||||
|
||||
|
||||
inline bool operator==(const QItemSelectionRange &other) const
|
||||
{ return (tl == other.tl && br == other.br); }
|
||||
|
@ -73,7 +73,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
|
||||
Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
|
||||
|
||||
public:
|
||||
QSortFilterProxyModel(QObject *parent = 0);
|
||||
explicit QSortFilterProxyModel(QObject *parent = 0);
|
||||
~QSortFilterProxyModel();
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel);
|
||||
|
@ -57,7 +57,7 @@ class Q_CORE_EXPORT QStringListModel : public QAbstractListModel
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QStringListModel(QObject *parent = 0);
|
||||
QStringListModel(const QStringList &strings, QObject *parent = 0);
|
||||
explicit QStringListModel(const QStringList &strings, QObject *parent = 0);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
|
@ -400,7 +400,8 @@ QString QJsonValue::toString() const
|
||||
if (t != String)
|
||||
return QString();
|
||||
stringData->ref.ref(); // the constructor below doesn't add a ref.
|
||||
return QString(*(const QConstStringData<1> *)stringData);
|
||||
QStringDataPtr holder = { stringData };
|
||||
return QString(holder);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -295,6 +295,16 @@ int QAbstractEventDispatcher::registerTimer(int interval, Qt::TimerType timerTyp
|
||||
\sa Qt::TimerType
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QAbstractEventDispatcher::remainingTime(int timerId)
|
||||
|
||||
Returns the remaining time in milliseconds with the given \a timerId.
|
||||
If the timer is inactive, the returned value will be -1. If the timer is
|
||||
overdue, the returned value will be 0.
|
||||
|
||||
\sa Qt::TimerType
|
||||
*/
|
||||
|
||||
/*! \fn void QAbstractEventDispatcher::wakeUp()
|
||||
\threadsafe
|
||||
|
||||
|
@ -93,6 +93,8 @@ public:
|
||||
virtual bool unregisterTimers(QObject *object) = 0;
|
||||
virtual QList<TimerInfo> registeredTimers(QObject *object) const = 0;
|
||||
|
||||
virtual int remainingTime(int timerId) = 0;
|
||||
|
||||
virtual void wakeUp() = 0;
|
||||
virtual void interrupt() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
@ -1513,26 +1513,29 @@ void QCoreApplication::quit()
|
||||
generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
|
||||
called.
|
||||
|
||||
The function returns true on success and false on failure.
|
||||
|
||||
\sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
|
||||
*/
|
||||
|
||||
void QCoreApplication::installTranslator(QTranslator *translationFile)
|
||||
bool QCoreApplication::installTranslator(QTranslator *translationFile)
|
||||
{
|
||||
if (!translationFile)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
|
||||
return;
|
||||
return false;
|
||||
QCoreApplicationPrivate *d = self->d_func();
|
||||
d->translators.prepend(translationFile);
|
||||
|
||||
#ifndef QT_NO_TRANSLATION_BUILDER
|
||||
if (translationFile->isEmpty())
|
||||
return;
|
||||
return false;
|
||||
#endif
|
||||
|
||||
QEvent ev(QEvent::LanguageChange);
|
||||
QCoreApplication::sendEvent(self, &ev);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1540,20 +1543,24 @@ void QCoreApplication::installTranslator(QTranslator *translationFile)
|
||||
translation files used by this application. (It does not delete the
|
||||
translation file from the file system.)
|
||||
|
||||
The function returns true on success and false on failure.
|
||||
|
||||
\sa installTranslator() translate(), QObject::tr()
|
||||
*/
|
||||
|
||||
void QCoreApplication::removeTranslator(QTranslator *translationFile)
|
||||
bool QCoreApplication::removeTranslator(QTranslator *translationFile)
|
||||
{
|
||||
if (!translationFile)
|
||||
return;
|
||||
return false;
|
||||
if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
|
||||
return;
|
||||
return false;
|
||||
QCoreApplicationPrivate *d = self->d_func();
|
||||
if (d->translators.removeAll(translationFile) && !self->closingDown()) {
|
||||
QEvent ev(QEvent::LanguageChange);
|
||||
QCoreApplication::sendEvent(self, &ev);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void replacePercentN(QString *result, int n)
|
||||
|
@ -134,8 +134,8 @@ public:
|
||||
#endif // QT_NO_LIBRARY
|
||||
|
||||
#ifndef QT_NO_TRANSLATION
|
||||
static void installTranslator(QTranslator * messageFile);
|
||||
static void removeTranslator(QTranslator * messageFile);
|
||||
static bool installTranslator(QTranslator * messageFile);
|
||||
static bool removeTranslator(QTranslator * messageFile);
|
||||
#endif
|
||||
enum Encoding { UnicodeUTF8, Latin1, DefaultCodec = Latin1
|
||||
#if QT_DEPRECATED_SINCE(5, 0)
|
||||
|
@ -170,7 +170,6 @@ QT_BEGIN_NAMESPACE
|
||||
\value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area.
|
||||
\value NonClientAreaMouseMove A mouse move occurred outside the client area.
|
||||
\value MacSizeChange The user changed his widget sizes (Mac OS X only).
|
||||
\value MenubarUpdated The window's menu bar has been updated.
|
||||
\value MetaCall An asynchronous method invocation via QMetaObject::invokeMethod().
|
||||
\value ModifiedChange Widgets modification state has been changed.
|
||||
\value MouseButtonDblClick Mouse press again (QMouseEvent).
|
||||
|
@ -192,9 +192,6 @@ public:
|
||||
#endif
|
||||
AcceptDropsChange = 152,
|
||||
|
||||
MenubarUpdated = 153, // Support event for Q3MainWindow, which needs to
|
||||
// knwow when QMenubar is updated.
|
||||
|
||||
ZeroTimerEvent = 154, // Used for Windows Zero timer events
|
||||
|
||||
GraphicsSceneMouseMove = 155, // GraphicsView
|
||||
@ -269,17 +266,14 @@ public:
|
||||
ScrollPrepare = 204,
|
||||
Scroll = 205,
|
||||
|
||||
Map = 206,
|
||||
Unmap = 207,
|
||||
Expose = 206,
|
||||
|
||||
Expose = 208,
|
||||
InputMethodQuery = 207,
|
||||
OrientationChange = 208, // Screen orientation has changed
|
||||
|
||||
InputMethodQuery = 209,
|
||||
OrientationChange = 210, // Screen orientation has changed
|
||||
TouchCancel = 209,
|
||||
|
||||
TouchCancel = 211,
|
||||
|
||||
ThemeChange = 212,
|
||||
ThemeChange = 210,
|
||||
|
||||
// 512 reserved for Qt Jambi's MetaCall event
|
||||
// 513 reserved for Qt Jambi's DeleteOnMainThread event
|
||||
|
@ -567,6 +567,19 @@ QList<QEventDispatcherGlib::TimerInfo> QEventDispatcherGlib::registeredTimers(QO
|
||||
return d->timerSource->timerList.registeredTimers(object);
|
||||
}
|
||||
|
||||
int QEventDispatcherGlib::remainingTime(int timerId)
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
if (timerId < 1) {
|
||||
qWarning("QEventDispatcherGlib::remainingTimeTime: invalid argument");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_D(QEventDispatcherGlib);
|
||||
return d->timerSource->timerList.timerRemainingTime(timerId);
|
||||
}
|
||||
|
||||
void QEventDispatcherGlib::interrupt()
|
||||
{
|
||||
wakeUp();
|
||||
|
@ -85,6 +85,8 @@ public:
|
||||
bool unregisterTimers(QObject *object);
|
||||
QList<TimerInfo> registeredTimers(QObject *object) const;
|
||||
|
||||
int remainingTime(int timerId);
|
||||
|
||||
void wakeUp();
|
||||
void interrupt();
|
||||
void flush();
|
||||
|
@ -628,6 +628,19 @@ bool QEventDispatcherUNIX::hasPendingEvents()
|
||||
return qGlobalPostedEventsCount();
|
||||
}
|
||||
|
||||
int QEventDispatcherUNIX::remainingTime(int timerId)
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
if (timerId < 1) {
|
||||
qWarning("QEventDispatcherUNIX::remainingTime: invalid argument");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_D(QEventDispatcherUNIX);
|
||||
return d->timerList.timerRemainingTime(timerId);
|
||||
}
|
||||
|
||||
void QEventDispatcherUNIX::wakeUp()
|
||||
{
|
||||
Q_D(QEventDispatcherUNIX);
|
||||
|
@ -116,6 +116,8 @@ public:
|
||||
bool unregisterTimers(QObject *object);
|
||||
QList<TimerInfo> registeredTimers(QObject *object) const;
|
||||
|
||||
int remainingTime(int timerId);
|
||||
|
||||
void wakeUp();
|
||||
void interrupt();
|
||||
void flush();
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "qvarlengtharray.h"
|
||||
#include "qwineventnotifier.h"
|
||||
|
||||
#include "qelapsedtimer.h"
|
||||
#include "qcoreapplication_p.h"
|
||||
#include <private/qthread_p.h>
|
||||
#include <private/qmutexpool_p.h>
|
||||
@ -532,6 +533,8 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
|
||||
ok = SetTimer(internalHwnd, t->timerId, interval, 0);
|
||||
}
|
||||
|
||||
t->timeout = qt_msectime() + interval;
|
||||
|
||||
if (ok == 0)
|
||||
qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer");
|
||||
}
|
||||
@ -998,6 +1001,42 @@ void QEventDispatcherWin32::activateEventNotifiers()
|
||||
}
|
||||
}
|
||||
|
||||
int QEventDispatcherWin32::remainingTime(int timerId)
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
if (timerId < 1) {
|
||||
qWarning("QEventDispatcherWin32::remainingTime: invalid argument");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_D(QEventDispatcherWin32);
|
||||
|
||||
if (d->timerVec.isEmpty())
|
||||
return -1;
|
||||
|
||||
quint64 currentTime = qt_msectime();
|
||||
|
||||
register WinTimerInfo *t;
|
||||
for (int i=0; i<d->timerVec.size(); i++) {
|
||||
t = d->timerVec.at(i);
|
||||
if (t && t->timerId == timerId) { // timer found
|
||||
if (currentTime < t->timeout) {
|
||||
// time to wait
|
||||
return t->timeout - currentTime;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
qWarning("QEventDispatcherWin32::remainingTime: timer id %s not found", timerId);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void QEventDispatcherWin32::wakeUp()
|
||||
{
|
||||
Q_D(QEventDispatcherWin32);
|
||||
|
@ -66,6 +66,7 @@ class QEventDispatcherWin32Private;
|
||||
|
||||
// forward declaration
|
||||
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
||||
int qt_msectime();
|
||||
|
||||
class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
|
||||
{
|
||||
@ -94,6 +95,8 @@ public:
|
||||
void unregisterEventNotifier(QWinEventNotifier *notifier);
|
||||
void activateEventNotifiers();
|
||||
|
||||
int remainingTime(int timerId);
|
||||
|
||||
void wakeUp();
|
||||
void interrupt();
|
||||
void flush();
|
||||
@ -123,6 +126,7 @@ struct WinTimerInfo { // internal timer info
|
||||
int timerId;
|
||||
int interval;
|
||||
Qt::TimerType timerType;
|
||||
quint64 timeout; // - when to actually fire
|
||||
QObject *obj; // - object to receive events
|
||||
bool inTimerEvent;
|
||||
int fastTimerId;
|
||||
|
@ -374,7 +374,7 @@ private:
|
||||
\brief The QEventLoopLocker class provides a means to quit an event loop when it is no longer needed.
|
||||
|
||||
The QEventLoopLocker operates on particular objects - either a QCoreApplication
|
||||
instance or a QEventLoop instance.
|
||||
instance, a QEventLoop instance or a QThread instance.
|
||||
|
||||
This makes it possible to, for example, run a batch of jobs with an event loop
|
||||
and exit that event loop after the last job is finished. That is accomplished
|
||||
@ -388,7 +388,7 @@ private:
|
||||
*/
|
||||
|
||||
/*!
|
||||
Creates an event locker operating on the \p app.
|
||||
Creates an event locker operating on the QCoreApplication.
|
||||
|
||||
The application will quit when there are no more QEventLoopLockers operating on it.
|
||||
|
||||
@ -401,7 +401,7 @@ QEventLoopLocker::QEventLoopLocker()
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates an event locker operating on the \p app.
|
||||
Creates an event locker operating on the \p loop.
|
||||
|
||||
This particular QEventLoop will quit when there are no more QEventLoopLockers operating on it.
|
||||
|
||||
@ -413,6 +413,13 @@ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates an event locker operating on the \p thread.
|
||||
|
||||
This particular QThread will quit when there are no more QEventLoopLockers operating on it.
|
||||
|
||||
\sa QThread::quit()
|
||||
*/
|
||||
QEventLoopLocker::QEventLoopLocker(QThread *thread)
|
||||
: d_ptr(new QEventLoopLockerPrivate(static_cast<QThreadPrivate*>(QObjectPrivate::get(thread))))
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,8 +57,13 @@ class Q_CORE_EXPORT QMetaMethod
|
||||
public:
|
||||
inline QMetaMethod() : mobj(0),handle(0) {}
|
||||
|
||||
const char *signature() const;
|
||||
QByteArray methodSignature() const;
|
||||
QByteArray name() const;
|
||||
const char *typeName() const;
|
||||
int returnType() const;
|
||||
int parameterCount() const;
|
||||
int parameterType(int index) const;
|
||||
void getParameterTypes(int *types) const;
|
||||
QList<QByteArray> parameterTypes() const;
|
||||
QList<QByteArray> parameterNames() const;
|
||||
const char *tag() const;
|
||||
@ -137,8 +142,16 @@ public:
|
||||
inline bool isValid() const { return mobj != 0; }
|
||||
|
||||
private:
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
// signature() has been renamed to methodSignature() in Qt 5.
|
||||
// Warning, that function returns a QByteArray; check the life time if
|
||||
// you convert to char*.
|
||||
char *signature(struct renamedInQt5_warning_checkTheLifeTime * = 0) Q_DECL_EQ_DELETE;
|
||||
#endif
|
||||
|
||||
const QMetaObject *mobj;
|
||||
uint handle;
|
||||
friend class QMetaMethodPrivate;
|
||||
friend struct QMetaObject;
|
||||
friend struct QMetaObjectPrivate;
|
||||
friend class QObject;
|
||||
|
@ -105,11 +105,64 @@ enum MetaObjectFlags {
|
||||
RequiresVariantMetaObject = 0x02
|
||||
};
|
||||
|
||||
enum MetaDataFlags {
|
||||
IsUnresolvedType = 0x80000000,
|
||||
TypeNameIndexMask = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
class QArgumentType
|
||||
{
|
||||
public:
|
||||
QArgumentType(int type)
|
||||
: _type(type)
|
||||
{}
|
||||
QArgumentType(const QByteArray &name)
|
||||
: _type(QMetaType::type(name.constData())), _name(name)
|
||||
{}
|
||||
QArgumentType()
|
||||
: _type(0)
|
||||
{}
|
||||
int type() const
|
||||
{ return _type; }
|
||||
QByteArray name() const
|
||||
{
|
||||
if (_type && _name.isEmpty())
|
||||
const_cast<QArgumentType *>(this)->_name = QMetaType::typeName(_type);
|
||||
return _name;
|
||||
}
|
||||
bool operator==(const QArgumentType &other) const
|
||||
{
|
||||
if (_type)
|
||||
return _type == other._type;
|
||||
else if (other._type)
|
||||
return false;
|
||||
else
|
||||
return _name == other._name;
|
||||
}
|
||||
bool operator!=(const QArgumentType &other) const
|
||||
{
|
||||
if (_type)
|
||||
return _type != other._type;
|
||||
else if (other._type)
|
||||
return true;
|
||||
else
|
||||
return _name != other._name;
|
||||
}
|
||||
|
||||
private:
|
||||
int _type;
|
||||
QByteArray _name;
|
||||
};
|
||||
|
||||
template <class T, int> class QVarLengthArray;
|
||||
typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
|
||||
|
||||
class QMetaMethodPrivate;
|
||||
class QMutex;
|
||||
|
||||
struct QMetaObjectPrivate
|
||||
{
|
||||
enum { OutputRevision = 6 }; // Used by moc and qmetaobjectbuilder
|
||||
enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus
|
||||
|
||||
int revision;
|
||||
int className;
|
||||
@ -122,18 +175,34 @@ struct QMetaObjectPrivate
|
||||
int signalCount; //since revision 4
|
||||
// revision 5 introduces changes in normalized signatures, no new members
|
||||
// revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
|
||||
// revision 7 is Qt 5
|
||||
|
||||
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
|
||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
|
||||
|
||||
static int indexOfSignalRelative(const QMetaObject **baseObject,
|
||||
const char* name,
|
||||
bool normalizeStringData);
|
||||
static int indexOfSlotRelative(const QMetaObject **m,
|
||||
const char *slot,
|
||||
bool normalizeStringData);
|
||||
static int originalClone(const QMetaObject *obj, int local_method_index);
|
||||
|
||||
static QByteArray decodeMethodSignature(const char *signature,
|
||||
QArgumentTypeArray &types);
|
||||
static int indexOfSignalRelative(const QMetaObject **baseObject,
|
||||
const QByteArray &name, int argc,
|
||||
const QArgumentType *types);
|
||||
static int indexOfSlotRelative(const QMetaObject **m,
|
||||
const QByteArray &name, int argc,
|
||||
const QArgumentType *types);
|
||||
static int indexOfSignal(const QMetaObject *m, const QByteArray &name,
|
||||
int argc, const QArgumentType *types);
|
||||
static int indexOfSlot(const QMetaObject *m, const QByteArray &name,
|
||||
int argc, const QArgumentType *types);
|
||||
static int indexOfMethod(const QMetaObject *m, const QByteArray &name,
|
||||
int argc, const QArgumentType *types);
|
||||
static int indexOfConstructor(const QMetaObject *m, const QByteArray &name,
|
||||
int argc, const QArgumentType *types);
|
||||
static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
|
||||
int methodArgc, const QArgumentType *methodTypes);
|
||||
static bool checkConnectArgs(const QMetaMethodPrivate *signal,
|
||||
const QMetaMethodPrivate *method);
|
||||
|
||||
static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
|
||||
|
||||
#ifndef QT_NO_QOBJECT
|
||||
|
@ -78,26 +78,17 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
|
||||
// copied from moc's generator.cpp
|
||||
uint qvariant_nameToType(const char* name)
|
||||
bool isBuiltinType(const QByteArray &type)
|
||||
{
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
uint tp = QMetaType::type(name);
|
||||
return tp < QMetaType::User ? tp : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns true if the type is a QVariant types.
|
||||
*/
|
||||
bool isVariantType(const char* type)
|
||||
{
|
||||
return qvariant_nameToType(type) != 0;
|
||||
int id = QMetaType::type(type);
|
||||
if (!id && !type.isEmpty() && type != "void")
|
||||
return false;
|
||||
return (id < QMetaType::User);
|
||||
}
|
||||
|
||||
// copied from qmetaobject.cpp
|
||||
static inline const QMetaObjectPrivate *priv(const uint* data)
|
||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
||||
// end of copied lines from qmetaobject.cpp
|
||||
|
||||
class QMetaMethodBuilderPrivate
|
||||
{
|
||||
@ -105,7 +96,7 @@ public:
|
||||
QMetaMethodBuilderPrivate
|
||||
(QMetaMethod::MethodType _methodType,
|
||||
const QByteArray& _signature,
|
||||
const QByteArray& _returnType = QByteArray(),
|
||||
const QByteArray& _returnType = QByteArray("void"),
|
||||
QMetaMethod::Access _access = QMetaMethod::Public,
|
||||
int _revision = 0)
|
||||
: signature(QMetaObject::normalizedSignature(_signature.constData())),
|
||||
@ -113,6 +104,7 @@ public:
|
||||
attributes(((int)_access) | (((int)_methodType) << 2)),
|
||||
revision(_revision)
|
||||
{
|
||||
Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull());
|
||||
}
|
||||
|
||||
QByteArray signature;
|
||||
@ -136,6 +128,21 @@ public:
|
||||
{
|
||||
attributes = ((attributes & ~AccessMask) | (int)value);
|
||||
}
|
||||
|
||||
QList<QByteArray> parameterTypes() const
|
||||
{
|
||||
return QMetaObjectPrivate::parameterTypeNamesFromSignature(signature);
|
||||
}
|
||||
|
||||
int parameterCount() const
|
||||
{
|
||||
return parameterTypes().size();
|
||||
}
|
||||
|
||||
QByteArray name() const
|
||||
{
|
||||
return signature.left(qMax(signature.indexOf('('), 0));
|
||||
}
|
||||
};
|
||||
|
||||
class QMetaPropertyBuilderPrivate
|
||||
@ -429,8 +436,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
|
||||
\a signature and \a returnType. Returns an object that can be
|
||||
used to adjust the other attributes of the method. The \a signature
|
||||
and \a returnType will be normalized before they are added to
|
||||
the class. If \a returnType is empty, then it indicates that
|
||||
the method has \c{void} as its return type.
|
||||
the class.
|
||||
|
||||
\sa method(), methodCount(), removeMethod(), indexOfMethod()
|
||||
*/
|
||||
@ -458,13 +464,13 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
|
||||
{
|
||||
QMetaMethodBuilder method;
|
||||
if (prototype.methodType() == QMetaMethod::Method)
|
||||
method = addMethod(prototype.signature());
|
||||
method = addMethod(prototype.methodSignature());
|
||||
else if (prototype.methodType() == QMetaMethod::Signal)
|
||||
method = addSignal(prototype.signature());
|
||||
method = addSignal(prototype.methodSignature());
|
||||
else if (prototype.methodType() == QMetaMethod::Slot)
|
||||
method = addSlot(prototype.signature());
|
||||
method = addSlot(prototype.methodSignature());
|
||||
else if (prototype.methodType() == QMetaMethod::Constructor)
|
||||
method = addConstructor(prototype.signature());
|
||||
method = addConstructor(prototype.methodSignature());
|
||||
method.setReturnType(prototype.typeName());
|
||||
method.setParameterNames(prototype.parameterNames());
|
||||
method.setTag(prototype.tag());
|
||||
@ -501,7 +507,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
|
||||
{
|
||||
int index = d->methods.size();
|
||||
d->methods.append(QMetaMethodBuilderPrivate
|
||||
(QMetaMethod::Signal, signature, QByteArray(), QMetaMethod::Protected));
|
||||
(QMetaMethod::Signal, signature, QByteArray("void"), QMetaMethod::Protected));
|
||||
return QMetaMethodBuilder(this, index);
|
||||
}
|
||||
|
||||
@ -517,7 +523,8 @@ QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
|
||||
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
|
||||
{
|
||||
int index = d->constructors.size();
|
||||
d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature));
|
||||
d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature,
|
||||
/*returnType=*/QByteArray()));
|
||||
return QMetaMethodBuilder(this, -(index + 1));
|
||||
}
|
||||
|
||||
@ -535,7 +542,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signatur
|
||||
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
|
||||
{
|
||||
Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
|
||||
QMetaMethodBuilder ctor = addConstructor(prototype.signature());
|
||||
QMetaMethodBuilder ctor = addConstructor(prototype.methodSignature());
|
||||
ctor.setReturnType(prototype.typeName());
|
||||
ctor.setParameterNames(prototype.parameterNames());
|
||||
ctor.setTag(prototype.tag());
|
||||
@ -588,7 +595,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
|
||||
if (prototype.hasNotifySignal()) {
|
||||
// Find an existing method for the notify signal, or add a new one.
|
||||
QMetaMethod method = prototype.notifySignal();
|
||||
int index = indexOfMethod(method.signature());
|
||||
int index = indexOfMethod(method.methodSignature());
|
||||
if (index == -1)
|
||||
index = addMethod(method).index();
|
||||
d->properties[property._index].notifySignal = index;
|
||||
@ -731,16 +738,12 @@ void QMetaObjectBuilder::addMetaObject
|
||||
|
||||
if ((members & RelatedMetaObjects) != 0) {
|
||||
const QMetaObject **objects;
|
||||
if (priv(prototype->d.data)->revision < 2) {
|
||||
objects = (const QMetaObject **)(prototype->d.extradata);
|
||||
} else
|
||||
{
|
||||
const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
|
||||
if (extra)
|
||||
objects = extra->objects;
|
||||
else
|
||||
objects = 0;
|
||||
}
|
||||
Q_ASSERT(priv(prototype->d.data)->revision >= 2);
|
||||
const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
|
||||
if (extra)
|
||||
objects = extra->objects;
|
||||
else
|
||||
objects = 0;
|
||||
if (objects) {
|
||||
while (*objects != 0) {
|
||||
addRelatedMetaObject(*objects);
|
||||
@ -750,12 +753,11 @@ void QMetaObjectBuilder::addMetaObject
|
||||
}
|
||||
|
||||
if ((members & StaticMetacall) != 0) {
|
||||
if (priv(prototype->d.data)->revision >= 6) {
|
||||
const QMetaObjectExtraData *extra =
|
||||
(const QMetaObjectExtraData *)(prototype->d.extradata);
|
||||
if (extra && extra->static_metacall)
|
||||
setStaticMetacallFunction(extra->static_metacall);
|
||||
}
|
||||
Q_ASSERT(priv(prototype->d.data)->revision >= 6);
|
||||
const QMetaObjectExtraData *extra =
|
||||
(const QMetaObjectExtraData *)(prototype->d.extradata);
|
||||
if (extra && extra->static_metacall)
|
||||
setStaticMetacallFunction(extra->static_metacall);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1070,75 +1072,79 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
|
||||
#define ALIGN(size,type) \
|
||||
(size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
|
||||
|
||||
class MetaStringTable
|
||||
/*!
|
||||
\class QMetaStringTable
|
||||
\internal
|
||||
\brief The QMetaStringTable class can generate a meta-object string table at runtime.
|
||||
*/
|
||||
|
||||
QMetaStringTable::QMetaStringTable()
|
||||
: m_index(0) {}
|
||||
|
||||
// Enters the given value into the string table (if it hasn't already been
|
||||
// entered). Returns the index of the string.
|
||||
int QMetaStringTable::enter(const QByteArray &value)
|
||||
{
|
||||
public:
|
||||
typedef QHash<QByteArray, int> Entries; // string --> offset mapping
|
||||
typedef Entries::const_iterator const_iterator;
|
||||
Entries::const_iterator constBegin() const
|
||||
{ return m_entries.constBegin(); }
|
||||
Entries::const_iterator constEnd() const
|
||||
{ return m_entries.constEnd(); }
|
||||
Entries::iterator it = m_entries.find(value);
|
||||
if (it != m_entries.end())
|
||||
return it.value();
|
||||
int pos = m_index;
|
||||
m_entries.insert(value, pos);
|
||||
++m_index;
|
||||
return pos;
|
||||
}
|
||||
|
||||
MetaStringTable() : m_offset(0) {}
|
||||
|
||||
int enter(const QByteArray &value)
|
||||
{
|
||||
Entries::iterator it = m_entries.find(value);
|
||||
if (it != m_entries.end())
|
||||
return it.value();
|
||||
int pos = m_offset;
|
||||
m_entries.insert(value, pos);
|
||||
m_offset += value.size() + 1;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int arraySize() const { return m_offset; }
|
||||
|
||||
private:
|
||||
Entries m_entries;
|
||||
int m_offset;
|
||||
};
|
||||
|
||||
// Build the parameter array string for a method.
|
||||
static QByteArray buildParameterNames
|
||||
(const QByteArray& signature, const QList<QByteArray>& parameterNames)
|
||||
int QMetaStringTable::preferredAlignment()
|
||||
{
|
||||
// If the parameter name list is specified, then concatenate them.
|
||||
if (!parameterNames.isEmpty()) {
|
||||
QByteArray names;
|
||||
bool first = true;
|
||||
foreach (const QByteArray &name, parameterNames) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
names += (char)',';
|
||||
names += name;
|
||||
}
|
||||
return names;
|
||||
}
|
||||
return Q_ALIGNOF(QByteArrayData);
|
||||
}
|
||||
|
||||
// Count commas in the signature, excluding those inside template arguments.
|
||||
int index = signature.indexOf('(');
|
||||
if (index < 0)
|
||||
return QByteArray();
|
||||
++index;
|
||||
if (index >= signature.size())
|
||||
return QByteArray();
|
||||
if (signature[index] == ')')
|
||||
return QByteArray();
|
||||
int count = 1;
|
||||
int brackets = 0;
|
||||
while (index < signature.size() && signature[index] != ',') {
|
||||
char ch = signature[index++];
|
||||
if (ch == '<')
|
||||
++brackets;
|
||||
else if (ch == '>')
|
||||
--brackets;
|
||||
else if (ch == ',' && brackets <= 0)
|
||||
++count;
|
||||
// Returns the size (in bytes) required for serializing this string table.
|
||||
int QMetaStringTable::blobSize() const
|
||||
{
|
||||
int size = m_entries.size() * sizeof(QByteArrayData);
|
||||
Entries::const_iterator it;
|
||||
for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
|
||||
size += it.key().size() + 1;
|
||||
return size;
|
||||
}
|
||||
|
||||
// Writes strings to string data struct.
|
||||
// The struct consists of an array of QByteArrayData, followed by a char array
|
||||
// containing the actual strings. This format must match the one produced by
|
||||
// moc (see generator.cpp).
|
||||
void QMetaStringTable::writeBlob(char *out)
|
||||
{
|
||||
Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1)));
|
||||
|
||||
int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData);
|
||||
int stringdataOffset = 0;
|
||||
for (int i = 0; i < m_entries.size(); ++i) {
|
||||
const QByteArray &str = m_entries.key(i);
|
||||
int size = str.size();
|
||||
qptrdiff offset = offsetOfStringdataMember + stringdataOffset
|
||||
- i * sizeof(QByteArrayData);
|
||||
const QByteArrayData data =
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset);
|
||||
|
||||
memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
|
||||
|
||||
memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
|
||||
out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
|
||||
|
||||
stringdataOffset += size + 1;
|
||||
}
|
||||
return QByteArray(count - 1, ',');
|
||||
}
|
||||
|
||||
// Returns the sum of all parameters (including return type) for the given
|
||||
// \a methods. This is needed for calculating the size of the methods'
|
||||
// parameter type/name meta-data.
|
||||
static int aggregateParameterCount(const QList<QMetaMethodBuilderPrivate> &methods)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < methods.size(); ++i)
|
||||
sum += methods.at(i).parameterCount() + 1; // +1 for return type
|
||||
return sum;
|
||||
}
|
||||
|
||||
// Build a QMetaObject in "buf" based on the information in "d".
|
||||
@ -1151,6 +1157,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
Q_UNUSED(expectedSize); // Avoid warning in release mode
|
||||
int size = 0;
|
||||
int dataIndex;
|
||||
int paramsIndex;
|
||||
int enumIndex;
|
||||
int index;
|
||||
bool hasRevisionedMethods = d->hasRevisionedMethods();
|
||||
@ -1181,8 +1188,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
break;
|
||||
}
|
||||
}
|
||||
int methodParametersDataSize =
|
||||
((aggregateParameterCount(d->methods)
|
||||
+ aggregateParameterCount(d->constructors)) * 2) // types and parameter names
|
||||
- d->methods.size() // return "parameters" don't have names
|
||||
- d->constructors.size(); // "this" parameters don't have names
|
||||
if (buf) {
|
||||
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 6, "QMetaObjectBuilder should generate the same version as moc");
|
||||
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QMetaObjectBuilder should generate the same version as moc");
|
||||
pmeta->revision = QMetaObjectPrivate::OutputRevision;
|
||||
pmeta->flags = d->flags;
|
||||
pmeta->className = 0; // Class name is always the first string.
|
||||
@ -1197,6 +1209,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
dataIndex += 5 * d->methods.size();
|
||||
if (hasRevisionedMethods)
|
||||
dataIndex += d->methods.size();
|
||||
paramsIndex = dataIndex;
|
||||
dataIndex += methodParametersDataSize;
|
||||
|
||||
pmeta->propertyCount = d->properties.size();
|
||||
pmeta->propertyData = dataIndex;
|
||||
@ -1218,6 +1232,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
dataIndex += 5 * d->methods.size();
|
||||
if (hasRevisionedMethods)
|
||||
dataIndex += d->methods.size();
|
||||
paramsIndex = dataIndex;
|
||||
dataIndex += methodParametersDataSize;
|
||||
dataIndex += 3 * d->properties.size();
|
||||
if (hasNotifySignals)
|
||||
dataIndex += d->properties.size();
|
||||
@ -1240,13 +1256,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
// Find the start of the data and string tables.
|
||||
int *data = reinterpret_cast<int *>(pmeta);
|
||||
size += dataIndex * sizeof(int);
|
||||
ALIGN(size, void *);
|
||||
char *str = reinterpret_cast<char *>(buf + size);
|
||||
if (buf) {
|
||||
if (relocatable) {
|
||||
meta->d.stringdata = reinterpret_cast<const char *>((quintptr)size);
|
||||
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size);
|
||||
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
||||
} else {
|
||||
meta->d.stringdata = str;
|
||||
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
|
||||
meta->d.data = reinterpret_cast<uint *>(data);
|
||||
}
|
||||
}
|
||||
@ -1254,7 +1271,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
// Reset the current data position to just past the QMetaObjectPrivate.
|
||||
dataIndex = MetaObjectPrivateFieldCount;
|
||||
|
||||
MetaStringTable strings;
|
||||
QMetaStringTable strings;
|
||||
strings.enter(d->className);
|
||||
|
||||
// Output the class infos,
|
||||
@ -1273,24 +1290,21 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
|
||||
for (index = 0; index < d->methods.size(); ++index) {
|
||||
QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
||||
int sig = strings.enter(method->signature);
|
||||
int params;
|
||||
QByteArray names = buildParameterNames
|
||||
(method->signature, method->parameterNames);
|
||||
params = strings.enter(names);
|
||||
int ret = strings.enter(method->returnType);
|
||||
int name = strings.enter(method->name());
|
||||
int argc = method->parameterCount();
|
||||
int tag = strings.enter(method->tag);
|
||||
int attrs = method->attributes;
|
||||
if (buf) {
|
||||
data[dataIndex] = sig;
|
||||
data[dataIndex + 1] = params;
|
||||
data[dataIndex + 2] = ret;
|
||||
data[dataIndex] = name;
|
||||
data[dataIndex + 1] = argc;
|
||||
data[dataIndex + 2] = paramsIndex;
|
||||
data[dataIndex + 3] = tag;
|
||||
data[dataIndex + 4] = attrs;
|
||||
if (method->methodType() == QMetaMethod::Signal)
|
||||
pmeta->signalCount++;
|
||||
}
|
||||
dataIndex += 5;
|
||||
paramsIndex += 1 + argc * 2;
|
||||
}
|
||||
if (hasRevisionedMethods) {
|
||||
for (index = 0; index < d->methods.size(); ++index) {
|
||||
@ -1301,23 +1315,59 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
}
|
||||
}
|
||||
|
||||
// Output the method parameters in the class.
|
||||
Q_ASSERT(!buf || dataIndex == pmeta->methodData + d->methods.size() * 5
|
||||
+ (hasRevisionedMethods ? d->methods.size() : 0));
|
||||
for (int x = 0; x < 2; ++x) {
|
||||
QList<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
|
||||
for (index = 0; index < methods.size(); ++index) {
|
||||
QMetaMethodBuilderPrivate *method = &(methods[index]);
|
||||
QList<QByteArray> paramTypeNames = method->parameterTypes();
|
||||
int paramCount = paramTypeNames.size();
|
||||
for (int i = -1; i < paramCount; ++i) {
|
||||
const QByteArray &typeName = (i < 0) ? method->returnType : paramTypeNames.at(i);
|
||||
int typeInfo;
|
||||
if (isBuiltinType(typeName))
|
||||
typeInfo = QMetaType::type(typeName);
|
||||
else
|
||||
typeInfo = IsUnresolvedType | strings.enter(typeName);
|
||||
if (buf)
|
||||
data[dataIndex] = typeInfo;
|
||||
++dataIndex;
|
||||
}
|
||||
|
||||
QList<QByteArray> paramNames = method->parameterNames;
|
||||
while (paramNames.size() < paramCount)
|
||||
paramNames.append(QByteArray());
|
||||
for (int i = 0; i < paramCount; ++i) {
|
||||
int stringIndex = strings.enter(paramNames.at(i));
|
||||
if (buf)
|
||||
data[dataIndex] = stringIndex;
|
||||
++dataIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output the properties in the class.
|
||||
Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
|
||||
for (index = 0; index < d->properties.size(); ++index) {
|
||||
QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
||||
int name = strings.enter(prop->name);
|
||||
int type = strings.enter(prop->type);
|
||||
|
||||
int typeInfo;
|
||||
if (isBuiltinType(prop->type))
|
||||
typeInfo = QMetaType::type(prop->type);
|
||||
else
|
||||
typeInfo = IsUnresolvedType | strings.enter(prop->type);
|
||||
|
||||
int flags = prop->flags;
|
||||
|
||||
if (!isVariantType(prop->type)) {
|
||||
if (!isBuiltinType(prop->type))
|
||||
flags |= EnumOrFlag;
|
||||
} else {
|
||||
flags |= qvariant_nameToType(prop->type) << 24;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
data[dataIndex] = name;
|
||||
data[dataIndex + 1] = type;
|
||||
data[dataIndex + 1] = typeInfo;
|
||||
data[dataIndex + 2] = flags;
|
||||
}
|
||||
dataIndex += 3;
|
||||
@ -1372,34 +1422,25 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
||||
Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
|
||||
for (index = 0; index < d->constructors.size(); ++index) {
|
||||
QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
||||
int sig = strings.enter(method->signature);
|
||||
int params;
|
||||
QByteArray names = buildParameterNames
|
||||
(method->signature, method->parameterNames);
|
||||
params = strings.enter(names);
|
||||
int ret = strings.enter(method->returnType);
|
||||
int name = strings.enter(method->name());
|
||||
int argc = method->parameterCount();
|
||||
int tag = strings.enter(method->tag);
|
||||
int attrs = method->attributes;
|
||||
if (buf) {
|
||||
data[dataIndex] = sig;
|
||||
data[dataIndex + 1] = params;
|
||||
data[dataIndex + 2] = ret;
|
||||
data[dataIndex] = name;
|
||||
data[dataIndex + 1] = argc;
|
||||
data[dataIndex + 2] = paramsIndex;
|
||||
data[dataIndex + 3] = tag;
|
||||
data[dataIndex + 4] = attrs;
|
||||
}
|
||||
dataIndex += 5;
|
||||
paramsIndex += 1 + argc * 2;
|
||||
}
|
||||
|
||||
size += strings.arraySize();
|
||||
size += strings.blobSize();
|
||||
|
||||
if (buf) {
|
||||
// Write strings to string data array.
|
||||
MetaStringTable::const_iterator it;
|
||||
for (it = strings.constBegin(); it != strings.constEnd(); ++it) {
|
||||
memcpy(str + it.value(), it.key().constData(), it.key().size());
|
||||
str[it.value() + it.key().size()] = '\0';
|
||||
}
|
||||
}
|
||||
if (buf)
|
||||
strings.writeBlob(str);
|
||||
|
||||
// Output the zero terminator in the data array.
|
||||
if (buf)
|
||||
@ -1508,7 +1549,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
||||
quintptr dataOffset = (quintptr)dataMo->d.data;
|
||||
|
||||
output->d.superdata = superclass;
|
||||
output->d.stringdata = buf + stringdataOffset;
|
||||
output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
|
||||
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
||||
output->d.extradata = 0;
|
||||
}
|
||||
@ -1896,7 +1937,7 @@ QByteArray QMetaMethodBuilder::returnType() const
|
||||
is empty, then the method's return type is \c{void}. The \a value
|
||||
will be normalized before it is added to the method.
|
||||
|
||||
\sa returnType(), signature()
|
||||
\sa returnType(), parameterTypes(), signature()
|
||||
*/
|
||||
void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
||||
{
|
||||
@ -1905,6 +1946,20 @@ void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
||||
d->returnType = QMetaObject::normalizedType(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the list of parameter types for this method.
|
||||
|
||||
\sa returnType(), parameterNames()
|
||||
*/
|
||||
QList<QByteArray> QMetaMethodBuilder::parameterTypes() const
|
||||
{
|
||||
QMetaMethodBuilderPrivate *d = d_func();
|
||||
if (d)
|
||||
return d->parameterTypes();
|
||||
else
|
||||
return QList<QByteArray>();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the list of parameter names for this method.
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user