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/
|
** 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$
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
** GNU Lesser General Public License Usage
|
** GNU Lesser General Public License Usage
|
||||||
@ -39,13 +39,17 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <mm3dnow.h>
|
#include <immintrin.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
|
|
||||||
|
|
||||||
int main(int, char**)
|
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;
|
return 0;
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
SOURCES = sse.cpp
|
SOURCES = avx2.cpp
|
||||||
CONFIG -= x11 qt
|
CONFIG -= x11 qt
|
||||||
mac:CONFIG -= app_bundle
|
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_QGTKSTYLE=auto
|
||||||
CFG_LARGEFILE=auto
|
CFG_LARGEFILE=auto
|
||||||
CFG_OPENSSL=auto
|
CFG_OPENSSL=auto
|
||||||
CFG_STL=auto
|
|
||||||
CFG_PRECOMPILE=auto
|
CFG_PRECOMPILE=auto
|
||||||
CFG_SEPARATE_DEBUG_INFO=no
|
CFG_SEPARATE_DEBUG_INFO=no
|
||||||
CFG_SEPARATE_DEBUG_INFO_NOCOPY=no
|
CFG_SEPARATE_DEBUG_INFO_NOCOPY=no
|
||||||
CFG_REDUCE_EXPORTS=auto
|
CFG_REDUCE_EXPORTS=auto
|
||||||
CFG_MMX=auto
|
|
||||||
CFG_3DNOW=auto
|
|
||||||
CFG_SSE=auto
|
|
||||||
CFG_SSE2=auto
|
CFG_SSE2=auto
|
||||||
CFG_SSE3=auto
|
CFG_SSE3=auto
|
||||||
CFG_SSSE3=auto
|
CFG_SSSE3=auto
|
||||||
CFG_SSE4_1=auto
|
CFG_SSE4_1=auto
|
||||||
CFG_SSE4_2=auto
|
CFG_SSE4_2=auto
|
||||||
CFG_AVX=auto
|
CFG_AVX=auto
|
||||||
|
CFG_AVX2=auto
|
||||||
CFG_REDUCE_RELOCATIONS=auto
|
CFG_REDUCE_RELOCATIONS=auto
|
||||||
CFG_ACCESSIBILITY=auto
|
CFG_ACCESSIBILITY=auto
|
||||||
CFG_IWMMXT=no
|
CFG_IWMMXT=no
|
||||||
@ -892,7 +889,7 @@ while [ "$#" -gt 0 ]; do
|
|||||||
VAL=no
|
VAL=no
|
||||||
;;
|
;;
|
||||||
#Qt style yes options
|
#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,"`
|
VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
|
||||||
VAL=yes
|
VAL=yes
|
||||||
;;
|
;;
|
||||||
@ -1428,13 +1425,6 @@ while [ "$#" -gt 0 ]; do
|
|||||||
UNKNOWN_OPT=yes
|
UNKNOWN_OPT=yes
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
stl)
|
|
||||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
|
||||||
CFG_STL="$VAL"
|
|
||||||
else
|
|
||||||
UNKNOWN_OPT=yes
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
pch)
|
pch)
|
||||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||||
CFG_PRECOMPILE="$VAL"
|
CFG_PRECOMPILE="$VAL"
|
||||||
@ -1459,27 +1449,6 @@ while [ "$#" -gt 0 ]; do
|
|||||||
UNKNOWN_OPT=yes
|
UNKNOWN_OPT=yes
|
||||||
fi
|
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)
|
sse2)
|
||||||
if [ "$VAL" = "no" ]; then
|
if [ "$VAL" = "no" ]; then
|
||||||
CFG_SSE2="$VAL"
|
CFG_SSE2="$VAL"
|
||||||
@ -1522,6 +1491,13 @@ while [ "$#" -gt 0 ]; do
|
|||||||
UNKNOWN_OPT=yes
|
UNKNOWN_OPT=yes
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
avx2)
|
||||||
|
if [ "$VAL" = "no" ]; then
|
||||||
|
CFG_AVX2="$VAL"
|
||||||
|
else
|
||||||
|
UNKNOWN_OPT=yes
|
||||||
|
fi
|
||||||
|
;;
|
||||||
iwmmxt)
|
iwmmxt)
|
||||||
CFG_IWMMXT="yes"
|
CFG_IWMMXT="yes"
|
||||||
;;
|
;;
|
||||||
@ -2816,13 +2792,6 @@ if [ "$OPT_HELP" = "yes" ]; then
|
|||||||
LFSY="*"
|
LFSY="*"
|
||||||
LFSN=" "
|
LFSN=" "
|
||||||
fi
|
fi
|
||||||
if [ "$CFG_STL" = "auto" ] || [ "$CFG_STL" = "yes" ]; then
|
|
||||||
SHY="*"
|
|
||||||
SHN=" "
|
|
||||||
else
|
|
||||||
SHY=" "
|
|
||||||
SHN="*"
|
|
||||||
fi
|
|
||||||
if [ "$CFG_PRECOMPILE" = "auto" ] || [ "$CFG_PRECOMPILE" = "no" ]; then
|
if [ "$CFG_PRECOMPILE" = "auto" ] || [ "$CFG_PRECOMPILE" = "no" ]; then
|
||||||
PHY=" "
|
PHY=" "
|
||||||
PHN="*"
|
PHN="*"
|
||||||
@ -2893,7 +2862,7 @@ Usage: $relconf [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir
|
|||||||
[-release] [-debug] [-debug-and-release]
|
[-release] [-debug] [-debug-and-release]
|
||||||
[-developer-build] [-shared] [-static] [-no-fast] [-fast] [-no-largefile]
|
[-developer-build] [-shared] [-static] [-no-fast] [-fast] [-no-largefile]
|
||||||
[-largefile] [-no-exceptions] [-exceptions] [-no-accessibility]
|
[-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]
|
[-plugin-sql-<driver>] [-system-sqlite]
|
||||||
[-platform] [-D <string>] [-I <string>] [-L <string>] [-help]
|
[-platform] [-D <string>] [-I <string>] [-L <string>] [-help]
|
||||||
[-qt-zlib] [-system-zlib] [-no-gif] [-no-libpng] [-qt-libpng] [-system-libpng]
|
[-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]
|
[-nomake <part>] [-R <string>] [-l <string>] [-no-rpath] [-rpath] [-continue]
|
||||||
[-verbose] [-v] [-silent] [-no-nis] [-nis] [-no-cups] [-cups] [-no-iconv]
|
[-verbose] [-v] [-silent] [-no-nis] [-nis] [-no-cups] [-cups] [-no-iconv]
|
||||||
[-iconv] [-no-pch] [-pch] [-no-dbus] [-dbus] [-dbus-linked] [-no-gui]
|
[-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]
|
[-no-sse3] [-no-ssse3] [-no-sse4.1] [-no-sse4.2] [-no-avx] [-no-neon]
|
||||||
[-qtnamespace <namespace>] [-qtlibinfix <infix>] [-separate-debug-info]
|
[-qtnamespace <namespace>] [-qtlibinfix <infix>] [-separate-debug-info]
|
||||||
[-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend]
|
[-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend]
|
||||||
@ -3000,9 +2969,6 @@ Configure options:
|
|||||||
-no-accessibility .. Do not compile Accessibility support.
|
-no-accessibility .. Do not compile Accessibility support.
|
||||||
* -accessibility ..... 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.
|
-no-sql-<driver> ... Disable SQL <driver> entirely.
|
||||||
-qt-sql-<driver> ... Enable a SQL <driver> in the QtSql library, by default
|
-qt-sql-<driver> ... Enable a SQL <driver> in the QtSql library, by default
|
||||||
none are turned on.
|
none are turned on.
|
||||||
@ -3029,15 +2995,13 @@ Configure options:
|
|||||||
See the README file for a list of supported
|
See the README file for a list of supported
|
||||||
operating systems and compilers.
|
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-sse2 ........... Do not compile with use of SSE2 instructions.
|
||||||
-no-sse3 ........... Do not compile with use of SSE3 instructions.
|
-no-sse3 ........... Do not compile with use of SSE3 instructions.
|
||||||
-no-ssse3 .......... Do not compile with use of SSSE3 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.1.......... Do not compile with use of SSE4.1 instructions.
|
||||||
-no-sse4.2.......... Do not compile with use of SSE4.2 instructions.
|
-no-sse4.2.......... Do not compile with use of SSE4.2 instructions.
|
||||||
-no-avx ............ Do not compile with use of AVX 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-neon ........... Do not compile with use of NEON instructions.
|
||||||
-no-mips_dsp ....... Do not compile with use of MIPS DSP 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.
|
-no-mips_dspr2 ..... Do not compile with use of MIPS DSP rev2 instructions.
|
||||||
@ -3733,33 +3697,6 @@ else
|
|||||||
CFG_USE_FLOATMATH=no
|
CFG_USE_FLOATMATH=no
|
||||||
fi
|
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
|
# detect sse2 support
|
||||||
if [ "${CFG_SSE2}" = "auto" ]; then
|
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
|
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
|
||||||
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
|
# check iWMMXt support
|
||||||
if [ "$CFG_IWMMXT" = "yes" ]; then
|
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"
|
"$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
|
||||||
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 &&
|
||||||
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then
|
[ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
|
||||||
HAVE_STL=yes
|
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
|
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()
|
# detect POSIX clock_gettime()
|
||||||
if [ "$CFG_CLOCK_GETTIME" = "auto" ]; then
|
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
|
if [ "$CFG_LARGEFILE" = "yes" ] && [ "$XPLATFORM_MINGW" != "yes" ]; then
|
||||||
QMAKE_CONFIG="$QMAKE_CONFIG largefile"
|
QMAKE_CONFIG="$QMAKE_CONFIG largefile"
|
||||||
fi
|
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
|
if [ "$CFG_USE_GNUMAKE" = "yes" ]; then
|
||||||
QMAKE_CONFIG="$QMAKE_CONFIG GNUmake"
|
QMAKE_CONFIG="$QMAKE_CONFIG GNUmake"
|
||||||
fi
|
fi
|
||||||
@ -5105,15 +5033,13 @@ fi
|
|||||||
if [ "$CFG_SEPARATE_DEBUG_INFO_NOCOPY" = "yes" ] ; then
|
if [ "$CFG_SEPARATE_DEBUG_INFO_NOCOPY" = "yes" ] ; then
|
||||||
QT_CONFIG="$QT_CONFIG separate_debug_info_nocopy"
|
QT_CONFIG="$QT_CONFIG separate_debug_info_nocopy"
|
||||||
fi
|
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_SSE2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse2"
|
||||||
[ "$CFG_SSE3" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse3"
|
[ "$CFG_SSE3" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse3"
|
||||||
[ "$CFG_SSSE3" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG ssse3"
|
[ "$CFG_SSSE3" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG ssse3"
|
||||||
[ "$CFG_SSE4_1" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse4_1"
|
[ "$CFG_SSE4_1" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse4_1"
|
||||||
[ "$CFG_SSE4_2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse4_2"
|
[ "$CFG_SSE4_2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG sse4_2"
|
||||||
[ "$CFG_AVX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx"
|
[ "$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_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt"
|
||||||
[ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon"
|
[ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon"
|
||||||
if [ "$CFG_ARCH" = "mips" ]; then
|
if [ "$CFG_ARCH" = "mips" ]; then
|
||||||
@ -5750,9 +5676,6 @@ elif [ "$CFG_DEBUG" = "no" ]; then
|
|||||||
fi
|
fi
|
||||||
QT_CONFIG="$QT_CONFIG release"
|
QT_CONFIG="$QT_CONFIG release"
|
||||||
fi
|
fi
|
||||||
if [ "$CFG_STL" = "yes" ]; then
|
|
||||||
QTCONFIG_CONFIG="$QTCONFIG_CONFIG stl"
|
|
||||||
fi
|
|
||||||
if [ "$CFG_FRAMEWORK" = "no" ]; then
|
if [ "$CFG_FRAMEWORK" = "no" ]; then
|
||||||
QTCONFIG_CONFIG="$QTCONFIG_CONFIG qt_no_framework"
|
QTCONFIG_CONFIG="$QTCONFIG_CONFIG qt_no_framework"
|
||||||
else
|
else
|
||||||
@ -6008,12 +5931,11 @@ else
|
|||||||
echo "JavaScriptCore JIT ..... $CFG_JAVASCRIPTCORE_JIT"
|
echo "JavaScriptCore JIT ..... $CFG_JAVASCRIPTCORE_JIT"
|
||||||
fi
|
fi
|
||||||
echo "QML debugging .......... $CFG_QML_DEBUG"
|
echo "QML debugging .......... $CFG_QML_DEBUG"
|
||||||
echo "STL support ............ $CFG_STL"
|
|
||||||
echo "PCH support ............ $CFG_PRECOMPILE"
|
echo "PCH support ............ $CFG_PRECOMPILE"
|
||||||
if [ "$CFG_ARCH" = "i386" -o "$CFG_ARCH" = "x86_64" ]; then
|
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 "SSE2/SSE3/SSSE3......... ${CFG_SSE2}/${CFG_SSE3}/${CFG_SSSE3}"
|
||||||
echo "SSSE3/SSE4.1/SSE4.2..... ${CFG_SSSE3}/${CFG_SSE4_1}/${CFG_SSE4_2}"
|
echo "SSE4.1/SSE4.2........... ${CFG_SSSE3}/${CFG_SSE4_1}/${CFG_SSE4_2}"
|
||||||
echo "AVX..................... ${CFG_AVX}"
|
echo "AVX/AVX2................ ${CFG_AVX}/${CFG_AVX2}"
|
||||||
elif [ "$CFG_ARCH" = "arm" ]; then
|
elif [ "$CFG_ARCH" = "arm" ]; then
|
||||||
echo "iWMMXt support ......... ${CFG_IWMMXT}"
|
echo "iWMMXt support ......... ${CFG_IWMMXT}"
|
||||||
echo "NEON support ........... ${CFG_NEON}"
|
echo "NEON support ........... ${CFG_NEON}"
|
||||||
@ -6317,7 +6239,7 @@ for file in .projects .projects.3; do
|
|||||||
fi
|
fi
|
||||||
SPEC=$XQMAKESPEC ;;
|
SPEC=$XQMAKESPEC ;;
|
||||||
*/qmake/qmake.pro) continue ;;
|
*/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
|
*) if [ "$CFG_NOPROCESS" = "yes" ]; then
|
||||||
continue
|
continue
|
||||||
else
|
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
|
- QCoreApplication::translate() will no longer return the source text when
|
||||||
the translation is empty. Use lrelease -removeidentical for optimization.
|
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::escape() is deprecated (but can be enabled via
|
||||||
QT_DISABLE_DEPRECATED_BEFORE), use QString::toHtmlEscaped() instead.
|
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::construct() has been renamed to QMetaType::create().
|
||||||
* QMetaType::unregisterType() has been removed.
|
* 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:
|
- QTestLib:
|
||||||
* The plain-text, xml and lightxml test output formats have been changed to
|
* 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
|
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.
|
- 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
|
- qMacVersion() has been removed. Use QSysInfo::macVersion() or
|
||||||
QSysInfo::MacintoshVersion instead.
|
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 *
|
* General *
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
@ -325,6 +350,10 @@ QtCore
|
|||||||
* QEvent::AccessibilityPrepare, AccessibilityHelp and AccessibilityDescription removed:
|
* QEvent::AccessibilityPrepare, AccessibilityHelp and AccessibilityDescription removed:
|
||||||
* The enum values simply didn't make sense in the first place and should simply be dropped.
|
* 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
|
QtGui
|
||||||
-----
|
-----
|
||||||
* Accessibility has been refactored. The hierachy of accessible objects is implemented via
|
* Accessibility has been refactored. The hierachy of accessible objects is implemented via
|
||||||
@ -378,6 +407,11 @@ QtWidgets
|
|||||||
* ResizeMode resizeMode(int logicalindex) const -
|
* ResizeMode resizeMode(int logicalindex) const -
|
||||||
use sectionResizeMode(int logicalindex) instead.
|
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
|
QtNetwork
|
||||||
---------
|
---------
|
||||||
* QHostAddress::isLoopback() API added. Returns true if the address is
|
* 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 openssl network backend now reads the ssl configuration file allowing
|
||||||
the use of openssl engines.
|
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
|
QtOpenGL
|
||||||
--------
|
--------
|
||||||
@ -466,6 +508,12 @@ changes. insertRows() and insertRecord() also respect the edit strategy.
|
|||||||
|
|
||||||
* QSqlTableModel::setData() and setRecord() in OnRowChange no longer have the
|
* QSqlTableModel::setData() and setRecord() in OnRowChange no longer have the
|
||||||
side effect of submitting the cached row when invoked on a different row.
|
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 *
|
* Database Drivers *
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
@ -580,6 +628,20 @@ Qt for Windows CE
|
|||||||
QMetaType::User, which means that it points to the first registered custom
|
QMetaType::User, which means that it points to the first registered custom
|
||||||
type, instead of a nonexistent type.
|
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
|
- QMessageBox
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ sock.connectToHost(url.host(), url.port(80));
|
|||||||
|
|
||||||
|
|
||||||
//! [4]
|
//! [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]
|
//! [4]
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i)
|
|||||||
const QMetaObject* metaObject = obj->metaObject();
|
const QMetaObject* metaObject = obj->metaObject();
|
||||||
QStringList methods;
|
QStringList methods;
|
||||||
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
|
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
|
||||||
methods << QString::fromLatin1(metaObject->method(i).signature());
|
methods << QString::fromLatin1(metaObject->method(i).methodSignature());
|
||||||
//! [methodCount]
|
//! [methodCount]
|
||||||
|
|
||||||
//! [6]
|
//! [6]
|
||||||
|
@ -73,7 +73,7 @@ MyStruct s2 = var.value<MyStruct>();
|
|||||||
|
|
||||||
//! [3]
|
//! [3]
|
||||||
int id = QMetaType::type("MyClass");
|
int id = QMetaType::type("MyClass");
|
||||||
if (id != 0) {
|
if (id != QMetaType::UnknownType) {
|
||||||
void *myClassPtr = QMetaType::create(id);
|
void *myClassPtr = QMetaType::create(id);
|
||||||
...
|
...
|
||||||
QMetaType::destroy(id, myClassPtr);
|
QMetaType::destroy(id, myClassPtr);
|
||||||
|
@ -155,9 +155,9 @@ inline bool operator==(const Employee &e1, const Employee &e2)
|
|||||||
&& e1.dateOfBirth() == e2.dateOfBirth();
|
&& 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
|
#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";
|
QString str = "banana and panama";
|
||||||
str.count(QRegExp("a[nm]a")); // returns 4
|
str.count(QRegExp("a[nm]a")); // returns 4
|
||||||
//! [18]
|
//! [18]
|
||||||
|
|
||||||
|
//! [95]
|
||||||
|
QString str = "banana and panama";
|
||||||
|
str.count(QRegularExpression("a[nm]a")); // returns 4
|
||||||
|
//! [95]
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::dataFunction()
|
void Widget::dataFunction()
|
||||||
@ -384,6 +389,11 @@ void Widget::firstIndexOfFunction()
|
|||||||
QString str = "the minimum";
|
QString str = "the minimum";
|
||||||
str.indexOf(QRegExp("m[aeiou]"), 0); // returns 4
|
str.indexOf(QRegExp("m[aeiou]"), 0); // returns 4
|
||||||
//! [25]
|
//! [25]
|
||||||
|
|
||||||
|
//! [93]
|
||||||
|
QString str = "the minimum";
|
||||||
|
str.indexOf(QRegularExpression("m[aeiou]"), 0); // returns 4
|
||||||
|
//! [93]
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::insertFunction()
|
void Widget::insertFunction()
|
||||||
@ -429,6 +439,11 @@ void Widget::lastIndexOfFunction()
|
|||||||
QString str = "the minimum";
|
QString str = "the minimum";
|
||||||
str.lastIndexOf(QRegExp("m[aeiou]")); // returns 8
|
str.lastIndexOf(QRegExp("m[aeiou]")); // returns 8
|
||||||
//! [30]
|
//! [30]
|
||||||
|
|
||||||
|
//! [94]
|
||||||
|
QString str = "the minimum";
|
||||||
|
str.lastIndexOf(QRegularExpression("m[aeiou]")); // returns 8
|
||||||
|
//! [94]
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::leftFunction()
|
void Widget::leftFunction()
|
||||||
@ -499,6 +514,12 @@ void Widget::removeFunction()
|
|||||||
r.remove(QRegExp("[aeiou]."));
|
r.remove(QRegExp("[aeiou]."));
|
||||||
// r == "The"
|
// r == "The"
|
||||||
//! [39]
|
//! [39]
|
||||||
|
|
||||||
|
//! [96]
|
||||||
|
QString r = "Telephone";
|
||||||
|
r.remove(QRegularExpression("[aeiou]."));
|
||||||
|
// r == "The"
|
||||||
|
//! [96]
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::replaceFunction()
|
void Widget::replaceFunction()
|
||||||
@ -533,6 +554,18 @@ void Widget::replaceFunction()
|
|||||||
equis.replace("xx", "x");
|
equis.replace("xx", "x");
|
||||||
// equis == "xxx"
|
// equis == "xxx"
|
||||||
//! [86]
|
//! [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()
|
void Widget::reserveFunction()
|
||||||
@ -627,9 +660,16 @@ void Widget::sectionFunction()
|
|||||||
//! [55]
|
//! [55]
|
||||||
QString line = "forename\tmiddlename surname \t \t phone";
|
QString line = "forename\tmiddlename surname \t \t phone";
|
||||||
QRegExp sep("\\s+");
|
QRegExp sep("\\s+");
|
||||||
str = line.section(sep, 2, 2); // s == "surname"
|
str = line.section(sep, 2, 2); // str == "surname"
|
||||||
str = line.section(sep, -3, -2); // s == "middlename surname"
|
str = line.section(sep, -3, -2); // str == "middlename surname"
|
||||||
//! [55]
|
//! [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()
|
void Widget::setNumFunction()
|
||||||
@ -682,6 +722,27 @@ void Widget::splitFunction()
|
|||||||
list = str.split(QRegExp("\\b"));
|
list = str.split(QRegExp("\\b"));
|
||||||
// list: [ "", "Now", ": ", "this", " ", "sentence", " ", "fragment", "." ]
|
// list: [ "", "Now", ": ", "this", " ", "sentence", " ", "fragment", "." ]
|
||||||
//! [61]
|
//! [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()
|
void Widget::splitCaseSensitiveFunction()
|
||||||
|
@ -144,6 +144,21 @@ Widget::Widget(QWidget *parent)
|
|||||||
list.replaceInStrings(QRegExp("^(.*), (.*)$"), "\\2 \\1");
|
list.replaceInStrings(QRegExp("^(.*), (.*)$"), "\\2 \\1");
|
||||||
// list == ["Bill Clinton", "Bill Murray"]
|
// list == ["Bill Clinton", "Bill Murray"]
|
||||||
//! [15]
|
//! [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[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -103,9 +103,9 @@ void Window::mouseMoveEvent(QMouseEvent *event)
|
|||||||
p.setRenderHint(QPainter::Antialiasing);
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
p.drawLine(m_lastPos, event->pos());
|
p.drawLine(m_lastPos, event->pos());
|
||||||
m_lastPos = event->pos();
|
m_lastPos = event->pos();
|
||||||
}
|
|
||||||
|
|
||||||
scheduleRender();
|
scheduleRender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::mouseReleaseEvent(QMouseEvent *event)
|
void Window::mouseReleaseEvent(QMouseEvent *event)
|
||||||
@ -115,9 +115,9 @@ void Window::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
p.setRenderHint(QPainter::Antialiasing);
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
p.drawLine(m_lastPos, event->pos());
|
p.drawLine(m_lastPos, event->pos());
|
||||||
m_lastPos = QPoint(-1, -1);
|
m_lastPos = QPoint(-1, -1);
|
||||||
}
|
|
||||||
|
|
||||||
scheduleRender();
|
scheduleRender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::exposeEvent(QExposeEvent *)
|
void Window::exposeEvent(QExposeEvent *)
|
||||||
@ -139,8 +139,7 @@ void Window::resizeEvent(QResizeEvent *)
|
|||||||
QPainter p(&m_image);
|
QPainter p(&m_image);
|
||||||
p.drawImage(0, 0, old);
|
p.drawImage(0, 0, old);
|
||||||
}
|
}
|
||||||
|
scheduleRender();
|
||||||
render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::keyPressEvent(QKeyEvent *event)
|
void Window::keyPressEvent(QKeyEvent *event)
|
||||||
@ -168,7 +167,8 @@ void Window::scheduleRender()
|
|||||||
|
|
||||||
void Window::timerEvent(QTimerEvent *)
|
void Window::timerEvent(QTimerEvent *)
|
||||||
{
|
{
|
||||||
render();
|
if (isExposed())
|
||||||
|
render();
|
||||||
killTimer(m_renderTimer);
|
killTimer(m_renderTimer);
|
||||||
m_renderTimer = 0;
|
m_renderTimer = 0;
|
||||||
}
|
}
|
||||||
|
@ -204,13 +204,11 @@ mac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#SIMD defines:
|
#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
|
sse2:DEFINES += QT_HAVE_SSE2
|
||||||
sse3:DEFINES += QT_HAVE_SSE3
|
sse3:DEFINES += QT_HAVE_SSE3
|
||||||
ssse3:DEFINES += QT_HAVE_SSSE3
|
ssse3:DEFINES += QT_HAVE_SSSE3
|
||||||
sse4_1:DEFINES += QT_HAVE_SSE4_1
|
sse4_1:DEFINES += QT_HAVE_SSE4_1
|
||||||
sse4_2:DEFINES += QT_HAVE_SSE4_2
|
sse4_2:DEFINES += QT_HAVE_SSE4_2
|
||||||
avx:DEFINES += QT_HAVE_AVX
|
avx:DEFINES += QT_HAVE_AVX
|
||||||
|
avx2:DEFINES += QT_HAVE_AVX2
|
||||||
iwmmxt:DEFINES += QT_HAVE_IWMMXT
|
iwmmxt:DEFINES += QT_HAVE_IWMMXT
|
||||||
|
@ -15,4 +15,4 @@ contains(QT_CONFIG, separate_debug_info_nocopy):CONFIG += separate_debug_info_no
|
|||||||
load(qt_targets)
|
load(qt_targets)
|
||||||
|
|
||||||
wince*:LIBS += $$QMAKE_LIBS_GUI
|
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
|
gbuild.o
|
||||||
|
|
||||||
#qt code
|
#qt code
|
||||||
QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
|
QOBJS=qtextcodec.o qutfcodec.o qstring.o qstringbuilder.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
|
||||||
qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.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 \
|
qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o qfilesystemiterator_unix.o \
|
||||||
qfsfileengine_unix.o qfsfileengine.o \
|
qfsfileengine_unix.o qfsfileengine.o \
|
||||||
qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.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 \
|
qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \
|
||||||
qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o qvariant.o qvsnprintf.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 \
|
qxmlstream.o qxmlutils.o qlogging.o \
|
||||||
$(QTOBJS)
|
$(QTOBJS)
|
||||||
|
|
||||||
@ -39,10 +39,12 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
|
|||||||
generators/integrity/gbuild.cpp \
|
generators/integrity/gbuild.cpp \
|
||||||
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.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/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/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \
|
||||||
$(SOURCE_PATH)/src/corelib/global/qmalloc.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/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/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/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \
|
||||||
$(SOURCE_PATH)/src/corelib/io/qfilesystemengine_mac.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/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/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/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.cpp \
|
||||||
$(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp \
|
$(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp \
|
||||||
$(SOURCE_PATH)/src/corelib/tools/qlocale_unix.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$(BUILD_PATH)/src/corelib/global \
|
||||||
-I$(SOURCE_PATH)/tools/shared \
|
-I$(SOURCE_PATH)/tools/shared \
|
||||||
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \
|
-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_COMPRESS -I$(QMAKESPEC) -DHAVE_QCONFIG_CPP -DQT_NO_THREAD -DQT_NO_QOBJECT \
|
||||||
-DQT_NO_GEOM_VARIANT -DQT_NO_DEPRECATED $(OPENSOURCE_CXXFLAGS)
|
-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
|
qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qcore_mac.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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
|
qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
|
||||||
$(CXX) -c -o $@ $(CXXFLAGS) $(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$(BUILD_PATH)\src\corelib\global \
|
||||||
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
|
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
|
||||||
-I$(SOURCE_PATH)\tools\shared \
|
-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_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \
|
||||||
-DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_BOOTSTRAPPED
|
-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)
|
CFLAGS = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS)
|
||||||
@ -78,12 +78,14 @@ QTOBJS= \
|
|||||||
qfilesystemiterator_win.obj \
|
qfilesystemiterator_win.obj \
|
||||||
qfsfileengine.obj \
|
qfsfileengine.obj \
|
||||||
qfsfileengine_iterator.obj \
|
qfsfileengine_iterator.obj \
|
||||||
|
qarraydata.obj \
|
||||||
qbytearray.obj \
|
qbytearray.obj \
|
||||||
qvsnprintf.obj \
|
qvsnprintf.obj \
|
||||||
qbytearraymatcher.obj \
|
qbytearraymatcher.obj \
|
||||||
qdatetime.obj \
|
qdatetime.obj \
|
||||||
qdir.obj \
|
qdir.obj \
|
||||||
qdiriterator.obj \
|
qdiriterator.obj \
|
||||||
|
qfiledevice.obj \
|
||||||
qfile.obj \
|
qfile.obj \
|
||||||
qtemporaryfile.obj \
|
qtemporaryfile.obj \
|
||||||
qabstractfileengine.obj \
|
qabstractfileengine.obj \
|
||||||
@ -105,6 +107,7 @@ QTOBJS= \
|
|||||||
qutfcodec.obj \
|
qutfcodec.obj \
|
||||||
qstring.obj \
|
qstring.obj \
|
||||||
qstringlist.obj \
|
qstringlist.obj \
|
||||||
|
qstringbuilder.obj \
|
||||||
qsystemerror.obj \
|
qsystemerror.obj \
|
||||||
qtextstream.obj \
|
qtextstream.obj \
|
||||||
qdatastream.obj \
|
qdatastream.obj \
|
||||||
@ -113,7 +116,6 @@ QTOBJS= \
|
|||||||
qsettings.obj \
|
qsettings.obj \
|
||||||
qlibraryinfo.obj \
|
qlibraryinfo.obj \
|
||||||
qvariant.obj \
|
qvariant.obj \
|
||||||
qurl.obj \
|
|
||||||
qsettings_win.obj \
|
qsettings_win.obj \
|
||||||
qmetatype.obj \
|
qmetatype.obj \
|
||||||
qxmlstream.obj \
|
qxmlstream.obj \
|
||||||
|
@ -49,7 +49,7 @@ CFLAGS = -c -o$@ -O \
|
|||||||
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
|
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
|
||||||
-I$(SOURCE_PATH)/tools/shared \
|
-I$(SOURCE_PATH)/tools/shared \
|
||||||
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT \
|
-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_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
|
||||||
-DQT_BOOTSTRAPPED
|
-DQT_BOOTSTRAPPED
|
||||||
CXXFLAGS = $(CFLAGS)
|
CXXFLAGS = $(CFLAGS)
|
||||||
@ -74,6 +74,7 @@ endif
|
|||||||
QTOBJS= \
|
QTOBJS= \
|
||||||
qbitarray.o \
|
qbitarray.o \
|
||||||
qbuffer.o \
|
qbuffer.o \
|
||||||
|
qarraydata.o \
|
||||||
qbytearray.o \
|
qbytearray.o \
|
||||||
qcryptographichash.o \
|
qcryptographichash.o \
|
||||||
qvsnprintf.o \
|
qvsnprintf.o \
|
||||||
@ -82,6 +83,7 @@ QTOBJS= \
|
|||||||
qdatetime.o \
|
qdatetime.o \
|
||||||
qdir.o \
|
qdir.o \
|
||||||
qdiriterator.o \
|
qdiriterator.o \
|
||||||
|
qfiledevice.o \
|
||||||
qfile.o \
|
qfile.o \
|
||||||
qtemporaryfile.o \
|
qtemporaryfile.o \
|
||||||
qfileinfo.o \
|
qfileinfo.o \
|
||||||
@ -109,12 +111,12 @@ QTOBJS= \
|
|||||||
qutfcodec.o \
|
qutfcodec.o \
|
||||||
qstring.o \
|
qstring.o \
|
||||||
qstringlist.o \
|
qstringlist.o \
|
||||||
|
qstringbuilder.o \
|
||||||
qsystemerror.o \
|
qsystemerror.o \
|
||||||
qsystemlibrary.o \
|
qsystemlibrary.o \
|
||||||
qtextstream.o \
|
qtextstream.o \
|
||||||
quuid.o \
|
quuid.o \
|
||||||
qvector.o \
|
qvector.o \
|
||||||
qurl.o \
|
|
||||||
qsettings.o \
|
qsettings.o \
|
||||||
qsettings_win.o \
|
qsettings_win.o \
|
||||||
qvariant.o \
|
qvariant.o \
|
||||||
|
@ -1928,7 +1928,7 @@ ProjectBuilderMakefileGenerator::writeSettings(QString var, QStringList vals, in
|
|||||||
{
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
const QString quote = (flags & SettingsNoQuote) ? "" : "\"";
|
const QString quote = (flags & SettingsNoQuote) ? "" : "\"";
|
||||||
const QString escape_quote = quote.isEmpty() ? "" : "\\" + quote;
|
const QString escape_quote = quote.isEmpty() ? "" : QString("\\" + quote);
|
||||||
QString newline = "\n";
|
QString newline = "\n";
|
||||||
for(int i = 0; i < indent_level; ++i)
|
for(int i = 0; i < indent_level; ++i)
|
||||||
newline += "\t";
|
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(),
|
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());
|
parser.line_no, scope_blocks.count(), scope_failed, s.toLatin1().constData());
|
||||||
} else if(iterator) {
|
} 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);
|
bool ret = iterator->exec(this, place);
|
||||||
delete iterator;
|
delete iterator;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
CONFIG += depend_includepath
|
CONFIG += depend_includepath
|
||||||
|
|
||||||
SKIP_DEPENDS += qconfig.h qmodules.h
|
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
|
QT_NO_GEOM_VARIANT QT_NO_DATASTREAM
|
||||||
|
|
||||||
#qmake code
|
#qmake code
|
||||||
@ -35,12 +35,14 @@ bootstrap { #Qt code
|
|||||||
SOURCES+= \
|
SOURCES+= \
|
||||||
qbitarray.cpp \
|
qbitarray.cpp \
|
||||||
qbuffer.cpp \
|
qbuffer.cpp \
|
||||||
|
qarraydata.cpp \
|
||||||
qbytearray.cpp \
|
qbytearray.cpp \
|
||||||
qbytearraymatcher.cpp \
|
qbytearraymatcher.cpp \
|
||||||
qcryptographichash.cpp \
|
qcryptographichash.cpp \
|
||||||
qdatetime.cpp \
|
qdatetime.cpp \
|
||||||
qdir.cpp \
|
qdir.cpp \
|
||||||
qdiriterator.cpp \
|
qdiriterator.cpp \
|
||||||
|
qfiledevice.cpp \
|
||||||
qfile.cpp \
|
qfile.cpp \
|
||||||
qabstractfileengine.cpp \
|
qabstractfileengine.cpp \
|
||||||
qfileinfo.cpp \
|
qfileinfo.cpp \
|
||||||
@ -66,7 +68,6 @@ bootstrap { #Qt code
|
|||||||
qstringlist.cpp \
|
qstringlist.cpp \
|
||||||
qtemporaryfile.cpp \
|
qtemporaryfile.cpp \
|
||||||
qtextstream.cpp \
|
qtextstream.cpp \
|
||||||
qurl.cpp \
|
|
||||||
quuid.cpp \
|
quuid.cpp \
|
||||||
qsettings.cpp \
|
qsettings.cpp \
|
||||||
qlibraryinfo.cpp \
|
qlibraryinfo.cpp \
|
||||||
@ -81,7 +82,10 @@ bootstrap { #Qt code
|
|||||||
HEADERS+= \
|
HEADERS+= \
|
||||||
qbitarray.h \
|
qbitarray.h \
|
||||||
qbuffer.h \
|
qbuffer.h \
|
||||||
|
qarraydata.h \
|
||||||
qbytearray.h \
|
qbytearray.h \
|
||||||
|
qarraydataops.h \
|
||||||
|
qarraydatapointer.h \
|
||||||
qbytearraymatcher.h \
|
qbytearraymatcher.h \
|
||||||
qchar.h \
|
qchar.h \
|
||||||
qcryptographichash.h \
|
qcryptographichash.h \
|
||||||
@ -113,7 +117,6 @@ bootstrap { #Qt code
|
|||||||
qsystemerror_p.h \
|
qsystemerror_p.h \
|
||||||
qtemporaryfile.h \
|
qtemporaryfile.h \
|
||||||
qtextstream.h \
|
qtextstream.h \
|
||||||
qurl.h \
|
|
||||||
quuid.h \
|
quuid.h \
|
||||||
qvector.h \
|
qvector.h \
|
||||||
qxmlstream.h \
|
qxmlstream.h \
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
|
|
||||||
#ifndef QMAKE_PCH_H
|
#ifndef QMAKE_PCH_H
|
||||||
#define 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>
|
#include <qglobal.h>
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# define _POSIX_
|
# define _POSIX_
|
||||||
|
@ -50,9 +50,7 @@
|
|||||||
#include <QtConcurrent/qtconcurrentmedian.h>
|
#include <QtConcurrent/qtconcurrentmedian.h>
|
||||||
#include <QtConcurrent/qtconcurrentthreadengine.h>
|
#include <QtConcurrent/qtconcurrentthreadengine.h>
|
||||||
|
|
||||||
#ifndef QT_NO_STL
|
#include <iterator>
|
||||||
# include <iterator>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QT_BEGIN_HEADER
|
QT_BEGIN_HEADER
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -62,15 +60,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
namespace QtConcurrent {
|
namespace QtConcurrent {
|
||||||
|
|
||||||
#ifndef QT_NO_STL
|
|
||||||
using std::advance;
|
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
|
The BlockSizeManager class manages how many iterations a thread should
|
||||||
@ -149,7 +139,6 @@ public:
|
|||||||
inline void * getPointer() { return 0; }
|
inline void * getPointer() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_STL
|
|
||||||
inline bool selectIteration(std::bidirectional_iterator_tag)
|
inline bool selectIteration(std::bidirectional_iterator_tag)
|
||||||
{
|
{
|
||||||
return false; // while
|
return false; // while
|
||||||
@ -164,14 +153,6 @@ inline bool selectIteration(std::random_access_iterator_tag)
|
|||||||
{
|
{
|
||||||
return true; // for
|
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>
|
template <typename Iterator, typename T>
|
||||||
class IterateKernel : public ThreadEngine<T>
|
class IterateKernel : public ThreadEngine<T>
|
||||||
@ -180,20 +161,10 @@ public:
|
|||||||
typedef T ResultType;
|
typedef T ResultType;
|
||||||
|
|
||||||
IterateKernel(Iterator _begin, Iterator _end)
|
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),
|
: begin(_begin), end(_end), current(_begin), currentIndex(0),
|
||||||
forIteration(selectIteration(typename std::iterator_traits<Iterator>::iterator_category())), progressReportingEnabled(true)
|
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;
|
iterationCount = forIteration ? std::distance(_begin, _end) : 0;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~IterateKernel() { }
|
virtual ~IterateKernel() { }
|
||||||
|
@ -9,14 +9,13 @@ HEADERS += \
|
|||||||
arch/qatomic_armv7.h \
|
arch/qatomic_armv7.h \
|
||||||
arch/qatomic_bfin.h \
|
arch/qatomic_bfin.h \
|
||||||
arch/qatomic_bootstrap.h \
|
arch/qatomic_bootstrap.h \
|
||||||
arch/qatomic_i386.h \
|
|
||||||
arch/qatomic_ia64.h \
|
arch/qatomic_ia64.h \
|
||||||
arch/qatomic_mips.h \
|
arch/qatomic_mips.h \
|
||||||
arch/qatomic_power.h \
|
arch/qatomic_power.h \
|
||||||
arch/qatomic_s390.h \
|
arch/qatomic_s390.h \
|
||||||
arch/qatomic_sh4a.h \
|
arch/qatomic_sh4a.h \
|
||||||
arch/qatomic_sparc.h \
|
arch/qatomic_sparc.h \
|
||||||
arch/qatomic_x86_64.h \
|
arch/qatomic_x86.h \
|
||||||
arch/qatomic_gcc.h \
|
arch/qatomic_gcc.h \
|
||||||
arch/qatomic_cxx11.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
|
#ifndef QATOMIC_X86_H
|
||||||
#define QATOMIC_X86_64_H
|
#define QATOMIC_X86_H
|
||||||
|
|
||||||
#include <QtCore/qgenericatomic.h>
|
#include <QtCore/qgenericatomic.h>
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)>
|
|||||||
typedef T Type;
|
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<char> { enum { IsInteger = 1 }; };
|
||||||
template<> struct QAtomicIntegerTraits<signed 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<long long> { enum { IsInteger = 1 }; };
|
||||||
template<> struct QAtomicIntegerTraits<unsigned 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
|
template<> template<typename T> inline
|
||||||
bool QBasicAtomicOps<1>::ref(T &_q_value)
|
bool QBasicAtomicOps<1>::ref(T &_q_value)
|
||||||
{
|
{
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
asm volatile("lock\n"
|
asm volatile("lock\n"
|
||||||
"incb %0\n"
|
"addb $1, %0\n"
|
||||||
"setne %1"
|
"setne %1"
|
||||||
: "=m" (_q_value), "=qm" (ret)
|
: "=m" (_q_value), "=qm" (ret)
|
||||||
: "m" (_q_value)
|
: "m" (_q_value)
|
||||||
@ -164,20 +192,7 @@ bool QBasicAtomicOps<4>::ref(T &_q_value)
|
|||||||
{
|
{
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
asm volatile("lock\n"
|
asm volatile("lock\n"
|
||||||
"incl %0\n"
|
"addl $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>::ref(T &_q_value)
|
|
||||||
{
|
|
||||||
unsigned char ret;
|
|
||||||
asm volatile("lock\n"
|
|
||||||
"incq %0\n"
|
|
||||||
"setne %1"
|
"setne %1"
|
||||||
: "=m" (_q_value), "=qm" (ret)
|
: "=m" (_q_value), "=qm" (ret)
|
||||||
: "m" (_q_value)
|
: "m" (_q_value)
|
||||||
@ -190,7 +205,7 @@ bool QBasicAtomicOps<1>::deref(T &_q_value)
|
|||||||
{
|
{
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
asm volatile("lock\n"
|
asm volatile("lock\n"
|
||||||
"decb %0\n"
|
"subb $1, %0\n"
|
||||||
"setne %1"
|
"setne %1"
|
||||||
: "=m" (_q_value), "=qm" (ret)
|
: "=m" (_q_value), "=qm" (ret)
|
||||||
: "m" (_q_value)
|
: "m" (_q_value)
|
||||||
@ -215,20 +230,7 @@ bool QBasicAtomicOps<4>::deref(T &_q_value)
|
|||||||
{
|
{
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
asm volatile("lock\n"
|
asm volatile("lock\n"
|
||||||
"decl %0\n"
|
"subl $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"
|
|
||||||
"decq %0\n"
|
|
||||||
"setne %1"
|
"setne %1"
|
||||||
: "=m" (_q_value), "=qm" (ret)
|
: "=m" (_q_value), "=qm" (ret)
|
||||||
: "m" (_q_value)
|
: "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_ALWAYS_NATIVE
|
||||||
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE
|
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE
|
||||||
|
|
||||||
#else // !Q_CC_INTEL && !Q_CC_GNU
|
#ifdef Q_PROCESSOR_X86_64
|
||||||
# error "This compiler for x86_64 is not supported"
|
// native support for 64-bit types
|
||||||
#endif // Q_CC_GNU || Q_CC_INTEL
|
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_NAMESPACE
|
||||||
|
|
||||||
QT_END_HEADER
|
QT_END_HEADER
|
||||||
|
|
||||||
#endif // QATOMIC_X86_64_H
|
#endif // QATOMIC_X86_H
|
@ -102,6 +102,10 @@
|
|||||||
# undef QT_HAVE_3DNOW
|
# undef QT_HAVE_3DNOW
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if defined(Q_CC_MSVC) && _MSC_VER >= 1400
|
||||||
|
# define Q_COMPILER_VARIADIC_MACROS
|
||||||
|
# endif
|
||||||
|
|
||||||
#if defined(Q_CC_MSVC) && _MSC_VER >= 1600
|
#if defined(Q_CC_MSVC) && _MSC_VER >= 1600
|
||||||
# define Q_COMPILER_RVALUE_REFS
|
# define Q_COMPILER_RVALUE_REFS
|
||||||
# define Q_COMPILER_AUTO_TYPE
|
# define Q_COMPILER_AUTO_TYPE
|
||||||
|
@ -159,9 +159,6 @@
|
|||||||
#ifndef QT_NO_DATETIMEEDIT
|
#ifndef QT_NO_DATETIMEEDIT
|
||||||
# define QT_NO_DATETIMEEDIT
|
# define QT_NO_DATETIMEEDIT
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_WORKSPACE
|
|
||||||
# define QT_NO_WORKSPACE
|
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_DIAL
|
#ifndef QT_NO_DIAL
|
||||||
# define QT_NO_DIAL
|
# define QT_NO_DIAL
|
||||||
#endif
|
#endif
|
||||||
|
@ -242,9 +242,6 @@
|
|||||||
#ifndef QT_NO_MENUBAR
|
#ifndef QT_NO_MENUBAR
|
||||||
# define QT_NO_MENUBAR
|
# define QT_NO_MENUBAR
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_WORKSPACE
|
|
||||||
# define QT_NO_WORKSPACE
|
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_PROGRESSBAR
|
#ifndef QT_NO_PROGRESSBAR
|
||||||
# define QT_NO_PROGRESSBAR
|
# define QT_NO_PROGRESSBAR
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,9 +43,6 @@
|
|||||||
#ifndef QT_NO_QUUID_STRING
|
#ifndef QT_NO_QUUID_STRING
|
||||||
# define QT_NO_QUUID_STRING
|
# define QT_NO_QUUID_STRING
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_STL
|
|
||||||
# define QT_NO_STL
|
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_TEXTDATE
|
#ifndef QT_NO_TEXTDATE
|
||||||
# define QT_NO_TEXTDATE
|
# define QT_NO_TEXTDATE
|
||||||
#endif
|
#endif
|
||||||
@ -494,9 +491,6 @@
|
|||||||
#ifndef QT_NO_MENUBAR
|
#ifndef QT_NO_MENUBAR
|
||||||
# define QT_NO_MENUBAR
|
# define QT_NO_MENUBAR
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_WORKSPACE
|
|
||||||
# define QT_NO_WORKSPACE
|
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_PROGRESSBAR
|
#ifndef QT_NO_PROGRESSBAR
|
||||||
# define QT_NO_PROGRESSBAR
|
# define QT_NO_PROGRESSBAR
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,9 +45,6 @@
|
|||||||
#ifndef QT_NO_QUUID_STRING
|
#ifndef QT_NO_QUUID_STRING
|
||||||
# define QT_NO_QUUID_STRING
|
# define QT_NO_QUUID_STRING
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_STL
|
|
||||||
# define QT_NO_STL
|
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_TEXTDATE
|
#ifndef QT_NO_TEXTDATE
|
||||||
# define QT_NO_TEXTDATE
|
# define QT_NO_TEXTDATE
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,9 +43,6 @@
|
|||||||
#ifndef QT_NO_QUUID_STRING
|
#ifndef QT_NO_QUUID_STRING
|
||||||
# define QT_NO_QUUID_STRING
|
# define QT_NO_QUUID_STRING
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_STL
|
|
||||||
# define QT_NO_STL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Dialogs */
|
/* Dialogs */
|
||||||
#ifndef QT_NO_COLORDIALOG
|
#ifndef QT_NO_COLORDIALOG
|
||||||
@ -282,9 +279,6 @@
|
|||||||
#ifndef QT_NO_MENUBAR
|
#ifndef QT_NO_MENUBAR
|
||||||
# define QT_NO_MENUBAR
|
# define QT_NO_MENUBAR
|
||||||
#endif
|
#endif
|
||||||
#ifndef QT_NO_WORKSPACE
|
|
||||||
# define QT_NO_WORKSPACE
|
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_PROGRESSBAR
|
#ifndef QT_NO_PROGRESSBAR
|
||||||
# define QT_NO_PROGRESSBAR
|
# define QT_NO_PROGRESSBAR
|
||||||
#endif
|
#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
|
// 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)
|
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)
|
/* T qFromLittleEndian(const uchar *src)
|
||||||
@ -171,6 +171,11 @@ template <> inline qint16 qFromLittleEndian<qint16>(const uchar *src)
|
|||||||
{ return static_cast<qint16>(qFromLittleEndian<quint16>(src)); }
|
{ return static_cast<qint16>(qFromLittleEndian<quint16>(src)); }
|
||||||
#endif
|
#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
|
/* 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.
|
* and return the value in host-endian encoding.
|
||||||
* There is no requirement that \a src must be aligned.
|
* 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)
|
template <> inline qint16 qFromBigEndian<qint16>(const uchar *src)
|
||||||
{ return static_cast<qint16>(qFromBigEndian<quint16>(src)); }
|
{ return static_cast<qint16>(qFromBigEndian<quint16>(src)); }
|
||||||
#endif
|
#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).
|
* T qbswap(T source).
|
||||||
* Changes the byte order of a value from big endian to little endian or vice versa.
|
* 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;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> inline qint8 qbswap<qint8>(qint8 source)
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
QT_END_HEADER
|
QT_END_HEADER
|
||||||
|
@ -208,9 +208,6 @@
|
|||||||
// Status Tip
|
// Status Tip
|
||||||
//#define QT_NO_STATUSTIP
|
//#define QT_NO_STATUSTIP
|
||||||
|
|
||||||
// Standard Template Library
|
|
||||||
//#define QT_NO_STL
|
|
||||||
|
|
||||||
// QMotifStyle
|
// QMotifStyle
|
||||||
//#define QT_NO_STYLE_MOTIF
|
//#define QT_NO_STYLE_MOTIF
|
||||||
|
|
||||||
@ -487,11 +484,6 @@
|
|||||||
#define QT_NO_STYLE_STYLESHEET
|
#define QT_NO_STYLE_STYLESHEET
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Q3TabDialog
|
|
||||||
#if !defined(QT_NO_TABDIALOG) && (defined(QT_NO_TABBAR))
|
|
||||||
#define QT_NO_TABDIALOG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// QColorDialog
|
// QColorDialog
|
||||||
#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_SPINBOX))
|
#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_SPINBOX))
|
||||||
#define QT_NO_COLORDIALOG
|
#define QT_NO_COLORDIALOG
|
||||||
@ -662,11 +654,6 @@
|
|||||||
#define QT_NO_PRINTPREVIEWWIDGET
|
#define QT_NO_PRINTPREVIEWWIDGET
|
||||||
#endif
|
#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
|
// 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))
|
#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
|
#define QT_NO_CALENDARWIDGET
|
||||||
|
@ -407,13 +407,6 @@ Requires: RUBBERBAND MAINWINDOW
|
|||||||
Name: QDockwidget
|
Name: QDockwidget
|
||||||
SeeAlso: ???
|
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
|
Feature: MDIAREA
|
||||||
Description: Provides an area in which MDI windows are displayed.
|
Description: Provides an area in which MDI windows are displayed.
|
||||||
Section: Widgets
|
Section: Widgets
|
||||||
@ -644,13 +637,6 @@ Requires: COMBOBOX SPINBOX STACKEDWIDGET
|
|||||||
Name: QInputDialog
|
Name: QInputDialog
|
||||||
SeeAlso: ???
|
SeeAlso: ???
|
||||||
|
|
||||||
Feature: TABDIALOG
|
|
||||||
Description: Supports a stack of tabbed widgets.
|
|
||||||
Section: Dialogs
|
|
||||||
Requires: TABBAR
|
|
||||||
Name: Q3TabDialog
|
|
||||||
SeeAlso: ???
|
|
||||||
|
|
||||||
Feature: ERRORMESSAGE
|
Feature: ERRORMESSAGE
|
||||||
Description: Supports an error message display dialog.
|
Description: Supports an error message display dialog.
|
||||||
Section: Dialogs
|
Section: Dialogs
|
||||||
|
@ -1968,13 +1968,6 @@ Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n)
|
|||||||
return p;
|
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 *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); }
|
void *qMemSet(void *dest, int c, size_t n) { return memset(dest, c, n); }
|
||||||
|
|
||||||
|
@ -69,9 +69,7 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#ifndef QT_NO_STL
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef QT_NAMESPACE /* user namespace */
|
#ifndef QT_NAMESPACE /* user namespace */
|
||||||
|
|
||||||
@ -254,6 +252,56 @@ typedef quint64 qulonglong;
|
|||||||
|
|
||||||
#if defined(__cplusplus)
|
#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.
|
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
|
#ifdef Q_COMPILER_EXPLICIT_OVERRIDES
|
||||||
# define Q_DECL_OVERRIDE override
|
# define Q_DECL_OVERRIDE override
|
||||||
# define Q_DECL_FINAL final
|
# 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
|
#else
|
||||||
# define Q_DECL_OVERRIDE
|
# define Q_DECL_OVERRIDE
|
||||||
# define Q_DECL_FINAL
|
# define Q_DECL_FINAL
|
||||||
|
# define Q_DECL_FINAL_CLASS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF)
|
#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF)
|
||||||
@ -1127,28 +1181,20 @@ static inline bool qIsNull(float f)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void qSwap(T &value1, T &value2)
|
inline void qSwap(T &value1, T &value2)
|
||||||
{
|
{
|
||||||
#ifdef QT_NO_STL
|
|
||||||
const T t = value1;
|
|
||||||
value1 = value2;
|
|
||||||
value2 = t;
|
|
||||||
#else
|
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(value1, value2);
|
swap(value1, value2);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#if QT_DEPRECATED_SINCE(5, 0)
|
||||||
These functions make it possible to use standard C++ functions with
|
Q_CORE_EXPORT QT_DEPRECATED void *qMalloc(size_t size) Q_ALLOC_SIZE(1);
|
||||||
a similar name from Qt header files (especially template classes).
|
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 void *qMalloc(size_t size) Q_ALLOC_SIZE(1);
|
Q_CORE_EXPORT QT_DEPRECATED void *qMemCopy(void *dest, const void *src, size_t n);
|
||||||
Q_CORE_EXPORT void qFree(void *ptr);
|
Q_CORE_EXPORT QT_DEPRECATED void *qMemSet(void *dest, int c, size_t n);
|
||||||
Q_CORE_EXPORT void *qRealloc(void *ptr, size_t size) Q_ALLOC_SIZE(2);
|
#endif
|
||||||
Q_CORE_EXPORT void *qMallocAligned(size_t size, size_t alignment) Q_ALLOC_SIZE(1);
|
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 *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 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
|
||||||
#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 T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
|
||||||
template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }
|
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)
|
# define Q_IS_ENUM(x) __is_enum(x)
|
||||||
# elif defined(Q_CC_MSVC) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER >=140050215)
|
# elif defined(Q_CC_MSVC) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER >=140050215)
|
||||||
# define Q_IS_ENUM(x) __is_enum(x)
|
# define Q_IS_ENUM(x) __is_enum(x)
|
||||||
# else
|
# elif defined(Q_CC_CLANG)
|
||||||
# include <QtCore/qtypetraits.h>
|
# if __has_extension(is_enum)
|
||||||
# define Q_IS_ENUM(x) QtPrivate::is_enum<x>::value
|
# define Q_IS_ENUM(x) __is_enum(x)
|
||||||
|
# endif
|
||||||
# endif
|
# 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
|
#endif // QISENUM_H
|
||||||
|
@ -342,7 +342,6 @@ public:
|
|||||||
WA_UpdatesDisabled = 10,
|
WA_UpdatesDisabled = 10,
|
||||||
WA_Mapped = 11,
|
WA_Mapped = 11,
|
||||||
WA_MacNoClickThrough = 12, // Mac only
|
WA_MacNoClickThrough = 12, // Mac only
|
||||||
WA_PaintOutsidePaintEvent = 13,
|
|
||||||
WA_InputMethodEnabled = 14,
|
WA_InputMethodEnabled = 14,
|
||||||
WA_WState_Visible = 15,
|
WA_WState_Visible = 15,
|
||||||
WA_WState_Hidden = 16,
|
WA_WState_Hidden = 16,
|
||||||
@ -1101,8 +1100,7 @@ public:
|
|||||||
enum TextFormat {
|
enum TextFormat {
|
||||||
PlainText,
|
PlainText,
|
||||||
RichText,
|
RichText,
|
||||||
AutoText,
|
AutoText
|
||||||
LogText
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AspectRatioMode {
|
enum AspectRatioMode {
|
||||||
@ -1111,12 +1109,6 @@ public:
|
|||||||
KeepAspectRatioByExpanding
|
KeepAspectRatioByExpanding
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is for Q3TextEdit only, actually.
|
|
||||||
enum AnchorAttribute {
|
|
||||||
AnchorName,
|
|
||||||
AnchorHref
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DockWidgetArea {
|
enum DockWidgetArea {
|
||||||
LeftDockWidgetArea = 0x1,
|
LeftDockWidgetArea = 0x1,
|
||||||
RightDockWidgetArea = 0x2,
|
RightDockWidgetArea = 0x2,
|
||||||
@ -1200,7 +1192,6 @@ public:
|
|||||||
AutoConnection,
|
AutoConnection,
|
||||||
DirectConnection,
|
DirectConnection,
|
||||||
QueuedConnection,
|
QueuedConnection,
|
||||||
AutoCompatConnection,
|
|
||||||
BlockingQueuedConnection,
|
BlockingQueuedConnection,
|
||||||
UniqueConnection = 0x80
|
UniqueConnection = 0x80
|
||||||
};
|
};
|
||||||
|
@ -537,13 +537,6 @@
|
|||||||
same pair of objects, then the connection will fail. This
|
same pair of objects, then the connection will fail. This
|
||||||
connection type was introduced in Qt 4.6.
|
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
|
With queued connections, the parameters must be of types that are
|
||||||
known to Qt's meta-object system, because Qt needs to copy the
|
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
|
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
|
require native painting primitives, you need to reimplement
|
||||||
QWidget::paintEngine() to return 0 and set this flag.
|
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
|
\value WA_PaintUnclipped Makes all painters operating on this widget
|
||||||
unclipped. Children of this widget or other widgets in front of it do not
|
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
|
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
|
\value AutoText The text string is interpreted as for
|
||||||
Qt::RichText if Qt::mightBeRichText() returns true, otherwise
|
Qt::RichText if Qt::mightBeRichText() returns true, otherwise
|
||||||
as Qt::PlainText.
|
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);
|
: qt_le_inf_bytes);
|
||||||
|
|
||||||
union { unsigned char c[8]; double d; } returnValue;
|
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;
|
return returnValue.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ static inline double qt_snan()
|
|||||||
: qt_le_snan_bytes);
|
: qt_le_snan_bytes);
|
||||||
|
|
||||||
union { unsigned char c[8]; double d; } returnValue;
|
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;
|
return returnValue.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ static inline double qt_qnan()
|
|||||||
: qt_le_qnan_bytes);
|
: qt_le_qnan_bytes);
|
||||||
|
|
||||||
union { unsigned char c[8]; double d; } returnValue;
|
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;
|
return returnValue.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#if defined __cplusplus
|
#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>
|
#include <qglobal.h>
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# define _POSIX_
|
# define _POSIX_
|
||||||
@ -63,5 +69,4 @@
|
|||||||
#include <qstring.h>
|
#include <qstring.h>
|
||||||
#include <qstringlist.h>
|
#include <qstringlist.h>
|
||||||
#include <qtextcodec.h>
|
#include <qtextcodec.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
#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
|
types must declare a 'bool isDetached(void) const;' member for this
|
||||||
to work.
|
to work.
|
||||||
*/
|
*/
|
||||||
#ifdef QT_NO_STL
|
|
||||||
#define Q_DECLARE_SHARED_STL(TYPE)
|
|
||||||
#else
|
|
||||||
#define Q_DECLARE_SHARED_STL(TYPE) \
|
#define Q_DECLARE_SHARED_STL(TYPE) \
|
||||||
QT_END_NAMESPACE \
|
QT_END_NAMESPACE \
|
||||||
namespace std { \
|
namespace std { \
|
||||||
@ -182,7 +179,6 @@ namespace std { \
|
|||||||
{ swap(value1.data_ptr(), value2.data_ptr()); } \
|
{ swap(value1.data_ptr(), value2.data_ptr()); } \
|
||||||
} \
|
} \
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Q_DECLARE_SHARED(TYPE) \
|
#define Q_DECLARE_SHARED(TYPE) \
|
||||||
template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \
|
template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \
|
||||||
|
@ -11,8 +11,11 @@ HEADERS += \
|
|||||||
io/qdir_p.h \
|
io/qdir_p.h \
|
||||||
io/qdiriterator.h \
|
io/qdiriterator.h \
|
||||||
io/qfile.h \
|
io/qfile.h \
|
||||||
|
io/qfiledevice.h \
|
||||||
|
io/qfiledevice_p.h \
|
||||||
io/qfileinfo.h \
|
io/qfileinfo.h \
|
||||||
io/qfileinfo_p.h \
|
io/qfileinfo_p.h \
|
||||||
|
io/qipaddress_p.h \
|
||||||
io/qiodevice.h \
|
io/qiodevice.h \
|
||||||
io/qiodevice_p.h \
|
io/qiodevice_p.h \
|
||||||
io/qnoncontiguousbytedevice_p.h \
|
io/qnoncontiguousbytedevice_p.h \
|
||||||
@ -25,6 +28,8 @@ HEADERS += \
|
|||||||
io/qresource_iterator_p.h \
|
io/qresource_iterator_p.h \
|
||||||
io/qstandardpaths.h \
|
io/qstandardpaths.h \
|
||||||
io/qurl.h \
|
io/qurl.h \
|
||||||
|
io/qurl_p.h \
|
||||||
|
io/qurlquery.h \
|
||||||
io/qurltlds_p.h \
|
io/qurltlds_p.h \
|
||||||
io/qtldurl_p.h \
|
io/qtldurl_p.h \
|
||||||
io/qsettings.h \
|
io/qsettings.h \
|
||||||
@ -49,7 +54,9 @@ SOURCES += \
|
|||||||
io/qdir.cpp \
|
io/qdir.cpp \
|
||||||
io/qdiriterator.cpp \
|
io/qdiriterator.cpp \
|
||||||
io/qfile.cpp \
|
io/qfile.cpp \
|
||||||
|
io/qfiledevice.cpp \
|
||||||
io/qfileinfo.cpp \
|
io/qfileinfo.cpp \
|
||||||
|
io/qipaddress.cpp \
|
||||||
io/qiodevice.cpp \
|
io/qiodevice.cpp \
|
||||||
io/qnoncontiguousbytedevice.cpp \
|
io/qnoncontiguousbytedevice.cpp \
|
||||||
io/qprocess.cpp \
|
io/qprocess.cpp \
|
||||||
@ -60,6 +67,9 @@ SOURCES += \
|
|||||||
io/qresource_iterator.cpp \
|
io/qresource_iterator.cpp \
|
||||||
io/qstandardpaths.cpp \
|
io/qstandardpaths.cpp \
|
||||||
io/qurl.cpp \
|
io/qurl.cpp \
|
||||||
|
io/qurlidna.cpp \
|
||||||
|
io/qurlquery.cpp \
|
||||||
|
io/qurlrecode.cpp \
|
||||||
io/qsettings.cpp \
|
io/qsettings.cpp \
|
||||||
io/qfsfileengine.cpp \
|
io/qfsfileengine.cpp \
|
||||||
io/qfsfileengine_iterator.cpp \
|
io/qfsfileengine_iterator.cpp \
|
||||||
|
@ -114,7 +114,7 @@ public:
|
|||||||
explicit QDataStream(QIODevice *);
|
explicit QDataStream(QIODevice *);
|
||||||
QDataStream(QByteArray *, QIODevice::OpenMode flags);
|
QDataStream(QByteArray *, QIODevice::OpenMode flags);
|
||||||
QDataStream(const QByteArray &);
|
QDataStream(const QByteArray &);
|
||||||
virtual ~QDataStream();
|
~QDataStream();
|
||||||
|
|
||||||
QIODevice *device() const;
|
QIODevice *device() const;
|
||||||
void setDevice(QIODevice *);
|
void setDevice(QIODevice *);
|
||||||
@ -385,7 +385,6 @@ Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap<aKey, aT> &ma
|
|||||||
in >> n;
|
in >> n;
|
||||||
|
|
||||||
map.detach();
|
map.detach();
|
||||||
map.setInsertInOrder(true);
|
|
||||||
for (quint32 i = 0; i < n; ++i) {
|
for (quint32 i = 0; i < n; ++i) {
|
||||||
if (in.status() != QDataStream::Ok)
|
if (in.status() != QDataStream::Ok)
|
||||||
break;
|
break;
|
||||||
@ -395,7 +394,6 @@ Q_OUTOFLINE_TEMPLATE QDataStream &operator>>(QDataStream &in, QMap<aKey, aT> &ma
|
|||||||
in >> key >> value;
|
in >> key >> value;
|
||||||
map.insertMulti(key, value);
|
map.insertMulti(key, value);
|
||||||
}
|
}
|
||||||
map.setInsertInOrder(false);
|
|
||||||
if (in.status() != QDataStream::Ok)
|
if (in.status() != QDataStream::Ok)
|
||||||
map.clear();
|
map.clear();
|
||||||
if (oldStatus != QDataStream::Ok)
|
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
|
// the following would have been the correct thing, but
|
||||||
// reality often differs from the specification. People have
|
// reality often differs from the specification. People have
|
||||||
// data: URIs with ? and #
|
// data: URIs with ? and #
|
||||||
//QByteArray data = QByteArray::fromPercentEncoding(uri.encodedPath());
|
//QByteArray data = QByteArray::fromPercentEncoding(uri.path(QUrl::PrettyDecoded).toLatin1());
|
||||||
QByteArray data = QByteArray::fromPercentEncoding(uri.toEncoded());
|
QByteArray data = QByteArray::fromPercentEncoding(uri.url(QUrl::PrettyDecoded | QUrl::RemoveScheme).toLatin1());
|
||||||
|
|
||||||
// remove the data: scheme
|
|
||||||
data.remove(0, 5);
|
|
||||||
|
|
||||||
// parse it:
|
// parse it:
|
||||||
int pos = data.indexOf(',');
|
int pos = data.indexOf(',');
|
||||||
|
@ -52,6 +52,7 @@ QT_BEGIN_HEADER
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class QDirIterator;
|
||||||
class QDirPrivate;
|
class QDirPrivate;
|
||||||
|
|
||||||
class Q_CORE_EXPORT QDir
|
class Q_CORE_EXPORT QDir
|
||||||
@ -210,6 +211,7 @@ protected:
|
|||||||
QSharedDataPointer<QDirPrivate> d_ptr;
|
QSharedDataPointer<QDirPrivate> d_ptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class QDirIterator;
|
||||||
// Q_DECLARE_PRIVATE equivalent for shared data pointers
|
// Q_DECLARE_PRIVATE equivalent for shared data pointers
|
||||||
QDirPrivate* d_func();
|
QDirPrivate* d_func();
|
||||||
inline const QDirPrivate* d_func() const
|
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)
|
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
|
const QDirPrivate *other = dir.d_ptr.constData();
|
||||||
class MyQDir : public QDir { public: const QDirPrivate *priv() const { return d_ptr.constData(); } };
|
|
||||||
const QDirPrivate *other = static_cast<const MyQDir*>(&dir)->priv();
|
|
||||||
d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull()));
|
d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public:
|
|||||||
QDir::Filters filters = QDir::NoFilter,
|
QDir::Filters filters = QDir::NoFilter,
|
||||||
IteratorFlags flags = NoIteratorFlags);
|
IteratorFlags flags = NoIteratorFlags);
|
||||||
|
|
||||||
virtual ~QDirIterator();
|
~QDirIterator();
|
||||||
|
|
||||||
QString next();
|
QString next();
|
||||||
bool hasNext() const;
|
bool hasNext() const;
|
||||||
|
@ -59,8 +59,6 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static const int QFILE_WRITEBUFFER_SIZE = 16384;
|
|
||||||
|
|
||||||
static QByteArray locale_encode(const QString &f)
|
static QByteArray locale_encode(const QString &f)
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_DARWIN)
|
#if defined(Q_OS_DARWIN)
|
||||||
@ -86,16 +84,11 @@ QFile::EncoderFn QFilePrivate::encoder = locale_encode;
|
|||||||
QFile::DecoderFn QFilePrivate::decoder = locale_decode;
|
QFile::DecoderFn QFilePrivate::decoder = locale_decode;
|
||||||
|
|
||||||
QFilePrivate::QFilePrivate()
|
QFilePrivate::QFilePrivate()
|
||||||
: fileEngine(0), lastWasWrite(false),
|
|
||||||
writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
|
|
||||||
cachedSize(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QFilePrivate::~QFilePrivate()
|
QFilePrivate::~QFilePrivate()
|
||||||
{
|
{
|
||||||
delete fileEngine;
|
|
||||||
fileEngine = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -137,39 +130,6 @@ QAbstractFileEngine *QFilePrivate::engine() const
|
|||||||
return fileEngine;
|
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
|
//************* QFile
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -278,98 +238,18 @@ QFilePrivate::setError(QFile::FileError err, int errNum)
|
|||||||
\sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
|
\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
|
#ifdef QT_NO_QOBJECT
|
||||||
QFile::QFile()
|
QFile::QFile()
|
||||||
: QIODevice(*new QFilePrivate)
|
: QFileDevice(*new QFilePrivate)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
QFile::QFile(const QString &name)
|
QFile::QFile(const QString &name)
|
||||||
: QIODevice(*new QFilePrivate)
|
: QFileDevice(*new QFilePrivate)
|
||||||
{
|
{
|
||||||
d_func()->fileName = name;
|
d_func()->fileName = name;
|
||||||
}
|
}
|
||||||
QFile::QFile(QFilePrivate &dd)
|
QFile::QFile(QFilePrivate &dd)
|
||||||
: QIODevice(dd)
|
: QFileDevice(dd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -377,21 +257,21 @@ QFile::QFile(QFilePrivate &dd)
|
|||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
QFile::QFile()
|
QFile::QFile()
|
||||||
: QIODevice(*new QFilePrivate, 0)
|
: QFileDevice(*new QFilePrivate, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
Constructs a new file object with the given \a parent.
|
Constructs a new file object with the given \a parent.
|
||||||
*/
|
*/
|
||||||
QFile::QFile(QObject *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.
|
Constructs a new file object to represent the file with the given \a name.
|
||||||
*/
|
*/
|
||||||
QFile::QFile(const QString &name)
|
QFile::QFile(const QString &name)
|
||||||
: QIODevice(*new QFilePrivate, 0)
|
: QFileDevice(*new QFilePrivate, 0)
|
||||||
{
|
{
|
||||||
Q_D(QFile);
|
Q_D(QFile);
|
||||||
d->fileName = name;
|
d->fileName = name;
|
||||||
@ -401,7 +281,7 @@ QFile::QFile(const QString &name)
|
|||||||
file with the specified \a name.
|
file with the specified \a name.
|
||||||
*/
|
*/
|
||||||
QFile::QFile(const QString &name, QObject *parent)
|
QFile::QFile(const QString &name, QObject *parent)
|
||||||
: QIODevice(*new QFilePrivate, parent)
|
: QFileDevice(*new QFilePrivate, parent)
|
||||||
{
|
{
|
||||||
Q_D(QFile);
|
Q_D(QFile);
|
||||||
d->fileName = name;
|
d->fileName = name;
|
||||||
@ -410,7 +290,7 @@ QFile::QFile(const QString &name, QObject *parent)
|
|||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
QFile::QFile(QFilePrivate &dd, QObject *parent)
|
QFile::QFile(QFilePrivate &dd, QObject *parent)
|
||||||
: QIODevice(dd, parent)
|
: QFileDevice(dd, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -420,7 +300,6 @@ QFile::QFile(QFilePrivate &dd, QObject *parent)
|
|||||||
*/
|
*/
|
||||||
QFile::~QFile()
|
QFile::~QFile()
|
||||||
{
|
{
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -966,20 +845,6 @@ QFile::copy(const QString &fileName, const QString &newName)
|
|||||||
return QFile(fileName).copy(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;
|
Opens the file using OpenMode \a mode, returning true if successful;
|
||||||
otherwise false.
|
otherwise false.
|
||||||
@ -1154,119 +1019,11 @@ bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the file handle of the file.
|
\reimp
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
*/
|
||||||
|
bool QFile::resize(qint64 sz)
|
||||||
int
|
|
||||||
QFile::handle() const
|
|
||||||
{
|
{
|
||||||
Q_D(const QFile);
|
return QFileDevice::resize(sz); // for now
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1287,18 +1044,11 @@ QFile::resize(const QString &fileName, qint64 sz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the complete OR-ed together combination of
|
\reimp
|
||||||
QFile::Permission for the file.
|
|
||||||
|
|
||||||
\sa setPermissions(), setFileName()
|
|
||||||
*/
|
*/
|
||||||
|
QFile::Permissions QFile::permissions() const
|
||||||
QFile::Permissions
|
|
||||||
QFile::permissions() const
|
|
||||||
{
|
{
|
||||||
Q_D(const QFile);
|
return QFileDevice::permissions(); // for now
|
||||||
QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
|
|
||||||
return QFile::Permissions((int)perms); //ewww
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1322,16 +1072,9 @@ QFile::permissions(const QString &fileName)
|
|||||||
\sa permissions(), setFileName()
|
\sa permissions(), setFileName()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool QFile::setPermissions(Permissions permissions)
|
||||||
QFile::setPermissions(Permissions permissions)
|
|
||||||
{
|
{
|
||||||
Q_D(QFile);
|
return QFileDevice::setPermissions(permissions); // for now
|
||||||
if (d->engine()->setPermissions(permissions)) {
|
|
||||||
unsetError();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
d->setError(QFile::PermissionsError, d->fileEngine->errorString());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1346,354 +1089,12 @@ QFile::setPermissions(const QString &fileName, Permissions permissions)
|
|||||||
return QFile(fileName).setPermissions(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;
|
\reimp
|
||||||
otherwise returns false.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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
|
qint64 QFile::size() const
|
||||||
{
|
{
|
||||||
Q_D(const QFile);
|
return QFileDevice::size(); // for now
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#ifndef QFILE_H
|
#ifndef QFILE_H
|
||||||
#define QFILE_H
|
#define QFILE_H
|
||||||
|
|
||||||
#include <QtCore/qiodevice.h>
|
#include <QtCore/qfiledevice.h>
|
||||||
#include <QtCore/qstring.h>
|
#include <QtCore/qstring.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QTemporaryFile;
|
class QTemporaryFile;
|
||||||
class QFilePrivate;
|
class QFilePrivate;
|
||||||
|
|
||||||
class Q_CORE_EXPORT QFile : public QIODevice
|
class Q_CORE_EXPORT QFile : public QFileDevice
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -65,39 +65,6 @@ class Q_CORE_EXPORT QFile : public QIODevice
|
|||||||
Q_DECLARE_PRIVATE(QFile)
|
Q_DECLARE_PRIVATE(QFile)
|
||||||
|
|
||||||
public:
|
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();
|
||||||
QFile(const QString &name);
|
QFile(const QString &name);
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
@ -106,9 +73,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
~QFile();
|
~QFile();
|
||||||
|
|
||||||
FileError error() const;
|
|
||||||
void unsetError();
|
|
||||||
|
|
||||||
QString fileName() const;
|
QString fileName() const;
|
||||||
void setFileName(const QString &name);
|
void setFileName(const QString &name);
|
||||||
|
|
||||||
@ -141,18 +105,11 @@ public:
|
|||||||
bool copy(const QString &newName);
|
bool copy(const QString &newName);
|
||||||
static bool copy(const QString &fileName, const QString &newName);
|
static bool copy(const QString &fileName, const QString &newName);
|
||||||
|
|
||||||
bool isSequential() const;
|
|
||||||
|
|
||||||
bool open(OpenMode flags);
|
bool open(OpenMode flags);
|
||||||
bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
||||||
bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
||||||
virtual void close();
|
|
||||||
|
|
||||||
qint64 size() const;
|
qint64 size() const;
|
||||||
qint64 pos() const;
|
|
||||||
bool seek(qint64 offset);
|
|
||||||
bool atEnd() const;
|
|
||||||
bool flush();
|
|
||||||
|
|
||||||
bool resize(qint64 sz);
|
bool resize(qint64 sz);
|
||||||
static bool resize(const QString &filename, qint64 sz);
|
static bool resize(const QString &filename, qint64 sz);
|
||||||
@ -162,15 +119,6 @@ public:
|
|||||||
bool setPermissions(Permissions permissionSpec);
|
bool setPermissions(Permissions permissionSpec);
|
||||||
static bool setPermissions(const QString &filename, 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:
|
protected:
|
||||||
#ifdef QT_NO_QOBJECT
|
#ifdef QT_NO_QOBJECT
|
||||||
QFile(QFilePrivate &dd);
|
QFile(QFilePrivate &dd);
|
||||||
@ -178,17 +126,11 @@ protected:
|
|||||||
QFile(QFilePrivate &dd, QObject *parent = 0);
|
QFile(QFilePrivate &dd, QObject *parent = 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qint64 readData(char *data, qint64 maxlen);
|
|
||||||
qint64 writeData(const char *data, qint64 len);
|
|
||||||
qint64 readLineData(char *data, qint64 maxlen);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QTemporaryFile;
|
friend class QTemporaryFile;
|
||||||
Q_DISABLE_COPY(QFile)
|
Q_DISABLE_COPY(QFile)
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QFile::Permissions)
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
QT_END_HEADER
|
QT_END_HEADER
|
||||||
|
@ -53,15 +53,13 @@
|
|||||||
// We mean it.
|
// We mean it.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "private/qabstractfileengine_p.h"
|
#include "private/qfiledevice_p.h"
|
||||||
#include "private/qiodevice_p.h"
|
|
||||||
#include "private/qringbuffer_p.h"
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QTemporaryFile;
|
class QTemporaryFile;
|
||||||
|
|
||||||
class QFilePrivate : public QIODevicePrivate
|
class QFilePrivate : public QFileDevicePrivate
|
||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(QFile)
|
Q_DECLARE_PUBLIC(QFile)
|
||||||
friend class QTemporaryFile;
|
friend class QTemporaryFile;
|
||||||
@ -76,20 +74,6 @@ protected:
|
|||||||
virtual QAbstractFileEngine *engine() const;
|
virtual QAbstractFileEngine *engine() const;
|
||||||
|
|
||||||
QString fileName;
|
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:
|
private:
|
||||||
static QFile::EncoderFn encoder;
|
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"
|
#include "qfilesystemengine_p.h"
|
||||||
|
|
||||||
#define _POSIX_
|
|
||||||
#include "qplatformdefs.h"
|
#include "qplatformdefs.h"
|
||||||
#include "private/qabstractfileengine_p.h"
|
#include "private/qabstractfileengine_p.h"
|
||||||
#include "private/qfsfileengine_p.h"
|
#include "private/qfsfileengine_p.h"
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define _POSIX_
|
|
||||||
#include "qplatformdefs.h"
|
#include "qplatformdefs.h"
|
||||||
#include "private/qabstractfileengine_p.h"
|
#include "private/qabstractfileengine_p.h"
|
||||||
#include "private/qfsfileengine_p.h"
|
#include "private/qfsfileengine_p.h"
|
||||||
@ -66,6 +65,7 @@
|
|||||||
#include <accctrl.h>
|
#include <accctrl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
#define SECURITY_WIN32
|
#define SECURITY_WIN32
|
||||||
#include <security.h>
|
#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/
|
** 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$
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
** GNU Lesser General Public License Usage
|
** GNU Lesser General Public License Usage
|
||||||
@ -39,31 +39,36 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef OLDNORMALIZEOBJECT_H
|
#ifndef QIPADDRESS_P_H
|
||||||
#define OLDNORMALIZEOBJECT_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;
|
#include "qstring.h"
|
||||||
class Class;
|
|
||||||
template <typename T> class Template;
|
|
||||||
|
|
||||||
// An object with old moc output that incorrectly normalizes 'T<C> const &' in the function
|
QT_BEGIN_NAMESPACE
|
||||||
// signatures
|
|
||||||
class OldNormalizeObject : public QObject
|
|
||||||
{
|
|
||||||
/* tmake ignore Q_OBJECT */
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
signals:
|
namespace QIPAddressUtils {
|
||||||
void typeRefSignal(Template<Class &> &ref);
|
|
||||||
void constTypeRefSignal(const Template<const Class &> &ref);
|
|
||||||
void typeConstRefSignal(Template<Class const &> const &ref);
|
|
||||||
|
|
||||||
public slots:
|
typedef quint32 IPv4Address;
|
||||||
void typeRefSlot(Template<Class &> &) {}
|
typedef quint8 IPv6Address[16];
|
||||||
void constTypeRefSlot(const Template<const Class &> &) {}
|
|
||||||
void typeConstRefSlot(Template<Class const &> const &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#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);
|
qDebug() << " " << child+j << " :: " << name(child+j);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
const uint h = qHash(segment);
|
const uint h = qt_hash(segment.toString());
|
||||||
|
|
||||||
//do the binary search for the hash
|
//do the binary search for the hash
|
||||||
int l = 0, r = child_count-1;
|
int l = 0, r = child_count-1;
|
||||||
|
@ -309,6 +309,27 @@ QString QStandardPaths::displayName(StandardLocation type)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QT_NO_STANDARDPATHS
|
#endif // QT_NO_STANDARDPATHS
|
||||||
|
@ -91,6 +91,8 @@ public:
|
|||||||
|
|
||||||
static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList());
|
static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList());
|
||||||
|
|
||||||
|
static void enableTestMode(bool testMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// prevent construction
|
// prevent construction
|
||||||
QStandardPaths();
|
QStandardPaths();
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QAtomicPointer>
|
#include <QAtomicPointer>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#ifndef QT_NO_STANDARDPATHS
|
#ifndef QT_NO_STANDARDPATHS
|
||||||
|
|
||||||
@ -62,6 +63,23 @@ public:
|
|||||||
|
|
||||||
Q_GLOBAL_STATIC(QStandardPathsPrivate, configCache);
|
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)
|
QString QStandardPaths::writableLocation(StandardLocation type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -73,6 +91,30 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
break;
|
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();
|
QJsonObject * localConfigObject = configCache()->object.loadAcquire();
|
||||||
if (localConfigObject == 0) {
|
if (localConfigObject == 0) {
|
||||||
QString configHome = QFile::decodeName(qgetenv("PATH_CONFIG_HOME"));
|
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.
|
Constructs a full unicode path from a FSRef.
|
||||||
*/
|
*/
|
||||||
@ -101,6 +108,16 @@ static QString getFullPath(const FSRef &ref)
|
|||||||
return QString();
|
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)
|
static QString macLocation(QStandardPaths::StandardLocation type, short domain)
|
||||||
{
|
{
|
||||||
// http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
|
// 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);
|
QString path = getFullPath(ref);
|
||||||
|
|
||||||
if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation) {
|
if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation)
|
||||||
if (!QCoreApplication::organizationName().isEmpty())
|
appendOrganizationAndApp(path);
|
||||||
path += QLatin1Char('/') + QCoreApplication::organizationName();
|
return path;
|
||||||
if (!QCoreApplication::applicationName().isEmpty())
|
|
||||||
path += QLatin1Char('/') + QCoreApplication::applicationName();
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QStandardPaths::writableLocation(StandardLocation type)
|
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) {
|
switch (type) {
|
||||||
case HomeLocation:
|
case HomeLocation:
|
||||||
return QDir::homePath();
|
return QDir::homePath();
|
||||||
|
@ -63,6 +63,13 @@ static void appendOrganizationAndApp(QString &path)
|
|||||||
path += QLatin1Char('/') + appName;
|
path += QLatin1Char('/') + appName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool qsp_testMode = false;
|
||||||
|
|
||||||
|
void QStandardPaths::enableTestMode(bool testMode)
|
||||||
|
{
|
||||||
|
qsp_testMode = testMode;
|
||||||
|
}
|
||||||
|
|
||||||
QString QStandardPaths::writableLocation(StandardLocation type)
|
QString QStandardPaths::writableLocation(StandardLocation type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -75,6 +82,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
{
|
{
|
||||||
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
|
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
|
||||||
QString xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
|
QString xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
|
||||||
|
if (qsp_testMode)
|
||||||
|
xdgCacheHome = QDir::homePath() + QLatin1String("/.qttest/cache");
|
||||||
if (xdgCacheHome.isEmpty())
|
if (xdgCacheHome.isEmpty())
|
||||||
xdgCacheHome = QDir::homePath() + QLatin1String("/.cache");
|
xdgCacheHome = QDir::homePath() + QLatin1String("/.cache");
|
||||||
if (type == QStandardPaths::CacheLocation)
|
if (type == QStandardPaths::CacheLocation)
|
||||||
@ -85,6 +94,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
case GenericDataLocation:
|
case GenericDataLocation:
|
||||||
{
|
{
|
||||||
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
|
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
|
||||||
|
if (qsp_testMode)
|
||||||
|
xdgDataHome = QDir::homePath() + QLatin1String("/.qttest/share");
|
||||||
if (xdgDataHome.isEmpty())
|
if (xdgDataHome.isEmpty())
|
||||||
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
|
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
|
||||||
if (type == QStandardPaths::DataLocation)
|
if (type == QStandardPaths::DataLocation)
|
||||||
@ -95,6 +106,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
{
|
{
|
||||||
// http://standards.freedesktop.org/basedir-spec/latest/
|
// http://standards.freedesktop.org/basedir-spec/latest/
|
||||||
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
|
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
|
||||||
|
if (qsp_testMode)
|
||||||
|
xdgConfigHome = QDir::homePath() + QLatin1String("/.qttest/config");
|
||||||
if (xdgConfigHome.isEmpty())
|
if (xdgConfigHome.isEmpty())
|
||||||
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
|
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
|
||||||
return xdgConfigHome;
|
return xdgConfigHome;
|
||||||
@ -140,7 +153,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
if (xdgConfigHome.isEmpty())
|
if (xdgConfigHome.isEmpty())
|
||||||
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
|
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
|
||||||
QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs"));
|
QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs"));
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (!qsp_testMode && file.open(QIODevice::ReadOnly)) {
|
||||||
QHash<QString, QString> lines;
|
QHash<QString, QString> lines;
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
// Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop"
|
// 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));
|
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 QStandardPaths::writableLocation(StandardLocation type)
|
||||||
{
|
{
|
||||||
QString result;
|
QString result;
|
||||||
@ -105,6 +112,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
|
if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
|
||||||
#endif
|
#endif
|
||||||
result = convertCharArray(path);
|
result = convertCharArray(path);
|
||||||
|
if (qsp_testMode)
|
||||||
|
result += QLatin1String("/qttest");
|
||||||
if (type != GenericDataLocation) {
|
if (type != GenericDataLocation) {
|
||||||
if (!QCoreApplication::organizationName().isEmpty())
|
if (!QCoreApplication::organizationName().isEmpty())
|
||||||
result += QLatin1Char('/') + QCoreApplication::organizationName();
|
result += QLatin1Char('/') + QCoreApplication::organizationName();
|
||||||
|
@ -696,7 +696,7 @@ void QTextStreamPrivate::flushWriteBuffer()
|
|||||||
|
|
||||||
// flush the file
|
// flush the file
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
QFile *file = qobject_cast<QFile *>(device);
|
QFileDevice *file = qobject_cast<QFileDevice *>(device);
|
||||||
bool flushed = !file || file->flush();
|
bool flushed = !file || file->flush();
|
||||||
#else
|
#else
|
||||||
bool flushed = true;
|
bool flushed = true;
|
||||||
|
@ -44,12 +44,13 @@
|
|||||||
#include "private/qurltlds_p.h"
|
#include "private/qurltlds_p.h"
|
||||||
#include "private/qtldurl_p.h"
|
#include "private/qtldurl_p.h"
|
||||||
#include "QtCore/qstringlist.h"
|
#include "QtCore/qstringlist.h"
|
||||||
|
#include "QtCore/qhash.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static bool containsTLDEntry(const QString &entry)
|
static bool containsTLDEntry(const QString &entry)
|
||||||
{
|
{
|
||||||
int index = qHash(entry) % tldCount;
|
int index = qt_hash(entry) % tldCount;
|
||||||
int currentDomainIndex = tldIndices[index];
|
int currentDomainIndex = tldIndices[index];
|
||||||
while (currentDomainIndex < tldIndices[index+1]) {
|
while (currentDomainIndex < tldIndices[index+1]) {
|
||||||
QString currentEntry = QString::fromUtf8(tldData + currentDomainIndex);
|
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 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Copyright (C) 2012 Intel Corporation.
|
||||||
** Contact: http://www.qt-project.org/
|
** Contact: http://www.qt-project.org/
|
||||||
**
|
**
|
||||||
** This file is part of the QtCore module of the Qt Toolkit.
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
@ -44,18 +45,74 @@
|
|||||||
|
|
||||||
#include <QtCore/qbytearray.h>
|
#include <QtCore/qbytearray.h>
|
||||||
#include <QtCore/qobjectdefs.h>
|
#include <QtCore/qobjectdefs.h>
|
||||||
#include <QtCore/qpair.h>
|
|
||||||
#include <QtCore/qstring.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_HEADER
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class QUrlQuery;
|
||||||
class QUrlPrivate;
|
class QUrlPrivate;
|
||||||
class QDataStream;
|
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
|
class Q_CORE_EXPORT QUrl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -65,7 +122,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// encoding / toString values
|
// encoding / toString values
|
||||||
enum FormattingOption {
|
enum UrlFormattingOption {
|
||||||
None = 0x0,
|
None = 0x0,
|
||||||
RemoveScheme = 0x1,
|
RemoveScheme = 0x1,
|
||||||
RemovePassword = 0x2,
|
RemovePassword = 0x2,
|
||||||
@ -75,23 +132,41 @@ public:
|
|||||||
RemovePath = 0x20,
|
RemovePath = 0x20,
|
||||||
RemoveQuery = 0x40,
|
RemoveQuery = 0x40,
|
||||||
RemoveFragment = 0x80,
|
RemoveFragment = 0x80,
|
||||||
// 0x100: private: normalized
|
// 0x100 was a private code in Qt 4, keep unused for a while
|
||||||
|
PreferLocalFile = 0x200,
|
||||||
StripTrailingSlash = 0x10000
|
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();
|
QUrl();
|
||||||
#ifdef QT_NO_URL_CAST_FROM_STRING
|
|
||||||
explicit
|
|
||||||
#endif
|
|
||||||
QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
|
||||||
QUrl(const QUrl ©);
|
QUrl(const QUrl ©);
|
||||||
QUrl &operator =(const QUrl ©);
|
QUrl &operator =(const QUrl ©);
|
||||||
#ifndef QT_NO_URL_CAST_FROM_STRING
|
#ifdef QT_NO_URL_CAST_FROM_STRING
|
||||||
QUrl &operator =(const QString &url);
|
explicit QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||||
|
#else
|
||||||
|
QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||||
|
QUrl &operator=(const QString &url);
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_COMPILER_RVALUE_REFS
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
|
QUrl(QUrl &&other) : d(0)
|
||||||
|
{ qSwap(d, other.d); }
|
||||||
inline QUrl &operator=(QUrl &&other)
|
inline QUrl &operator=(QUrl &&other)
|
||||||
{ qSwap(d, other.d); return *this; }
|
{ qSwap(d, other.d); return *this; }
|
||||||
#endif
|
#endif
|
||||||
@ -100,96 +175,63 @@ public:
|
|||||||
inline void swap(QUrl &other) { qSwap(d, other.d); }
|
inline void swap(QUrl &other) { qSwap(d, other.d); }
|
||||||
|
|
||||||
void setUrl(const QString &url, ParsingMode mode = TolerantMode);
|
void setUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||||
QString url(FormattingOptions options = None) const;
|
QString url(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
|
||||||
QString toString(FormattingOptions options = None) const;
|
QString toString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
|
||||||
QString toDisplayString(FormattingOptions options = None) 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;
|
bool isValid() const;
|
||||||
|
QString errorString() const;
|
||||||
|
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void setScheme(const QString &scheme);
|
void setScheme(const QString &scheme);
|
||||||
QString scheme() const;
|
QString scheme() const;
|
||||||
|
|
||||||
void setAuthority(const QString &authority);
|
void setAuthority(const QString &authority);
|
||||||
QString authority() const;
|
QString authority(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||||
|
|
||||||
void setUserInfo(const QString &userInfo);
|
void setUserInfo(const QString &userInfo);
|
||||||
QString userInfo() const;
|
QString userInfo(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||||
|
|
||||||
void setUserName(const QString &userName);
|
void setUserName(const QString &userName);
|
||||||
QString userName() const;
|
QString userName(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||||
void setEncodedUserName(const QByteArray &userName);
|
|
||||||
QByteArray encodedUserName() const;
|
|
||||||
|
|
||||||
void setPassword(const QString &password);
|
void setPassword(const QString &password);
|
||||||
QString password() const;
|
QString password(ComponentFormattingOptions = PrettyDecoded) const;
|
||||||
void setEncodedPassword(const QByteArray &password);
|
|
||||||
QByteArray encodedPassword() const;
|
|
||||||
|
|
||||||
void setHost(const QString &host);
|
void setHost(const QString &host);
|
||||||
QString host() const;
|
QString host(ComponentFormattingOptions = PrettyDecoded) const;
|
||||||
void setEncodedHost(const QByteArray &host);
|
QString topLevelDomain(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||||
QByteArray encodedHost() const;
|
|
||||||
|
|
||||||
void setPort(int port);
|
void setPort(int port);
|
||||||
int port(int defaultPort = -1) const;
|
int port(int defaultPort = -1) const;
|
||||||
|
|
||||||
void setPath(const QString &path);
|
void setPath(const QString &path);
|
||||||
QString path() const;
|
QString path(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||||
void setEncodedPath(const QByteArray &path);
|
|
||||||
QByteArray encodedPath() const;
|
|
||||||
|
|
||||||
bool hasQuery() 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;
|
bool hasFragment() const;
|
||||||
#ifndef QT_BOOTSTRAPPED
|
QString fragment(ComponentFormattingOptions options = PrettyDecoded) const;
|
||||||
QString topLevelDomain() const;
|
void setFragment(const QString &fragment);
|
||||||
#endif
|
|
||||||
|
|
||||||
QUrl resolved(const QUrl &relative) const;
|
QUrl resolved(const QUrl &relative) const;
|
||||||
|
|
||||||
bool isRelative() const;
|
bool isRelative() const;
|
||||||
bool isParentOf(const QUrl &url) const;
|
bool isParentOf(const QUrl &url) const;
|
||||||
|
|
||||||
|
bool isLocalFile() const;
|
||||||
static QUrl fromLocalFile(const QString &localfile);
|
static QUrl fromLocalFile(const QString &localfile);
|
||||||
QString toLocalFile() const;
|
QString toLocalFile() const;
|
||||||
bool isLocalFile() const;
|
|
||||||
|
|
||||||
QByteArray toEncoded(FormattingOptions options = None) const;
|
|
||||||
|
|
||||||
static QUrl fromUserInput(const QString &userInput);
|
|
||||||
|
|
||||||
void detach();
|
void detach();
|
||||||
bool isDetached() const;
|
bool isDetached() const;
|
||||||
@ -202,37 +244,121 @@ public:
|
|||||||
static QByteArray toPercentEncoding(const QString &,
|
static QByteArray toPercentEncoding(const QString &,
|
||||||
const QByteArray &exclude = QByteArray(),
|
const QByteArray &exclude = QByteArray(),
|
||||||
const QByteArray &include = QByteArray());
|
const QByteArray &include = QByteArray());
|
||||||
static QString fromPunycode(const QByteArray &);
|
#if QT_DEPRECATED_SINCE(5,0)
|
||||||
static QByteArray toPunycode(const QString &);
|
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 QString fromAce(const QByteArray &);
|
||||||
static QByteArray toAce(const QString &);
|
static QByteArray toAce(const QString &);
|
||||||
static QStringList idnWhitelist();
|
static QStringList idnWhitelist();
|
||||||
static void setIdnWhitelist(const QStringList &);
|
static void setIdnWhitelist(const QStringList &);
|
||||||
|
friend Q_CORE_EXPORT uint qHash(const QUrl &url, uint seed = 0);
|
||||||
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
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUrlPrivate *d;
|
QUrlPrivate *d;
|
||||||
|
friend class QUrlQuery;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef QUrlPrivate * DataPtr;
|
typedef QUrlPrivate * DataPtr;
|
||||||
inline DataPtr &data_ptr() { return d; }
|
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_TYPEINFO(QUrl, Q_MOVABLE_TYPE);
|
||||||
Q_DECLARE_SHARED(QUrl)
|
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
|
#ifndef QT_NO_DATASTREAM
|
||||||
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QUrl &);
|
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QUrl &);
|
||||||
@ -245,6 +371,10 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QUrl &);
|
|||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#if QT_DEPRECATED_SINCE(5,0)
|
||||||
|
# include <QtCore/qurlquery.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_END_HEADER
|
QT_END_HEADER
|
||||||
|
|
||||||
#endif // QURL_H
|
#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
|
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.
|
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
|
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
|
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
|
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
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QAbstractProxyModel(QObject *parent = 0);
|
explicit QAbstractProxyModel(QObject *parent = 0);
|
||||||
~QAbstractProxyModel();
|
~QAbstractProxyModel();
|
||||||
|
|
||||||
virtual void setSourceModel(QAbstractItemModel *sourceModel);
|
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.
|
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()) {
|
if (model() == other.model() && parent() == other.parent()) {
|
||||||
QModelIndex topLeft = model()->index(qMax(top(), other.top()),
|
QModelIndex topLeft = model()->index(qMax(top(), other.top()),
|
||||||
|
@ -92,9 +92,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool intersects(const QItemSelectionRange &other) const;
|
bool intersects(const QItemSelectionRange &other) const;
|
||||||
QItemSelectionRange intersect(const QItemSelectionRange &other) const; // ### Qt 5: make QT4_SUPPORT
|
#if QT_DEPRECATED_SINCE(5, 0)
|
||||||
inline QItemSelectionRange intersected(const QItemSelectionRange &other) const
|
inline QItemSelectionRange intersect(const QItemSelectionRange &other) const
|
||||||
{ return intersect(other); }
|
{ return intersected(other); }
|
||||||
|
#endif
|
||||||
|
QItemSelectionRange intersected(const QItemSelectionRange &other) const;
|
||||||
|
|
||||||
|
|
||||||
inline bool operator==(const QItemSelectionRange &other) const
|
inline bool operator==(const QItemSelectionRange &other) const
|
||||||
{ return (tl == other.tl && br == other.br); }
|
{ 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)
|
Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSortFilterProxyModel(QObject *parent = 0);
|
explicit QSortFilterProxyModel(QObject *parent = 0);
|
||||||
~QSortFilterProxyModel();
|
~QSortFilterProxyModel();
|
||||||
|
|
||||||
void setSourceModel(QAbstractItemModel *sourceModel);
|
void setSourceModel(QAbstractItemModel *sourceModel);
|
||||||
|
@ -57,7 +57,7 @@ class Q_CORE_EXPORT QStringListModel : public QAbstractListModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit QStringListModel(QObject *parent = 0);
|
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;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
|
@ -400,7 +400,8 @@ QString QJsonValue::toString() const
|
|||||||
if (t != String)
|
if (t != String)
|
||||||
return QString();
|
return QString();
|
||||||
stringData->ref.ref(); // the constructor below doesn't add a ref.
|
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
|
\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()
|
/*! \fn void QAbstractEventDispatcher::wakeUp()
|
||||||
\threadsafe
|
\threadsafe
|
||||||
|
|
||||||
|
@ -93,6 +93,8 @@ public:
|
|||||||
virtual bool unregisterTimers(QObject *object) = 0;
|
virtual bool unregisterTimers(QObject *object) = 0;
|
||||||
virtual QList<TimerInfo> registeredTimers(QObject *object) const = 0;
|
virtual QList<TimerInfo> registeredTimers(QObject *object) const = 0;
|
||||||
|
|
||||||
|
virtual int remainingTime(int timerId) = 0;
|
||||||
|
|
||||||
virtual void wakeUp() = 0;
|
virtual void wakeUp() = 0;
|
||||||
virtual void interrupt() = 0;
|
virtual void interrupt() = 0;
|
||||||
virtual void flush() = 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
|
generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
|
||||||
called.
|
called.
|
||||||
|
|
||||||
|
The function returns true on success and false on failure.
|
||||||
|
|
||||||
\sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
|
\sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void QCoreApplication::installTranslator(QTranslator *translationFile)
|
bool QCoreApplication::installTranslator(QTranslator *translationFile)
|
||||||
{
|
{
|
||||||
if (!translationFile)
|
if (!translationFile)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
|
if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
|
||||||
return;
|
return false;
|
||||||
QCoreApplicationPrivate *d = self->d_func();
|
QCoreApplicationPrivate *d = self->d_func();
|
||||||
d->translators.prepend(translationFile);
|
d->translators.prepend(translationFile);
|
||||||
|
|
||||||
#ifndef QT_NO_TRANSLATION_BUILDER
|
#ifndef QT_NO_TRANSLATION_BUILDER
|
||||||
if (translationFile->isEmpty())
|
if (translationFile->isEmpty())
|
||||||
return;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QEvent ev(QEvent::LanguageChange);
|
QEvent ev(QEvent::LanguageChange);
|
||||||
QCoreApplication::sendEvent(self, &ev);
|
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 files used by this application. (It does not delete the
|
||||||
translation file from the file system.)
|
translation file from the file system.)
|
||||||
|
|
||||||
|
The function returns true on success and false on failure.
|
||||||
|
|
||||||
\sa installTranslator() translate(), QObject::tr()
|
\sa installTranslator() translate(), QObject::tr()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void QCoreApplication::removeTranslator(QTranslator *translationFile)
|
bool QCoreApplication::removeTranslator(QTranslator *translationFile)
|
||||||
{
|
{
|
||||||
if (!translationFile)
|
if (!translationFile)
|
||||||
return;
|
return false;
|
||||||
if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
|
if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
|
||||||
return;
|
return false;
|
||||||
QCoreApplicationPrivate *d = self->d_func();
|
QCoreApplicationPrivate *d = self->d_func();
|
||||||
if (d->translators.removeAll(translationFile) && !self->closingDown()) {
|
if (d->translators.removeAll(translationFile) && !self->closingDown()) {
|
||||||
QEvent ev(QEvent::LanguageChange);
|
QEvent ev(QEvent::LanguageChange);
|
||||||
QCoreApplication::sendEvent(self, &ev);
|
QCoreApplication::sendEvent(self, &ev);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void replacePercentN(QString *result, int n)
|
static void replacePercentN(QString *result, int n)
|
||||||
|
@ -134,8 +134,8 @@ public:
|
|||||||
#endif // QT_NO_LIBRARY
|
#endif // QT_NO_LIBRARY
|
||||||
|
|
||||||
#ifndef QT_NO_TRANSLATION
|
#ifndef QT_NO_TRANSLATION
|
||||||
static void installTranslator(QTranslator * messageFile);
|
static bool installTranslator(QTranslator * messageFile);
|
||||||
static void removeTranslator(QTranslator * messageFile);
|
static bool removeTranslator(QTranslator * messageFile);
|
||||||
#endif
|
#endif
|
||||||
enum Encoding { UnicodeUTF8, Latin1, DefaultCodec = Latin1
|
enum Encoding { UnicodeUTF8, Latin1, DefaultCodec = Latin1
|
||||||
#if QT_DEPRECATED_SINCE(5, 0)
|
#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 NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area.
|
||||||
\value NonClientAreaMouseMove A mouse move 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 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 MetaCall An asynchronous method invocation via QMetaObject::invokeMethod().
|
||||||
\value ModifiedChange Widgets modification state has been changed.
|
\value ModifiedChange Widgets modification state has been changed.
|
||||||
\value MouseButtonDblClick Mouse press again (QMouseEvent).
|
\value MouseButtonDblClick Mouse press again (QMouseEvent).
|
||||||
|
@ -192,9 +192,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
AcceptDropsChange = 152,
|
AcceptDropsChange = 152,
|
||||||
|
|
||||||
MenubarUpdated = 153, // Support event for Q3MainWindow, which needs to
|
|
||||||
// knwow when QMenubar is updated.
|
|
||||||
|
|
||||||
ZeroTimerEvent = 154, // Used for Windows Zero timer events
|
ZeroTimerEvent = 154, // Used for Windows Zero timer events
|
||||||
|
|
||||||
GraphicsSceneMouseMove = 155, // GraphicsView
|
GraphicsSceneMouseMove = 155, // GraphicsView
|
||||||
@ -269,17 +266,14 @@ public:
|
|||||||
ScrollPrepare = 204,
|
ScrollPrepare = 204,
|
||||||
Scroll = 205,
|
Scroll = 205,
|
||||||
|
|
||||||
Map = 206,
|
Expose = 206,
|
||||||
Unmap = 207,
|
|
||||||
|
|
||||||
Expose = 208,
|
InputMethodQuery = 207,
|
||||||
|
OrientationChange = 208, // Screen orientation has changed
|
||||||
|
|
||||||
InputMethodQuery = 209,
|
TouchCancel = 209,
|
||||||
OrientationChange = 210, // Screen orientation has changed
|
|
||||||
|
|
||||||
TouchCancel = 211,
|
ThemeChange = 210,
|
||||||
|
|
||||||
ThemeChange = 212,
|
|
||||||
|
|
||||||
// 512 reserved for Qt Jambi's MetaCall event
|
// 512 reserved for Qt Jambi's MetaCall event
|
||||||
// 513 reserved for Qt Jambi's DeleteOnMainThread 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);
|
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()
|
void QEventDispatcherGlib::interrupt()
|
||||||
{
|
{
|
||||||
wakeUp();
|
wakeUp();
|
||||||
|
@ -85,6 +85,8 @@ public:
|
|||||||
bool unregisterTimers(QObject *object);
|
bool unregisterTimers(QObject *object);
|
||||||
QList<TimerInfo> registeredTimers(QObject *object) const;
|
QList<TimerInfo> registeredTimers(QObject *object) const;
|
||||||
|
|
||||||
|
int remainingTime(int timerId);
|
||||||
|
|
||||||
void wakeUp();
|
void wakeUp();
|
||||||
void interrupt();
|
void interrupt();
|
||||||
void flush();
|
void flush();
|
||||||
|
@ -628,6 +628,19 @@ bool QEventDispatcherUNIX::hasPendingEvents()
|
|||||||
return qGlobalPostedEventsCount();
|
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()
|
void QEventDispatcherUNIX::wakeUp()
|
||||||
{
|
{
|
||||||
Q_D(QEventDispatcherUNIX);
|
Q_D(QEventDispatcherUNIX);
|
||||||
|
@ -116,6 +116,8 @@ public:
|
|||||||
bool unregisterTimers(QObject *object);
|
bool unregisterTimers(QObject *object);
|
||||||
QList<TimerInfo> registeredTimers(QObject *object) const;
|
QList<TimerInfo> registeredTimers(QObject *object) const;
|
||||||
|
|
||||||
|
int remainingTime(int timerId);
|
||||||
|
|
||||||
void wakeUp();
|
void wakeUp();
|
||||||
void interrupt();
|
void interrupt();
|
||||||
void flush();
|
void flush();
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "qvarlengtharray.h"
|
#include "qvarlengtharray.h"
|
||||||
#include "qwineventnotifier.h"
|
#include "qwineventnotifier.h"
|
||||||
|
|
||||||
|
#include "qelapsedtimer.h"
|
||||||
#include "qcoreapplication_p.h"
|
#include "qcoreapplication_p.h"
|
||||||
#include <private/qthread_p.h>
|
#include <private/qthread_p.h>
|
||||||
#include <private/qmutexpool_p.h>
|
#include <private/qmutexpool_p.h>
|
||||||
@ -532,6 +533,8 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
|
|||||||
ok = SetTimer(internalHwnd, t->timerId, interval, 0);
|
ok = SetTimer(internalHwnd, t->timerId, interval, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t->timeout = qt_msectime() + interval;
|
||||||
|
|
||||||
if (ok == 0)
|
if (ok == 0)
|
||||||
qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer");
|
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()
|
void QEventDispatcherWin32::wakeUp()
|
||||||
{
|
{
|
||||||
Q_D(QEventDispatcherWin32);
|
Q_D(QEventDispatcherWin32);
|
||||||
|
@ -66,6 +66,7 @@ class QEventDispatcherWin32Private;
|
|||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
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
|
class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
|
||||||
{
|
{
|
||||||
@ -94,6 +95,8 @@ public:
|
|||||||
void unregisterEventNotifier(QWinEventNotifier *notifier);
|
void unregisterEventNotifier(QWinEventNotifier *notifier);
|
||||||
void activateEventNotifiers();
|
void activateEventNotifiers();
|
||||||
|
|
||||||
|
int remainingTime(int timerId);
|
||||||
|
|
||||||
void wakeUp();
|
void wakeUp();
|
||||||
void interrupt();
|
void interrupt();
|
||||||
void flush();
|
void flush();
|
||||||
@ -123,6 +126,7 @@ struct WinTimerInfo { // internal timer info
|
|||||||
int timerId;
|
int timerId;
|
||||||
int interval;
|
int interval;
|
||||||
Qt::TimerType timerType;
|
Qt::TimerType timerType;
|
||||||
|
quint64 timeout; // - when to actually fire
|
||||||
QObject *obj; // - object to receive events
|
QObject *obj; // - object to receive events
|
||||||
bool inTimerEvent;
|
bool inTimerEvent;
|
||||||
int fastTimerId;
|
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.
|
\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
|
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
|
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
|
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.
|
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.
|
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)
|
QEventLoopLocker::QEventLoopLocker(QThread *thread)
|
||||||
: d_ptr(new QEventLoopLockerPrivate(static_cast<QThreadPrivate*>(QObjectPrivate::get(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:
|
public:
|
||||||
inline QMetaMethod() : mobj(0),handle(0) {}
|
inline QMetaMethod() : mobj(0),handle(0) {}
|
||||||
|
|
||||||
const char *signature() const;
|
QByteArray methodSignature() const;
|
||||||
|
QByteArray name() const;
|
||||||
const char *typeName() 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> parameterTypes() const;
|
||||||
QList<QByteArray> parameterNames() const;
|
QList<QByteArray> parameterNames() const;
|
||||||
const char *tag() const;
|
const char *tag() const;
|
||||||
@ -137,8 +142,16 @@ public:
|
|||||||
inline bool isValid() const { return mobj != 0; }
|
inline bool isValid() const { return mobj != 0; }
|
||||||
|
|
||||||
private:
|
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;
|
const QMetaObject *mobj;
|
||||||
uint handle;
|
uint handle;
|
||||||
|
friend class QMetaMethodPrivate;
|
||||||
friend struct QMetaObject;
|
friend struct QMetaObject;
|
||||||
friend struct QMetaObjectPrivate;
|
friend struct QMetaObjectPrivate;
|
||||||
friend class QObject;
|
friend class QObject;
|
||||||
|
@ -105,11 +105,64 @@ enum MetaObjectFlags {
|
|||||||
RequiresVariantMetaObject = 0x02
|
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;
|
class QMutex;
|
||||||
|
|
||||||
struct QMetaObjectPrivate
|
struct QMetaObjectPrivate
|
||||||
{
|
{
|
||||||
enum { OutputRevision = 6 }; // Used by moc and qmetaobjectbuilder
|
enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus
|
||||||
|
|
||||||
int revision;
|
int revision;
|
||||||
int className;
|
int className;
|
||||||
@ -122,18 +175,34 @@ struct QMetaObjectPrivate
|
|||||||
int signalCount; //since revision 4
|
int signalCount; //since revision 4
|
||||||
// revision 5 introduces changes in normalized signatures, no new members
|
// 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 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)
|
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
|
||||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
|
{ 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 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);
|
static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
|
||||||
|
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
|
@ -78,26 +78,17 @@ QT_BEGIN_NAMESPACE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// copied from moc's generator.cpp
|
// copied from moc's generator.cpp
|
||||||
uint qvariant_nameToType(const char* name)
|
bool isBuiltinType(const QByteArray &type)
|
||||||
{
|
{
|
||||||
if (!name)
|
int id = QMetaType::type(type);
|
||||||
return 0;
|
if (!id && !type.isEmpty() && type != "void")
|
||||||
|
return false;
|
||||||
uint tp = QMetaType::type(name);
|
return (id < QMetaType::User);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copied from qmetaobject.cpp
|
||||||
static inline const QMetaObjectPrivate *priv(const uint* data)
|
static inline const QMetaObjectPrivate *priv(const uint* data)
|
||||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
||||||
// end of copied lines from qmetaobject.cpp
|
|
||||||
|
|
||||||
class QMetaMethodBuilderPrivate
|
class QMetaMethodBuilderPrivate
|
||||||
{
|
{
|
||||||
@ -105,7 +96,7 @@ public:
|
|||||||
QMetaMethodBuilderPrivate
|
QMetaMethodBuilderPrivate
|
||||||
(QMetaMethod::MethodType _methodType,
|
(QMetaMethod::MethodType _methodType,
|
||||||
const QByteArray& _signature,
|
const QByteArray& _signature,
|
||||||
const QByteArray& _returnType = QByteArray(),
|
const QByteArray& _returnType = QByteArray("void"),
|
||||||
QMetaMethod::Access _access = QMetaMethod::Public,
|
QMetaMethod::Access _access = QMetaMethod::Public,
|
||||||
int _revision = 0)
|
int _revision = 0)
|
||||||
: signature(QMetaObject::normalizedSignature(_signature.constData())),
|
: signature(QMetaObject::normalizedSignature(_signature.constData())),
|
||||||
@ -113,6 +104,7 @@ public:
|
|||||||
attributes(((int)_access) | (((int)_methodType) << 2)),
|
attributes(((int)_access) | (((int)_methodType) << 2)),
|
||||||
revision(_revision)
|
revision(_revision)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray signature;
|
QByteArray signature;
|
||||||
@ -136,6 +128,21 @@ public:
|
|||||||
{
|
{
|
||||||
attributes = ((attributes & ~AccessMask) | (int)value);
|
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
|
class QMetaPropertyBuilderPrivate
|
||||||
@ -429,8 +436,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
|
|||||||
\a signature and \a returnType. Returns an object that can be
|
\a signature and \a returnType. Returns an object that can be
|
||||||
used to adjust the other attributes of the method. The \a signature
|
used to adjust the other attributes of the method. The \a signature
|
||||||
and \a returnType will be normalized before they are added to
|
and \a returnType will be normalized before they are added to
|
||||||
the class. If \a returnType is empty, then it indicates that
|
the class.
|
||||||
the method has \c{void} as its return type.
|
|
||||||
|
|
||||||
\sa method(), methodCount(), removeMethod(), indexOfMethod()
|
\sa method(), methodCount(), removeMethod(), indexOfMethod()
|
||||||
*/
|
*/
|
||||||
@ -458,13 +464,13 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
|
|||||||
{
|
{
|
||||||
QMetaMethodBuilder method;
|
QMetaMethodBuilder method;
|
||||||
if (prototype.methodType() == QMetaMethod::Method)
|
if (prototype.methodType() == QMetaMethod::Method)
|
||||||
method = addMethod(prototype.signature());
|
method = addMethod(prototype.methodSignature());
|
||||||
else if (prototype.methodType() == QMetaMethod::Signal)
|
else if (prototype.methodType() == QMetaMethod::Signal)
|
||||||
method = addSignal(prototype.signature());
|
method = addSignal(prototype.methodSignature());
|
||||||
else if (prototype.methodType() == QMetaMethod::Slot)
|
else if (prototype.methodType() == QMetaMethod::Slot)
|
||||||
method = addSlot(prototype.signature());
|
method = addSlot(prototype.methodSignature());
|
||||||
else if (prototype.methodType() == QMetaMethod::Constructor)
|
else if (prototype.methodType() == QMetaMethod::Constructor)
|
||||||
method = addConstructor(prototype.signature());
|
method = addConstructor(prototype.methodSignature());
|
||||||
method.setReturnType(prototype.typeName());
|
method.setReturnType(prototype.typeName());
|
||||||
method.setParameterNames(prototype.parameterNames());
|
method.setParameterNames(prototype.parameterNames());
|
||||||
method.setTag(prototype.tag());
|
method.setTag(prototype.tag());
|
||||||
@ -501,7 +507,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
|
|||||||
{
|
{
|
||||||
int index = d->methods.size();
|
int index = d->methods.size();
|
||||||
d->methods.append(QMetaMethodBuilderPrivate
|
d->methods.append(QMetaMethodBuilderPrivate
|
||||||
(QMetaMethod::Signal, signature, QByteArray(), QMetaMethod::Protected));
|
(QMetaMethod::Signal, signature, QByteArray("void"), QMetaMethod::Protected));
|
||||||
return QMetaMethodBuilder(this, index);
|
return QMetaMethodBuilder(this, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,7 +523,8 @@ QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
|
|||||||
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
|
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
|
||||||
{
|
{
|
||||||
int index = d->constructors.size();
|
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));
|
return QMetaMethodBuilder(this, -(index + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +542,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signatur
|
|||||||
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
|
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
|
||||||
{
|
{
|
||||||
Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
|
Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
|
||||||
QMetaMethodBuilder ctor = addConstructor(prototype.signature());
|
QMetaMethodBuilder ctor = addConstructor(prototype.methodSignature());
|
||||||
ctor.setReturnType(prototype.typeName());
|
ctor.setReturnType(prototype.typeName());
|
||||||
ctor.setParameterNames(prototype.parameterNames());
|
ctor.setParameterNames(prototype.parameterNames());
|
||||||
ctor.setTag(prototype.tag());
|
ctor.setTag(prototype.tag());
|
||||||
@ -588,7 +595,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
|
|||||||
if (prototype.hasNotifySignal()) {
|
if (prototype.hasNotifySignal()) {
|
||||||
// Find an existing method for the notify signal, or add a new one.
|
// Find an existing method for the notify signal, or add a new one.
|
||||||
QMetaMethod method = prototype.notifySignal();
|
QMetaMethod method = prototype.notifySignal();
|
||||||
int index = indexOfMethod(method.signature());
|
int index = indexOfMethod(method.methodSignature());
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
index = addMethod(method).index();
|
index = addMethod(method).index();
|
||||||
d->properties[property._index].notifySignal = index;
|
d->properties[property._index].notifySignal = index;
|
||||||
@ -731,16 +738,12 @@ void QMetaObjectBuilder::addMetaObject
|
|||||||
|
|
||||||
if ((members & RelatedMetaObjects) != 0) {
|
if ((members & RelatedMetaObjects) != 0) {
|
||||||
const QMetaObject **objects;
|
const QMetaObject **objects;
|
||||||
if (priv(prototype->d.data)->revision < 2) {
|
Q_ASSERT(priv(prototype->d.data)->revision >= 2);
|
||||||
objects = (const QMetaObject **)(prototype->d.extradata);
|
const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
|
||||||
} else
|
if (extra)
|
||||||
{
|
objects = extra->objects;
|
||||||
const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
|
else
|
||||||
if (extra)
|
objects = 0;
|
||||||
objects = extra->objects;
|
|
||||||
else
|
|
||||||
objects = 0;
|
|
||||||
}
|
|
||||||
if (objects) {
|
if (objects) {
|
||||||
while (*objects != 0) {
|
while (*objects != 0) {
|
||||||
addRelatedMetaObject(*objects);
|
addRelatedMetaObject(*objects);
|
||||||
@ -750,12 +753,11 @@ void QMetaObjectBuilder::addMetaObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((members & StaticMetacall) != 0) {
|
if ((members & StaticMetacall) != 0) {
|
||||||
if (priv(prototype->d.data)->revision >= 6) {
|
Q_ASSERT(priv(prototype->d.data)->revision >= 6);
|
||||||
const QMetaObjectExtraData *extra =
|
const QMetaObjectExtraData *extra =
|
||||||
(const QMetaObjectExtraData *)(prototype->d.extradata);
|
(const QMetaObjectExtraData *)(prototype->d.extradata);
|
||||||
if (extra && extra->static_metacall)
|
if (extra && extra->static_metacall)
|
||||||
setStaticMetacallFunction(extra->static_metacall);
|
setStaticMetacallFunction(extra->static_metacall);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,75 +1072,79 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
|
|||||||
#define ALIGN(size,type) \
|
#define ALIGN(size,type) \
|
||||||
(size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
|
(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:
|
Entries::iterator it = m_entries.find(value);
|
||||||
typedef QHash<QByteArray, int> Entries; // string --> offset mapping
|
if (it != m_entries.end())
|
||||||
typedef Entries::const_iterator const_iterator;
|
return it.value();
|
||||||
Entries::const_iterator constBegin() const
|
int pos = m_index;
|
||||||
{ return m_entries.constBegin(); }
|
m_entries.insert(value, pos);
|
||||||
Entries::const_iterator constEnd() const
|
++m_index;
|
||||||
{ return m_entries.constEnd(); }
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
MetaStringTable() : m_offset(0) {}
|
int QMetaStringTable::preferredAlignment()
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
// If the parameter name list is specified, then concatenate them.
|
return Q_ALIGNOF(QByteArrayData);
|
||||||
if (!parameterNames.isEmpty()) {
|
}
|
||||||
QByteArray names;
|
|
||||||
bool first = true;
|
|
||||||
foreach (const QByteArray &name, parameterNames) {
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
names += (char)',';
|
|
||||||
names += name;
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count commas in the signature, excluding those inside template arguments.
|
// Returns the size (in bytes) required for serializing this string table.
|
||||||
int index = signature.indexOf('(');
|
int QMetaStringTable::blobSize() const
|
||||||
if (index < 0)
|
{
|
||||||
return QByteArray();
|
int size = m_entries.size() * sizeof(QByteArrayData);
|
||||||
++index;
|
Entries::const_iterator it;
|
||||||
if (index >= signature.size())
|
for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
|
||||||
return QByteArray();
|
size += it.key().size() + 1;
|
||||||
if (signature[index] == ')')
|
return size;
|
||||||
return QByteArray();
|
}
|
||||||
int count = 1;
|
|
||||||
int brackets = 0;
|
// Writes strings to string data struct.
|
||||||
while (index < signature.size() && signature[index] != ',') {
|
// The struct consists of an array of QByteArrayData, followed by a char array
|
||||||
char ch = signature[index++];
|
// containing the actual strings. This format must match the one produced by
|
||||||
if (ch == '<')
|
// moc (see generator.cpp).
|
||||||
++brackets;
|
void QMetaStringTable::writeBlob(char *out)
|
||||||
else if (ch == '>')
|
{
|
||||||
--brackets;
|
Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1)));
|
||||||
else if (ch == ',' && brackets <= 0)
|
|
||||||
++count;
|
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".
|
// 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
|
Q_UNUSED(expectedSize); // Avoid warning in release mode
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int dataIndex;
|
int dataIndex;
|
||||||
|
int paramsIndex;
|
||||||
int enumIndex;
|
int enumIndex;
|
||||||
int index;
|
int index;
|
||||||
bool hasRevisionedMethods = d->hasRevisionedMethods();
|
bool hasRevisionedMethods = d->hasRevisionedMethods();
|
||||||
@ -1181,8 +1188,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
break;
|
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) {
|
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->revision = QMetaObjectPrivate::OutputRevision;
|
||||||
pmeta->flags = d->flags;
|
pmeta->flags = d->flags;
|
||||||
pmeta->className = 0; // Class name is always the first string.
|
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();
|
dataIndex += 5 * d->methods.size();
|
||||||
if (hasRevisionedMethods)
|
if (hasRevisionedMethods)
|
||||||
dataIndex += d->methods.size();
|
dataIndex += d->methods.size();
|
||||||
|
paramsIndex = dataIndex;
|
||||||
|
dataIndex += methodParametersDataSize;
|
||||||
|
|
||||||
pmeta->propertyCount = d->properties.size();
|
pmeta->propertyCount = d->properties.size();
|
||||||
pmeta->propertyData = dataIndex;
|
pmeta->propertyData = dataIndex;
|
||||||
@ -1218,6 +1232,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
dataIndex += 5 * d->methods.size();
|
dataIndex += 5 * d->methods.size();
|
||||||
if (hasRevisionedMethods)
|
if (hasRevisionedMethods)
|
||||||
dataIndex += d->methods.size();
|
dataIndex += d->methods.size();
|
||||||
|
paramsIndex = dataIndex;
|
||||||
|
dataIndex += methodParametersDataSize;
|
||||||
dataIndex += 3 * d->properties.size();
|
dataIndex += 3 * d->properties.size();
|
||||||
if (hasNotifySignals)
|
if (hasNotifySignals)
|
||||||
dataIndex += d->properties.size();
|
dataIndex += d->properties.size();
|
||||||
@ -1240,13 +1256,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
// Find the start of the data and string tables.
|
// Find the start of the data and string tables.
|
||||||
int *data = reinterpret_cast<int *>(pmeta);
|
int *data = reinterpret_cast<int *>(pmeta);
|
||||||
size += dataIndex * sizeof(int);
|
size += dataIndex * sizeof(int);
|
||||||
|
ALIGN(size, void *);
|
||||||
char *str = reinterpret_cast<char *>(buf + size);
|
char *str = reinterpret_cast<char *>(buf + size);
|
||||||
if (buf) {
|
if (buf) {
|
||||||
if (relocatable) {
|
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);
|
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
||||||
} else {
|
} else {
|
||||||
meta->d.stringdata = str;
|
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
|
||||||
meta->d.data = reinterpret_cast<uint *>(data);
|
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.
|
// Reset the current data position to just past the QMetaObjectPrivate.
|
||||||
dataIndex = MetaObjectPrivateFieldCount;
|
dataIndex = MetaObjectPrivateFieldCount;
|
||||||
|
|
||||||
MetaStringTable strings;
|
QMetaStringTable strings;
|
||||||
strings.enter(d->className);
|
strings.enter(d->className);
|
||||||
|
|
||||||
// Output the class infos,
|
// Output the class infos,
|
||||||
@ -1273,24 +1290,21 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
|
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
|
||||||
for (index = 0; index < d->methods.size(); ++index) {
|
for (index = 0; index < d->methods.size(); ++index) {
|
||||||
QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
||||||
int sig = strings.enter(method->signature);
|
int name = strings.enter(method->name());
|
||||||
int params;
|
int argc = method->parameterCount();
|
||||||
QByteArray names = buildParameterNames
|
|
||||||
(method->signature, method->parameterNames);
|
|
||||||
params = strings.enter(names);
|
|
||||||
int ret = strings.enter(method->returnType);
|
|
||||||
int tag = strings.enter(method->tag);
|
int tag = strings.enter(method->tag);
|
||||||
int attrs = method->attributes;
|
int attrs = method->attributes;
|
||||||
if (buf) {
|
if (buf) {
|
||||||
data[dataIndex] = sig;
|
data[dataIndex] = name;
|
||||||
data[dataIndex + 1] = params;
|
data[dataIndex + 1] = argc;
|
||||||
data[dataIndex + 2] = ret;
|
data[dataIndex + 2] = paramsIndex;
|
||||||
data[dataIndex + 3] = tag;
|
data[dataIndex + 3] = tag;
|
||||||
data[dataIndex + 4] = attrs;
|
data[dataIndex + 4] = attrs;
|
||||||
if (method->methodType() == QMetaMethod::Signal)
|
if (method->methodType() == QMetaMethod::Signal)
|
||||||
pmeta->signalCount++;
|
pmeta->signalCount++;
|
||||||
}
|
}
|
||||||
dataIndex += 5;
|
dataIndex += 5;
|
||||||
|
paramsIndex += 1 + argc * 2;
|
||||||
}
|
}
|
||||||
if (hasRevisionedMethods) {
|
if (hasRevisionedMethods) {
|
||||||
for (index = 0; index < d->methods.size(); ++index) {
|
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.
|
// Output the properties in the class.
|
||||||
Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
|
Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
|
||||||
for (index = 0; index < d->properties.size(); ++index) {
|
for (index = 0; index < d->properties.size(); ++index) {
|
||||||
QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
||||||
int name = strings.enter(prop->name);
|
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;
|
int flags = prop->flags;
|
||||||
|
|
||||||
if (!isVariantType(prop->type)) {
|
if (!isBuiltinType(prop->type))
|
||||||
flags |= EnumOrFlag;
|
flags |= EnumOrFlag;
|
||||||
} else {
|
|
||||||
flags |= qvariant_nameToType(prop->type) << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
data[dataIndex] = name;
|
data[dataIndex] = name;
|
||||||
data[dataIndex + 1] = type;
|
data[dataIndex + 1] = typeInfo;
|
||||||
data[dataIndex + 2] = flags;
|
data[dataIndex + 2] = flags;
|
||||||
}
|
}
|
||||||
dataIndex += 3;
|
dataIndex += 3;
|
||||||
@ -1372,34 +1422,25 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
|
Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
|
||||||
for (index = 0; index < d->constructors.size(); ++index) {
|
for (index = 0; index < d->constructors.size(); ++index) {
|
||||||
QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
||||||
int sig = strings.enter(method->signature);
|
int name = strings.enter(method->name());
|
||||||
int params;
|
int argc = method->parameterCount();
|
||||||
QByteArray names = buildParameterNames
|
|
||||||
(method->signature, method->parameterNames);
|
|
||||||
params = strings.enter(names);
|
|
||||||
int ret = strings.enter(method->returnType);
|
|
||||||
int tag = strings.enter(method->tag);
|
int tag = strings.enter(method->tag);
|
||||||
int attrs = method->attributes;
|
int attrs = method->attributes;
|
||||||
if (buf) {
|
if (buf) {
|
||||||
data[dataIndex] = sig;
|
data[dataIndex] = name;
|
||||||
data[dataIndex + 1] = params;
|
data[dataIndex + 1] = argc;
|
||||||
data[dataIndex + 2] = ret;
|
data[dataIndex + 2] = paramsIndex;
|
||||||
data[dataIndex + 3] = tag;
|
data[dataIndex + 3] = tag;
|
||||||
data[dataIndex + 4] = attrs;
|
data[dataIndex + 4] = attrs;
|
||||||
}
|
}
|
||||||
dataIndex += 5;
|
dataIndex += 5;
|
||||||
|
paramsIndex += 1 + argc * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += strings.arraySize();
|
size += strings.blobSize();
|
||||||
|
|
||||||
if (buf) {
|
if (buf)
|
||||||
// Write strings to string data array.
|
strings.writeBlob(str);
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output the zero terminator in the data array.
|
// Output the zero terminator in the data array.
|
||||||
if (buf)
|
if (buf)
|
||||||
@ -1508,7 +1549,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
|||||||
quintptr dataOffset = (quintptr)dataMo->d.data;
|
quintptr dataOffset = (quintptr)dataMo->d.data;
|
||||||
|
|
||||||
output->d.superdata = superclass;
|
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.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
||||||
output->d.extradata = 0;
|
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
|
is empty, then the method's return type is \c{void}. The \a value
|
||||||
will be normalized before it is added to the method.
|
will be normalized before it is added to the method.
|
||||||
|
|
||||||
\sa returnType(), signature()
|
\sa returnType(), parameterTypes(), signature()
|
||||||
*/
|
*/
|
||||||
void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
||||||
{
|
{
|
||||||
@ -1905,6 +1946,20 @@ void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
|||||||
d->returnType = QMetaObject::normalizedType(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.
|
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