summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io
diff options
context:
space:
mode:
authorHolger Ihrig <holger.ihrig@nokia.com>2011-08-24 12:53:32 +0200
committerHolger Ihrig <holger.ihrig@nokia.com>2011-08-31 10:08:38 +0200
commit012ba8c0e5270f962dbc891039c32f49d31c565b (patch)
tree499a88b02862551708eb0f2c0f366afa8b998054 /tests/auto/corelib/io
parenta7d682dd9c9271d137d5aa73a9192a812492a596 (diff)
Moving relevant tests to corelib/io
Marked Test for qdiriterator as insignificant. See QTBUG-21160 Marked Test for qresourceengine as insignificant. See QTBUG-21159 Task-number: QTBUG-21066 Change-Id: I72848a651ff3e7aff1d6105dd49124e4ed070a44 Reviewed-on: http://codereview.qt.nokia.com/3577 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com> Reviewed-by: Jason McDonald <jason.mcdonald@nokia.com>
Diffstat (limited to 'tests/auto/corelib/io')
-rw-r--r--tests/auto/corelib/io/io.pro23
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro6
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc5
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/resources/file.txt1
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp794
-rw-r--r--tests/auto/corelib/io/qbuffer/.gitignore1
-rw-r--r--tests/auto/corelib/io/qbuffer/qbuffer.pro4
-rw-r--r--tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp608
-rw-r--r--tests/auto/corelib/io/qdatastream/.gitignore2
-rw-r--r--tests/auto/corelib/io/qdatastream/datastream.q42bin0 -> 668 bytes
-rw-r--r--tests/auto/corelib/io/qdatastream/qdatastream.pro20
-rw-r--r--tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp3232
-rw-r--r--tests/auto/corelib/io/qdebug/.gitignore1
-rw-r--r--tests/auto/corelib/io/qdebug/qdebug.pro4
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp158
-rw-r--r--tests/auto/corelib/io/qdir/.gitignore1
-rw-r--r--tests/auto/corelib/io/qdir/entrylist/directory/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/entrylist/file0
-rw-r--r--tests/auto/corelib/io/qdir/qdir.pro24
-rw-r--r--tests/auto/corelib/io/qdir/qdir.qrc5
-rw-r--r--tests/auto/corelib/io/qdir/resources/entryList/file1.data0
-rw-r--r--tests/auto/corelib/io/qdir/resources/entryList/file2.data0
-rw-r--r--tests/auto/corelib/io/qdir/resources/entryList/file3.data0
-rw-r--r--tests/auto/corelib/io/qdir/resources/entryList/file4.nothing0
-rw-r--r--tests/auto/corelib/io/qdir/searchdir/subdir1/picker.png1
-rw-r--r--tests/auto/corelib/io/qdir/searchdir/subdir2/picker.png1
-rw-r--r--tests/auto/corelib/io/qdir/testData/empty1
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/qdir.pro2
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp42
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/tmp/empty0
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp42
-rw-r--r--tests/auto/corelib/io/qdir/testdir/spaces/foo. bar0
-rw-r--r--tests/auto/corelib/io/qdir/testdir/spaces/foo.bar0
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp1952
-rw-r--r--tests/auto/corelib/io/qdir/types/a0
-rw-r--r--tests/auto/corelib/io/qdir/types/a.a1
-rw-r--r--tests/auto/corelib/io/qdir/types/a.b1
-rw-r--r--tests/auto/corelib/io/qdir/types/a.c1
-rw-r--r--tests/auto/corelib/io/qdir/types/b0
-rw-r--r--tests/auto/corelib/io/qdir/types/b.a1
-rw-r--r--tests/auto/corelib/io/qdir/types/b.b1
-rw-r--r--tests/auto/corelib/io/qdir/types/b.c1
-rw-r--r--tests/auto/corelib/io/qdir/types/c0
-rw-r--r--tests/auto/corelib/io/qdir/types/c.a1
-rw-r--r--tests/auto/corelib/io/qdir/types/c.b1
-rw-r--r--tests/auto/corelib/io/qdir/types/c.c1
-rw-r--r--tests/auto/corelib/io/qdir/types/d.a/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/d.b/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/d.c/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/d/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/e.a/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/e.b/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/e.c/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/e/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/f.a/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/f.b/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/f.c/dummy0
-rw-r--r--tests/auto/corelib/io/qdir/types/f/dummy0
-rw-r--r--tests/auto/corelib/io/qdiriterator/.gitignore1
-rw-r--r--tests/auto/corelib/io/qdiriterator/entrylist/directory/dummy0
-rw-r--r--tests/auto/corelib/io/qdiriterator/entrylist/file0
-rw-r--r--tests/auto/corelib/io/qdiriterator/qdiriterator.pro9
-rw-r--r--tests/auto/corelib/io/qdiriterator/qdiriterator.qrc6
-rw-r--r--tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp639
-rw-r--r--tests/auto/corelib/io/qfile/.gitattributes2
-rw-r--r--tests/auto/corelib/io/qfile/.gitignore8
-rw-r--r--tests/auto/corelib/io/qfile/copy-fallback.qrc5
-rw-r--r--tests/auto/corelib/io/qfile/dosfile.txt14
-rw-r--r--tests/auto/corelib/io/qfile/forCopying.txt1
-rw-r--r--tests/auto/corelib/io/qfile/forRenaming.txt7
-rw-r--r--tests/auto/corelib/io/qfile/largefile/largefile.pro8
-rw-r--r--tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp538
-rw-r--r--tests/auto/corelib/io/qfile/noendofline.txt3
-rw-r--r--tests/auto/corelib/io/qfile/qfile.pro10
-rw-r--r--tests/auto/corelib/io/qfile/qfile.qrc5
-rw-r--r--tests/auto/corelib/io/qfile/rename-fallback.qrc5
-rw-r--r--tests/auto/corelib/io/qfile/resources/file1.ext11
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/main.cpp72
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro6
-rw-r--r--tests/auto/corelib/io/qfile/test/test.pro44
-rw-r--r--tests/auto/corelib/io/qfile/testfile.txt6
-rw-r--r--tests/auto/corelib/io/qfile/testlog.txt144
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp3406
-rw-r--r--tests/auto/corelib/io/qfile/two.dots.file1
-rw-r--r--tests/auto/corelib/io/qfileinfo/.gitignore1
-rw-r--r--tests/auto/corelib/io/qfileinfo/qfileinfo.pro33
-rw-r--r--tests/auto/corelib/io/qfileinfo/qfileinfo.qrc5
-rw-r--r--tests/auto/corelib/io/qfileinfo/resources/file10
-rw-r--r--tests/auto/corelib/io/qfileinfo/resources/file1.ext10
-rw-r--r--tests/auto/corelib/io/qfileinfo/resources/file1.ext1.ext20
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp1803
-rw-r--r--tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro8
-rw-r--r--tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp387
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/.gitignore1
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro6
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp574
-rw-r--r--tests/auto/corelib/io/qiodevice/.gitignore2
-rw-r--r--tests/auto/corelib/io/qiodevice/qiodevice.pro23
-rw-r--r--tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp611
-rw-r--r--tests/auto/corelib/io/qprocess/.gitignore22
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro10
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp59
-rw-r--r--tests/auto/corelib/io/qprocess/qprocess.pro32
-rw-r--r--tests/auto/corelib/io/qprocess/test/test.pro124
-rwxr-xr-xtests/auto/corelib/io/qprocess/testBatFiles/simple.bat2
-rwxr-xr-xtests/auto/corelib/io/qprocess/testBatFiles/with space.bat2
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/main.cpp84
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/testDetached.pro10
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/main.cpp48
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp59
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp53
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp52
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro10
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp58
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp59
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp58
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro10
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp61
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp67
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp61
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro12
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessLoopback/main.cpp57
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp46
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp66
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp69
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro11
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro12
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp51
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro7
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp62
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp58
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro16
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp56
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro13
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp2472
-rw-r--r--tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro6
-rw-r--r--tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp320
-rw-r--r--tests/auto/corelib/io/qresourceengine/.gitattributes1
-rw-r--r--tests/auto/corelib/io/qresourceengine/.gitignore1
-rw-r--r--tests/auto/corelib/io/qresourceengine/parentdir.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/qresourceengine.pro47
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/compressme.txt322
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/search_file.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/searchpath1/search_file.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/searchpath2/search_file.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test.qrc30
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test/german.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp488
-rw-r--r--tests/auto/corelib/io/qsettings/.gitattributes5
-rw-r--r--tests/auto/corelib/io/qsettings/.gitignore1
-rw-r--r--tests/auto/corelib/io/qsettings/qsettings.pro10
-rw-r--r--tests/auto/corelib/io/qsettings/qsettings.qrc9
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile.ini46
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile2.ini46
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile3.ini50
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile4.ini2
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile5.ini2
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp3179
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/.gitignore1
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro14
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp729
-rw-r--r--tests/auto/corelib/io/qtextstream/.gitattributes3
-rw-r--r--tests/auto/corelib/io/qtextstream/.gitignore11
-rw-r--r--tests/auto/corelib/io/qtextstream/qtextstream.pro6
-rw-r--r--tests/auto/corelib/io/qtextstream/qtextstream.qrc6
-rw-r--r--tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp50
-rw-r--r--tests/auto/corelib/io/qtextstream/readAllStdinProcess/readAllStdinProcess.pro7
-rw-r--r--tests/auto/corelib/io/qtextstream/readLineStdinProcess/main.cpp57
-rw-r--r--tests/auto/corelib/io/qtextstream/readLineStdinProcess/readLineStdinProcess.pro7
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_2.databin0 -> 6 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_3.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_4.databin0 -> 116 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_0.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_1.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_2.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_3.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_4.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_2.databin0 -> 6 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_3.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_4.databin0 -> 116 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_0.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_1.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_2.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_3.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_4.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_1.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_2.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_3.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_4.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_5.databin0 -> 32 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_6.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.databin0 -> 36 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_5.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_6.databin0 -> 36 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_5.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_6.databin0 -> 36 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_1.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_2.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_3.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_4.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_4.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_5.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_6.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_7.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_8.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_8.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_8.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_5.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_6.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_7.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_8.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_8.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_8.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_2.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_1.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_1.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_4.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_4.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource10.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource11.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource12.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource20.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource21.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource9.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_2.databin0 -> 6 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_3.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_4.databin0 -> 116 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_0.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_1.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_2.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_3.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_4.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_2.databin0 -> 6 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_3.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_4.databin0 -> 116 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_0.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_1.data0
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_3.data2
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_2.databin0 -> 8 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_3.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_4.databin0 -> 118 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_0.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_1.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_2.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_3.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_4.databin0 -> 2 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_0.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_1.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_2.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_3.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_4.databin0 -> 4 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_1.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_2.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_3.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_4.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_5.databin0 -> 32 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_6.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.databin0 -> 36 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_5.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_6.databin0 -> 36 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_5.databin0 -> 34 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_6.databin0 -> 36 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_1.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_2.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_3.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_4.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_1.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_2.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_3.databin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_4.databin0 -> 30 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_4.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_5.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_6.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_7.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_8.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_8.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_8.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_5.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_6.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_7.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_8.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_8.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_5.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_6.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_7.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_8.databin0 -> 26 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_2.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_1.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_1.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_4.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_4.databin0 -> 22 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_4.databin0 -> 24 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_0.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_1.databin0 -> 14 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_2.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_3.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_4.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_0.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_1.databin0 -> 16 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_2.databin0 -> 18 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_3.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_4.databin0 -> 20 bytes
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource0.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource1.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource10.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource11.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource12.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource2.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource20.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource21.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource3.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource4.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource5.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource6.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource7.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource8.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource9.data1
-rw-r--r--tests/auto/corelib/io/qtextstream/rfc3261.txt15067
-rw-r--r--tests/auto/corelib/io/qtextstream/shift-jis.txt764
-rw-r--r--tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp55
-rw-r--r--tests/auto/corelib/io/qtextstream/stdinProcess/stdinProcess.pro7
-rw-r--r--tests/auto/corelib/io/qtextstream/task113817.txt1095
-rw-r--r--tests/auto/corelib/io/qtextstream/test/test.pro40
-rw-r--r--tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp2919
-rw-r--r--tests/auto/corelib/io/qurl/.gitignore1
-rw-r--r--tests/auto/corelib/io/qurl/idna-test.c199
-rw-r--r--tests/auto/corelib/io/qurl/qurl.pro5
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp4049
1211 files changed, 49505 insertions, 0 deletions
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
new file mode 100644
index 0000000000..cbe2b609b9
--- /dev/null
+++ b/tests/auto/corelib/io/io.pro
@@ -0,0 +1,23 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qabstractfileengine \
+ qbuffer \
+ qdatastream \
+ qdebug \
+ qdir \
+ qdiriterator \
+ qfile \
+ qfileinfo \
+ qfilesystementry \
+ qfilesystemwatcher \
+ qiodevice \
+ qprocess \
+ qprocessenvironment \
+ qresourceengine \
+ qsettings \
+ qtemporaryfile \
+ qtextstream \
+ qurl \
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qfileinfo
diff --git a/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro b/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro
new file mode 100644
index 0000000000..870473a4cb
--- /dev/null
+++ b/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+QT = core
+
+SOURCES = tst_qabstractfileengine.cpp
+RESOURCES += qabstractfileengine.qrc
+
diff --git a/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc b/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc
new file mode 100644
index 0000000000..5401b086b2
--- /dev/null
+++ b/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/tst_qabstractfileengine/">
+ <file>resources/</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qabstractfileengine/resources/file.txt b/tests/auto/corelib/io/qabstractfileengine/resources/file.txt
new file mode 100644
index 0000000000..8a03e0e55f
--- /dev/null
+++ b/tests/auto/corelib/io/qabstractfileengine/resources/file.txt
@@ -0,0 +1 @@
+This is a simple text file.
diff --git a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
new file mode 100644
index 0000000000..a81633341d
--- /dev/null
+++ b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
@@ -0,0 +1,794 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the FOO 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 <QtCore/QAbstractFileEngine>
+#include <QtCore/QFSFileEngine>
+
+#include <QtCore/QMutex>
+#include <QtCore/QMutexLocker>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QHash>
+
+#include <QtTest/QTest>
+
+#include <QtCore/QDebug>
+
+class tst_QAbstractFileEngine
+ : public QObject
+{
+ Q_OBJECT
+public slots:
+ void cleanupTestCase();
+
+private slots:
+ void customHandler();
+
+ void fileIO_data();
+ void fileIO();
+
+private:
+ QStringList filesForRemoval;
+};
+
+class ReferenceFileEngine
+ : public QAbstractFileEngine
+{
+public:
+ ReferenceFileEngine(const QString &fileName)
+ : fileName_(fileName)
+ , position_(-1)
+ , openForRead_(false)
+ , openForWrite_(false)
+ {
+ }
+
+ bool open(QIODevice::OpenMode openMode)
+ {
+ if (openForRead_ || openForWrite_) {
+ qWarning("%s: file is already open for %s",
+ Q_FUNC_INFO,
+ (openForRead_ ? "reading" : "writing"));
+ return false;
+ }
+
+ openFile_ = resolveFile(openMode & QIODevice::WriteOnly);
+ if (!openFile_)
+ return false;
+
+ position_ = 0;
+ if (openMode & QIODevice::ReadOnly)
+ openForRead_ = true;
+
+ if (openMode & QIODevice::WriteOnly) {
+ openForWrite_ = true;
+
+ QMutexLocker lock(&openFile_->mutex);
+ if (openMode & QIODevice::Truncate
+ || !(openForRead_ || openMode & QIODevice::Append))
+ openFile_->content.clear();
+
+ if (openMode & QIODevice::Append)
+ position_ = openFile_->content.size();
+ }
+
+ return true;
+ }
+
+ bool close()
+ {
+ openFile_.clear();
+
+ openForRead_ = false;
+ openForWrite_ = false;
+ position_ = -1;
+
+ return true;
+ }
+
+ qint64 size() const
+ {
+ QSharedPointer<File> file = resolveFile(false);
+ if (!file)
+ return 0;
+
+ QMutexLocker lock(&file->mutex);
+ return file->content.size();
+ }
+
+ qint64 pos() const
+ {
+ if (!openForRead_ && !openForWrite_) {
+ qWarning("%s: file is not open", Q_FUNC_INFO);
+ return -1;
+ }
+ return position_;
+ }
+
+ bool seek(qint64 pos)
+ {
+ if (!openForRead_ && !openForWrite_) {
+ qWarning("%s: file is not open", Q_FUNC_INFO);
+ return false;
+ }
+
+ if (pos >= 0) {
+ position_ = pos;
+ return true;
+ }
+
+ return false;
+ }
+
+ bool flush()
+ {
+ if (!openForRead_ && !openForWrite_) {
+ qWarning("%s: file is not open", Q_FUNC_INFO);
+ return false;
+ }
+
+ return true;
+ }
+
+ bool remove()
+ {
+ QMutexLocker lock(&fileSystemMutex);
+ int count = fileSystem.remove(fileName_);
+
+ return (count == 1);
+ }
+
+ bool copy(const QString &newName)
+ {
+ QMutexLocker lock(&fileSystemMutex);
+ if (!fileSystem.contains(fileName_)
+ || fileSystem.contains(newName))
+ return false;
+
+ fileSystem.insert(newName, fileSystem.value(fileName_));
+ return true;
+ }
+
+ bool rename(const QString &newName)
+ {
+ QMutexLocker lock(&fileSystemMutex);
+ if (!fileSystem.contains(fileName_)
+ || fileSystem.contains(newName))
+ return false;
+
+ fileSystem.insert(newName, fileSystem.take(fileName_));
+ return true;
+ }
+
+ // bool link(const QString &newName)
+ // {
+ // Q_UNUSED(newName)
+ // return false;
+ // }
+
+ // bool mkdir(const QString &dirName, bool createParentDirectories) const
+ // {
+ // Q_UNUSED(dirName)
+ // Q_UNUSED(createParentDirectories)
+
+ // return false;
+ // }
+
+ // bool rmdir(const QString &dirName, bool recurseParentDirectories) const
+ // {
+ // Q_UNUSED(dirName)
+ // Q_UNUSED(recurseParentDirectories)
+
+ // return false;
+ // }
+
+ bool setSize(qint64 size)
+ {
+ if (size < 0)
+ return false;
+
+ QSharedPointer<File> file = resolveFile(false);
+ if (!file)
+ return false;
+
+ QMutexLocker lock(&file->mutex);
+ file->content.resize(size);
+
+ if (openForRead_ || openForWrite_)
+ if (position_ > size)
+ position_ = size;
+
+ return (file->content.size() == size);
+ }
+
+ FileFlags fileFlags(FileFlags type) const
+ {
+ QSharedPointer<File> file = resolveFile(false);
+ if (file) {
+ QMutexLocker lock(&file->mutex);
+ return (file->fileFlags & type);
+ }
+
+ return FileFlags();
+ }
+
+ // bool setPermissions(uint perms)
+ // {
+ // Q_UNUSED(perms)
+
+ // return false;
+ // }
+
+ QString fileName(FileName file) const
+ {
+ switch (file) {
+ case DefaultName:
+ return QLatin1String("DefaultName");
+ case BaseName:
+ return QLatin1String("BaseName");
+ case PathName:
+ return QLatin1String("PathName");
+ case AbsoluteName:
+ return QLatin1String("AbsoluteName");
+ case AbsolutePathName:
+ return QLatin1String("AbsolutePathName");
+ case LinkName:
+ return QLatin1String("LinkName");
+ case CanonicalName:
+ return QLatin1String("CanonicalName");
+ case CanonicalPathName:
+ return QLatin1String("CanonicalPathName");
+ case BundleName:
+ return QLatin1String("BundleName");
+
+ default:
+ break;
+ }
+
+ return QString();
+ }
+
+ uint ownerId(FileOwner owner) const
+ {
+ QSharedPointer<File> file = resolveFile(false);
+ if (file) {
+ switch (owner) {
+ case OwnerUser:
+ {
+ QMutexLocker lock(&file->mutex);
+ return file->userId;
+ }
+ case OwnerGroup:
+ {
+ QMutexLocker lock(&file->mutex);
+ return file->groupId;
+ }
+ }
+ }
+
+ return -2;
+ }
+
+ QString owner(FileOwner owner) const
+ {
+ QSharedPointer<File> file = resolveFile(false);
+ if (file) {
+ uint ownerId;
+ switch (owner) {
+ case OwnerUser:
+ {
+ QMutexLocker lock(&file->mutex);
+ ownerId = file->userId;
+ }
+
+ {
+ QMutexLocker lock(&fileSystemMutex);
+ return fileSystemUsers.value(ownerId);
+ }
+
+ case OwnerGroup:
+ {
+ QMutexLocker lock(&file->mutex);
+ ownerId = file->groupId;
+ }
+
+ {
+ QMutexLocker lock(&fileSystemMutex);
+ return fileSystemGroups.value(ownerId);
+ }
+ }
+ }
+
+ return QString();
+ }
+
+ QDateTime fileTime(FileTime time) const
+ {
+ QSharedPointer<File> file = resolveFile(false);
+ if (file) {
+ QMutexLocker lock(&file->mutex);
+ switch (time) {
+ case CreationTime:
+ return file->creation;
+ case ModificationTime:
+ return file->modification;
+ case AccessTime:
+ return file->access;
+ }
+ }
+
+ return QDateTime();
+ }
+
+ void setFileName(const QString &file)
+ {
+ if (openForRead_ || openForWrite_)
+ qWarning("%s: Can't set file name while file is open", Q_FUNC_INFO);
+ else
+ fileName_ = file;
+ }
+
+ // typedef QAbstractFileEngineIterator Iterator;
+ // Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames)
+ // {
+ // Q_UNUSED(filters)
+ // Q_UNUSED(filterNames)
+
+ // return 0;
+ // }
+
+ // Iterator *endEntryList()
+ // {
+ // return 0;
+ // }
+
+ qint64 read(char *data, qint64 maxLen)
+ {
+ if (!openForRead_) {
+ qWarning("%s: file must be open for reading", Q_FUNC_INFO);
+ return -1;
+ }
+
+ if (openFile_.isNull()) {
+ qWarning("%s: file must not be null", Q_FUNC_INFO);
+ return -1;
+ }
+
+ QMutexLocker lock(&openFile_->mutex);
+ qint64 readSize = qMin(openFile_->content.size() - position_, maxLen);
+ if (readSize < 0)
+ return -1;
+
+ qMemCopy(data, openFile_->content.constData() + position_, readSize);
+ position_ += readSize;
+
+ return readSize;
+ }
+
+ qint64 write(const char *data, qint64 length)
+ {
+ if (!openForWrite_) {
+ qWarning("%s: file must be open for writing", Q_FUNC_INFO);
+ return -1;
+ }
+
+ if (openFile_.isNull()) {
+ qWarning("%s: file must not be null", Q_FUNC_INFO);
+ return -1;
+ }
+
+ if (length < 0)
+ return -1;
+
+ QMutexLocker lock(&openFile_->mutex);
+ if (openFile_->content.size() == position_)
+ openFile_->content.append(data, length);
+ else {
+ if (position_ + length > openFile_->content.size())
+ openFile_->content.resize(position_ + length);
+ openFile_->content.replace(position_, length, data, length);
+ }
+
+ qint64 writeSize = qMin(length, openFile_->content.size() - position_);
+ position_ += writeSize;
+
+ return writeSize;
+ }
+
+protected:
+ // void setError(QFile::FileError error, const QString &str);
+
+ struct File
+ {
+ File()
+ : userId(0)
+ , groupId(0)
+ , fileFlags(
+ ReadOwnerPerm | WriteOwnerPerm | ExeOwnerPerm
+ | ReadUserPerm | WriteUserPerm | ExeUserPerm
+ | ReadGroupPerm | WriteGroupPerm | ExeGroupPerm
+ | ReadOtherPerm | WriteOtherPerm | ExeOtherPerm
+ | FileType | ExistsFlag)
+ {
+ }
+
+ QMutex mutex;
+
+ uint userId, groupId;
+ QAbstractFileEngine::FileFlags fileFlags;
+ QDateTime creation, modification, access;
+
+ QByteArray content;
+ };
+
+ QSharedPointer<File> resolveFile(bool create) const
+ {
+ if (openForRead_ || openForWrite_) {
+ if (!openFile_)
+ qWarning("%s: file should not be null", Q_FUNC_INFO);
+ return openFile_;
+ }
+
+ QMutexLocker lock(&fileSystemMutex);
+ if (create) {
+ QSharedPointer<File> &p = fileSystem[fileName_];
+ if (p.isNull())
+ p = QSharedPointer<File>(new File);
+ return p;
+ }
+
+ return fileSystem.value(fileName_);
+ }
+
+ static QMutex fileSystemMutex;
+ static QHash<uint, QString> fileSystemUsers, fileSystemGroups;
+ static QHash<QString, QSharedPointer<File> > fileSystem;
+
+private:
+ QString fileName_;
+ qint64 position_;
+ bool openForRead_;
+ bool openForWrite_;
+
+ mutable QSharedPointer<File> openFile_;
+};
+
+QMutex ReferenceFileEngine::fileSystemMutex;
+QHash<uint, QString> ReferenceFileEngine::fileSystemUsers, ReferenceFileEngine::fileSystemGroups;
+QHash<QString, QSharedPointer<ReferenceFileEngine::File> > ReferenceFileEngine::fileSystem;
+
+class FileEngineHandler
+ : QAbstractFileEngineHandler
+{
+ QAbstractFileEngine *create(const QString &fileName) const
+ {
+ if (fileName.startsWith("QFSFileEngine:"))
+ return new QFSFileEngine(fileName.mid(14));
+ if (fileName.startsWith("reference-file-engine:"))
+ return new ReferenceFileEngine(fileName.mid(22));
+ if (fileName.startsWith("resource:"))
+ return QAbstractFileEngine::create(QLatin1String(":/tst_qabstractfileengine/resources/") + fileName.mid(9));
+ return 0;
+ }
+};
+
+void tst_QAbstractFileEngine::cleanupTestCase()
+{
+ bool failed = false;
+
+ FileEngineHandler handler;
+ Q_FOREACH(QString file, filesForRemoval)
+ if (!QFile::remove(file)
+ || QFile::exists(file)) {
+ failed = true;
+ qDebug() << "Couldn't remove file:" << file;
+ }
+
+ QVERIFY(!failed);
+}
+
+void tst_QAbstractFileEngine::customHandler()
+{
+ QScopedPointer<QAbstractFileEngine> file;
+ {
+ file.reset(QAbstractFileEngine::create("resource:file.txt"));
+
+ QVERIFY(file);
+ }
+
+ {
+ FileEngineHandler handler;
+
+ QFile file("resource:file.txt");
+ QVERIFY(file.exists());
+ }
+
+ {
+ QFile file("resource:file.txt");
+ QVERIFY(!file.exists());
+ }
+}
+
+void tst_QAbstractFileEngine::fileIO_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QByteArray>("readContent");
+ QTest::addColumn<QByteArray>("writeContent");
+ QTest::addColumn<bool>("fileExists");
+
+ QString resourceTxtFile(":/tst_qabstractfileengine/resources/file.txt");
+ QByteArray readContent("This is a simple text file.\n");
+ QByteArray writeContent("This contains two lines of text.\n");
+
+ QTest::newRow("resource") << resourceTxtFile << readContent << QByteArray() << true;
+ QTest::newRow("native") << "native-file.txt" << readContent << writeContent << false;
+ QTest::newRow("Forced QFSFileEngine") << "QFSFileEngine:QFSFileEngine-file.txt" << readContent << writeContent << false;
+ QTest::newRow("Custom FE") << "reference-file-engine:file.txt" << readContent << writeContent << false;
+
+ QTest::newRow("Forced QFSFileEngine (native)") << "QFSFileEngine:native-file.txt" << readContent << writeContent << true;
+ QTest::newRow("native (Forced QFSFileEngine)") << "QFSFileEngine-file.txt" << readContent << writeContent << true;
+ QTest::newRow("Custom FE (2)") << "reference-file-engine:file.txt" << readContent << writeContent << true;
+}
+
+void tst_QAbstractFileEngine::fileIO()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QByteArray, readContent);
+ QFETCH(QByteArray, writeContent);
+ QFETCH(bool, fileExists);
+
+ FileEngineHandler handler;
+
+
+ {
+ QFile file(fileName);
+ QCOMPARE(file.exists(), fileExists);
+
+ if (!fileExists) {
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered));
+ filesForRemoval.append(fileName);
+
+ QCOMPARE(file.write(readContent), qint64(readContent.size()));
+ }
+ }
+
+ //
+ // File content is: readContent
+ //
+
+ qint64 fileSize = readContent.size();
+ {
+ // Reading
+ QFile file(fileName);
+
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
+
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ QCOMPARE(file.pos(), qint64(0));
+
+ QCOMPARE(file.size(), fileSize);
+ QCOMPARE(file.readAll(), readContent);
+ QCOMPARE(file.pos(), fileSize);
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ }
+
+ if (writeContent.isEmpty())
+ return;
+
+ {
+ // Writing / appending
+ QFile file(fileName);
+
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered));
+
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ QCOMPARE(file.pos(), fileSize);
+
+ QCOMPARE(file.write(writeContent), qint64(writeContent.size()));
+
+ fileSize += writeContent.size();
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ }
+
+ //
+ // File content is: readContent + writeContent
+ //
+
+ {
+ // Reading and Writing
+ QFile file(fileName);
+
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered));
+
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ QCOMPARE(file.pos(), qint64(0));
+
+ QCOMPARE(file.readAll(), readContent + writeContent);
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ QVERIFY(file.seek(writeContent.size()));
+ QCOMPARE(file.pos(), qint64(writeContent.size()));
+ QCOMPARE(file.size(), fileSize);
+
+ QCOMPARE(file.write(readContent), qint64(readContent.size()));
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ QVERIFY(file.seek(0));
+ QCOMPARE(file.pos(), qint64(0));
+ QCOMPARE(file.size(), fileSize);
+
+ QCOMPARE(file.write(writeContent), qint64(writeContent.size()));
+ QCOMPARE(file.pos(), qint64(writeContent.size()));
+ QCOMPARE(file.size(), fileSize);
+
+ QVERIFY(file.seek(0));
+ QCOMPARE(file.read(writeContent.size()), writeContent);
+ QCOMPARE(file.pos(), qint64(writeContent.size()));
+ QCOMPARE(file.size(), fileSize);
+
+ QCOMPARE(file.readAll(), readContent);
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ }
+
+ //
+ // File content is: writeContent + readContent
+ //
+
+ {
+ // Writing
+ QFile file(fileName);
+
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered));
+
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ QCOMPARE(file.pos(), qint64(0));
+
+ QCOMPARE(file.write(writeContent), qint64(writeContent.size()));
+ QCOMPARE(file.pos(), qint64(writeContent.size()));
+ QCOMPARE(file.size(), fileSize);
+
+ QVERIFY(file.resize(writeContent.size()));
+ QCOMPARE(file.size(), qint64(writeContent.size()));
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.size(), qint64(writeContent.size()));
+
+ QVERIFY(file.resize(fileSize));
+ QCOMPARE(file.size(), fileSize);
+ }
+
+ //
+ // File content is: writeContent + <undefined>
+ // File size is : (readContent + writeContent).size()
+ //
+
+ {
+ // Writing / extending
+ QFile file(fileName);
+
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered));
+
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ QCOMPARE(file.pos(), qint64(0));
+
+ QVERIFY(file.seek(1024));
+ QCOMPARE(file.pos(), qint64(1024));
+ QCOMPARE(file.size(), fileSize);
+
+ fileSize = 1024 + writeContent.size();
+ QCOMPARE(file.write(writeContent), qint64(writeContent.size()));
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ QVERIFY(file.seek(1028));
+ QCOMPARE(file.pos(), qint64(1028));
+ QCOMPARE(file.size(), fileSize);
+
+ fileSize = 1028 + writeContent.size();
+ QCOMPARE(file.write(writeContent), qint64(writeContent.size()));
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ }
+
+ //
+ // File content is: writeContent + <undefined> + writeContent
+ // File size is : 1024 + writeContent.size()
+ //
+
+ {
+ // Writing / truncating
+ QFile file(fileName);
+
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered));
+
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.size(), qint64(0));
+ QCOMPARE(file.pos(), qint64(0));
+
+ fileSize = readContent.size();
+ QCOMPARE(file.write(readContent), fileSize);
+ QCOMPARE(file.pos(), fileSize);
+ QCOMPARE(file.size(), fileSize);
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.size(), fileSize);
+ }
+
+ //
+ // File content is: readContent
+ //
+}
+
+QTEST_APPLESS_MAIN(tst_QAbstractFileEngine)
+#include "tst_qabstractfileengine.moc"
+
diff --git a/tests/auto/corelib/io/qbuffer/.gitignore b/tests/auto/corelib/io/qbuffer/.gitignore
new file mode 100644
index 0000000000..40447ec0db
--- /dev/null
+++ b/tests/auto/corelib/io/qbuffer/.gitignore
@@ -0,0 +1 @@
+tst_qbuffer
diff --git a/tests/auto/corelib/io/qbuffer/qbuffer.pro b/tests/auto/corelib/io/qbuffer/qbuffer.pro
new file mode 100644
index 0000000000..b768eb82d8
--- /dev/null
+++ b/tests/auto/corelib/io/qbuffer/qbuffer.pro
@@ -0,0 +1,4 @@
+load(qttest_p4)
+SOURCES += tst_qbuffer.cpp
+QT = core
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
new file mode 100644
index 0000000000..bf4842ff94
--- /dev/null
+++ b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
@@ -0,0 +1,608 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+
+
+#include <QBuffer>
+#include <QByteArray>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QBuffer : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QBuffer();
+
+private slots:
+ void open();
+ void getSetCheck();
+ void readBlock();
+ void readBlockPastEnd();
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+ void isSequential();
+ void signalTest_data();
+ void signalTest();
+ void isClosedAfterClose();
+ void readLine_data();
+ void readLine();
+ void canReadLine_data();
+ void canReadLine();
+ void atEnd();
+ void readLineBoundaries();
+ void writeAfterQByteArrayResize();
+ void read_null();
+
+protected slots:
+ void readyReadSlot();
+ void bytesWrittenSlot(qint64 written);
+
+private:
+ qint64 totalBytesWritten;
+ bool gotReadyRead;
+};
+
+// Testing get/set functions
+void tst_QBuffer::getSetCheck()
+{
+ QBuffer obj1;
+ // const QByteArray & QBuffer::data()
+ // void QBuffer::setData(const QByteArray &)
+ QByteArray var1("Bogus data");
+ obj1.setData(var1);
+ QCOMPARE(var1, obj1.data());
+ obj1.setData(QByteArray());
+ QCOMPARE(QByteArray(), obj1.data());
+}
+
+tst_QBuffer::tst_QBuffer()
+{
+}
+
+void tst_QBuffer::open()
+{
+ QByteArray data(10, 'f');
+
+ QBuffer b;
+
+ QTest::ignoreMessage(QtWarningMsg, "QBuffer::open: Buffer access not specified");
+ QVERIFY(!b.open(QIODevice::NotOpen));
+ QVERIFY(!b.isOpen());
+ b.close();
+
+ QTest::ignoreMessage(QtWarningMsg, "QBuffer::open: Buffer access not specified");
+ QVERIFY(!b.open(QIODevice::Text));
+ QVERIFY(!b.isOpen());
+ b.close();
+
+ QTest::ignoreMessage(QtWarningMsg, "QBuffer::open: Buffer access not specified");
+ QVERIFY(!b.open(QIODevice::Unbuffered));
+ QVERIFY(!b.isOpen());
+ b.close();
+
+ QVERIFY(b.open(QIODevice::ReadOnly));
+ QVERIFY(b.isReadable());
+ b.close();
+
+ QVERIFY(b.open(QIODevice::WriteOnly));
+ QVERIFY(b.isWritable());
+ b.close();
+
+ b.setData(data);
+ QVERIFY(b.open(QIODevice::Append));
+ QVERIFY(b.isWritable());
+ QCOMPARE(b.size(), qint64(10));
+ QCOMPARE(b.pos(), b.size());
+ b.close();
+
+ b.setData(data);
+ QVERIFY(b.open(QIODevice::Truncate));
+ QVERIFY(b.isWritable());
+ QCOMPARE(b.size(), qint64(0));
+ QCOMPARE(b.pos(), qint64(0));
+ b.close();
+
+ QVERIFY(b.open(QIODevice::ReadWrite));
+ QVERIFY(b.isReadable());
+ QVERIFY(b.isWritable());
+ b.close();
+}
+
+// some status() tests, too
+void tst_QBuffer::readBlock()
+{
+// QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: File not open");
+// QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: Read operation not permitted");
+
+ const int arraySize = 10;
+ char a[arraySize];
+ QBuffer b;
+ QCOMPARE(b.read(a, arraySize), (qint64) -1); // not opened
+ QVERIFY(b.atEnd());
+
+ QByteArray ba;
+ ba.resize(arraySize);
+ b.setBuffer(&ba);
+ b.open(QIODevice::WriteOnly);
+ QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device");
+ QCOMPARE(b.read(a, arraySize), (qint64) -1); // no read access
+ b.close();
+
+ b.open(QIODevice::ReadOnly);
+ QCOMPARE(b.read(a, arraySize), (qint64) arraySize);
+ QVERIFY(b.atEnd());
+
+ // up to 3.0.x reading beyond the end was an error while ok
+ // this has been made consistent with other QIODevice sub classes in 3.1
+ QCOMPARE(b.read(a, 1), qint64(0));
+ QVERIFY(b.atEnd());
+
+ // read in two chunks
+ b.close();
+ b.open(QIODevice::ReadOnly);
+ QCOMPARE(b.read(a, arraySize/2), (qint64) arraySize/2);
+ QCOMPARE(b.read(a + arraySize/2, arraySize - arraySize/2),
+ (qint64)(arraySize - arraySize/2));
+ QVERIFY(b.atEnd());
+}
+
+void tst_QBuffer::readBlockPastEnd()
+{
+ QByteArray arr(4096 + 3616, 'd');
+ QBuffer buf(&arr);
+
+ buf.open(QIODevice::ReadOnly);
+ char dummy[4096];
+
+ buf.read(1);
+
+ QCOMPARE(buf.read(dummy, 4096), qint64(4096));
+ QCOMPARE(buf.read(dummy, 4096), qint64(3615));
+ QVERIFY(buf.atEnd());
+}
+
+void tst_QBuffer::writeBlock_data()
+{
+ QTest::addColumn<QString>("str");
+
+ QTest::newRow( "small_bytearray" ) << QString("Test");
+ QTest::newRow( "large_bytearray" ) << QString("The QBuffer class is an I/O device that operates on a QByteArray.\n"
+ "QBuffer is used to read and write to a memory buffer. It is normally "
+ "used with a QTextStream or a QDataStream. QBuffer has an associated "
+ "QByteArray which holds the buffer data. The size() of the buffer is "
+ "automatically adjusted as data is written.\n"
+ "The constructor QBuffer(QByteArray) creates a QBuffer using an existing "
+ "byte array. The byte array can also be set with setBuffer(). Writing to "
+ "the QBuffer will modify the original byte array because QByteArray is "
+ "explicitly shared.\n"
+ "Use open() to open the buffer before use and to set the mode (read-only, "
+ "write-only, etc.). close() closes the buffer. The buffer must be closed "
+ "before reopening or calling setBuffer().\n"
+ "A common way to use QBuffer is through QDataStream or QTextStream, which "
+ "have constructors that take a QBuffer parameter. For convenience, there "
+ "are also QDataStream and QTextStream constructors that take a QByteArray "
+ "parameter. These constructors create and open an internal QBuffer.\n"
+ "Note that QTextStream can also operate on a QString (a Unicode string); a "
+ "QBuffer cannot.\n"
+ "You can also use QBuffer directly through the standard QIODevice functions "
+ "readBlock(), writeBlock() readLine(), at(), getch(), putch() and ungetch().\n"
+ "See also QFile, QDataStream, QTextStream, QByteArray, Shared Classes, Collection "
+ "Classes and Input/Output and Networking.\n\n"
+ "The QBuffer class is an I/O device that operates on a QByteArray.\n"
+ "QBuffer is used to read and write to a memory buffer. It is normally "
+ "used with a QTextStream or a QDataStream. QBuffer has an associated "
+ "QByteArray which holds the buffer data. The size() of the buffer is "
+ "automatically adjusted as data is written.\n"
+ "The constructor QBuffer(QByteArray) creates a QBuffer using an existing "
+ "byte array. The byte array can also be set with setBuffer(). Writing to "
+ "the QBuffer will modify the original byte array because QByteArray is "
+ "explicitly shared.\n"
+ "Use open() to open the buffer before use and to set the mode (read-only, "
+ "write-only, etc.). close() closes the buffer. The buffer must be closed "
+ "before reopening or calling setBuffer().\n"
+ "A common way to use QBuffer is through QDataStream or QTextStream, which "
+ "have constructors that take a QBuffer parameter. For convenience, there "
+ "are also QDataStream and QTextStream constructors that take a QByteArray "
+ "parameter. These constructors create and open an internal QBuffer.\n"
+ "Note that QTextStream can also operate on a QString (a Unicode string); a "
+ "QBuffer cannot.\n"
+ "You can also use QBuffer directly through the standard QIODevice functions "
+ "readBlock(), writeBlock() readLine(), at(), getch(), putch() and ungetch().\n"
+ "See also QFile, QDataStream, QTextStream, QByteArray, Shared Classes, Collection "
+ "Classes and Input/Output and Networking.\n\n"
+ "The QBuffer class is an I/O device that operates on a QByteArray.\n"
+ "QBuffer is used to read and write to a memory buffer. It is normally "
+ "used with a QTextStream or a QDataStream. QBuffer has an associated "
+ "QByteArray which holds the buffer data. The size() of the buffer is "
+ "automatically adjusted as data is written.\n"
+ "The constructor QBuffer(QByteArray) creates a QBuffer using an existing "
+ "byte array. The byte array can also be set with setBuffer(). Writing to "
+ "the QBuffer will modify the original byte array because QByteArray is "
+ "explicitly shared.\n"
+ "Use open() to open the buffer before use and to set the mode (read-only, "
+ "write-only, etc.). close() closes the buffer. The buffer must be closed "
+ "before reopening or calling setBuffer().\n"
+ "A common way to use QBuffer is through QDataStream or QTextStream, which "
+ "have constructors that take a QBuffer parameter. For convenience, there "
+ "are also QDataStream and QTextStream constructors that take a QByteArray "
+ "parameter. These constructors create and open an internal QBuffer.\n"
+ "Note that QTextStream can also operate on a QString (a Unicode string); a "
+ "QBuffer cannot.\n"
+ "You can also use QBuffer directly through the standard QIODevice functions "
+ "readBlock(), writeBlock() readLine(), at(), getch(), putch() and ungetch().\n"
+ "See also QFile, QDataStream, QTextStream, QByteArray, Shared Classes, Collection "
+ "Classes and Input/Output and Networking.");
+}
+
+void tst_QBuffer::writeBlock()
+{
+ QFETCH( QString, str );
+
+ QByteArray ba;
+ QBuffer buf( &ba );
+ buf.open(QIODevice::ReadWrite);
+ QByteArray data = str.toLatin1();
+ QCOMPARE(buf.write( data.constData(), data.size() ), qint64(data.size()));
+
+ QCOMPARE(buf.data(), str.toLatin1());
+}
+
+void tst_QBuffer::seek()
+{
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QCOMPARE(buffer.size(), qint64(0));
+ QCOMPARE(buffer.pos(), qint64(0));
+ const qint64 pos = 10;
+ QVERIFY(buffer.seek(pos));
+ QCOMPARE(buffer.size(), pos);
+}
+
+void tst_QBuffer::seekTest_data()
+{
+ writeBlock_data();
+}
+
+#define DO_VALID_SEEK(position) { \
+ char c; \
+ QVERIFY(buf.seek(qint64(position))); \
+ QCOMPARE(buf.pos(), qint64(position)); \
+ QVERIFY(buf.getChar(&c)); \
+ QCOMPARE(QChar(c), str.at(qint64(position))); \
+}
+#define DO_INVALID_SEEK(position) { \
+ qint64 prev_pos = buf.pos(); \
+ QVERIFY(!buf.seek(qint64(position))); \
+ QCOMPARE(buf.pos(), prev_pos); /* position should not be changed */ \
+}
+
+void tst_QBuffer::seekTest()
+{
+ QFETCH(QString, str);
+
+ QByteArray ba;
+ QBuffer buf(&ba);
+#if 0
+ QCOMPARE(buf.pos(), qint64(-1));
+#endif
+ buf.open(QIODevice::ReadWrite);
+ QCOMPARE(buf.pos(), qint64(0));
+
+ QByteArray data = str.toLatin1();
+ QCOMPARE(buf.write( data.constData(), data.size() ), qint64(data.size()));
+
+ QTest::ignoreMessage(QtWarningMsg, "QBuffer::seek: Invalid pos: -1");
+ DO_INVALID_SEEK(-1);
+
+ DO_VALID_SEEK(0);
+ DO_VALID_SEEK(str.size() - 1);
+ QVERIFY(buf.atEnd());
+ DO_VALID_SEEK(str.size() / 2);
+
+ // Special case: valid to seek one position past the buffer.
+ // Its then legal to write, but not read.
+ {
+ char c = 'a';
+ QVERIFY(buf.seek(qint64(str.size())));
+ QCOMPARE(buf.read(&c, qint64(1)), qint64(0));
+ QCOMPARE(c, 'a');
+ QCOMPARE(buf.write(&c, qint64(1)), qint64(1));
+ }
+
+ // Special case 2: seeking to an arbitrary position beyond the buffer auto-expands it
+ // (see Task 184730)
+ {
+ char c;
+ const int offset = 1; // any positive integer will do
+ const qint64 pos = buf.size() + offset;
+ QVERIFY(buf.seek(pos));
+ QCOMPARE(buf.pos(), pos);
+ QVERIFY(!buf.getChar(&c));
+ QVERIFY(buf.seek(pos - 1));
+ QVERIFY(buf.getChar(&c));
+ QCOMPARE(c, buf.data().at(pos - 1));
+ QVERIFY(buf.seek(pos));
+ QVERIFY(buf.putChar(c));
+ }
+}
+
+void tst_QBuffer::read_rawdata()
+{
+ static const unsigned char mydata[] = {
+ 0x01, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
+ 0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99,
+ 0x6d, 0x5b
+ };
+
+ QByteArray data = QByteArray::fromRawData((const char *)mydata, sizeof(mydata));
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ QDataStream in(&buffer);
+ quint8 ch;
+ for (int i = 0; i < (int)sizeof(mydata); ++i) {
+ QVERIFY(!buffer.atEnd());
+ in >> ch;
+ QVERIFY(ch == (quint8)mydata[i]);
+ }
+ QVERIFY(buffer.atEnd());
+}
+
+void tst_QBuffer::isSequential()
+{
+ QBuffer buf;
+ QVERIFY(!buf.isSequential());
+}
+
+void tst_QBuffer::signalTest_data()
+{
+ QTest::addColumn<QByteArray>("sample");
+
+ QTest::newRow("empty") << QByteArray();
+ QTest::newRow("size 1") << QByteArray("1");
+ QTest::newRow("size 2") << QByteArray("11");
+ QTest::newRow("size 100") << QByteArray(100, '1');
+}
+
+void tst_QBuffer::signalTest()
+{
+ QFETCH(QByteArray, sample);
+
+ totalBytesWritten = 0;
+
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+
+ buf.buffer().resize(sample.size() * 10);
+ connect(&buf, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
+ connect(&buf, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64)));
+
+ for (int i = 0; i < 10; ++i) {
+ gotReadyRead = false;
+ QCOMPARE(buf.write(sample), qint64(sample.size()));
+ if (sample.size() > 0) {
+ QTestEventLoop::instance().enterLoop(5);
+ if (QTestEventLoop::instance().timeout())
+ QFAIL("Timed out when waiting for readyRead()");
+ QCOMPARE(totalBytesWritten, qint64(sample.size() * (i + 1)));
+ QVERIFY(gotReadyRead);
+ } else {
+ QCOMPARE(totalBytesWritten, qint64(0));
+ QVERIFY(!gotReadyRead);
+ }
+ }
+}
+
+void tst_QBuffer::readyReadSlot()
+{
+ gotReadyRead = true;
+ QTestEventLoop::instance().exitLoop();
+}
+
+void tst_QBuffer::bytesWrittenSlot(qint64 written)
+{
+ totalBytesWritten += written;
+}
+
+void tst_QBuffer::isClosedAfterClose()
+{
+ QBuffer buffer;
+ buffer.open(QBuffer::ReadOnly);
+ QVERIFY(buffer.isOpen());
+ buffer.close();
+ QVERIFY(!buffer.isOpen());
+}
+
+void tst_QBuffer::readLine_data()
+{
+ QTest::addColumn<QByteArray>("src");
+ QTest::addColumn<int>("maxlen");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("1") << QByteArray("line1\nline2\n") << 1024
+ << QByteArray("line1\n");
+ QTest::newRow("2") << QByteArray("hi there") << 1024
+ << QByteArray("hi there");
+ QTest::newRow("3") << QByteArray("l\n") << 3 << QByteArray("l\n");
+ QTest::newRow("4") << QByteArray("l\n") << 2 << QByteArray("l");
+}
+
+void tst_QBuffer::readLine()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(int, maxlen);
+ QFETCH(QByteArray, expected);
+
+ QBuffer buf;
+ buf.setBuffer(&src);
+ char *result = new char[maxlen + 1];
+ result[maxlen] = '\0';
+
+ QVERIFY(buf.open(QIODevice::ReadOnly));
+
+ qint64 bytes_read = buf.readLine(result, maxlen);
+
+ QCOMPARE(bytes_read, qint64(expected.size()));
+ QCOMPARE(QByteArray(result), expected);
+
+ buf.close();
+ delete[] result;
+
+}
+
+void tst_QBuffer::canReadLine_data()
+{
+ QTest::addColumn<QByteArray>("src");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("1") << QByteArray("no newline") << false;
+ QTest::newRow("2") << QByteArray("two \n lines\n") << true;
+ QTest::newRow("3") << QByteArray("\n") << true;
+ QTest::newRow("4") << QByteArray() << false;
+}
+
+void tst_QBuffer::canReadLine()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(bool, expected);
+
+ QBuffer buf;
+ buf.setBuffer(&src);
+ QVERIFY(!buf.canReadLine());
+ QVERIFY(buf.open(QIODevice::ReadOnly));
+ QCOMPARE(buf.canReadLine(), expected);
+}
+
+void tst_QBuffer::atEnd()
+{
+ QBuffer buffer;
+ buffer.open(QBuffer::Append);
+ buffer.write("heisann");
+ buffer.close();
+
+ buffer.open(QBuffer::ReadOnly);
+ buffer.seek(buffer.size());
+ char c;
+ QVERIFY(!buffer.getChar(&c));
+ QCOMPARE(buffer.read(&c, 1), qint64(0));
+}
+
+void tst_QBuffer::readLineBoundaries()
+{
+ QByteArray line = "This is a line\n";
+ QBuffer buffer;
+ buffer.open(QIODevice::ReadWrite);
+ while (buffer.size() < 16384)
+ buffer.write(line);
+
+/*
+ buffer.seek(0);
+ QFile out1("out1.txt");
+ out1.open(QFile::WriteOnly);
+ out1.write(buffer.readAll());
+ out1.close();
+*/
+ buffer.seek(0);
+
+ char c;
+ buffer.getChar(&c);
+ buffer.ungetChar(c);
+
+ QFile out2("out2.txt");
+ out2.open(QFile::WriteOnly);
+ while (!buffer.atEnd())
+ out2.write(buffer.readLine());
+
+ out2.close();
+ out2.remove();
+}
+
+void tst_QBuffer::writeAfterQByteArrayResize()
+{
+ QBuffer buffer;
+ QVERIFY(buffer.open(QIODevice::WriteOnly));
+
+ buffer.write(QByteArray().fill('a', 1000));
+ QCOMPARE(buffer.buffer().size(), 1000);
+
+ // resize the QByteArray behind QBuffer's back
+ buffer.buffer().clear();
+ buffer.seek(0);
+ QCOMPARE(buffer.buffer().size(), 0);
+
+ buffer.write(QByteArray().fill('b', 1000));
+ QCOMPARE(buffer.buffer().size(), 1000);
+}
+
+void tst_QBuffer::read_null()
+{
+ QByteArray buffer;
+ buffer.resize(32000);
+ for (int i = 0; i < buffer.size(); ++i)
+ buffer[i] = char(i & 0xff);
+
+ QBuffer in(&buffer);
+ in.open(QIODevice::ReadOnly);
+
+ QByteArray chunk;
+
+ chunk.resize(16380);
+ in.read(chunk.data(), 16380);
+
+ QCOMPARE(chunk, buffer.mid(0, chunk.size()));
+
+ in.read(chunk.data(), 0);
+
+ chunk.resize(8);
+ in.read(chunk.data(), chunk.size());
+
+ QCOMPARE(chunk, buffer.mid(16380, chunk.size()));
+}
+
+QTEST_MAIN(tst_QBuffer)
+#include "tst_qbuffer.moc"
diff --git a/tests/auto/corelib/io/qdatastream/.gitignore b/tests/auto/corelib/io/qdatastream/.gitignore
new file mode 100644
index 0000000000..cdcbaa591e
--- /dev/null
+++ b/tests/auto/corelib/io/qdatastream/.gitignore
@@ -0,0 +1,2 @@
+datastream.tmp
+tst_qdatastream
diff --git a/tests/auto/corelib/io/qdatastream/datastream.q42 b/tests/auto/corelib/io/qdatastream/datastream.q42
new file mode 100644
index 0000000000..5c83f5c7fc
--- /dev/null
+++ b/tests/auto/corelib/io/qdatastream/datastream.q42
Binary files differ
diff --git a/tests/auto/corelib/io/qdatastream/qdatastream.pro b/tests/auto/corelib/io/qdatastream/qdatastream.pro
new file mode 100644
index 0000000000..5e503aea78
--- /dev/null
+++ b/tests/auto/corelib/io/qdatastream/qdatastream.pro
@@ -0,0 +1,20 @@
+load(qttest_p4)
+SOURCES += tst_qdatastream.cpp
+
+wince*: {
+ addFiles.files = datastream.q42
+ addFiles.path = .
+ DEPLOYMENT += addFiles
+ DEFINES += SRCDIR=\\\"\\\"
+} else:symbian {
+ # SRCDIR defined in code in symbian
+ addFiles.files = datastream.q42
+ addFiles.path = .
+ DEPLOYMENT += addFiles
+ TARGET.EPOCHEAPSIZE = 1000000 10000000
+ TARGET.UID3 = 0xE0340001
+ DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x",""))
+}else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp
new file mode 100644
index 0000000000..e5a80d9bf3
--- /dev/null
+++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp
@@ -0,0 +1,3232 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+#include <QtGui/QtGui>
+
+#if defined(Q_OS_SYMBIAN)
+# define STRINGIFY(x) #x
+# define TOSTRING(x) STRINGIFY(x)
+# define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID) "/"
+#endif
+
+Q_DECLARE_METATYPE(QBitArray)
+Q_DECLARE_METATYPE(qint64)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QDataStream : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QDataStream();
+ virtual ~tst_QDataStream();
+
+ void stream_data(int noOfElements);
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void stream_bool_data();
+ void stream_bool();
+
+ void stream_QBool_data();
+ void stream_QBool();
+
+ void stream_QBool_in_4_0();
+
+ void stream_QBitArray_data();
+ void stream_QBitArray();
+
+ void stream_QBrush_data();
+ void stream_QBrush();
+
+ void stream_QColor_data();
+ void stream_QColor();
+
+ void stream_QByteArray_data();
+ void stream_QByteArray();
+
+ void stream_QCursor_data();
+ void stream_QCursor();
+
+ void stream_QDate_data();
+ void stream_QDate();
+
+ void stream_QTime_data();
+ void stream_QTime();
+
+ void stream_QDateTime_data();
+ void stream_QDateTime();
+
+ void stream_QFont_data();
+ void stream_QFont();
+
+ void stream_QImage_data();
+ void stream_QImage();
+
+ void stream_QPen_data();
+ void stream_QPen();
+
+ void stream_QPixmap_data();
+ void stream_QPixmap();
+
+ void stream_QPoint_data();
+ void stream_QPoint();
+
+ void stream_QRect_data();
+ void stream_QRect();
+
+ void stream_QPolygon_data();
+ void stream_QPolygon();
+
+ void stream_QRegion_data();
+ void stream_QRegion();
+
+ void stream_QSize_data();
+ void stream_QSize();
+
+ void stream_QString_data();
+ void stream_QString();
+
+ void stream_QRegExp_data();
+ void stream_QRegExp();
+
+ void stream_Map_data();
+ void stream_Map();
+
+ void stream_Hash_data();
+ void stream_Hash();
+
+ void stream_qint64_data();
+ void stream_qint64();
+
+ void stream_QIcon_data();
+ void stream_QIcon();
+
+ void stream_QEasingCurve_data();
+ void stream_QEasingCurve();
+
+ void stream_atEnd_data();
+ void stream_atEnd();
+
+ void stream_writeError();
+
+ void stream_QByteArray2();
+
+ void setVersion_data();
+ void setVersion();
+
+ void skipRawData_data();
+ void skipRawData();
+
+ void status_qint8_data();
+ void status_qint8();
+ void status_qint16_data();
+ void status_qint16();
+ void status_qint32_data();
+ void status_qint32();
+ void status_qint64_data();
+ void status_qint64();
+
+ void status_float_data();
+ void status_float();
+ void status_double_data();
+ void status_double();
+
+ void status_charptr_QByteArray_data();
+ void status_charptr_QByteArray();
+
+ void status_QString_data();
+ void status_QString();
+
+ void status_QBitArray_data();
+ void status_QBitArray();
+
+ void status_QHash_QMap();
+
+ void status_QLinkedList_QList_QVector();
+
+ void streamToAndFromQByteArray();
+
+ void streamRealDataTypes();
+
+ void floatingPointPrecision();
+
+ void compatibility_Qt3();
+ void compatibility_Qt2();
+
+private:
+ void writebool(QDataStream *s);
+ void writeQBool(QDataStream *s);
+ void writeQBitArray(QDataStream *s);
+ void writeQBrush(QDataStream *s);
+ void writeQColor(QDataStream *s);
+ void writeQByteArray(QDataStream *s);
+ void writeQCursor(QDataStream *s);
+ void writeQWaitCursor(QDataStream *s);
+ void writeQDate(QDataStream *s);
+ void writeQTime(QDataStream *s);
+ void writeQDateTime(QDataStream *s);
+ void writeQFont(QDataStream *s);
+ void writeQImage(QDataStream *s);
+ void writeQPen(QDataStream *s);
+ void writeQPixmap(QDataStream *s);
+ void writeQPoint(QDataStream *s);
+ void writeQRect(QDataStream *s);
+ void writeQPolygon(QDataStream *s);
+ void writeQRegion(QDataStream *s);
+ void writeQSize(QDataStream *s);
+ void writeQString(QDataStream* dev);
+ void writeQRegExp(QDataStream* dev);
+ void writeMap(QDataStream* dev);
+ void writeHash(QDataStream* dev);
+ void writeqint64(QDataStream *s);
+ void writeQIcon(QDataStream *s);
+ void writeQEasingCurve(QDataStream *s);
+
+ void readbool(QDataStream *s);
+ void readQBool(QDataStream *s);
+ void readQBitArray(QDataStream *s);
+ void readQBrush(QDataStream *s);
+ void readQColor(QDataStream *s);
+ void readQByteArray(QDataStream *s);
+ void readQCursor(QDataStream *s);
+ void readQDate(QDataStream *s);
+ void readQTime(QDataStream *s);
+ void readQDateTime(QDataStream *s);
+ void readQFont(QDataStream *s);
+ void readQImage(QDataStream *s);
+ void readQPen(QDataStream *s);
+ void readQPixmap(QDataStream *s);
+ void readQPoint(QDataStream *s);
+ void readQRect(QDataStream *s);
+ void readQPolygon(QDataStream *s);
+ void readQRegion(QDataStream *s);
+ void readQSize(QDataStream *s);
+ void readQString(QDataStream *s);
+ void readQRegExp(QDataStream *s);
+ void readMap(QDataStream *s);
+ void readHash(QDataStream *s);
+ void readqint64(QDataStream *s);
+ void readQIcon(QDataStream *s);
+ void readQEasingCurve(QDataStream *s);
+};
+
+static int NColorRoles[] = {
+ QPalette::NoRole, // No Version
+ QPalette::NoRole, // Qt_1_0
+ QPalette::HighlightedText + 1, // Qt_2_0
+ QPalette::HighlightedText + 1, // Qt_2_1
+ QPalette::LinkVisited + 1, // Qt_3_0
+ QPalette::HighlightedText + 1, // Qt_3_1
+ QPalette::HighlightedText + 1, // Qt_3_3
+ QPalette::HighlightedText + 1, // Qt_4_0, Qt_4_1
+ QPalette::HighlightedText + 1, // Qt_4_2
+ QPalette::AlternateBase + 1, // Qt_4_3
+ QPalette::ToolTipText + 1, // Qt_4_4
+ QPalette::ToolTipText + 1, // Qt_4_5
+ QPalette::ToolTipText + 1, // Qt_4_6
+ 0 // add the correct value for Qt_4_7 here later
+};
+
+// Testing get/set functions
+void tst_QDataStream::getSetCheck()
+{
+ QDataStream obj1;
+ // QIODevice * QDataStream::device()
+ // void QDataStream::setDevice(QIODevice *)
+ QFile *var1 = new QFile;
+ obj1.setDevice(var1);
+ QCOMPARE((QIODevice *)var1, (QIODevice *)obj1.device());
+ obj1.setDevice((QIODevice *)0);
+ QCOMPARE((QIODevice *)0, (QIODevice *)obj1.device());
+ delete var1;
+
+ // Status QDataStream::status()
+ // void QDataStream::setStatus(Status)
+ obj1.setStatus(QDataStream::Ok);
+ QCOMPARE(QDataStream::Ok, obj1.status());
+ obj1.setStatus(QDataStream::ReadPastEnd);
+ QCOMPARE(QDataStream::ReadPastEnd, obj1.status());
+ obj1.resetStatus();
+ obj1.setStatus(QDataStream::ReadCorruptData);
+ QCOMPARE(QDataStream::ReadCorruptData, obj1.status());
+}
+
+tst_QDataStream::tst_QDataStream()
+{
+}
+
+tst_QDataStream::~tst_QDataStream()
+{
+ QFile::remove(QLatin1String("qdatastream.out"));
+}
+
+void tst_QDataStream::init()
+{
+}
+
+void tst_QDataStream::cleanup()
+{
+}
+
+static int dataIndex(const QString &tag)
+{
+ int pos = tag.lastIndexOf("_");
+ if (pos >= 0) {
+ int ret = 0;
+ QString count = tag.mid(pos + 1);
+ bool ok;
+ ret = count.toInt(&ok);
+ if (ok)
+ return ret;
+ }
+ return -1;
+}
+
+static const char * const devices[] = {
+ "file",
+ "bytearray",
+ "buffer",
+ 0
+};
+
+/*
+ IMPORTANT.
+ In this testcase i follow a different approach than usual: I don't use the full power of
+ QtTestTable and QtTestData. This is done deliberately because QtTestData uses a QDataStream
+ itself to handle its data. So it would be a bit inapropriate to fully rely on QtTestData in this
+ testcase.
+ I do use QString in QtTestData because this is thouroughly tested in the selftest.
+*/
+void tst_QDataStream::stream_data(int noOfElements)
+{
+ QTest::addColumn<QString>("device");
+ QTest::addColumn<QString>("byteOrder");
+
+ for (int d=0; devices[d] != 0; d++) {
+ QString device = devices[d];
+ for (int b=0; b<2; b++) {
+ QString byte_order = b == 0 ? "BigEndian" : "LittleEndian";
+
+ QString tag = device + "_" + byte_order;
+ for (int e=0; e<noOfElements; e++) {
+ QTest::newRow(qPrintable(tag + QString("_%1").arg(e))) << device << QString(byte_order);
+ }
+ }
+ }
+}
+
+static const char* open_xpm[]={
+"16 13 6 1",
+". c None",
+"b c #ffff00",
+"d c #000000",
+"* c #999999",
+"c c #cccccc",
+"a c #ffffff",
+"...*****........",
+"..*aaaaa*.......",
+".*abcbcba******.",
+".*acbcbcaaaaaa*d",
+".*abcbcbcbcbcb*d",
+"*************b*d",
+"*aaaaaaaaaa**c*d",
+"*abcbcbcbcbbd**d",
+".*abcbcbcbcbcd*d",
+".*acbcbcbcbcbd*d",
+"..*acbcbcbcbb*dd",
+"..*************d",
+"...ddddddddddddd"};
+
+#define STREAM_IMPL(TYPE) \
+ QFETCH(QString, device); \
+ if (device == "bytearray") { \
+ QByteArray ba; \
+ QDataStream sout(&ba, QIODevice::WriteOnly); \
+ write##TYPE(&sout); \
+ QDataStream sin(&ba, QIODevice::ReadOnly); \
+ read##TYPE(&sin); \
+ } else if (device == "file") { \
+ QString fileName = "qdatastream.out"; \
+ QFile fOut(fileName); \
+ QVERIFY(fOut.open(QIODevice::WriteOnly)); \
+ QDataStream sout(&fOut); \
+ write##TYPE(&sout); \
+ fOut.close(); \
+ QFile fIn(fileName); \
+ QVERIFY(fIn.open(QIODevice::ReadOnly)); \
+ QDataStream sin(&fIn); \
+ read##TYPE(&sin); \
+ fIn.close(); \
+ } else if (device == "buffer") { \
+ QByteArray ba(10000, '\0'); \
+ QBuffer bOut(&ba); \
+ bOut.open(QIODevice::WriteOnly); \
+ QDataStream sout(&bOut); \
+ write##TYPE(&sout); \
+ bOut.close(); \
+ QBuffer bIn(&ba); \
+ bIn.open(QIODevice::ReadOnly); \
+ QDataStream sin(&bIn); \
+ read##TYPE(&sin); \
+ bIn.close(); \
+ }
+
+// ************************************
+
+static QString QStringData(int index)
+{
+ switch (index) {
+ case 0: return QString();
+ case 1: return QString("");
+ case 2: return QString("A");
+ case 3: return QString("ABCDE FGHI");
+ case 4: return QString("This is a long string");
+ case 5: return QString("And again a string with a \nCRLF");
+ case 6: return QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/");
+ }
+ return QString("foo");
+}
+#define MAX_QSTRING_DATA 7
+
+void tst_QDataStream::stream_QString_data()
+{
+ stream_data(MAX_QSTRING_DATA);
+}
+
+void tst_QDataStream::stream_QString()
+{
+ STREAM_IMPL(QString);
+}
+
+void tst_QDataStream::writeQString(QDataStream* s)
+{
+ QString test(QStringData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+ *s << QString("Her er det noe tekst");
+ *s << test;
+ *s << QString();
+ *s << test;
+ *s << QString("");
+ *s << test;
+ *s << QString("nonempty");
+ *s << test;
+}
+
+void tst_QDataStream::readQString(QDataStream *s)
+{
+ QString S;
+ QString test(QStringData(dataIndex(QTest::currentDataTag())));
+
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QCOMPARE(S, QString("Her er det noe tekst"));
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QVERIFY(S.isNull());
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QVERIFY(S.isEmpty());
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QCOMPARE(S, QString("nonempty"));
+ *s >> S;
+ QCOMPARE(S, test);
+}
+
+// ************************************
+
+static QRegExp QRegExpData(int index)
+{
+ switch (index) {
+ case 0: return QRegExp();
+ case 1: return QRegExp("");
+ case 2: return QRegExp("A", Qt::CaseInsensitive);
+ case 3: return QRegExp("ABCDE FGHI", Qt::CaseSensitive, QRegExp::Wildcard);
+ case 4: return QRegExp("This is a long string", Qt::CaseInsensitive, QRegExp::FixedString);
+ case 5: return QRegExp("And again a string with a \nCRLF", Qt::CaseInsensitive, QRegExp::RegExp);
+ case 6:
+ {
+ QRegExp rx("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/");
+ rx.setMinimal(true);
+ return rx;
+ }
+ }
+ return QRegExp("foo");
+}
+#define MAX_QREGEXP_DATA 7
+
+void tst_QDataStream::stream_QRegExp_data()
+{
+ stream_data(MAX_QREGEXP_DATA);
+}
+
+void tst_QDataStream::stream_QRegExp()
+{
+ STREAM_IMPL(QRegExp);
+}
+
+void tst_QDataStream::writeQRegExp(QDataStream* s)
+{
+ QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+ *s << QString("Her er det noe tekst");
+ *s << test;
+ *s << QString("nonempty");
+ *s << test;
+ *s << QVariant(test);
+}
+
+void tst_QDataStream::readQRegExp(QDataStream *s)
+{
+ QRegExp R;
+ QString S;
+ QVariant V;
+ QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag())));
+
+ *s >> R;
+ QCOMPARE(R, test);
+ *s >> S;
+ QCOMPARE(S, QString("Her er det noe tekst"));
+ *s >> R;
+ QCOMPARE(R, test);
+ *s >> S;
+ QCOMPARE(S, QString("nonempty"));
+ *s >> R;
+ QCOMPARE(R, test);
+ *s >> V;
+ QVERIFY(V.type() == QVariant::RegExp);
+ QCOMPARE(V.toRegExp(), test);
+}
+
+// ************************************
+
+typedef QMap<int, QString> Map;
+
+static Map MapData(int index)
+{
+ Map map;
+
+ switch (index) {
+ case 0:
+ default:
+ break;
+ case 1:
+ map.insert(1, "a");
+ map.insert(2, "bbb");
+ map.insert(3, "cccccc");
+ break;
+ case 2:
+ map.insert(1, "a");
+ map.insert(2, "one");
+ map.insertMulti(2, "two");
+ map.insertMulti(2, "three");
+ map.insert(3, "cccccc");
+ }
+ return map;
+}
+#define MAX_MAP_DATA 3
+
+void tst_QDataStream::stream_Map_data()
+{
+ stream_data(MAX_MAP_DATA);
+}
+
+void tst_QDataStream::stream_Map()
+{
+ STREAM_IMPL(Map);
+}
+
+void tst_QDataStream::writeMap(QDataStream* s)
+{
+ Map test(MapData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+ *s << test;
+}
+
+void tst_QDataStream::readMap(QDataStream *s)
+{
+ Map S;
+ Map test(MapData(dataIndex(QTest::currentDataTag())));
+
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QCOMPARE(S, test);
+}
+
+// ************************************
+
+typedef QHash<int, QString> Hash;
+
+static Hash HashData(int index)
+{
+ Hash map;
+
+ switch (index) {
+ case 0:
+ default:
+ break;
+ case 1:
+ map.insert(1, "a");
+ map.insert(2, "bbb");
+ map.insert(3, "cccccc");
+ break;
+ case 2:
+ map.insert(1, "a");
+ map.insert(2, "one");
+ map.insertMulti(2, "two");
+ map.insertMulti(2, "three");
+ map.insert(3, "cccccc");
+ }
+ return map;
+}
+#define MAX_HASH_DATA 3
+
+void tst_QDataStream::stream_Hash_data()
+{
+ stream_data(MAX_HASH_DATA);
+}
+
+void tst_QDataStream::stream_Hash()
+{
+ STREAM_IMPL(Hash);
+}
+
+void tst_QDataStream::writeHash(QDataStream* s)
+{
+ Hash test(HashData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+ *s << test;
+}
+
+void tst_QDataStream::readHash(QDataStream *s)
+{
+ Hash S;
+ Hash test(HashData(dataIndex(QTest::currentDataTag())));
+
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QCOMPARE(S, test);
+}
+
+// ************************************
+
+static QEasingCurve QEasingCurveData(int index)
+{
+ QEasingCurve easing;
+
+ switch (index) {
+ case 0:
+ default:
+ break;
+ case 1:
+ easing.setType(QEasingCurve::Linear);
+ break;
+ case 2:
+ easing.setType(QEasingCurve::OutCubic);
+ break;
+ case 3:
+ easing.setType(QEasingCurve::InOutSine);
+ break;
+ case 4:
+ easing.setType(QEasingCurve::InOutElastic);
+ easing.setPeriod(1.5);
+ easing.setAmplitude(2.0);
+ break;
+ case 5:
+ easing.setType(QEasingCurve::OutInBack);
+ break;
+ case 6:
+ easing.setType(QEasingCurve::OutCurve);
+ break;
+ case 7:
+ easing.setType(QEasingCurve::InOutBack);
+ easing.setOvershoot(0.5);
+ break;
+ }
+ return easing;
+}
+#define MAX_EASING_DATA 8
+
+void tst_QDataStream::stream_QEasingCurve_data()
+{
+ stream_data(MAX_EASING_DATA);
+}
+
+void tst_QDataStream::stream_QEasingCurve()
+{
+ STREAM_IMPL(QEasingCurve);
+}
+
+void tst_QDataStream::writeQEasingCurve(QDataStream* s)
+{
+ QEasingCurve test(QEasingCurveData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+}
+
+void tst_QDataStream::readQEasingCurve(QDataStream *s)
+{
+ QEasingCurve S;
+ QEasingCurve expected(QEasingCurveData(dataIndex(QTest::currentDataTag())));
+
+ *s >> S;
+ QCOMPARE(S, expected);
+}
+
+// ************************************
+
+// contains some quint64 testing as well
+
+#define MAX_qint64_DATA 4
+
+static qint64 qint64Data(int index)
+{
+ switch (index) {
+ case 0: return qint64(0);
+ case 1: return qint64(1);
+ case 2: return qint64(-1);
+ case 3: return qint64(1) << 40;
+ case MAX_qint64_DATA: return -(qint64(1) << 40);
+ }
+
+ return -1;
+}
+
+void tst_QDataStream::stream_qint64_data()
+{
+ stream_data(MAX_qint64_DATA+1);
+}
+
+void tst_QDataStream::stream_qint64()
+{
+ STREAM_IMPL(qint64);
+}
+
+void tst_QDataStream::writeqint64(QDataStream* s)
+{
+ qint64 test = qint64Data(dataIndex(QTest::currentDataTag()));
+ *s << test;
+ *s << int(1);
+ *s << (quint64)test;
+}
+
+void tst_QDataStream::readqint64(QDataStream *s)
+{
+ qint64 test = qint64Data(dataIndex(QTest::currentDataTag()));
+ qint64 i64;
+ quint64 ui64;
+ int i;
+ *s >> i64;
+ QCOMPARE(i64, test);
+ *s >> i;
+ QCOMPARE(i, int(1));
+ *s >> ui64;
+ QCOMPARE(ui64, (quint64)test);
+}
+
+// ************************************
+
+static bool boolData(int index)
+{
+ switch (index) {
+ case 0: return true;
+ case 1: return false;
+ case 2: return bool(2);
+ case 3: return bool(-1);
+ case 4: return bool(127);
+ }
+
+ return false;
+}
+
+void tst_QDataStream::stream_bool_data()
+{
+ stream_data(5);
+}
+
+void tst_QDataStream::stream_bool()
+{
+ STREAM_IMPL(bool);
+}
+
+void tst_QDataStream::writebool(QDataStream *s)
+{
+ bool d1 = boolData(dataIndex(QTest::currentDataTag()));
+ *s << d1;
+}
+
+void tst_QDataStream::readbool(QDataStream *s)
+{
+ bool expected = boolData(dataIndex(QTest::currentDataTag()));
+
+ bool d1;
+ *s >> d1;
+ QVERIFY(d1 == expected);
+}
+
+// ************************************
+
+static QBool QBoolData(int index)
+{
+ switch (index) {
+ case 0: return QBool(true);
+ case 1: return QBool(false);
+ case 2: return QBool(bool(2));
+ case 3: return QBool(bool(-1));
+ case 4: return QBool(bool(127));
+ }
+
+ return QBool(false);
+}
+
+void tst_QDataStream::stream_QBool_data()
+{
+ stream_data(5);
+}
+
+void tst_QDataStream::stream_QBool()
+{
+ STREAM_IMPL(QBool);
+}
+
+void tst_QDataStream::writeQBool(QDataStream *s)
+{
+ QBool d1 = QBoolData(dataIndex(QTest::currentDataTag()));
+ *s << d1;
+}
+
+void tst_QDataStream::readQBool(QDataStream *s)
+{
+ QBool expected = QBoolData(dataIndex(QTest::currentDataTag()));
+
+ bool d1 = true;
+ *s >> d1;
+ QVERIFY(d1 == expected);
+}
+
+void tst_QDataStream::stream_QBool_in_4_0()
+{
+ QByteArray byteArray;
+ QDataStream out(&byteArray, QIODevice::WriteOnly);
+
+ QString str("ABC");
+ out << str.contains('A') << str.contains('Z');
+
+ QCOMPARE(byteArray.size(), 2);
+}
+
+// ************************************
+
+static void QBitArrayData(QBitArray *b, int index)
+{
+ QString filler = "";
+ switch (index) {
+ case 0: filler = ""; break;
+ case 1: filler = ""; break;
+ case 2: filler = "0"; break;
+ case 3: filler = "1"; break;
+ case 4: filler = "0000"; break;
+ case 5: filler = "0001"; break;
+ case 6: filler = "0010"; break;
+ case 7: filler = "0100"; break;
+ case 8: filler = "1000"; break;
+ case 9: filler = "1111"; break;
+ case 10: filler = "00000000"; break;
+ case 11: filler = "00000001"; break;
+ case 12: filler = "11111111"; break;
+ case 13: filler = "000000001"; break;
+ case 14: filler = "000000000001"; break;
+ case 15: filler = "0000000000000001"; break;
+ case 16: filler = "0101010101010101010101010101010101010101010101010101010101010101"; break;
+ case 17: filler = "1010101010101010101010101010101010101010101010101010101010101010"; break;
+ case 18: filler = "1111111111111111111111111111111111111111111111111111111111111111"; break;
+ }
+
+ b->resize(filler.length());
+ b->fill(0); // reset all bits to zero
+
+ for (int i = 0; i < filler.length(); ++i) {
+ if (filler.at(i) == '1')
+ b->setBit(i, TRUE);
+ }
+}
+
+void tst_QDataStream::stream_QBitArray_data()
+{
+ stream_data(19);
+}
+
+void tst_QDataStream::stream_QBitArray()
+{
+ STREAM_IMPL(QBitArray);
+}
+
+void tst_QDataStream::writeQBitArray(QDataStream *s)
+{
+ QBitArray d1;
+ QBitArrayData(&d1, dataIndex(QTest::currentDataTag()));
+ *s << d1;
+}
+
+void tst_QDataStream::readQBitArray(QDataStream *s)
+{
+ QBitArray expected;
+ QBitArrayData(&expected, dataIndex(QTest::currentDataTag()));
+
+ QBitArray d1;
+ *s >> d1;
+ QVERIFY(d1 == expected);
+}
+
+// ************************************
+
+static QBrush qBrushData(int index)
+{
+ switch (index) {
+ case 0: return QBrush(Qt::NoBrush);
+ case 1: return QBrush(Qt::SolidPattern);
+ case 2: return QBrush(Qt::Dense7Pattern);
+ case 3: return QBrush(Qt::red, Qt::NoBrush);
+ case 4: return QBrush(Qt::green, Qt::SolidPattern);
+ case 5: return QBrush(Qt::blue, Qt::Dense7Pattern);
+ case 6:
+ {
+ QPixmap pm(open_xpm);
+ QBrush custom(Qt::black, pm);
+ return custom;
+ }
+ case 7:
+ QLinearGradient gradient(QPoint(2.718, 3.142), QPoint(3.1337, 42));
+ gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
+ gradient.setSpread(QGradient::ReflectSpread);
+ gradient.setInterpolationMode(QGradient::ComponentInterpolation);
+ gradient.setColorAt(0.2, Qt::red);
+ gradient.setColorAt(0.6, Qt::transparent);
+ gradient.setColorAt(0.8, Qt::blue);
+ return QBrush(gradient);
+ }
+
+ return QBrush(Qt::NoBrush);
+}
+
+void tst_QDataStream::stream_QBrush_data()
+{
+ stream_data(8);
+}
+
+void tst_QDataStream::stream_QBrush()
+{
+ if (QString(QTest::currentDataTag()).endsWith("6"))
+ QSKIP("Custom brushes don't seem to be supported with QDataStream", SkipSingle);
+
+ STREAM_IMPL(QBrush);
+}
+
+void tst_QDataStream::writeQBrush(QDataStream *s)
+{
+ QBrush brush = qBrushData(dataIndex(QTest::currentDataTag()));
+ *s << brush;
+}
+
+void tst_QDataStream::readQBrush(QDataStream *s)
+{
+ QBrush d2;
+ *s >> d2;
+
+ QBrush brush = qBrushData(dataIndex(QTest::currentDataTag()));
+ QVERIFY(d2 == brush);
+}
+
+// ************************************
+
+static QColor QColorData(int index)
+{
+ switch (index) {
+ case 0: return QColor(0,0,0);
+ case 1: return QColor(0,0,0);
+ case 2: return QColor(0,0,0);
+ case 3: return QColor(0,0,0);
+ case 4: return QColor(0,0,0);
+ case 5: return QColor(0,0,0);
+ case 6: return QColor(0,0,0);
+ case 7: return QColor(0,0,0);
+ }
+
+ return QColor(0,0,0);
+}
+
+void tst_QDataStream::stream_QColor_data()
+{
+ stream_data(8);
+}
+
+void tst_QDataStream::stream_QColor()
+{
+ STREAM_IMPL(QColor);
+}
+
+void tst_QDataStream::writeQColor(QDataStream *s)
+{
+ QColor d3(QColorData(dataIndex(QTest::currentDataTag())));
+ *s << d3;
+}
+
+void tst_QDataStream::readQColor(QDataStream *s)
+{
+ QColor test(QColorData(dataIndex(QTest::currentDataTag())));
+ QColor d3;
+ *s >> d3;
+ QVERIFY(d3 == test);
+}
+
+
+// ************************************
+
+static QByteArray qByteArrayData(int index)
+{
+ switch (index) {
+ case 0: return QByteArray();
+ case 1: return QByteArray("");
+ case 2: return QByteArray("foo");
+ case 3: return QByteArray("foo bar");
+ case 4: return QByteArray("two\nlines");
+ case 5: return QByteArray("ABCDEFG");
+ case 6: return QByteArray("baec zxv 123"); // kept for nostalgic reasons
+ case 7: return QByteArray("jbc;UBC;jd clhdbcahd vcbd vgdv dhvb laifv kadf jkhfbvljd khd lhvjh ");
+ }
+
+ return QByteArray("foo");
+}
+
+void tst_QDataStream::stream_QByteArray_data()
+{
+ stream_data(8);
+}
+
+void tst_QDataStream::stream_QByteArray()
+{
+ STREAM_IMPL(QByteArray);
+}
+
+void tst_QDataStream::writeQByteArray(QDataStream *s)
+{
+ QByteArray d4(qByteArrayData(dataIndex(QTest::currentDataTag())));
+ *s << d4;
+}
+
+void tst_QDataStream::readQByteArray(QDataStream *s)
+{
+ QByteArray test(qByteArrayData(dataIndex(QTest::currentDataTag())));
+ QByteArray d4;
+ *s >> d4;
+ QCOMPARE(d4, test);
+}
+
+// ************************************
+#ifndef QT_NO_CURSOR
+static QCursor qCursorData(int index)
+{
+ switch (index) {
+ case 0: return QCursor(Qt::ArrowCursor);
+ case 1: return QCursor(Qt::WaitCursor);
+ case 2: return QCursor(Qt::BitmapCursor);
+ case 3: return QCursor(Qt::BlankCursor);
+ case 4: return QCursor(Qt::BlankCursor);
+ case 5: return QCursor(QPixmap(open_xpm), 1, 1);
+ case 6: { QPixmap pm(open_xpm); return QCursor(QBitmap(pm), pm.mask(), 3, 4); }
+ case 7: return QCursor(QPixmap(open_xpm), -1, 5);
+ case 8: return QCursor(QPixmap(open_xpm), 5, -1);
+ }
+
+ return QCursor();
+}
+#endif
+
+void tst_QDataStream::stream_QCursor_data()
+{
+#ifndef QT_NO_CURSOR
+ stream_data(9);
+#endif
+}
+
+void tst_QDataStream::stream_QCursor()
+{
+#ifndef QT_NO_CURSOR
+ STREAM_IMPL(QCursor);
+#endif
+}
+
+void tst_QDataStream::writeQCursor(QDataStream *s)
+{
+#ifndef QT_NO_CURSOR
+ QCursor d5(qCursorData(dataIndex(QTest::currentDataTag())));
+ *s << d5;
+#endif
+}
+
+void tst_QDataStream::readQCursor(QDataStream *s)
+{
+#ifndef QT_NO_CURSOR
+ QCursor test(qCursorData(dataIndex(QTest::currentDataTag())));
+ QCursor d5;
+ *s >> d5;
+
+ QVERIFY(d5.shape() == test.shape()); //## lacks operator==
+ QVERIFY(d5.hotSpot() == test.hotSpot());
+ QVERIFY((d5.bitmap() != 0 && test.bitmap() != 0) || (d5.bitmap() == 0 && test.bitmap() == 0));
+ if (d5.bitmap() != 0)
+ QVERIFY(pixmapsAreEqual(d5.bitmap(), test.bitmap()));
+ QVERIFY((d5.mask() != 0 && test.mask() != 0) || (d5.mask() == 0 && test.mask() == 0));
+ if (d5.mask() != 0)
+ QVERIFY(pixmapsAreEqual(d5.mask(), test.mask()));
+#endif
+}
+
+// ************************************
+
+static QDate qDateData(int index)
+{
+ switch (index) {
+ case 0: return QDate(1752, 9, 14); // the first valid date
+ case 1: return QDate(1900, 1, 1);
+ case 2: return QDate(1976, 4, 5);
+ case 3: return QDate(1960, 5, 27);
+ case 4: return QDate(1999, 12, 31); // w2k effects?
+ case 5: return QDate(2000, 1, 1);
+ case 6: return QDate(2050, 1, 1);// test some values far in the future too
+ case 7: return QDate(3001, 12, 31);
+ case 8: return QDate(4002, 1, 1);
+ case 9: return QDate(4003, 12, 31);
+ case 10: return QDate(5004, 1, 1);
+ case 11: return QDate(5005, 12, 31);
+ case 12: return QDate(6006, 1, 1);
+ case 13: return QDate(6007, 12, 31);
+ case 14: return QDate(7008, 1, 1);
+ case 15: return QDate(7009, 12, 31);
+ }
+ return QDate();
+}
+#define MAX_QDATE_DATA 16
+
+void tst_QDataStream::stream_QDate_data()
+{
+ stream_data(MAX_QDATE_DATA);
+}
+
+void tst_QDataStream::stream_QDate()
+{
+ STREAM_IMPL(QDate);
+}
+
+void tst_QDataStream::writeQDate(QDataStream *s)
+{
+ QDate d6(qDateData(dataIndex(QTest::currentDataTag())));
+ *s << d6;
+}
+
+void tst_QDataStream::readQDate(QDataStream *s)
+{
+ QDate test(qDateData(dataIndex(QTest::currentDataTag())));
+ QDate d6;
+ *s >> d6;
+ QVERIFY(d6 == test);
+}
+
+// ************************************
+
+static QTime qTimeData(int index)
+{
+ switch (index) {
+ case 0 : return QTime(0, 0, 0, 0);
+ case 1 : return QTime(0, 0, 0, 1);
+ case 2 : return QTime(0, 0, 0, 99);
+ case 3 : return QTime(0, 0, 0, 100);
+ case 4 : return QTime(0, 0, 0, 999);
+ case 5 : return QTime(0, 0, 1, 0);
+ case 6 : return QTime(0, 0, 1, 1);
+ case 7 : return QTime(0, 0, 1, 99);
+ case 8 : return QTime(0, 0, 1, 100);
+ case 9 : return QTime(0, 0, 1, 999);
+ case 10: return QTime(0, 0, 59, 0);
+ case 11: return QTime(0, 0, 59, 1);
+ case 12: return QTime(0, 0, 59, 99);
+ case 13: return QTime(0, 0, 59, 100);
+ case 14: return QTime(0, 0, 59, 999);
+ case 15: return QTime(0, 59, 0, 0);
+ case 16: return QTime(0, 59, 0, 1);
+ case 17: return QTime(0, 59, 0, 99);
+ case 18: return QTime(0, 59, 0, 100);
+ case 19: return QTime(0, 59, 0, 999);
+ case 20: return QTime(0, 59, 1, 0);
+ case 21: return QTime(0, 59, 1, 1);
+ case 22: return QTime(0, 59, 1, 99);
+ case 23: return QTime(0, 59, 1, 100);
+ case 24: return QTime(0, 59, 1, 999);
+ case 25: return QTime(0, 59, 59, 0);
+ case 26: return QTime(0, 59, 59, 1);
+ case 27: return QTime(0, 59, 59, 99);
+ case 28: return QTime(0, 59, 59, 100);
+ case 29: return QTime(0, 59, 59, 999);
+ case 30: return QTime(23, 0, 0, 0);
+ case 31: return QTime(23, 0, 0, 1);
+ case 32: return QTime(23, 0, 0, 99);
+ case 33: return QTime(23, 0, 0, 100);
+ case 34: return QTime(23, 0, 0, 999);
+ case 35: return QTime(23, 0, 1, 0);
+ case 36: return QTime(23, 0, 1, 1);
+ case 37: return QTime(23, 0, 1, 99);
+ case 38: return QTime(23, 0, 1, 100);
+ case 39: return QTime(23, 0, 1, 999);
+ case 40: return QTime(23, 0, 59, 0);
+ case 41: return QTime(23, 0, 59, 1);
+ case 42: return QTime(23, 0, 59, 99);
+ case 43: return QTime(23, 0, 59, 100);
+ case 44: return QTime(23, 0, 59, 999);
+ case 45: return QTime(23, 59, 0, 0);
+ case 46: return QTime(23, 59, 0, 1);
+ case 47: return QTime(23, 59, 0, 99);
+ case 48: return QTime(23, 59, 0, 100);
+ case 49: return QTime(23, 59, 0, 999);
+ case 50: return QTime(23, 59, 1, 0);
+ case 51: return QTime(23, 59, 1, 1);
+ case 52: return QTime(23, 59, 1, 99);
+ case 53: return QTime(23, 59, 1, 100);
+ case 54: return QTime(23, 59, 1, 999);
+ case 55: return QTime(23, 59, 59, 0);
+ case 56: return QTime(23, 59, 59, 1);
+ case 57: return QTime(23, 59, 59, 99);
+ case 58: return QTime(23, 59, 59, 100);
+ case 59: return QTime(23, 59, 59, 999);
+ }
+ return QTime(0, 0, 0);
+}
+#define MAX_QTIME_DATA 60
+
+void tst_QDataStream::stream_QTime_data()
+{
+ stream_data(MAX_QTIME_DATA);
+}
+
+void tst_QDataStream::stream_QTime()
+{
+ STREAM_IMPL(QTime);
+}
+
+void tst_QDataStream::writeQTime(QDataStream *s)
+{
+ QTime d7 = qTimeData(dataIndex(QTest::currentDataTag()));
+ *s << d7;
+}
+
+void tst_QDataStream::readQTime(QDataStream *s)
+{
+ QTime test = qTimeData(dataIndex(QTest::currentDataTag()));
+ QTime d7;
+ *s >> d7;
+ QVERIFY(d7 == test);
+}
+
+// ************************************
+
+static QDateTime qDateTimeData(int index)
+{
+ switch (index) {
+ case 0: return QDateTime(QDate(1900, 1, 1), QTime(0,0,0,0));
+ case 1: return QDateTime(QDate(1900, 1, 2), QTime(1,1,1,1));
+ case 2: return QDateTime(QDate(1900, 1, 3), QTime(12,0,0,0));
+ case 3: return QDateTime(QDate(1900, 1, 4), QTime(23,59,59,999));
+ case 4: return QDateTime(QDate(1999, 1, 1), QTime(0,0,0,0));
+ case 5: return QDateTime(QDate(1999, 1, 2), QTime(1,1,1,1));
+ case 6: return QDateTime(QDate(1999, 1, 3), QTime(12,0,0,0));
+ case 7: return QDateTime(QDate(1999, 1, 4), QTime(23,59,59,999));
+ case 8: return QDateTime(QDate(2000, 1, 1), QTime(0,0,0,0));
+ case 9: return QDateTime(QDate(2000, 1, 2), QTime(1,1,1,1));
+ case 10: return QDateTime(QDate(2000, 1, 3), QTime(12,0,0,0));
+ case 11: return QDateTime(QDate(2000, 1, 4), QTime(23,59,59,999));
+ case 12: return QDateTime(QDate(2000, 12, 31), QTime(0,0,0,0));
+ case 13: return QDateTime(QDate(2000, 12, 31), QTime(1,1,1,1));
+ case 14: return QDateTime(QDate(2000, 12, 31), QTime(12,0,0,0));
+ case 15: return QDateTime(QDate(2000, 12, 31), QTime(23,59,59,999));
+ }
+ return QDateTime(QDate(1900, 1, 1), QTime(0,0,0));
+}
+#define MAX_QDATETIME_DATA 16
+
+void tst_QDataStream::stream_QDateTime_data()
+{
+ stream_data(MAX_QDATETIME_DATA);
+}
+
+void tst_QDataStream::stream_QDateTime()
+{
+ STREAM_IMPL(QDateTime);
+}
+
+void tst_QDataStream::writeQDateTime(QDataStream *s)
+{
+ QDateTime dt(qDateTimeData(dataIndex(QTest::currentDataTag())));
+ *s << dt;
+}
+
+void tst_QDataStream::readQDateTime(QDataStream *s)
+{
+ QDateTime test(qDateTimeData(dataIndex(QTest::currentDataTag())));
+ QDateTime d8;
+ *s >> d8;
+ QVERIFY(d8 == test);
+}
+
+// ************************************
+
+static QFont qFontData(int index)
+{
+ switch (index) {
+ case 0: return QFont("Courier", 20, QFont::Bold, TRUE);
+ case 1: return QFont("Courier", 18, QFont::Bold, FALSE);
+ case 2: return QFont("Courier", 16, QFont::Light, TRUE);
+ case 3: return QFont("Courier", 14, QFont::Normal, FALSE);
+ case 4: return QFont("Courier", 12, QFont::DemiBold, TRUE);
+ case 5: return QFont("Courier", 10, QFont::Black, FALSE);
+ case 6:
+ {
+ QFont f("Helvetica", 10, QFont::Normal, FALSE);
+ f.setPixelSize(2);
+ f.setUnderline(FALSE);
+ f.setStrikeOut(FALSE);
+ f.setFixedPitch(FALSE);
+ return f;
+ }
+ case 7:
+ {
+ QFont f("Helvetica", 10, QFont::Bold, FALSE);
+ f.setPixelSize(4);
+ f.setUnderline(TRUE);
+ f.setStrikeOut(FALSE);
+ f.setFixedPitch(FALSE);
+ return f;
+ }
+ case 8:
+ {
+ QFont f("Helvetica", 10, QFont::Light, FALSE);
+ f.setPixelSize(6);
+ f.setUnderline(FALSE);
+ f.setStrikeOut(TRUE);
+ f.setFixedPitch(FALSE);
+ return f;
+ }
+ case 9:
+ {
+ QFont f("Helvetica", 10, QFont::DemiBold, FALSE);
+ f.setPixelSize(8);
+ f.setUnderline(FALSE);
+ f.setStrikeOut(FALSE);
+ f.setFixedPitch(TRUE);
+ return f;
+ }
+ case 10:
+ {
+ QFont f("Helvetica", 10, QFont::Black, FALSE);
+ f.setPixelSize(10);
+ f.setUnderline(TRUE);
+ f.setStrikeOut(TRUE);
+ f.setFixedPitch(FALSE);
+ return f;
+ }
+ case 11:
+ {
+ QFont f("Helvetica", 10, QFont::Normal, TRUE);
+ f.setPixelSize(12);
+ f.setUnderline(FALSE);
+ f.setStrikeOut(TRUE);
+ f.setFixedPitch(TRUE);
+ return f;
+ }
+ case 12:
+ {
+ QFont f("Helvetica", 10, QFont::Bold, TRUE);
+ f.setPixelSize(14);
+ f.setUnderline(TRUE);
+ f.setStrikeOut(TRUE);
+ f.setFixedPitch(TRUE);
+ return f;
+ }
+ case 13:
+ {
+ QFont f("Helvetica", 10, QFont::Bold, TRUE);
+ f.setStretch(200);
+ return f;
+ }
+ }
+ return QFont("Courier", 18, QFont::Bold, TRUE);
+}
+#define MAX_QFONT_DATA 14
+
+void tst_QDataStream::stream_QFont_data()
+{
+ stream_data(MAX_QFONT_DATA);
+}
+
+void tst_QDataStream::stream_QFont()
+{
+ STREAM_IMPL(QFont);
+}
+
+void tst_QDataStream::writeQFont(QDataStream *s)
+{
+ QFont d9(qFontData(dataIndex(QTest::currentDataTag())));
+ *s << d9;
+}
+
+void tst_QDataStream::readQFont(QDataStream *s)
+{
+ QFont test(qFontData(dataIndex(QTest::currentDataTag())));
+ QFont d9;
+ *s >> d9;
+
+ // maybe a bit overkill ...
+ QCOMPARE(d9.family(), test.family());
+ QCOMPARE(d9.pointSize(), test.pointSize());
+ QCOMPARE(d9.pixelSize(), test.pixelSize());
+ QCOMPARE(d9.weight(), test.weight());
+ QCOMPARE(d9.bold(), test.bold());
+ QCOMPARE(d9.italic(), test.italic());
+ QCOMPARE(d9.underline(), test.underline());
+ QCOMPARE(d9.overline(), test.overline());
+ QCOMPARE(d9.strikeOut(), test.strikeOut());
+ QCOMPARE(d9.fixedPitch(), test.fixedPitch());
+ QCOMPARE(d9.styleHint(), test.styleHint());
+ QCOMPARE(d9.toString(), test.toString());
+
+ QCOMPARE(d9, test);
+}
+
+// ************************************
+
+void tst_QDataStream::stream_QImage_data()
+{
+ stream_data(1);
+}
+
+void tst_QDataStream::stream_QImage()
+{
+ STREAM_IMPL(QImage);
+}
+
+void tst_QDataStream::writeQImage(QDataStream *s)
+{
+ QImage d12(open_xpm);
+ *s << d12;
+}
+
+void tst_QDataStream::readQImage(QDataStream *s)
+{
+ QImage ref(open_xpm);
+
+ QImage d12;
+ *s >> d12;
+ QVERIFY(d12 == ref);
+
+ // do some extra neurotic tests
+ QVERIFY(d12.size() == ref.size());
+ QVERIFY(d12.isNull() == ref.isNull());
+ QVERIFY(d12.width() == ref.width());
+ QVERIFY(d12.height() == ref.height());
+ QVERIFY(d12.depth() == ref.depth());
+ QVERIFY(d12.colorCount() == ref.colorCount());
+ QVERIFY(d12.hasAlphaChannel() == ref.hasAlphaChannel());
+
+// ################ Bug : ref and orig has ff in alpha; readback has 0
+// ### (Was like this in 1.44 as well)
+//
+// for(int i = 0; i < d12.height(); i++)
+// for(int j = 0; j < d12.width(); j++)
+// if (d12.pixel(j, i) != ref.pixel(j, i))
+// qDebug("Feil %i %i", j, i);
+//
+}
+
+// ************************************
+
+static QPen qPenData(int index)
+{
+ switch (index) {
+ case 0:
+ {
+ QPen p(Qt::blue, 0, Qt::NoPen);
+ p.setCapStyle(Qt::FlatCap);
+ p.setJoinStyle(Qt::MiterJoin);
+ return p;
+ }
+ case 1:
+ {
+ QPen p(Qt::red, 1, Qt::SolidLine);
+ p.setCapStyle(Qt::SquareCap);
+ p.setJoinStyle(Qt::BevelJoin);
+ return p;
+ }
+ case 2:
+ {
+ QPen p(Qt::red, 4, Qt::DashDotDotLine);
+ p.setCapStyle(Qt::RoundCap);
+ p.setJoinStyle(Qt::RoundJoin);
+ return p;
+ }
+ case 3:
+ {
+ QPen p(Qt::blue, 12, Qt::NoPen);
+ p.setCapStyle(Qt::FlatCap);
+ p.setJoinStyle(Qt::RoundJoin);
+ return p;
+ }
+ case 4:
+ {
+ QPen p(Qt::red, 99, Qt::SolidLine);
+ p.setCapStyle(Qt::SquareCap);
+ p.setJoinStyle(Qt::MiterJoin);
+ return p;
+ }
+ case 5:
+ {
+ QPen p(Qt::red, 255, Qt::DashDotLine);
+ p.setCapStyle(Qt::RoundCap);
+ p.setJoinStyle(Qt::BevelJoin);
+ return p;
+ }
+ case 6:
+ {
+ QPen p(Qt::red, 256, Qt::DashDotLine);
+ p.setCapStyle(Qt::RoundCap);
+ p.setJoinStyle(Qt::BevelJoin);
+ return p;
+ }
+ case 7:
+ {
+ QPen p(Qt::red, 0.25, Qt::DashDotLine);
+ p.setCapStyle(Qt::RoundCap);
+ p.setJoinStyle(Qt::BevelJoin);
+ return p;
+ }
+ }
+
+ return QPen();
+}
+#define MAX_QPEN_DATA 8
+
+void tst_QDataStream::stream_QPen_data()
+{
+ stream_data(MAX_QPEN_DATA);
+}
+
+void tst_QDataStream::stream_QPen()
+{
+ /*
+ edba:
+ data6 fails because the width is clipped to a byte (max 255) in the datastream.
+ This limitation is not documented.
+ */
+
+ STREAM_IMPL(QPen);
+}
+
+void tst_QDataStream::writeQPen(QDataStream *s)
+{
+ QPen d15(qPenData(dataIndex(QTest::currentDataTag())));
+ *s << d15;
+}
+
+void tst_QDataStream::readQPen(QDataStream *s)
+{
+ QPen origPen(qPenData(dataIndex(QTest::currentDataTag())));
+ QPen d15;
+ *s >> d15;
+ QCOMPARE(d15.style(), origPen.style());
+ QCOMPARE(d15.width(), origPen.width());
+ QCOMPARE(d15.color(), origPen.color());
+ QVERIFY(d15.capStyle() == origPen.capStyle());
+ QVERIFY(d15.joinStyle() == origPen.joinStyle());
+ QVERIFY(d15 == origPen);
+}
+
+// ************************************
+
+// pixmap testing is currently limited to one pixmap only.
+//
+void tst_QDataStream::stream_QPixmap_data()
+{
+#ifndef Q_OS_WINCE
+ stream_data(1);
+#endif
+}
+
+void tst_QDataStream::stream_QPixmap()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Test depends on more memory than available on Qt/CE", SkipAll);
+#endif
+ STREAM_IMPL(QPixmap);
+}
+
+void tst_QDataStream::stream_QIcon_data()
+{
+#ifndef Q_OS_WINCE
+ stream_data(1);
+#endif
+}
+
+void tst_QDataStream::stream_QIcon()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Test depends on more memory than available on Qt/CE", SkipAll);
+#endif
+ STREAM_IMPL(QIcon);
+}
+
+void tst_QDataStream::writeQPixmap(QDataStream *s)
+{
+ QPixmap d16(open_xpm);
+ *s << d16;
+}
+
+void tst_QDataStream::readQPixmap(QDataStream *s)
+{
+ QPixmap pm(open_xpm);
+ QPixmap d16;
+ *s >> d16;
+ QVERIFY(!d16.isNull() && !pm.isNull());
+ QVERIFY(d16.width() == pm.width());
+ QVERIFY(d16.height() == pm.height());
+ QVERIFY(d16.size() == pm.size());
+ QVERIFY(d16.rect() == pm.rect());
+ QVERIFY(d16.depth() == pm.depth());
+}
+
+void tst_QDataStream::writeQIcon(QDataStream *s)
+{
+ QPixmap pm(open_xpm);
+ QIcon d16(pm);
+ *s << d16;
+}
+
+void tst_QDataStream::readQIcon(QDataStream *s)
+{
+ QPixmap pm(open_xpm);
+ QIcon icon(pm);
+ QIcon d16;
+ *s >> d16;
+ QVERIFY(!d16.isNull() && !icon.isNull());
+ QCOMPARE(d16.pixmap(100), pm);
+}
+
+// ************************************
+
+QPoint qPointData(int index)
+{
+ switch (index) {
+ case 0: return QPoint(0, 0);
+ case 1: return QPoint(-1, 0);
+ case 2: return QPoint(0, -1);
+ case 3: return QPoint(1, 0);
+ case 4: return QPoint(0, 1);
+ case 5: return QPoint(-1, -1);
+ case 6: return QPoint(1, 1);
+ case 7: return QPoint(255, 255);
+ case 8: return QPoint(256, 256);
+ case 9: return QPoint(-254, -254);
+ case 10: return QPoint(-255, -255);
+ }
+
+ return QPoint();
+}
+#define MAX_QPOINT_DATA 11
+
+
+void tst_QDataStream::stream_QPoint_data()
+{
+ stream_data(MAX_QPOINT_DATA);
+}
+
+void tst_QDataStream::stream_QPoint()
+{
+ STREAM_IMPL(QPoint);
+}
+
+void tst_QDataStream::writeQPoint(QDataStream *s)
+{
+ QPoint d17(qPointData(dataIndex(QTest::currentDataTag())));
+ *s << d17;
+
+ QPointF d17f = d17;
+ *s << d17f;
+}
+
+void tst_QDataStream::readQPoint(QDataStream *s)
+{
+ QPoint ref(qPointData(dataIndex(QTest::currentDataTag())));
+ QPoint d17;
+ *s >> d17;
+ QVERIFY(d17 == ref);
+
+ QPointF d17f;
+ *s >> d17f;
+ QVERIFY(d17f == QPointF(ref));
+}
+
+// ************************************
+
+static QRect qRectData(int index)
+{
+ switch (index) {
+ case 0: return QRect(0, 0, 0, 0);
+ case 1: return QRect(1, 1, 1, 1);
+ case 2: return QRect(1, 2, 3, 4);
+ case 3: return QRect(-1, -1, -1, -1);
+ case 4: return QRect(-1, -2, -3, -4);
+ case 5: return QRect(255, -5, 256, -6);
+ case 6: return QRect(-7, 255, -8, 256);
+ case 7: return QRect(9, -255, 10, -255);
+ case 8: return QRect(-255, 11, -255, 12);
+ case 9: return QRect(256, 512, 1024, 2048);
+ case 10: return QRect(-256, -512, -1024, -2048);
+ }
+ return QRect();
+}
+#define MAX_QRECT_DATA 11
+
+void tst_QDataStream::stream_QRect_data()
+{
+ stream_data(MAX_QRECT_DATA);
+}
+
+void tst_QDataStream::stream_QRect()
+{
+ STREAM_IMPL(QRect);
+}
+
+void tst_QDataStream::writeQRect(QDataStream *s)
+{
+ QRect d18(qRectData(dataIndex(QTest::currentDataTag())));
+ *s << d18;
+
+ QRectF d18f(d18);
+ *s << d18f;
+}
+
+void tst_QDataStream::readQRect(QDataStream *s)
+{
+ QRect ref(qRectData(dataIndex(QTest::currentDataTag())));
+ QRect d18;
+ *s >> d18;
+ QVERIFY(d18 == ref);
+
+ QRectF d18f;
+ *s >> d18f;
+ QVERIFY(d18f == QRectF(ref));
+}
+
+// ************************************
+
+static QPolygon qPolygonData(int index)
+{
+ QPoint p0(0, 0);
+ QPoint p1(1, 1);
+ QPoint p2(-1, -1);
+ QPoint p3(1, -1);
+ QPoint p4(-1, 1);
+ QPoint p5(0, 255);
+ QPoint p6(0, 256);
+ QPoint p7(0, 1024);
+ QPoint p8(255, 0);
+ QPoint p9(256, 0);
+ QPoint p10(1024, 0);
+ QPoint p11(345, 678);
+ QPoint p12(23456, 99999);
+ QPoint p13(-99998, -34567);
+ QPoint p14(45678, -99999);
+
+ switch (index) {
+ case 0:
+ return QPolygon(0);
+ case 1:
+ {
+ QPolygon p(1);
+ p.setPoint(0, p0);
+ return p;
+ }
+ case 2:
+ {
+ QPolygon p(1);
+ p.setPoint(0, p5);
+ return p;
+ }
+ case 3:
+ {
+ QPolygon p(1);
+ p.setPoint(0, p12);
+ return p;
+ }
+ case 4:
+ {
+ QPolygon p(3);
+ p.setPoint(0, p1);
+ p.setPoint(1, p10);
+ p.setPoint(2, p13);
+ return p;
+ }
+ case 5:
+ {
+ QPolygon p(6);
+ p.setPoint(0, p2);
+ p.setPoint(1, p11);
+ p.setPoint(2, p14);
+ return p;
+ }
+ case 6:
+ {
+ QPolygon p(15);
+ p.setPoint(0, p0);
+ p.setPoint(1, p1);
+ p.setPoint(2, p2);
+ p.setPoint(3, p3);
+ p.setPoint(4, p4);
+ p.setPoint(5, p5);
+ p.setPoint(6, p6);
+ p.setPoint(7, p7);
+ p.setPoint(8, p8);
+ p.setPoint(9, p9);
+ p.setPoint(10, p10);
+ p.setPoint(11, p11);
+ p.setPoint(12, p12);
+ p.setPoint(13, p13);
+ p.setPoint(14, p14);
+ return p;
+ }
+ }
+ return QRect();
+}
+#define MAX_QPOINTARRAY_DATA 7
+
+void tst_QDataStream::stream_QPolygon_data()
+{
+ stream_data(1);
+}
+
+void tst_QDataStream::stream_QPolygon()
+{
+ STREAM_IMPL(QPolygon);
+}
+
+void tst_QDataStream::writeQPolygon(QDataStream *s)
+{
+ QPolygon d19(qPolygonData(dataIndex(QTest::currentDataTag())));
+ *s << d19;
+
+ QPolygonF d19f(d19);
+ *s << d19f;
+}
+
+void tst_QDataStream::readQPolygon(QDataStream *s)
+{
+ QPolygon ref(qPolygonData(dataIndex(QTest::currentDataTag())));
+ QPolygon d19;
+ *s >> d19;
+ QVERIFY(d19 == ref);
+
+ QPolygonF d19f;
+ *s >> d19f;
+ QVERIFY(d19f == QPolygonF(ref));
+}
+
+// ************************************
+
+static QRegion qRegionData(int index)
+{
+ switch (index) {
+ case 0: return QRegion(0, 0, 0, 0, QRegion::Rectangle);
+ case 1:
+ {
+ QRegion r(1, 2, 300, 400, QRegion::Rectangle);
+ if (r != QRegion(1, 2, 300, 400, QRegion::Rectangle))
+ qDebug("Error creating a region");
+ return r;
+ }
+ case 2: return QRegion(100, 100, 1024, 768, QRegion::Rectangle);
+ case 3: return QRegion(-100, -100, 1024, 1024, QRegion::Rectangle);
+ case 4: return QRegion(100, -100, 2048, 4096, QRegion::Rectangle);
+ case 5: return QRegion(-100, 100, 4096, 2048, QRegion::Rectangle);
+ case 6: return QRegion(0, 0, 0, 0, QRegion::Ellipse);
+#if defined(Q_OS_SYMBIAN) || (!defined(Q_OS_UNIX) && !defined(Q_OS_WINCE)) // all our Unix platforms use X regions.
+ case 7: return QRegion(1, 2, 300, 400, QRegion::Ellipse);
+ case 8: return QRegion(100, 100, 1024, 768, QRegion::Ellipse);
+ case 9: return QRegion(-100, -100, 1024, 1024, QRegion::Ellipse);
+ case 10: return QRegion(100, -100, 2048, 4096, QRegion::Ellipse);
+ case 11: return QRegion(-100, 100, 4096, 2048, QRegion::Ellipse);
+ // simplest X11 case that fails:
+ case 12: return QRegion(0, 0, 3, 3, QRegion::Ellipse);
+#else
+ case 7:
+ qWarning("Skipping streaming of elliptical regions on embedded, Mac OS X, and X11;"
+ " our pointarray stuff is not that great at approximating.");
+#endif
+ }
+ return QRegion();
+}
+#define MAX_QREGION_DATA 12
+
+void tst_QDataStream::stream_QRegion_data()
+{
+ stream_data(MAX_QREGION_DATA);
+}
+
+void tst_QDataStream::stream_QRegion()
+{
+ STREAM_IMPL(QRegion);
+}
+
+void tst_QDataStream::writeQRegion(QDataStream *s)
+{
+ QRegion r(qRegionData(dataIndex(QTest::currentDataTag())));
+ *s << r;
+}
+
+void tst_QDataStream::readQRegion(QDataStream *s)
+{
+ QRegion ref(qRegionData(dataIndex(QTest::currentDataTag())));
+ QRegion r;
+ *s >> r;
+ QVERIFY(r == ref);
+}
+
+// ************************************
+
+static QSize qSizeData(int index)
+{
+ switch (index) {
+ case 0: return QSize(0, 0);
+ case 1: return QSize(-1, 0);
+ case 2: return QSize(0, -1);
+ case 3: return QSize(1, 0);
+ case 4: return QSize(0, 1);
+ case 5: return QSize(-1, -1);
+ case 6: return QSize(1, 1);
+ case 7: return QSize(255, 255);
+ case 8: return QSize(256, 256);
+ case 9: return QSize(-254, -254);
+ case 10: return QSize(-255, -255);
+ }
+ return QSize();
+}
+#define MAX_QSIZE_DATA 11
+
+void tst_QDataStream::stream_QSize_data()
+{
+ stream_data(MAX_QSIZE_DATA);
+}
+
+void tst_QDataStream::stream_QSize()
+{
+ STREAM_IMPL(QSize);
+}
+
+void tst_QDataStream::writeQSize(QDataStream *s)
+{
+ QSize d21(qSizeData(dataIndex(QTest::currentDataTag())));
+ *s << d21;
+
+ QSizeF d21f(d21);
+ *s << d21f;
+}
+
+void tst_QDataStream::readQSize(QDataStream *s)
+{
+ QSize ref(qSizeData(dataIndex(QTest::currentDataTag())));
+ QSize d21;
+ *s >> d21;
+ QVERIFY(d21 == ref);
+
+ QSizeF d21f;
+ *s >> d21f;
+ QVERIFY(d21f == QSizeF(ref));
+}
+
+// *********************** atEnd ******************************
+
+void tst_QDataStream::stream_atEnd_data()
+{
+ stream_data(MAX_QSTRING_DATA);
+}
+
+void tst_QDataStream::stream_atEnd()
+{
+ QFETCH(QString, device);
+ if (device == "bytearray") {
+ QByteArray ba;
+ QDataStream sout(&ba, QIODevice::WriteOnly);
+ writeQString(&sout);
+
+ QDataStream sin(&ba, QIODevice::ReadOnly);
+ readQString(&sin);
+ QVERIFY(sin.atEnd());
+ } else if (device == "file") {
+ QString fileName = "qdatastream.out";
+ QFile fOut(fileName);
+ QVERIFY(fOut.open(QIODevice::WriteOnly));
+ QDataStream sout(&fOut);
+ writeQString(&sout);
+ fOut.close();
+
+ QFile fIn(fileName);
+ QVERIFY(fIn.open(QIODevice::ReadOnly));
+ QDataStream sin(&fIn);
+ readQString(&sin);
+ QVERIFY(sin.atEnd());
+ fIn.close();
+ } else if (device == "buffer") {
+ {
+ QByteArray ba(0);
+ QBuffer bOut(&ba);
+ bOut.open(QIODevice::WriteOnly);
+ QDataStream sout(&bOut);
+ writeQString(&sout);
+ bOut.close();
+
+ QBuffer bIn(&ba);
+ bIn.open(QIODevice::ReadOnly);
+ QDataStream sin(&bIn);
+ readQString(&sin);
+ QVERIFY(sin.atEnd());
+ bIn.close();
+ }
+
+ // Do the same test again, but this time with an initial size for the bytearray.
+ {
+ QByteArray ba(10000, '\0');
+ QBuffer bOut(&ba);
+ bOut.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ QDataStream sout(&bOut);
+ writeQString(&sout);
+ bOut.close();
+
+ QBuffer bIn(&ba);
+ bIn.open(QIODevice::ReadOnly);
+ QDataStream sin(&bIn);
+ readQString(&sin);
+ QVERIFY(sin.atEnd());
+ bIn.close();
+ }
+ }
+}
+
+class FakeBuffer : public QBuffer
+{
+protected:
+ qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); }
+public:
+ FakeBuffer(bool locked = false) : m_lock(locked) {}
+ void setLocked(bool locked) { m_lock = locked; }
+private:
+ bool m_lock;
+};
+
+#define TEST_WRITE_ERROR(op) \
+ { \
+ FakeBuffer fb(false); \
+ QVERIFY(fb.open(QBuffer::ReadWrite)); \
+ QDataStream fs(&fb); \
+ fs.writeRawData("hello", 5); \
+ /* first write some initial content */ \
+ QCOMPARE(fs.status(), QDataStream::Ok); \
+ QCOMPARE(fb.data(), QByteArray("hello")); \
+ /* then test that writing can cause an error */ \
+ fb.setLocked(true); \
+ fs op; \
+ QCOMPARE(fs.status(), QDataStream::WriteFailed); \
+ QCOMPARE(fb.data(), QByteArray("hello")); \
+ /* finally test that writing after an error doesn't change the stream any more */ \
+ fb.setLocked(false); \
+ fs op; \
+ QCOMPARE(fs.status(), QDataStream::WriteFailed); \
+ QCOMPARE(fb.data(), QByteArray("hello")); \
+ }
+
+void tst_QDataStream::stream_writeError()
+{
+ TEST_WRITE_ERROR(<< true)
+ TEST_WRITE_ERROR(<< (qint8)1)
+ TEST_WRITE_ERROR(<< (quint8)1)
+ TEST_WRITE_ERROR(<< (qint16)1)
+ TEST_WRITE_ERROR(<< (quint16)1)
+ TEST_WRITE_ERROR(<< (qint32)1)
+ TEST_WRITE_ERROR(<< (quint32)1)
+ TEST_WRITE_ERROR(<< (qint64)1)
+ TEST_WRITE_ERROR(<< (quint64)1)
+ TEST_WRITE_ERROR(<< "hello")
+ TEST_WRITE_ERROR(<< (float)1.0)
+ TEST_WRITE_ERROR(<< (double)1.0)
+ TEST_WRITE_ERROR(.writeRawData("test", 4))
+}
+
+void tst_QDataStream::stream_QByteArray2()
+{
+ QByteArray ba;
+ {
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ s << QByteArray("hallo");
+ s << QByteArray("");
+ s << QByteArray();
+ }
+
+ {
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ QByteArray res;
+ s >> res;
+ QCOMPARE(res, QByteArray("hallo"));
+ s >> res;
+ QCOMPARE(res, QByteArray(""));
+ QVERIFY(res.isEmpty());
+ QVERIFY(!res.isNull());
+ s >> res;
+ QCOMPARE(res, QByteArray());
+ QVERIFY(res.isEmpty());
+ QVERIFY(res.isNull());
+ }
+}
+
+void tst_QDataStream::setVersion_data()
+{
+ QTest::addColumn<int>("vers");
+ QDataStream latest;
+
+ for (int vers = 1; vers <= latest.version(); ++vers)
+ QTest::newRow(qPrintable(QString("v_%1").arg(vers))) << vers;
+}
+
+void tst_QDataStream::setVersion()
+{
+ QDataStream latest;
+ QFETCH(int, vers);
+
+ /*
+ Test QKeySequence.
+ */
+ QByteArray ba1;
+ {
+ QDataStream out(&ba1, QIODevice::WriteOnly);
+ out.setVersion(vers);
+ out << QKeySequence(Qt::Key_A) << QKeySequence(Qt::Key_B, Qt::Key_C)
+ << (quint32)0xDEADBEEF;
+ }
+ {
+ QKeySequence keyseq1, keyseq2;
+ quint32 deadbeef;
+ QDataStream in(&ba1, QIODevice::ReadOnly);
+ in.setVersion(vers);
+ in >> keyseq1 >> keyseq2 >> deadbeef;
+ QVERIFY(keyseq1 == QKeySequence(Qt::Key_A));
+ if (vers >= 5) {
+ QVERIFY(keyseq2 == QKeySequence(Qt::Key_B, Qt::Key_C));
+ } else {
+ QVERIFY(keyseq2 == QKeySequence(Qt::Key_B));
+ }
+ QVERIFY(deadbeef == 0xDEADBEEF);
+ }
+
+ /*
+ Test QPalette.
+ */
+
+ // revise the test if new color roles or color groups are added
+ QVERIFY(QPalette::NColorRoles == QPalette::ToolTipText + 1);
+ QVERIFY(QPalette::NColorGroups == 3);
+
+ QByteArray ba2;
+ QPalette pal1, pal2;
+ for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
+ for (int role = 0; role < (int)QPalette::NColorRoles; ++role) {
+ // random stuff
+ pal1.setColor((QPalette::ColorGroup)grp, (QPalette::ColorRole)role,
+ QColor(grp * 13, 255 - grp, role));
+ pal2.setColor((QPalette::ColorGroup)grp, (QPalette::ColorRole)role,
+ QColor(role * 11, 254 - role, grp));
+ }
+ }
+
+ {
+ QDataStream out(&ba2, QIODevice::WriteOnly);
+ out.setVersion(vers);
+ out << pal1 << pal2 << (quint32)0xCAFEBABE;
+ }
+ {
+ QPalette inPal1, inPal2;
+ quint32 cafebabe;
+ QDataStream in(&ba2, QIODevice::ReadOnly);
+ in.setVersion(vers);
+ in >> inPal1 >> inPal2;
+ in >> cafebabe;
+
+ QCOMPARE(cafebabe, 0xCAFEBABE);
+
+ QCOMPARE(NColorRoles[latest.version()], (int)QPalette::NColorRoles); //if this fails you need to update the NColorRoles array
+
+ if (vers == 1) {
+ for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Foreground)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Foreground));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Background)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Background));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Light)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Light));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Dark)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Dark));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Mid)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Mid));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Text)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Text));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Base)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Base));
+
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Midlight)
+ != inPal1.color((QPalette::ColorGroup)grp, QPalette::Midlight));
+ }
+ } else {
+ if (NColorRoles[vers] < QPalette::NColorRoles) {
+ QVERIFY(pal1 != inPal1);
+ QVERIFY(pal2 != inPal2);
+
+ for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
+ for (int i = NColorRoles[vers]; i < QPalette::NColorRoles; ++i) {
+ inPal1.setColor((QPalette::ColorGroup)grp, (QPalette::ColorRole)i,
+ pal1.color((QPalette::ColorGroup)grp, (QPalette::ColorRole)i));
+ inPal2.setColor((QPalette::ColorGroup)grp, (QPalette::ColorRole)i,
+ pal2.color((QPalette::ColorGroup)grp, (QPalette::ColorRole)i));
+ }
+ }
+ }
+ QVERIFY(pal1 == inPal1);
+ QVERIFY(pal2 == inPal2);
+ }
+ }
+}
+
+class SequentialBuffer : public QBuffer
+{
+public:
+ SequentialBuffer(QByteArray *data) : QBuffer(data) { offset = 0; }
+
+ bool isSequential() const { return true; }
+ bool seek(qint64 pos) { offset = pos; return QBuffer::seek(pos); }
+ qint64 pos() const { return qint64(offset); }
+
+protected:
+ qint64 readData(char *data, qint64 maxSize)
+ {
+ qint64 ret = QBuffer::readData(data, maxSize);
+ offset += ret;
+ return ret;
+ }
+
+private:
+ int offset;
+};
+
+void tst_QDataStream::skipRawData_data()
+{
+ QTest::addColumn<QString>("deviceType");
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("read");
+ QTest::addColumn<int>("skip");
+ QTest::addColumn<int>("skipped");
+ QTest::addColumn<char>("expect");
+
+ QByteArray bigData;
+ bigData.fill('a', 20000);
+ bigData[10001] = 'x';
+
+ QTest::newRow("1") << QString("sequential") << QByteArray("abcdefghij") << 3 << 6 << 6 << 'j';
+ QTest::newRow("2") << QString("random-access") << QByteArray("abcdefghij") << 3 << 6 << 6 << 'j';
+ QTest::newRow("3") << QString("sequential") << bigData << 1 << 10000 << 10000 << 'x';
+ QTest::newRow("4") << QString("random-access") << bigData << 1 << 10000 << 10000 << 'x';
+ QTest::newRow("5") << QString("sequential") << bigData << 1 << 20000 << 19999 << '\0';
+ QTest::newRow("6") << QString("random-access") << bigData << 1 << 20000 << 19999 << '\0';
+}
+
+void tst_QDataStream::skipRawData()
+{
+ QFETCH(QString, deviceType);
+ QFETCH(QByteArray, data);
+ QFETCH(int, read);
+ QFETCH(int, skip);
+ QFETCH(int, skipped);
+ QFETCH(char, expect);
+ qint8 dummy;
+
+ QIODevice *dev = 0;
+ if (deviceType == "sequential") {
+ dev = new SequentialBuffer(&data);
+ } else if (deviceType == "random-access") {
+ dev = new QBuffer(&data);
+ }
+ QVERIFY(dev);
+ dev->open(QIODevice::ReadOnly);
+
+ QDataStream in(dev);
+ for (int i = 0; i < read; ++i)
+ in >> dummy;
+
+ QCOMPARE(in.skipRawData(skip), skipped);
+ in >> dummy;
+ QCOMPARE((char)dummy, expect);
+
+ delete dev;
+}
+
+#define TEST_qint(T, UT) \
+ void tst_QDataStream::status_##T() \
+ { \
+ QFETCH(QByteArray, bigEndianData); \
+ QFETCH(QByteArray, littleEndianData); \
+ QFETCH(int, expectedStatus); \
+ QFETCH(qint64, expectedValue); \
+ \
+ { \
+ QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \
+ T i; \
+ stream >> i; \
+ QCOMPARE((int) stream.status(), expectedStatus); \
+ QCOMPARE(i, (T) expectedValue); \
+ } \
+ { \
+ QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \
+ UT i; \
+ stream >> i; \
+ QCOMPARE((int) stream.status(), expectedStatus); \
+ QCOMPARE((T) i, (T) expectedValue); \
+ } \
+ { \
+ QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \
+ stream.setByteOrder(QDataStream::LittleEndian); \
+ T i; \
+ stream >> i; \
+ QCOMPARE((int) stream.status(), expectedStatus); \
+ QCOMPARE(i, (T) expectedValue); \
+ } \
+ { \
+ QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \
+ stream.setByteOrder(QDataStream::LittleEndian); \
+ UT i; \
+ stream >> i; \
+ QCOMPARE((int) stream.status(), expectedStatus); \
+ QCOMPARE((T) i, (T) expectedValue); \
+ } \
+ }
+
+#define TEST_FLOAT(T) \
+ void tst_QDataStream::status_##T() \
+ { \
+ QFETCH(QByteArray, bigEndianData); \
+ QFETCH(QByteArray, littleEndianData); \
+ QFETCH(int, expectedStatus); \
+ QFETCH(double, expectedValue); \
+ \
+ QDataStream::FloatingPointPrecision prec = sizeof(T) == sizeof(double) ? QDataStream::DoublePrecision : QDataStream::SinglePrecision; \
+ \
+ { \
+ QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \
+ stream.setFloatingPointPrecision(prec); \
+ T i; \
+ stream >> i; \
+ QCOMPARE((int) stream.status(), expectedStatus); \
+ QCOMPARE((float) i, (float) expectedValue); \
+ } \
+ { \
+ QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \
+ stream.setByteOrder(QDataStream::LittleEndian); \
+ stream.setFloatingPointPrecision(prec); \
+ T i; \
+ stream >> i; \
+ QCOMPARE((int) stream.status(), expectedStatus); \
+ QCOMPARE((float) i, (float) expectedValue); \
+ } \
+ }
+
+void tst_QDataStream::status_qint8_data()
+{
+ QTest::addColumn<QByteArray>("bigEndianData");
+ QTest::addColumn<QByteArray>("littleEndianData");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<qint64>("expectedValue");
+
+ // ok
+ QTest::newRow("0") << QByteArray(1, '\x0') << QByteArray(1, '\x0') << (int) QDataStream::Ok << qint64(0);
+ QTest::newRow("-1") << QByteArray(1, '\xff') << QByteArray(1, '\xff') << (int) QDataStream::Ok << qint64(-1);
+ QTest::newRow("1") << QByteArray(1, '\x01') << QByteArray(1, '\x01') << (int) QDataStream::Ok << qint64(1);
+ QTest::newRow("37") << QByteArray(1, '\x25') << QByteArray(1, '\x25') << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("37j") << QByteArray("\x25j") << QByteArray("\x25j") << (int) QDataStream::Ok << qint64(37);
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
+}
+
+TEST_qint(qint8, quint8)
+
+void tst_QDataStream::status_qint16_data()
+{
+ QTest::addColumn<QByteArray>("bigEndianData");
+ QTest::addColumn<QByteArray>("littleEndianData");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<qint64>("expectedValue");
+
+ // ok
+ QTest::newRow("0") << QByteArray(2, '\x0') << QByteArray(2, '\x0') << (int) QDataStream::Ok << qint64(0);
+ QTest::newRow("-1") << QByteArray("\xff\xff", 2) << QByteArray("\xff\xff", 2) << (int) QDataStream::Ok << qint64(-1);
+ QTest::newRow("1") << QByteArray("\x00\x01", 2) << QByteArray("\x01\x00", 2) << (int) QDataStream::Ok << qint64(1);
+ QTest::newRow("37") << QByteArray("\x00\x25", 2) << QByteArray("\x25\x00", 2) << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("37j") << QByteArray("\x00\x25j", 3) << QByteArray("\x25\x00j", 3) << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("0x1234") << QByteArray("\x12\x34", 2) << QByteArray("\x34\x12", 2) << (int) QDataStream::Ok << qint64(0x1234);
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
+}
+
+TEST_qint(qint16, quint16)
+
+void tst_QDataStream::status_qint32_data()
+{
+ QTest::addColumn<QByteArray>("bigEndianData");
+ QTest::addColumn<QByteArray>("littleEndianData");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<qint64>("expectedValue");
+
+ // ok
+ QTest::newRow("0") << QByteArray(4, '\x0') << QByteArray(4, '\x0') << (int) QDataStream::Ok << qint64(0);
+ QTest::newRow("-1") << QByteArray("\xff\xff\xff\xff", 4) << QByteArray("\xff\xff\xff\xff", 4) << (int) QDataStream::Ok << qint64(-1);
+ QTest::newRow("1") << QByteArray("\x00\x00\x00\x01", 4) << QByteArray("\x01\x00\x00\x00", 4) << (int) QDataStream::Ok << qint64(1);
+ QTest::newRow("37") << QByteArray("\x00\x00\x00\x25", 4) << QByteArray("\x25\x00\x00\x00", 4) << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("37j") << QByteArray("\x00\x00\x00\x25j", 5) << QByteArray("\x25\x00\x00\x00j", 5) << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("0x12345678") << QByteArray("\x12\x34\x56\x78", 4) << QByteArray("\x78\x56\x34\x12", 4) << (int) QDataStream::Ok << qint64(0x12345678);
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << qint64(0);
+}
+
+TEST_qint(qint32, quint32)
+
+void tst_QDataStream::status_qint64_data()
+{
+ QTest::addColumn<QByteArray>("bigEndianData");
+ QTest::addColumn<QByteArray>("littleEndianData");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<qint64>("expectedValue");
+
+ // ok
+ QTest::newRow("0") << QByteArray(8, '\x0') << QByteArray(8, '\x0') << (int) QDataStream::Ok << qint64(0);
+ QTest::newRow("-1") << QByteArray("\xff\xff\xff\xff\xff\xff\xff\xff", 8) << QByteArray("\xff\xff\xff\xff\xff\xff\xff\xff", 8) << (int) QDataStream::Ok << qint64(-1);
+ QTest::newRow("1") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x01", 8) << QByteArray("\x01\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << qint64(1);
+ QTest::newRow("37") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x25", 8) << QByteArray("\x25\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("37j") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x25j", 9) << QByteArray("\x25\x00\x00\x00\x00\x00\x00\x00j", 9) << (int) QDataStream::Ok << qint64(37);
+ QTest::newRow("0x123456789ABCDEF0") << QByteArray("\x12\x34\x56\x78\x9a\xbc\xde\xf0", 8) << QByteArray("\xf0\xde\xbc\x9a\x78\x56\x34\x12", 8) << (int) QDataStream::Ok << (qint64)Q_INT64_C(0x123456789ABCDEF0);
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 5") << QByteArray("1111", 4) << QByteArray("1111", 4) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 6") << QByteArray("11111", 5) << QByteArray("11111", 5) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 7") << QByteArray("111111", 6) << QByteArray("111111", 6) << (int) QDataStream::ReadPastEnd << qint64(0);
+ QTest::newRow("end 8") << QByteArray("1111111", 7) << QByteArray("1111111", 7) << (int) QDataStream::ReadPastEnd << qint64(0);
+}
+
+TEST_qint(qint64, quint64)
+
+void tst_QDataStream::status_float_data()
+{
+ QTest::addColumn<QByteArray>("bigEndianData");
+ QTest::addColumn<QByteArray>("littleEndianData");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<double>("expectedValue");
+
+ // ok
+ QTest::newRow("0") << QByteArray(4, '\0') << QByteArray(4, '\0') << (int) QDataStream::Ok << (double) 0.0;
+ QTest::newRow("-1") << QByteArray("\xbf\x80\x00\x00", 4) << QByteArray("\x00\x00\x80\xbf", 4) << (int) QDataStream::Ok << (double) -1;
+ QTest::newRow("1") << QByteArray("\x3f\x80\x00\x00", 4) << QByteArray("\x00\x00\x80\x3f", 4) << (int) QDataStream::Ok << (double) 1;
+ QTest::newRow("37") << QByteArray("\x42\x14\x00\x00", 4) << QByteArray("\x00\x00\x14\x42", 4) << (int) QDataStream::Ok << (double) 37;
+ QTest::newRow("37j") << QByteArray("\x42\x14\x00\x00j", 5) << QByteArray("\x00\x00\x14\x42j", 5) << (int) QDataStream::Ok << (double) 37;
+ QTest::newRow("3.14") << QByteArray("\x40\x48\xf5\xc3", 4) << QByteArray("\xc3\xf5\x48\x40", 4) << (int) QDataStream::Ok << (double) 3.14;
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << double(0);
+}
+
+TEST_FLOAT(float)
+
+void tst_QDataStream::status_double_data()
+{
+ QTest::addColumn<QByteArray>("bigEndianData");
+ QTest::addColumn<QByteArray>("littleEndianData");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<double>("expectedValue");
+
+ // ok
+ QTest::newRow("0") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << (double) 0;
+ QTest::newRow("-1") << QByteArray("\xbf\xf0\x00\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x00\xf0\xbf", 8) << (int) QDataStream::Ok << (double) -1;
+ QTest::newRow("1") << QByteArray("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8) << (int) QDataStream::Ok << (double) 1;
+ QTest::newRow("37") << QByteArray("\x40\x42\x80\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x80\x42\x40", 8) << (int) QDataStream::Ok << (double) 37;
+ QTest::newRow("37j") << QByteArray("\x40\x42\x80\x00\x00\x00\x00\x00j", 9) << QByteArray("\x00\x00\x00\x00\x00\x80\x42\x40j", 9) << (int) QDataStream::Ok << (double) 37;
+ QTest::newRow("3.14") << QByteArray("\x40\x09\x1e\xb8\x60\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x60\xb8\x1e\x09\x40", 8) << (int) QDataStream::Ok << (double) 3.14;
+ QTest::newRow("1234.5678") << QByteArray("\x40\x93\x4a\x45\x6d\x5c\xfa\xad", 8) << QByteArray("\xad\xfa\x5c\x6d\x45\x4a\x93\x40", 8) << (int) QDataStream::Ok << (double) 1234.5678;
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 5") << QByteArray("1111", 4) << QByteArray("1111", 4) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 6") << QByteArray("11111", 5) << QByteArray("11111", 5) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 7") << QByteArray("111111", 6) << QByteArray("111111", 6) << (int) QDataStream::ReadPastEnd << double(0);
+ QTest::newRow("end 8") << QByteArray("1111111", 7) << QByteArray("1111111", 7) << (int) QDataStream::ReadPastEnd << double(0);
+}
+
+TEST_FLOAT(double)
+
+void tst_QDataStream::status_charptr_QByteArray_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<QByteArray>("expectedString");
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QByteArray oneMbMinus1(1024 * 1024 - 1, '\0');
+ for (int i = 0; i < oneMbMinus1.size(); ++i)
+ oneMbMinus1[i] = 0x1 | (8 * ((uchar)i / 9));
+ QByteArray threeMbMinus1 = oneMbMinus1 + 'j' + oneMbMinus1 + 'k' + oneMbMinus1;
+#endif
+
+ // ok
+ QTest::newRow("size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QByteArray();
+ QTest::newRow("size 1") << QByteArray("\x00\x00\x00\x01j", 5) << (int) QDataStream::Ok << QByteArray("j");
+ QTest::newRow("size 2") << QByteArray("\x00\x00\x00\x02jk", 6) << (int) QDataStream::Ok << QByteArray("jk");
+ QTest::newRow("size 3") << QByteArray("\x00\x00\x00\x03jkl", 7) << (int) QDataStream::Ok << QByteArray("jkl");
+ QTest::newRow("size 4") << QByteArray("\x00\x00\x00\x04jklm", 8) << (int) QDataStream::Ok << QByteArray("jklm");
+ QTest::newRow("size 4j") << QByteArray("\x00\x00\x00\x04jklmj", 8) << (int) QDataStream::Ok << QByteArray("jklm");
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("size 1MB-1") << QByteArray("\x00\x0f\xff\xff", 4) + oneMbMinus1 + QByteArray("j") << (int) QDataStream::Ok << oneMbMinus1;
+ QTest::newRow("size 1MB") << QByteArray("\x00\x10\x00\x00", 4) + oneMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << oneMbMinus1 + "j";
+ QTest::newRow("size 1MB+1") << QByteArray("\x00\x10\x00\x01", 4) + oneMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << oneMbMinus1 + "jk";
+ QTest::newRow("size 3MB-1") << QByteArray("\x00\x2f\xff\xff", 4) + threeMbMinus1 + QByteArray("j") << (int) QDataStream::Ok << threeMbMinus1;
+ QTest::newRow("size 3MB") << QByteArray("\x00\x30\x00\x00", 4) + threeMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << threeMbMinus1 + "j";
+ QTest::newRow("size 3MB+1") << QByteArray("\x00\x30\x00\x01", 4) + threeMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << threeMbMinus1 + "jk";
+#endif
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("trunclen 1") << QByteArray("x") << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("trunclen 2") << QByteArray("xx") << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("trunclen 3") << QByteArray("xxx") << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("truncdata 1") << QByteArray("xxxx") << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("truncdata 2") << QByteArray("xxxxyyyy") << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 1") << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 2") << QByteArray("\x00\x00\x00\x02j", 5) << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 3") << QByteArray("\x00\x00\x00\x03jk", 6) << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 4") << QByteArray("\x00\x00\x00\x04jkl", 7) << (int) QDataStream::ReadPastEnd << QByteArray();
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("badsize 1MB") << QByteArray("\x00\x10\x00\x00", 4) + oneMbMinus1 << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 1MB+1") << QByteArray("\x00\x10\x00\x01", 4) + oneMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 3MB") << QByteArray("\x00\x30\x00\x00", 4) + threeMbMinus1 << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("badsize 3MB+1") << QByteArray("\x00\x30\x00\x01", 4) + threeMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
+#endif
+ QTest::newRow("size -1") << QByteArray("\xff\xff\xff\xff", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
+ QTest::newRow("size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
+}
+
+void tst_QDataStream::status_charptr_QByteArray()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, expectedStatus);
+ QFETCH(QByteArray, expectedString);
+
+ {
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ char *buf;
+ stream >> buf;
+
+ QCOMPARE((int)qstrlen(buf), expectedString.size());
+ QCOMPARE(QByteArray(buf), expectedString);
+ QCOMPARE(int(stream.status()), expectedStatus);
+ delete [] buf;
+ }
+ {
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ char *buf;
+ uint len;
+ stream.readBytes(buf, len);
+
+ QCOMPARE((int)len, expectedString.size());
+ QCOMPARE(QByteArray(buf, len), expectedString);
+ QCOMPARE(int(stream.status()), expectedStatus);
+ delete [] buf;
+ }
+ {
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ QByteArray buf;
+ stream >> buf;
+
+ if (data.startsWith("\xff\xff\xff\xff")) {
+ // QByteArray, unlike 'char *', supports the null/empty distinction
+ QVERIFY(buf.isNull());
+ } else {
+ QCOMPARE(buf.size(), expectedString.size());
+ QCOMPARE(buf, expectedString);
+ QCOMPARE(int(stream.status()), expectedStatus);
+ }
+ }
+}
+
+static QByteArray qstring2qbytearray(const QString &str)
+{
+ QByteArray ba(str.size() * 2 , '\0');
+ for (int i = 0; i < str.size(); ++i) {
+ // BigEndian
+ ba[2 * i] = str[i].row();
+ ba[2 * i + 1] = str[i].cell();
+ }
+ return ba;
+}
+
+void tst_QDataStream::status_QString_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<QString>("expectedString");
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QString oneMbMinus1;
+ oneMbMinus1.resize(1024 * 1024 - 1);
+ for (int i = 0; i < oneMbMinus1.size(); ++i)
+ oneMbMinus1[i] = 0x1 | (8 * ((uchar)i / 9));
+ QString threeMbMinus1 = oneMbMinus1 + QChar('j') + oneMbMinus1 + QChar('k') + oneMbMinus1;
+
+ QByteArray threeMbMinus1Data = qstring2qbytearray(threeMbMinus1);
+ QByteArray oneMbMinus1Data = qstring2qbytearray(oneMbMinus1);
+#endif
+
+ // ok
+ QTest::newRow("size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QString();
+ QTest::newRow("size 1") << QByteArray("\x00\x00\x00\x02\x00j", 6) << (int) QDataStream::Ok << QString("j");
+ QTest::newRow("size 2") << QByteArray("\x00\x00\x00\x04\x00j\x00k", 8) << (int) QDataStream::Ok << QString("jk");
+ QTest::newRow("size 3") << QByteArray("\x00\x00\x00\x06\x00j\x00k\x00l", 10) << (int) QDataStream::Ok << QString("jkl");
+ QTest::newRow("size 4") << QByteArray("\x00\x00\x00\x08\x00j\x00k\x00l\x00m", 12) << (int) QDataStream::Ok << QString("jklm");
+ QTest::newRow("size 4j") << QByteArray("\x00\x00\x00\x08\x00j\x00k\x00l\x00mjj", 14) << (int) QDataStream::Ok << QString("jklm");
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("size 1MB-1") << QByteArray("\x00\x1f\xff\xfe", 4) + oneMbMinus1Data + QByteArray("jj") << (int) QDataStream::Ok << oneMbMinus1;
+ QTest::newRow("size 1MB") << QByteArray("\x00\x20\x00\x00", 4) + oneMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << oneMbMinus1 + "j";
+ QTest::newRow("size 1MB+1") << QByteArray("\x00\x20\x00\x02", 4) + oneMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << oneMbMinus1 + "jk";
+ QTest::newRow("size 3MB-1") << QByteArray("\x00\x5f\xff\xfe", 4) + threeMbMinus1Data + QByteArray("jj") << (int) QDataStream::Ok << threeMbMinus1;
+ QTest::newRow("size 3MB") << QByteArray("\x00\x60\x00\x00", 4) + threeMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << threeMbMinus1 + "j";
+ QTest::newRow("size 3MB+1") << QByteArray("\x00\x60\x00\x02", 4) + threeMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << threeMbMinus1 + "jk";
+#endif
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("trunclen 1") << QByteArray("x") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("trunclen 2") << QByteArray("xx") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("trunclen 3") << QByteArray("xxx") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("truncdata 1") << QByteArray("xxxx") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("truncdata 2") << QByteArray("xxxxyyyy") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 1") << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 2") << QByteArray("\x00\x00\x00\x04jj", 6) << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 3") << QByteArray("\x00\x00\x00\x06jjkk", 8) << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 4") << QByteArray("\x00\x00\x00\x08jjkkll", 10) << (int) QDataStream::ReadPastEnd << QString();
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("badsize 1MB") << QByteArray("\x00\x20\x00\x00", 4) + oneMbMinus1Data << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 1MB+1") << QByteArray("\x00\x20\x00\x02", 4) + oneMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 3MB") << QByteArray("\x00\x60\x00\x00", 4) + threeMbMinus1Data << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("badsize 3MB+1") << QByteArray("\x00\x60\x00\x02", 4) + threeMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("size MAX") << QByteArray("\x7f\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
+#endif
+
+ // corrupt data
+ QTest::newRow("corrupt1") << QByteArray("yyyy") << (int) QDataStream::ReadCorruptData << QString();
+ QTest::newRow("size -3") << QByteArray("\xff\xff\xff\xfd", 4) << (int) QDataStream::ReadCorruptData << QString();
+}
+
+void tst_QDataStream::status_QString()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, expectedStatus);
+ QFETCH(QString, expectedString);
+
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ QString str;
+ stream >> str;
+
+ QCOMPARE(str.size(), expectedString.size());
+ QCOMPARE(str, expectedString);
+ QCOMPARE(int(stream.status()), expectedStatus);
+}
+
+static QBitArray bitarray(const QString &str)
+{
+ QBitArray array(str.size());
+ for (int i = 0; i < str.size(); ++i)
+ array[i] = (str[i] != '0');
+ return array;
+}
+
+void tst_QDataStream::status_QBitArray_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("expectedStatus");
+ QTest::addColumn<QBitArray>("expectedString");
+
+ // ok
+ QTest::newRow("size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QBitArray();
+ QTest::newRow("size 1a") << QByteArray("\x00\x00\x00\x01\x00", 5) << (int) QDataStream::Ok << bitarray("0");
+ QTest::newRow("size 1b") << QByteArray("\x00\x00\x00\x01\x01", 5) << (int) QDataStream::Ok << bitarray("1");
+ QTest::newRow("size 2") << QByteArray("\x00\x00\x00\x02\x03", 5) << (int) QDataStream::Ok << bitarray("11");
+ QTest::newRow("size 3") << QByteArray("\x00\x00\x00\x03\x07", 5) << (int) QDataStream::Ok << bitarray("111");
+ QTest::newRow("size 4") << QByteArray("\x00\x00\x00\x04\x0f", 5) << (int) QDataStream::Ok << bitarray("1111");
+ QTest::newRow("size 5") << QByteArray("\x00\x00\x00\x05\x1f", 5) << (int) QDataStream::Ok << bitarray("11111");
+ QTest::newRow("size 6") << QByteArray("\x00\x00\x00\x06\x3f", 5) << (int) QDataStream::Ok << bitarray("111111");
+ QTest::newRow("size 7a") << QByteArray("\x00\x00\x00\x07\x7f", 5) << (int) QDataStream::Ok << bitarray("1111111");
+ QTest::newRow("size 7b") << QByteArray("\x00\x00\x00\x07\x7e", 5) << (int) QDataStream::Ok << bitarray("0111111");
+ QTest::newRow("size 7c") << QByteArray("\x00\x00\x00\x07\x00", 5) << (int) QDataStream::Ok << bitarray("0000000");
+ QTest::newRow("size 7d") << QByteArray("\x00\x00\x00\x07\x39", 5) << (int) QDataStream::Ok << bitarray("1001110");
+ QTest::newRow("size 8") << QByteArray("\x00\x00\x00\x08\xff", 5) << (int) QDataStream::Ok << bitarray("11111111");
+ QTest::newRow("size 9") << QByteArray("\x00\x00\x00\x09\xff\x01", 6) << (int) QDataStream::Ok << bitarray("111111111");
+ QTest::newRow("size 15") << QByteArray("\x00\x00\x00\x0f\xff\x7f", 6) << (int) QDataStream::Ok << bitarray("111111111111111");
+ QTest::newRow("size 16") << QByteArray("\x00\x00\x00\x10\xff\xff", 6) << (int) QDataStream::Ok << bitarray("1111111111111111");
+ QTest::newRow("size 17") << QByteArray("\x00\x00\x00\x11\xff\xff\x01", 7) << (int) QDataStream::Ok << bitarray("11111111111111111");
+ QTest::newRow("size 32") << QByteArray("\x00\x00\x00\x20\xff\xff\xff\xff", 8) << (int) QDataStream::Ok << bitarray("11111111111111111111111111111111");
+
+ // past end
+ QTest::newRow("empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 0a") << QByteArray("\x00", 1) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 0a") << QByteArray("\x00\x00", 2) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 0a") << QByteArray("\x00\x00\x00", 3) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 1") << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 2") << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 3") << QByteArray("\x00\x00\x00\x03", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 7") << QByteArray("\x00\x00\x00\x04", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("size 8") << QByteArray("\x00\x00\x00\x08", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("size 9") << QByteArray("\x00\x00\x00\x09\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("size 15") << QByteArray("\x00\x00\x00\x0f\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("size 16") << QByteArray("\x00\x00\x00\x10\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("size 17") << QByteArray("\x00\x00\x00\x11\xff\xff", 6) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("size 32") << QByteArray("\x00\x00\x00\x20\xff\xff\xff", 7) << (int) QDataStream::ReadPastEnd << QBitArray();
+
+ // corrupt data
+ QTest::newRow("junk 1a") << QByteArray("\x00\x00\x00\x01\x02", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1b") << QByteArray("\x00\x00\x00\x01\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1c") << QByteArray("\x00\x00\x00\x01\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1d") << QByteArray("\x00\x00\x00\x01\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1e") << QByteArray("\x00\x00\x00\x01\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1f") << QByteArray("\x00\x00\x00\x01\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1g") << QByteArray("\x00\x00\x00\x01\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 2") << QByteArray("\x00\x00\x00\x02\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 3") << QByteArray("\x00\x00\x00\x03\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 4") << QByteArray("\x00\x00\x00\x04\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 5") << QByteArray("\x00\x00\x00\x05\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 6") << QByteArray("\x00\x00\x00\x06\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 7") << QByteArray("\x00\x00\x00\x07\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+}
+
+void tst_QDataStream::status_QBitArray()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, expectedStatus);
+ QFETCH(QBitArray, expectedString);
+
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ QBitArray str;
+ stream >> str;
+
+ QCOMPARE(int(stream.status()), expectedStatus);
+ QCOMPARE(str.size(), expectedString.size());
+ QCOMPARE(str, expectedString);
+}
+
+#define MAP_TEST(byteArray, expectedStatus, expectedHash) \
+ { \
+ QByteArray ba = byteArray; \
+ QDataStream stream(&ba, QIODevice::ReadOnly); \
+ stream >> hash; \
+ QCOMPARE((int)stream.status(), (int)expectedStatus); \
+ QCOMPARE(hash.size(), expectedHash.size()); \
+ QCOMPARE(hash, expectedHash); \
+ } \
+ { \
+ QByteArray ba = byteArray; \
+ StringMap expectedMap; \
+ StringHash::const_iterator it = expectedHash.constBegin(); \
+ for (; it != expectedHash.constEnd(); ++it) \
+ expectedMap.insert(it.key(), it.value()); \
+ QDataStream stream(&ba, QIODevice::ReadOnly); \
+ stream >> map; \
+ QCOMPARE((int)stream.status(), (int)expectedStatus); \
+ QCOMPARE(map.size(), expectedMap.size()); \
+ QCOMPARE(map, expectedMap); \
+ }
+
+void tst_QDataStream::status_QHash_QMap()
+{
+ typedef QHash<QString, QString> StringHash;
+ typedef QMap<QString, QString> StringMap;
+ StringHash hash;
+ StringMap map;
+
+ StringHash hash1;
+ hash1.insert("", "");
+
+ StringHash hash2;
+ hash2.insert("J", "K");
+ hash2.insert("L", "MN");
+
+ // ok
+ MAP_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, StringHash());
+ MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 12), QDataStream::Ok, hash1);
+ MAP_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J\x00\x00\x00\x02\x00K"
+ "\x00\x00\x00\x02\x00L\x00\x00\x00\x04\x00M\x00N", 30), QDataStream::Ok, hash2);
+
+ // past end
+ MAP_TEST(QByteArray(), QDataStream::ReadPastEnd, StringHash());
+ MAP_TEST(QByteArray("\x00", 1), QDataStream::ReadPastEnd, StringHash());
+ MAP_TEST(QByteArray("\x00\x00", 2), QDataStream::ReadPastEnd, StringHash());
+ MAP_TEST(QByteArray("\x00\x00\x00", 3), QDataStream::ReadPastEnd, StringHash());
+ MAP_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::ReadPastEnd, StringHash());
+ for (int i = 4; i < 12; ++i) {
+ MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", i), QDataStream::ReadPastEnd, StringHash());
+ }
+
+ // corrupt data
+ MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::ReadCorruptData, StringHash());
+ MAP_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x01\x00J\x00\x00\x00\x01\x00K"
+ "\x00\x00\x00\x01\x00L\x00\x00\x00\x02\x00M\x00N", 30), QDataStream::ReadCorruptData, StringHash());
+}
+
+#define LIST_TEST(byteArray, expectedStatus, expectedList) \
+ { \
+ QByteArray ba = byteArray; \
+ QDataStream stream(&ba, QIODevice::ReadOnly); \
+ stream >> list; \
+ QCOMPARE((int)stream.status(), (int)expectedStatus); \
+ QCOMPARE(list.size(), expectedList.size()); \
+ QCOMPARE(list, expectedList); \
+ } \
+ { \
+ LinkedList expectedLinkedList; \
+ for (int i = 0; i < expectedList.count(); ++i) \
+ expectedLinkedList << expectedList.at(i); \
+ QByteArray ba = byteArray; \
+ QDataStream stream(&ba, QIODevice::ReadOnly); \
+ stream >> linkedList; \
+ QCOMPARE((int)stream.status(), (int)expectedStatus); \
+ QCOMPARE(linkedList.size(), expectedLinkedList.size()); \
+ QCOMPARE(linkedList, expectedLinkedList); \
+ } \
+ { \
+ Vector expectedVector; \
+ for (int i = 0; i < expectedList.count(); ++i) \
+ expectedVector << expectedList.at(i); \
+ QByteArray ba = byteArray; \
+ QDataStream stream(&ba, QIODevice::ReadOnly); \
+ stream >> vector; \
+ QCOMPARE((int)stream.status(), (int)expectedStatus); \
+ QCOMPARE(vector.size(), expectedVector.size()); \
+ QCOMPARE(vector, expectedVector); \
+ }
+
+void tst_QDataStream::status_QLinkedList_QList_QVector()
+{
+ typedef QLinkedList<QString> LinkedList;
+ typedef QList<QString> List;
+ typedef QVector<QString> Vector;
+ LinkedList linkedList;
+ List list;
+ Vector vector;
+
+ LIST_TEST(QByteArray(), QDataStream::ReadPastEnd, List());
+ LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, List());
+}
+
+void tst_QDataStream::streamToAndFromQByteArray()
+{
+ QByteArray data;
+ QDataStream in(&data, QIODevice::WriteOnly);
+ QDataStream out(&data, QIODevice::ReadOnly);
+
+ quint32 x = 0xdeadbeef;
+ quint32 y;
+ in << x;
+ out >> y;
+
+ QCOMPARE(y, x);
+}
+
+void tst_QDataStream::streamRealDataTypes()
+{
+ // Generate QPicture from pixmap.
+ QPixmap pm(open_xpm);
+ QVERIFY(!pm.isNull());
+ QPicture picture;
+ picture.setBoundingRect(QRect(QPoint(0, 0), pm.size()));
+ QPainter painter(&picture);
+ painter.drawPixmap(0, 0, pm);
+ painter.end();
+
+ // Generate path
+ QPainterPath path;
+ path.lineTo(10, 0);
+ path.cubicTo(0, 0, 10, 10, 20, 20);
+ path.arcTo(4, 5, 6, 7, 8, 9);
+ path.quadTo(1, 2, 3, 4);
+
+ QColor color(64, 64, 64);
+ color.setAlphaF(0.5);
+ QRadialGradient radialGradient(5, 6, 7, 8, 9);
+ QBrush radialBrush(radialGradient);
+ QConicalGradient conicalGradient(5, 6, 7);
+ QBrush conicalBrush(conicalGradient);
+
+ for (int i = 0; i < 2; ++i) {
+ QFile file;
+ if (i == 0) {
+ file.setFileName(SRCDIR "datastream.q42");
+ } else {
+ file.setFileName("datastream.tmp");
+
+ // Generate data
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QDataStream stream(&file);
+ stream.setVersion(QDataStream::Qt_4_2);
+ stream << qreal(0) << qreal(1.0) << qreal(1.1) << qreal(3.14) << qreal(-3.14) << qreal(-1);
+ stream << QPointF(3, 5) << QRectF(-1, -2, 3, 4) << (QPolygonF() << QPointF(0, 0) << QPointF(1, 2));
+ stream << QMatrix().rotate(90).scale(2, 2);
+ stream << path;
+ stream << picture;
+ stream << QTextLength(QTextLength::VariableLength, 1.5);
+ stream << color;
+ stream << radialBrush << conicalBrush;
+ stream << QPen(QBrush(Qt::red), 1.5);
+
+ file.close();
+ }
+
+ QPointF point;
+ QRectF rect;
+ QPolygonF polygon;
+ QMatrix matrix;
+ QPainterPath p;
+ QPicture pict;
+ QTextLength textLength;
+ QColor col;
+ QBrush rGrad;
+ QBrush cGrad;
+ QPen pen;
+
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QDataStream stream(&file);
+ stream.setVersion(QDataStream::Qt_4_2);
+
+ if (i == 0) {
+ // the reference stream for 4.2 contains doubles,
+ // so we must read them out as doubles!
+ double a, b, c, d, e, f;
+ stream >> a;
+ QCOMPARE(a, 0.0);
+ stream >> b;
+ QCOMPARE(b, 1.0);
+ stream >> c;
+ QCOMPARE(c, 1.1);
+ stream >> d;
+ QCOMPARE(d, 3.14);
+ stream >> e;
+ QCOMPARE(e, -3.14);
+ stream >> f;
+ QCOMPARE(f, -1.0);
+ } else {
+ qreal a, b, c, d, e, f;
+ stream >> a;
+ QCOMPARE(a, qreal(0));
+ stream >> b;
+ QCOMPARE(b, qreal(1.0));
+ stream >> c;
+ QCOMPARE(c, qreal(1.1));
+ stream >> d;
+ QCOMPARE(d, qreal(3.14));
+ stream >> e;
+ QCOMPARE(e, qreal(-3.14));
+ stream >> f;
+ QCOMPARE(f, qreal(-1));
+ }
+ stream >> point;
+ QCOMPARE(point, QPointF(3, 5));
+ stream >> rect;
+ QCOMPARE(rect, QRectF(-1, -2, 3, 4));
+ stream >> polygon;
+ QCOMPARE((QVector<QPointF> &)polygon, (QPolygonF() << QPointF(0, 0) << QPointF(1, 2)));
+ stream >> matrix;
+ QCOMPARE(matrix, QMatrix().rotate(90).scale(2, 2));
+ stream >> p;
+ QCOMPARE(p, path);
+ if (i == 1) {
+ stream >> pict;
+
+ QByteArray pictA, pictB;
+ QBuffer bufA, bufB;
+ QVERIFY(bufA.open(QIODevice::ReadWrite));
+ QVERIFY(bufB.open(QIODevice::ReadWrite));
+
+ picture.save(&bufA);
+ pict.save(&bufB);
+
+ QCOMPARE(pictA, pictB);
+ }
+ stream >> textLength;
+ QCOMPARE(textLength, QTextLength(QTextLength::VariableLength, 1.5));
+ stream >> col;
+ QCOMPARE(col, color);
+ stream >> rGrad;
+ QCOMPARE(rGrad.style(), radialBrush.style());
+ QCOMPARE(rGrad.matrix(), radialBrush.matrix());
+ QCOMPARE(rGrad.gradient()->type(), radialBrush.gradient()->type());
+ QCOMPARE(rGrad.gradient()->stops(), radialBrush.gradient()->stops());
+ QCOMPARE(rGrad.gradient()->spread(), radialBrush.gradient()->spread());
+ QCOMPARE(((QRadialGradient *)rGrad.gradient())->center(), ((QRadialGradient *)radialBrush.gradient())->center());
+ QCOMPARE(((QRadialGradient *)rGrad.gradient())->focalPoint(), ((QRadialGradient *)radialBrush.gradient())->focalPoint());
+ QCOMPARE(((QRadialGradient *)rGrad.gradient())->radius(), ((QRadialGradient *)radialBrush.gradient())->radius());
+ stream >> cGrad;
+ QCOMPARE(cGrad.style(), conicalBrush.style());
+ QCOMPARE(cGrad.matrix(), conicalBrush.matrix());
+ QCOMPARE(cGrad.gradient()->type(), conicalBrush.gradient()->type());
+ QCOMPARE(cGrad.gradient()->stops(), conicalBrush.gradient()->stops());
+ QCOMPARE(cGrad.gradient()->spread(), conicalBrush.gradient()->spread());
+ QCOMPARE(((QConicalGradient *)cGrad.gradient())->center(), ((QConicalGradient *)conicalBrush.gradient())->center());
+ QCOMPARE(((QConicalGradient *)cGrad.gradient())->angle(), ((QConicalGradient *)conicalBrush.gradient())->angle());
+
+ QCOMPARE(cGrad, conicalBrush);
+ stream >> pen;
+ QCOMPARE(pen.widthF(), qreal(1.5));
+
+ QCOMPARE(stream.status(), QDataStream::Ok);
+ }
+}
+
+void tst_QDataStream::compatibility_Qt3()
+{
+ QByteArray ba("hello");
+ QVariant var = ba;
+ const quint32 invalidColor = 0x49000000;
+ QByteArray stream;
+ {
+ QDataStream out(&stream, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_3_3);
+ out << var;
+ out << QColor();
+ out << QColor(Qt::darkYellow);
+ out << QColor(Qt::darkCyan);
+ out << invalidColor;
+ }
+ {
+ QDataStream in(stream);
+ in.setVersion(QDataStream::Qt_3_3);
+
+ //task 196100
+ quint32 type;
+ in >> type;
+ //29 is the type of a QByteArray in Qt3
+ QCOMPARE(type, quint32(29));
+ QByteArray ba2;
+ in >> ba2;
+ QCOMPARE(ba2, ba);
+
+ //task196415
+ quint32 color;
+ in >> color;
+ QCOMPARE(color, invalidColor);
+ in >> color;
+ QCOMPARE(color, QColor(Qt::darkYellow).rgb());
+ QColor col;
+ in >> col;
+ QCOMPARE(col, QColor(Qt::darkCyan));
+ in >> col;
+ QVERIFY(!col.isValid());
+ }
+ {
+ QLinearGradient gradient(QPointF(0,0), QPointF(1,1));
+ gradient.setColorAt(0, Qt::red);
+ gradient.setColorAt(1, Qt::blue);
+
+ QBrush brush(gradient);
+ QPalette palette;
+ palette.setBrush(QPalette::Button, brush);
+ palette.setColor(QPalette::Light, Qt::green);
+
+ QByteArray stream;
+ {
+ QDataStream out(&stream, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_3_3);
+ out << palette;
+ out << brush;
+ }
+ QBrush in_brush;
+ QPalette in_palette;
+ {
+ QDataStream in(stream);
+ in.setVersion(QDataStream::Qt_3_3);
+ in >> in_palette;
+ in >> in_brush;
+ }
+ QVERIFY(in_brush.style() == Qt::NoBrush);
+ QVERIFY(in_palette.brush(QPalette::Button).style() == Qt::NoBrush);
+ QVERIFY(in_palette.color(QPalette::Light) == Qt::green);
+ }
+}
+
+void tst_QDataStream::compatibility_Qt2()
+{
+ QLinearGradient gradient(QPointF(0,0), QPointF(1,1));
+ gradient.setColorAt(0, Qt::red);
+ gradient.setColorAt(1, Qt::blue);
+
+ QBrush brush(gradient);
+ QPalette palette;
+ palette.setBrush(QPalette::Button, brush);
+ palette.setColor(QPalette::Light, Qt::green);
+
+ QByteArray stream;
+ {
+ QDataStream out(&stream, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_2_1);
+ out << palette;
+ out << brush;
+ }
+ QBrush in_brush;
+ QPalette in_palette;
+ {
+ QDataStream in(stream);
+ in.setVersion(QDataStream::Qt_2_1);
+ in >> in_palette;
+ in >> in_brush;
+ }
+ QVERIFY(in_brush.style() == Qt::NoBrush);
+ QVERIFY(in_palette.brush(QPalette::Button).style() == Qt::NoBrush);
+ QVERIFY(in_palette.color(QPalette::Light) == Qt::green);
+}
+
+void tst_QDataStream::floatingPointPrecision()
+{
+ QByteArray ba;
+ {
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ QCOMPARE(QDataStream::DoublePrecision, stream.floatingPointPrecision());
+
+ float f = 123.0f;
+ stream << f;
+ QCOMPARE(ba.size(), int(sizeof(double)));
+
+ double d = 234.0;
+ stream << d;
+ QCOMPARE(ba.size(), int(sizeof(double)*2));
+
+ stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
+
+ f = 123.0f;
+ stream << f;
+ QCOMPARE(ba.size(), int(sizeof(double)*2 + sizeof(float)));
+
+ d = 234.0;
+ stream << d;
+ QCOMPARE(ba.size(), int(sizeof(double)*2 + sizeof(float)*2));
+ }
+
+ {
+ QDataStream stream(ba);
+
+ float f = 0.0f;
+ stream >> f;
+ QCOMPARE(123.0f, f);
+
+ double d = 0.0;
+ stream >> d;
+ QCOMPARE(234.0, d);
+
+ f = 0.0f;
+ stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
+ stream >> f;
+ QCOMPARE(123.0f, f);
+
+ d = 0.0;
+ stream >> d;
+ QCOMPARE(234.0, d);
+ }
+
+}
+
+QTEST_MAIN(tst_QDataStream)
+#include "tst_qdatastream.moc"
+
diff --git a/tests/auto/corelib/io/qdebug/.gitignore b/tests/auto/corelib/io/qdebug/.gitignore
new file mode 100644
index 0000000000..af993e9625
--- /dev/null
+++ b/tests/auto/corelib/io/qdebug/.gitignore
@@ -0,0 +1 @@
+tst_qdebug
diff --git a/tests/auto/corelib/io/qdebug/qdebug.pro b/tests/auto/corelib/io/qdebug/qdebug.pro
new file mode 100644
index 0000000000..2b5716860c
--- /dev/null
+++ b/tests/auto/corelib/io/qdebug/qdebug.pro
@@ -0,0 +1,4 @@
+load(qttest_p4)
+SOURCES += tst_qdebug.cpp
+QT = core
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
new file mode 100644
index 0000000000..772fd9fd04
--- /dev/null
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore/QtCore>
+#include <QtCore/QtDebug>
+#include <QtTest/QtTest>
+
+class tst_QDebug: public QObject
+{
+ Q_OBJECT
+private slots:
+ void assignment() const;
+ void warningWithoutDebug() const;
+ void criticalWithoutDebug() const;
+ void debugWithQBool() const;
+ void veryLongWarningMessage() const;
+ void qDebugQStringRef() const;
+};
+
+void tst_QDebug::assignment() const
+{
+ QDebug debug1(QtDebugMsg);
+ QDebug debug2(QtWarningMsg);
+
+ QTest::ignoreMessage(QtDebugMsg, "foo ");
+ QTest::ignoreMessage(QtWarningMsg, "bar 1 2 ");
+
+ debug1 << "foo";
+ debug2 << "bar";
+ debug1 = debug2;
+ debug1 << "1";
+ debug2 << "2";
+}
+
+static QtMsgType s_msgType;
+static QByteArray s_msg;
+
+static void myMessageHandler(QtMsgType type, const char *msg)
+{
+ s_msg = msg;
+ s_msgType = type;
+}
+
+/*! \internal
+ The qWarning() stream should be usable even if QT_NO_DEBUG is defined.
+ */
+void tst_QDebug::warningWithoutDebug() const
+{
+ qInstallMsgHandler(myMessageHandler);
+ { qWarning() << "A qWarning() message"; }
+ QCOMPARE(s_msgType, QtWarningMsg);
+ QCOMPARE(QString::fromLatin1(s_msg.data()), QString::fromLatin1("A qWarning() message "));
+ qInstallMsgHandler(0);
+}
+
+/*! \internal
+ The qCritical() stream should be usable even if QT_NO_DEBUG is defined.
+ */
+void tst_QDebug::criticalWithoutDebug() const
+{
+ qInstallMsgHandler(myMessageHandler);
+ { qCritical() << "A qCritical() message"; }
+ QCOMPARE(s_msgType, QtCriticalMsg);
+ QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("A qCritical() message "));
+ qInstallMsgHandler(0);
+}
+
+void tst_QDebug::debugWithQBool() const
+{
+ qInstallMsgHandler(myMessageHandler);
+ { qDebug() << QBool(false) << QBool(true); }
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("false true "));
+ qInstallMsgHandler(0);
+}
+
+void tst_QDebug::veryLongWarningMessage() const
+{
+ qInstallMsgHandler(myMessageHandler);
+ QString test;
+ {
+ QString part("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
+ for (int i = 0; i < 1000; ++i)
+ test.append(part);
+ qWarning("Test output:\n%s\nend", qPrintable(test));
+ }
+ QCOMPARE(s_msgType, QtWarningMsg);
+ QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("Test output:\n")+test+QString::fromLatin1("\nend"));
+ qInstallMsgHandler(0);
+}
+
+void tst_QDebug::qDebugQStringRef() const
+{
+ /* Use a basic string. */
+ {
+ const QString in(QLatin1String("input"));
+ const QStringRef inRef(&in);
+
+ qInstallMsgHandler(myMessageHandler);
+ { qDebug() << inRef; }
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("\"input\" "));
+ qInstallMsgHandler(0);
+ }
+
+ /* Use a null QStringRef. */
+ {
+ const QStringRef inRef;
+
+ qInstallMsgHandler(myMessageHandler);
+ { qDebug() << inRef; }
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("\"\" "));
+ qInstallMsgHandler(0);
+ }
+}
+
+QTEST_MAIN(tst_QDebug);
+#include "tst_qdebug.moc"
diff --git a/tests/auto/corelib/io/qdir/.gitignore b/tests/auto/corelib/io/qdir/.gitignore
new file mode 100644
index 0000000000..889f51029c
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/.gitignore
@@ -0,0 +1 @@
+tst_qdir
diff --git a/tests/auto/corelib/io/qdir/entrylist/directory/dummy b/tests/auto/corelib/io/qdir/entrylist/directory/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/entrylist/directory/dummy
diff --git a/tests/auto/corelib/io/qdir/entrylist/file b/tests/auto/corelib/io/qdir/entrylist/file
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/entrylist/file
diff --git a/tests/auto/corelib/io/qdir/qdir.pro b/tests/auto/corelib/io/qdir/qdir.pro
new file mode 100644
index 0000000000..fc266a2a97
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/qdir.pro
@@ -0,0 +1,24 @@
+load(qttest_p4)
+SOURCES += tst_qdir.cpp
+RESOURCES += qdir.qrc
+QT = core
+
+wince*|symbian {
+ DirFiles.files = testdir testData searchdir resources entrylist types tst_qdir.cpp
+ DirFiles.path = .
+ DEPLOYMENT += DirFiles
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"\\\"
+} else:symbian {
+ TARGET.CAPABILITY += AllFiles
+ TARGET.UID3 = 0xE0340002
+ DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x",""))
+ LIBS += -lefsrv
+ INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qdir/qdir.qrc b/tests/auto/corelib/io/qdir/qdir.qrc
new file mode 100644
index 0000000000..4c5b5af3b8
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/qdir.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/tst_qdir/">
+ <file>resources/entryList/</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qdir/resources/entryList/file1.data b/tests/auto/corelib/io/qdir/resources/entryList/file1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/resources/entryList/file1.data
diff --git a/tests/auto/corelib/io/qdir/resources/entryList/file2.data b/tests/auto/corelib/io/qdir/resources/entryList/file2.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/resources/entryList/file2.data
diff --git a/tests/auto/corelib/io/qdir/resources/entryList/file3.data b/tests/auto/corelib/io/qdir/resources/entryList/file3.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/resources/entryList/file3.data
diff --git a/tests/auto/corelib/io/qdir/resources/entryList/file4.nothing b/tests/auto/corelib/io/qdir/resources/entryList/file4.nothing
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/resources/entryList/file4.nothing
diff --git a/tests/auto/corelib/io/qdir/searchdir/subdir1/picker.png b/tests/auto/corelib/io/qdir/searchdir/subdir1/picker.png
new file mode 100644
index 0000000000..52eee4fe28
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/searchdir/subdir1/picker.png
@@ -0,0 +1 @@
+mostly empty
diff --git a/tests/auto/corelib/io/qdir/searchdir/subdir2/picker.png b/tests/auto/corelib/io/qdir/searchdir/subdir2/picker.png
new file mode 100644
index 0000000000..52eee4fe28
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/searchdir/subdir2/picker.png
@@ -0,0 +1 @@
+mostly empty
diff --git a/tests/auto/corelib/io/qdir/testData/empty b/tests/auto/corelib/io/qdir/testData/empty
new file mode 100644
index 0000000000..a437d5b711
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testData/empty
@@ -0,0 +1 @@
+this is just so QDir has something to dive into.
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro b/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro
@@ -0,0 +1,2 @@
+
+
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp b/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp
new file mode 100644
index 0000000000..74114760c9
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/tmp/empty b/tests/auto/corelib/io/qdir/testdir/dir/tmp/empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/dir/tmp/empty
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp
new file mode 100644
index 0000000000..74114760c9
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+
diff --git a/tests/auto/corelib/io/qdir/testdir/spaces/foo. bar b/tests/auto/corelib/io/qdir/testdir/spaces/foo. bar
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/spaces/foo. bar
diff --git a/tests/auto/corelib/io/qdir/testdir/spaces/foo.bar b/tests/auto/corelib/io/qdir/testdir/spaces/foo.bar
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/spaces/foo.bar
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
new file mode 100644
index 0000000000..700e11a347
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -0,0 +1,1952 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include "../../../network-settings.h"
+
+#if defined(Q_OS_WIN)
+#define _WIN32_WINNT 0x500
+#endif
+
+#include "../../../../shared/filesystem.h"
+
+#if defined(Q_OS_SYMBIAN)
+# include <f32file.h>
+# define STRINGIFY(x) #x
+# define TOSTRING(x) STRINGIFY(x)
+# define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID) "/"
+#elif defined(Q_OS_UNIX)
+# include <unistd.h>
+# include <sys/stat.h>
+#endif
+
+#if defined(Q_OS_VXWORKS)
+#define Q_NO_SYMLINKS
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+#define Q_NO_SYMLINKS
+#define Q_NO_SYMLINKS_TO_DIRS
+#endif
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QDir : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QDir();
+ virtual ~tst_QDir();
+
+private slots:
+ void getSetCheck();
+ void construction();
+
+ void setPath_data();
+ void setPath();
+
+ void entryList_data();
+ void entryList();
+
+ void entryListSimple_data();
+ void entryListSimple();
+
+ void entryListWithSymLinks();
+
+ void mkdir_data();
+ void mkdir();
+
+ void makedirReturnCode();
+
+ void rmdir_data();
+ void rmdir();
+
+ void exists_data();
+ void exists();
+
+ void isRelativePath_data();
+ void isRelativePath();
+
+ void canonicalPath_data();
+ void canonicalPath();
+
+ void current_data();
+ void current();
+
+ void cd_data();
+ void cd();
+
+ void setNameFilters_data();
+ void setNameFilters();
+
+ void cleanPath_data();
+ void cleanPath();
+
+ void compare();
+ void QDir_default();
+
+ void filePath_data();
+ void filePath();
+
+ void absoluteFilePath_data();
+ void absoluteFilePath();
+
+ void absolutePath_data();
+ void absolutePath();
+
+ void relativeFilePath_data();
+ void relativeFilePath();
+
+ void remove();
+ void rename();
+
+ void exists2_data();
+ void exists2();
+
+ void dirName_data();
+ void dirName();
+
+ void operator_eq();
+
+ void dotAndDotDot();
+ void homePath();
+ void tempPath();
+ void rootPath();
+
+ void nativeSeparators();
+
+ void searchPaths();
+ void searchPaths_data();
+
+ void entryListWithSearchPaths();
+
+ void longFileName_data();
+ void longFileName();
+
+ void updateFileLists();
+
+ void detachingOperations();
+
+ void testCaching();
+
+ void isRoot_data();
+ void isRoot();
+
+#ifndef QT_NO_REGEXP
+ void match_data();
+ void match();
+#endif
+
+ void drives();
+
+ void arrayOperator();
+
+ void equalityOperator_data();
+ void equalityOperator();
+
+ void isRelative_data();
+ void isRelative();
+
+ void isReadable();
+};
+
+// Testing get/set functions
+void tst_QDir::getSetCheck()
+{
+ QDir obj1;
+ // Filters QDir::filter()
+ // void QDir::setFilter(Filters)
+ obj1.setFilter(QDir::Filters(QDir::Dirs));
+ QCOMPARE(QDir::Filters(QDir::Dirs), obj1.filter());
+ obj1.setFilter(QDir::Filters(QDir::Dirs | QDir::Files));
+ QCOMPARE(QDir::Filters(QDir::Dirs | QDir::Files), obj1.filter());
+ obj1.setFilter(QDir::Filters(QDir::NoFilter));
+ QCOMPARE(QDir::Filters(QDir::NoFilter), obj1.filter());
+
+ // SortFlags QDir::sorting()
+ // void QDir::setSorting(SortFlags)
+ obj1.setSorting(QDir::SortFlags(QDir::Name));
+ QCOMPARE(QDir::SortFlags(QDir::Name), obj1.sorting());
+ obj1.setSorting(QDir::SortFlags(QDir::Name | QDir::IgnoreCase));
+ QCOMPARE(QDir::SortFlags(QDir::Name | QDir::IgnoreCase), obj1.sorting());
+ obj1.setSorting(QDir::SortFlags(QDir::NoSort));
+ QCOMPARE(QDir::SortFlags(QDir::NoSort), obj1.sorting());
+}
+
+tst_QDir::tst_QDir()
+{
+#ifdef Q_OS_SYMBIAN
+ // Can't deploy empty test dir, so create it here
+ QDir dir(SRCDIR);
+ dir.mkdir("testData");
+#endif
+}
+
+tst_QDir::~tst_QDir()
+{
+#ifdef Q_OS_SYMBIAN
+ // Remove created test dir
+ QDir dir(SRCDIR);
+ dir.rmdir("testData");
+#endif
+}
+
+void tst_QDir::construction()
+{
+ QFileInfo myFileInfo("/machine/share/dir1/file1");
+ QDir myDir(myFileInfo.absoluteDir()); // this asserted
+ QCOMPARE(myFileInfo.absoluteDir().absolutePath(), myDir.absolutePath());
+}
+
+void tst_QDir::setPath_data()
+{
+ QTest::addColumn<QString>("dir1");
+ QTest::addColumn<QString>("dir2");
+
+ QTest::newRow("data0") << QString(".") << QString("..");
+#if (defined(Q_WS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("data1") << QString("c:/") << QDir::currentPath();
+#endif
+}
+
+void tst_QDir::setPath()
+{
+ QFETCH(QString, dir1);
+ QFETCH(QString, dir2);
+
+ QDir shared;
+ QDir qDir1(dir1);
+ QStringList entries1 = qDir1.entryList();
+ shared.setPath(dir1);
+ QCOMPARE(shared.entryList(), entries1);
+
+ QDir qDir2(dir2);
+ QStringList entries2 = qDir2.entryList();
+ shared.setPath(dir2);
+ QCOMPARE(shared.entryList(), entries2);
+}
+
+void tst_QDir::mkdir_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("recurse");
+
+ QStringList dirs;
+ dirs << QDir::currentPath() + "/testdir/one/two/three"
+ << QDir::currentPath() + "/testdir/two"
+ << QDir::currentPath() + "/testdir/two/three";
+ QTest::newRow("data0") << dirs.at(0) << true;
+ QTest::newRow("data1") << dirs.at(1) << false;
+ QTest::newRow("data2") << dirs.at(2) << false;
+
+ // Ensure that none of these directories already exist
+ QDir dir;
+ for (int i = 0; i < dirs.count(); ++i)
+ dir.rmpath(dirs.at(i));
+}
+
+void tst_QDir::mkdir()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, recurse);
+
+ QDir dir;
+ dir.rmdir(path);
+ if (recurse)
+ QVERIFY(dir.mkpath(path));
+ else
+ QVERIFY(dir.mkdir(path));
+
+ //make sure it really exists (ie that mkdir returns the right value)
+ QFileInfo fi(path);
+ QVERIFY(fi.exists() && fi.isDir());
+}
+
+void tst_QDir::makedirReturnCode()
+{
+ QString dirName = QString::fromLatin1("makedirReturnCode");
+ QDir::current().rmdir(dirName); // cleanup a previous run.
+ QDir dir(dirName);
+ QVERIFY(!dir.exists());
+ QVERIFY(QDir::current().mkdir(dirName));
+ QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail.
+ QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass
+}
+
+void tst_QDir::rmdir_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("recurse");
+
+ QTest::newRow("data0") << QDir::currentPath() + "/testdir/one/two/three" << true;
+ QTest::newRow("data1") << QDir::currentPath() + "/testdir/two/three" << false;
+ QTest::newRow("data2") << QDir::currentPath() + "/testdir/two" << false;
+}
+
+void tst_QDir::rmdir()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, recurse);
+
+ QDir dir;
+ if (recurse)
+ QVERIFY(dir.rmpath(path));
+ else
+ QVERIFY(dir.rmdir(path));
+
+ //make sure it really doesn't exist (ie that rmdir returns the right value)
+ QFileInfo fi(path);
+ QVERIFY(!fi.exists());
+}
+
+void tst_QDir::exists_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("data0") << QDir::currentPath() << true;
+ QTest::newRow("data0.1") << QDir::currentPath() + "/" << true;
+ QTest::newRow("data1") << QString("/I/Do_not_expect_this_path_to_exist/") << false;
+ QTest::newRow("resource0") << QString(":/tst_qdir/") << true;
+ QTest::newRow("resource1") << QString(":/I/Do_not_expect_this_resource_to_exist/") << false;
+
+ QTest::newRow("simple dir") << SRCDIR "resources" << true;
+ QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true;
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE))
+ QTest::newRow("unc 1") << "//" + QtNetworkSettings::winServerName() << true;
+ QTest::newRow("unc 2") << "//" + QtNetworkSettings::winServerName() + "/" << true;
+ QTest::newRow("unc 3") << "//" + QtNetworkSettings::winServerName() + "/testshare" << true;
+ QTest::newRow("unc 4") << "//" + QtNetworkSettings::winServerName() + "/testshare/" << true;
+ QTest::newRow("unc 5") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp" << true;
+ QTest::newRow("unc 6") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp/" << true;
+ QTest::newRow("unc 7") << "//" + QtNetworkSettings::winServerName() + "/testshare/adirthatshouldnotexist" << false;
+ QTest::newRow("unc 8") << "//" + QtNetworkSettings::winServerName() + "/asharethatshouldnotexist" << false;
+ QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << false;
+#endif
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("This drive should exist") << "C:/" << true;
+ // find a non-existing drive and check if it does not exist
+ QFileInfoList drives = QFSFileEngine::drives();
+ QStringList driveLetters;
+ for (int i = 0; i < drives.count(); ++i) {
+ driveLetters+=drives.at(i).absoluteFilePath();
+ }
+ char drive = 'Z';
+ QString driv;
+ do {
+ driv = QString::fromAscii("%1:/").arg(drive);
+ if (!driveLetters.contains(driv)) break;
+ --drive;
+ } while (drive >= 'A');
+ if (drive >= 'A') {
+ QTest::newRow("This drive should not exist") << driv << false;
+ }
+#endif
+}
+
+void tst_QDir::exists()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, expected);
+
+ QDir dir(path);
+ QCOMPARE(dir.exists(), expected);
+}
+
+void tst_QDir::isRelativePath_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("relative");
+
+ QTest::newRow("data0") << "../somedir" << true;
+#if (defined(Q_WS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("data1") << "C:/sOmedir" << false;
+#endif
+ QTest::newRow("data2") << "somedir" << true;
+ QTest::newRow("data3") << "/somedir" << false;
+
+ QTest::newRow("resource0") << ":/prefix" << false;
+ QTest::newRow("resource1") << ":/prefix/foo.bar" << false;
+}
+
+void tst_QDir::isRelativePath()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, relative);
+
+ QCOMPARE(QDir::isRelativePath(path),relative);
+}
+
+
+void tst_QDir::QDir_default()
+{
+ //default constructor QDir();
+ QDir dir; // according to documentation should be currentDirPath
+ QCOMPARE(dir.absolutePath(), QDir::currentPath());
+}
+
+void tst_QDir::compare()
+{
+ // operator==
+ QDir dir;
+ dir.makeAbsolute();
+ QVERIFY(dir == QDir::currentPath());
+}
+
+static QStringList filterLinks(const QStringList &list)
+{
+#ifndef Q_NO_SYMLINKS
+ return list;
+#else
+ QStringList result;
+ foreach (QString str, list) {
+ if (!str.endsWith(QLatin1String(".lnk")))
+ result.append(str);
+ }
+ return result;
+#endif
+}
+
+void tst_QDir::entryList_data()
+{
+ QTest::addColumn<QString>("dirName"); // relative from current path or abs
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<int>("filterspec");
+ QTest::addColumn<int>("sortspec");
+ QTest::addColumn<QStringList>("expected");
+ QTest::newRow("spaces1") << SRCDIR "testdir/spaces" << QStringList("*. bar")
+ << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+ << QStringList("foo. bar"); // notice how spaces5 works
+ QTest::newRow("spaces2") << SRCDIR "testdir/spaces" << QStringList("*.bar")
+ << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+ << QStringList("foo.bar");
+ QTest::newRow("spaces3") << SRCDIR "testdir/spaces" << QStringList("foo.*")
+ << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+ << QString("foo. bar,foo.bar").split(',');
+ QTest::newRow("files1") << SRCDIR "testdir/dir" << QString("*r.cpp *.pro").split(" ")
+ << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+ << QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(',');
+ QTest::newRow("testdir1") << SRCDIR "testdir" << QStringList()
+ << (int)(QDir::AllDirs) << (int)(QDir::NoSort)
+ << QString(".,..,dir,spaces").split(',');
+// #### this test uses filenames that cannot be represented on all filesystems we test, in
+// particular HFS+ on the Mac. When checking out the files with perforce it silently ignores the
+// error that it cannot represent the file names stored in the repository and the test fails. That
+// is why the test is marked as 'skip' for the mac. When checking out the files with git on the mac
+// the error of not being able to represent the files stored in the repository is not silently
+// ignored but git reports an error. The test only tried to prevent QDir from _hanging_ when listing
+// the directory.
+// QTest::newRow("unprintablenames") << SRCDIR "unprintablenames" << QStringList("*")
+// << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+// << QString(".,..").split(",");
+ QTest::newRow("resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
+ << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+ << QString("file1.data,file2.data,file3.data").split(',');
+ QTest::newRow("resources2") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
+ << (int)(QDir::Files) << (int)(QDir::NoSort)
+ << QString("file1.data,file2.data,file3.data").split(',');
+
+ QTest::newRow("nofilter") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::AllEntries") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllEntries) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::Files") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Files) << int(QDir::Name)
+ << filterLinks(QString("file,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::Dirs") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Dirs) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(','));
+ QTest::newRow("QDir::Dirs | QDir::NoDotAndDotDot") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Dirs | QDir::NoDotAndDotDot) << int(QDir::Name)
+ << filterLinks(QString("directory,linktodirectory.lnk").split(','));
+ QTest::newRow("QDir::AllDirs") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllDirs) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(','));
+ QTest::newRow("QDir::AllDirs | QDir::Dirs") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllDirs | QDir::Dirs) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(','));
+ QTest::newRow("QDir::AllDirs | QDir::Files") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllDirs | QDir::Files) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::AllEntries | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllEntries | QDir::NoSymLinks) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,file,writable").split(','));
+ QTest::newRow("QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot) << int(QDir::Name)
+ << filterLinks(QString("directory,file,writable").split(','));
+ QTest::newRow("QDir::Files | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Files | QDir::NoSymLinks) << int(QDir::Name)
+ << filterLinks(QString("file,writable").split(','));
+ QTest::newRow("QDir::Dirs | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Dirs | QDir::NoSymLinks) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory").split(','));
+ QTest::newRow("QDir::Drives | QDir::Files | QDir::NoDotAndDotDot") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Drives | QDir::Files | QDir::NoDotAndDotDot) << int(QDir::Name)
+ << filterLinks(QString("file,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::System") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::System) << int(QDir::Name)
+ << filterLinks(QStringList("brokenlink.lnk"));
+ QTest::newRow("QDir::Hidden") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Hidden) << int(QDir::Name)
+ << QStringList();
+ QTest::newRow("QDir::System | QDir::Hidden") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::System | QDir::Hidden) << int(QDir::Name)
+ << filterLinks(QStringList("brokenlink.lnk"));
+ QTest::newRow("QDir::AllDirs | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllDirs | QDir::NoSymLinks) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory").split(','));
+ QTest::newRow("QDir::AllEntries | QDir::Hidden | QDir::System") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllEntries | QDir::Hidden | QDir::System) << int(QDir::Name)
+ << filterLinks(QString(".,..,brokenlink.lnk,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::AllEntries | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllEntries | QDir::Readable) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::AllEntries | QDir::Writable") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::AllEntries | QDir::Writable) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,linktodirectory.lnk,writable").split(','));
+ QTest::newRow("QDir::Files | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Files | QDir::Readable) << int(QDir::Name)
+ << filterLinks(QString("file,linktofile.lnk,writable").split(','));
+ QTest::newRow("QDir::Dirs | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::Dirs | QDir::Readable) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(','));
+ QTest::newRow("Namefilters b*") << SRCDIR "entrylist/" << QStringList("d*")
+ << int(QDir::NoFilter) << int(QDir::Name)
+ << filterLinks(QString("directory").split(','));
+ QTest::newRow("Namefilters f*") << SRCDIR "entrylist/" << QStringList("f*")
+ << int(QDir::NoFilter) << int(QDir::Name)
+ << filterLinks(QString("file").split(','));
+ QTest::newRow("Namefilters link*") << SRCDIR "entrylist/" << QStringList("link*")
+ << int(QDir::NoFilter) << int(QDir::Name)
+ << filterLinks(QString("linktodirectory.lnk,linktofile.lnk").split(','));
+ QTest::newRow("Namefilters *to*") << SRCDIR "entrylist/" << QStringList("*to*")
+ << int(QDir::NoFilter) << int(QDir::Name)
+ << filterLinks(QString("directory,linktodirectory.lnk,linktofile.lnk").split(','));
+ QTest::newRow("Sorting QDir::Name") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Name)
+ << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ QTest::newRow("Sorting QDir::Name | QDir::Reversed") << SRCDIR "entrylist/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Name | QDir::Reversed)
+ << filterLinks(QString("writable,linktofile.lnk,linktodirectory.lnk,file,directory,..,.").split(','));
+
+ QTest::newRow("Sorting QDir::Type") << SRCDIR "types/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Type)
+ << QString(".,..,a,b,c,d,e,f,a.a,b.a,c.a,d.a,e.a,f.a,a.b,b.b,c.b,d.b,e.b,f.b,a.c,b.c,c.c,d.c,e.c,f.c").split(',');
+ QTest::newRow("Sorting QDir::Type | QDir::Reversed") << SRCDIR "types/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Type | QDir::Reversed)
+ << QString("f.c,e.c,d.c,c.c,b.c,a.c,f.b,e.b,d.b,c.b,b.b,a.b,f.a,e.a,d.a,c.a,b.a,a.a,f,e,d,c,b,a,..,.").split(',');
+ QTest::newRow("Sorting QDir::Type | QDir::DirsLast") << SRCDIR "types/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Type | QDir::DirsLast)
+ << QString("a,b,c,a.a,b.a,c.a,a.b,b.b,c.b,a.c,b.c,c.c,.,..,d,e,f,d.a,e.a,f.a,d.b,e.b,f.b,d.c,e.c,f.c").split(',');
+ QTest::newRow("Sorting QDir::Type | QDir::DirsFirst") << SRCDIR "types/" << QStringList("*")
+ << int(QDir::NoFilter) << int(QDir::Type | QDir::DirsFirst)
+ << QString(".,..,d,e,f,d.a,e.a,f.a,d.b,e.b,f.b,d.c,e.c,f.c,a,b,c,a.a,b.a,c.a,a.b,b.b,c.b,a.c,b.c,c.c").split(',');
+ QTest::newRow("Sorting QDir::Size") << SRCDIR "types/" << QStringList("*")
+ << int(QDir::AllEntries|QDir::NoDotAndDotDot) << int(QDir::Size | QDir::DirsFirst)
+ << QString("d,d.a,d.b,d.c,e,e.a,e.b,e.c,f,f.a,f.b,f.c,c.a,c.b,c.c,b.a,b.c,b.b,a.c,a.b,a.a,a,b,c").split(',');
+ QTest::newRow("Sorting QDir::Size | QDir::Reversed") << SRCDIR "types/" << QStringList("*")
+ << int(QDir::AllEntries|QDir::NoDotAndDotDot) << int(QDir::Size | QDir::Reversed | QDir::DirsLast)
+ << QString("c,b,a,a.a,a.b,a.c,b.b,b.c,b.a,c.c,c.b,c.a,f.c,f.b,f.a,f,e.c,e.b,e.a,e,d.c,d.b,d.a,d").split(',');
+}
+
+void tst_QDir::entryList()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(int, filterspec);
+ QFETCH(int, sortspec);
+ QFETCH(QStringList, expected);
+
+ QFile(SRCDIR "entrylist/writable").open(QIODevice::ReadWrite);
+ QFile(SRCDIR "entrylist/file").setPermissions(QFile::ReadOwner | QFile::ReadUser);
+ QFile::remove(SRCDIR "entrylist/linktofile");
+ QFile::remove(SRCDIR "entrylist/linktodirectory");
+ QFile::remove(SRCDIR "entrylist/linktofile.lnk");
+ QFile::remove(SRCDIR "entrylist/linktodirectory.lnk");
+ QFile::remove(SRCDIR "entrylist/brokenlink.lnk");
+ QFile::remove(SRCDIR "entrylist/brokenlink");
+
+ // WinCE/Symbian does not have . and .. in the directory listing
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ expected.removeAll(".");
+ expected.removeAll("..");
+#endif
+
+#ifndef Q_NO_SYMLINKS
+#if defined(Q_OS_WIN)
+ // ### Sadly, this is a platform difference right now.
+ QFile::link(SRCDIR "entryList/file", SRCDIR "entrylist/linktofile.lnk");
+ QFile::link(SRCDIR "entryList/directory", SRCDIR "entrylist/linktodirectory.lnk");
+ QFile::link(SRCDIR "entryList/nothing", SRCDIR "entrylist/brokenlink.lnk");
+#elif defined(Q_OS_SYMBIAN)
+ // Symbian doesn't support links to directories
+ expected.removeAll("linktodirectory.lnk");
+
+ // Expecting failures from a couple of OpenC bugs. Do checks only once.
+ static int xFailChecked = false;
+ static int expectedFail1 = false;
+ static int expectedFail2 = false;
+
+ if (!expectedFail1) {
+ // Can't create link if file doesn't exist in symbian, so create file temporarily,
+ // But only if testing for
+ QFile tempFile(SRCDIR "entryList/nothing");
+ tempFile.open(QIODevice::WriteOnly);
+ tempFile.link(SRCDIR "entryList/brokenlink.lnk");
+ tempFile.remove();
+ }
+
+ if (!expectedFail2) {
+ QFile::link(SRCDIR "entryList/file", SRCDIR "entrylist/linktofile.lnk");
+ }
+
+ if (!xFailChecked) {
+ // ### Until OpenC supports stat correctly for symbolic links, expect them to fail.
+ expectedFail1 = QFileInfo(SRCDIR "entryList/brokenlink.lnk").exists();
+ expectedFail2 = !(QFileInfo(SRCDIR "entryList/linktofile.lnk").isFile());
+
+ QEXPECT_FAIL("", "OpenC bug, stat for broken links returns normally, when it should return error.", Continue);
+ QVERIFY(!expectedFail1);
+
+ QEXPECT_FAIL("", "OpenC bug, stat for file links doesn't indicate them as such.", Continue);
+ QVERIFY(!expectedFail2);
+ xFailChecked = true;
+ }
+
+ if (expectedFail1) {
+ expected.removeAll("brokenlink.lnk");
+ QFile::remove(SRCDIR "entrylist/brokenlink.lnk");
+ }
+
+ if (expectedFail2) {
+ expected.removeAll("linktofile.lnk");
+ QFile::remove(SRCDIR "entrylist/linktofile.lnk");
+ }
+#else
+ QFile::link("file", SRCDIR "entrylist/linktofile.lnk");
+ QFile::link("directory", SRCDIR "entrylist/linktodirectory.lnk");
+ QFile::link("nothing", SRCDIR "entrylist/brokenlink.lnk");
+#endif
+#endif //Q_NO_SYMLINKS
+
+#ifdef Q_WS_MAC
+ if (qstrcmp(QTest::currentDataTag(), "unprintablenames") == 0)
+ QSKIP("p4 doesn't sync the files with the unprintable names properly on Mac",SkipSingle);
+#endif
+ QDir dir(dirName);
+ QVERIFY(dir.exists());
+
+ QStringList actual = dir.entryList(nameFilters, (QDir::Filters)filterspec,
+ (QDir::SortFlags)sortspec);
+
+ int max = qMin(actual.count(), expected.count());
+
+ if (qstrcmp(QTest::currentDataTag(), "unprintablenames") == 0) {
+ // The purpose of this entry is to check that QDir doesn't
+ // lock up. The actual result depends on the file system.
+ return;
+ }
+ bool doContentCheck = true;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ if (qstrcmp(QTest::currentDataTag(), "QDir::AllEntries | QDir::Writable") == 0) {
+ // for root, everything is writeable
+ if (::getuid() == 0)
+ doContentCheck = false;
+ }
+#endif
+
+ if (doContentCheck) {
+ for (int i=0; i<max; ++i)
+ QCOMPARE(actual[i], expected[i]);
+
+ QCOMPARE(actual.count(), expected.count());
+ }
+
+#if defined(Q_OS_SYMBIAN)
+ // Test cleanup on device requires setting the permissions back to normal
+ QFile(SRCDIR "entrylist/file").setPermissions(QFile::WriteUser | QFile::ReadUser);
+#endif
+
+ QFile::remove(SRCDIR "entrylist/writable");
+ QFile::remove(SRCDIR "entrylist/linktofile");
+ QFile::remove(SRCDIR "entrylist/linktodirectory");
+ QFile::remove(SRCDIR "entrylist/linktofile.lnk");
+ QFile::remove(SRCDIR "entrylist/linktodirectory.lnk");
+ QFile::remove(SRCDIR "entrylist/brokenlink.lnk");
+ QFile::remove(SRCDIR "entrylist/brokenlink");
+}
+
+void tst_QDir::entryListSimple_data()
+{
+ QTest::addColumn<QString>("dirName");
+ QTest::addColumn<int>("countMin");
+
+ QTest::newRow("data2") << "do_not_expect_this_path_to_exist/" << 0;
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("simple dir") << SRCDIR "resources" << 0;
+ QTest::newRow("simple dir with slash") << SRCDIR "resources/" << 0;
+#else
+ QTest::newRow("simple dir") << SRCDIR "resources" << 2;
+ QTest::newRow("simple dir with slash") << SRCDIR "resources/" << 2;
+#endif
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QTest::newRow("unc 1") << "//" + QtNetworkSettings::winServerName() << 2;
+ QTest::newRow("unc 2") << "//" + QtNetworkSettings::winServerName() + "/" << 2;
+ QTest::newRow("unc 3") << "//" + QtNetworkSettings::winServerName() + "/testshare" << 2;
+ QTest::newRow("unc 4") << "//" + QtNetworkSettings::winServerName() + "/testshare/" << 2;
+ QTest::newRow("unc 5") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp" << 2;
+ QTest::newRow("unc 6") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp/" << 2;
+ QTest::newRow("unc 7") << "//" + QtNetworkSettings::winServerName() + "/testshare/adirthatshouldnotexist" << 0;
+ QTest::newRow("unc 8") << "//" + QtNetworkSettings::winServerName() + "/asharethatshouldnotexist" << 0;
+ QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << 0;
+#endif
+}
+
+void tst_QDir::entryListSimple()
+{
+ QFETCH(QString, dirName);
+ QFETCH(int, countMin);
+
+ QDir dir(dirName);
+ QStringList actual = dir.entryList();
+ QVERIFY(actual.count() >= countMin);
+}
+
+void tst_QDir::entryListWithSymLinks()
+{
+#ifndef Q_NO_SYMLINKS
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ QFile::remove("myLinkToDir.lnk");
+# endif
+ QFile::remove("myLinkToFile.lnk");
+ QFile::remove("testfile.cpp");
+ QDir dir;
+ dir.mkdir("myDir");
+ QFile("testfile.cpp").open(QIODevice::WriteOnly);
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
+# endif
+ QVERIFY(QFile::link("testfile.cpp", "myLinkToFile.lnk"));
+
+ {
+ QStringList entryList = QDir().entryList();
+ QVERIFY(entryList.contains("myDir"));
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ QVERIFY(entryList.contains("myLinkToDir.lnk"));
+#endif
+ QVERIFY(entryList.contains("myLinkToFile.lnk"));
+ }
+ {
+ QStringList entryList = QDir().entryList(QDir::Dirs);
+ QVERIFY(entryList.contains("myDir"));
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ QVERIFY(entryList.contains("myLinkToDir.lnk"));
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QEXPECT_FAIL("", "OpenC stat for symlinks is buggy.", Continue);
+#endif
+ QVERIFY(!entryList.contains("myLinkToFile.lnk"));
+ }
+ {
+ QStringList entryList = QDir().entryList(QDir::Dirs | QDir::NoSymLinks);
+ QVERIFY(entryList.contains("myDir"));
+ QVERIFY(!entryList.contains("myLinkToDir.lnk"));
+ QVERIFY(!entryList.contains("myLinkToFile.lnk"));
+ }
+
+ QFile::remove("myLinkToDir.lnk");
+ QFile::remove("myLinkToFile.lnk");
+ QFile::remove("testfile.cpp");
+ dir.rmdir("myDir");
+#endif
+}
+
+void tst_QDir::canonicalPath_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("canonicalPath");
+ QString appPath = SRCDIR;
+ if (appPath.isEmpty())
+ appPath = QCoreApplication::instance()->applicationDirPath();
+ else
+ appPath.chop(1); // remove the ending slash
+
+#if defined Q_WS_WIN
+ if (appPath.endsWith("release", Qt::CaseInsensitive) || appPath.endsWith("debug", Qt::CaseInsensitive)) {
+ QDir appDir(appPath);
+ QVERIFY(appDir.cdUp());
+ appPath = appDir.absolutePath();
+ }
+#endif
+
+ QTest::newRow("relative") << "." << appPath;
+ QTest::newRow("relativeSubDir") << "./testData/../testData" << appPath + "/testData";
+
+#ifndef Q_WS_WIN
+ QTest::newRow("absPath") << appPath + "/testData/../testData" << appPath + "/testData";
+#else
+ QTest::newRow("absPath") << appPath + "\\testData\\..\\testData" << appPath + "/testData";
+#endif
+ QTest::newRow("nonexistant") << "testd" << QString();
+
+ QTest::newRow("rootPath") << QDir::rootPath() << QDir::rootPath();
+
+#ifdef Q_OS_MAC
+ // On Mac OS X 10.5 and earlier, canonicalPath depends on cleanPath which
+ // is itself very broken and fundamentally wrong on "/./" which, this would
+ // exercise
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6)
+#endif
+ QTest::newRow("rootPath + ./") << QDir::rootPath().append("./") << QDir::rootPath();
+
+ QTest::newRow("rootPath + ../.. ") << QDir::rootPath().append("../..") << QDir::rootPath();
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("drive:\\") << QDir::toNativeSeparators(QDir::rootPath()) << QDir::rootPath();
+ QTest::newRow("drive:\\.\\") << QDir::toNativeSeparators(QDir::rootPath().append("./")) << QDir::rootPath();
+ QTest::newRow("drive:\\..\\..") << QDir::toNativeSeparators(QDir::rootPath().append("../..")) << QDir::rootPath();
+ QTest::newRow("drive:") << QDir().canonicalPath().left(2) << QDir().canonicalPath();
+#endif
+
+ QTest::newRow("resource") << ":/tst_qdir/resources/entryList" << ":/tst_qdir/resources/entryList";
+}
+
+void tst_QDir::canonicalPath()
+{
+ QDir srcPath;
+ if (strlen(SRCDIR) > 0)
+ srcPath = QDir(SRCDIR);
+ else
+ srcPath = QDir(".");
+ if (srcPath.absolutePath() != srcPath.canonicalPath())
+ QSKIP("This test does not work if this directory path consists of symlinks.", SkipAll);
+
+ QString oldpwd = QDir::currentPath();
+ QDir::setCurrent(srcPath.absolutePath());
+
+ QFETCH(QString, path);
+ QFETCH(QString, canonicalPath);
+
+ QDir dir(path);
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(dir.canonicalPath().toLower(), canonicalPath.toLower());
+#else
+ QCOMPARE(dir.canonicalPath(), canonicalPath);
+#endif
+
+ QDir::setCurrent(oldpwd);
+}
+
+void tst_QDir::current_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("currentDir");
+ QString appPath = SRCDIR;
+ if (appPath.isEmpty())
+ appPath = QCoreApplication::instance()->applicationDirPath();
+ else
+ appPath.chop(1); // remove the ending slash
+#if defined Q_WS_WIN
+ if (appPath.endsWith("release", Qt::CaseInsensitive))
+ appPath = appPath.left(appPath.length()-8);
+ else if (appPath.endsWith("debug", Qt::CaseInsensitive))
+ appPath = appPath.left(appPath.length()-6);
+#endif
+
+ QTest::newRow("startup") << QString() << appPath;
+ QTest::newRow("relPath") << "testData" << appPath + "/testData";
+#ifndef Q_WS_WIN
+ QTest::newRow("absPath") << appPath + "/testData" << appPath + "/testData";
+#else
+ QTest::newRow("absPath") << appPath + "\\testData" << appPath + "/testData";
+#endif
+ QTest::newRow("nonexistant") << "testd" << QString();
+
+ QTest::newRow("parent") << ".." << appPath.left(appPath.lastIndexOf('/'));
+}
+
+void tst_QDir::current()
+{
+ QString oldDir = QDir::currentPath();
+ QString appPath = SRCDIR;
+ if (appPath.isEmpty())
+ appPath = QCoreApplication::instance()->applicationDirPath();
+ QDir::setCurrent(appPath);
+ QFETCH(QString, path);
+ QFETCH(QString, currentDir);
+
+ if (!path.isEmpty()) {
+ bool b = QDir::setCurrent(path);
+ // If path is non existent, then setCurrent should be false (currentDir is empty in testData)
+ QVERIFY(b == !currentDir.isEmpty());
+ }
+ if (!currentDir.isEmpty()) {
+ QDir newCurrent = QDir::current();
+ QDir::setCurrent(oldDir);
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(newCurrent.absolutePath().toLower(), currentDir.toLower());
+#else
+ QCOMPARE(newCurrent.absolutePath(), currentDir);
+#endif
+ }
+
+ QDir::setCurrent(oldDir);
+}
+
+void tst_QDir::cd_data()
+{
+ QTest::addColumn<QString>("startDir");
+ QTest::addColumn<QString>("cdDir");
+ QTest::addColumn<bool>("successExpected");
+ QTest::addColumn<QString>("newDir");
+
+ QString appPath = QDir::currentPath();
+ int index = appPath.lastIndexOf("/");
+ QTest::newRow("cdUp") << QDir::currentPath() << ".." << true << appPath.left(index==0?1:index);
+ QTest::newRow("noChange") << QDir::currentPath() << "." << true << appPath;
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) // on windows QDir::root() is usually c:/ but cd "/" will not force it to be root
+ QTest::newRow("absolute") << QDir::currentPath() << "/" << true << "/";
+#else
+ QTest::newRow("absolute") << QDir::currentPath() << "/" << true << QDir::root().absolutePath();
+#endif
+ QTest::newRow("non existant") << "." << "../anonexistingdir" << false << QDir::currentPath();
+ QTest::newRow("self") << "." << (QString("../") + QFileInfo(QDir::currentPath()).fileName()) << true << QDir::currentPath();
+ QTest::newRow("file") << "." << "qdir.pro" << false << "";
+}
+
+void tst_QDir::cd()
+{
+ QFETCH(QString, startDir);
+ QFETCH(QString, cdDir);
+ QFETCH(bool, successExpected);
+ QFETCH(QString, newDir);
+
+ QDir d = startDir;
+ bool notUsed = d.exists(); // make sure we cache this before so we can see if 'cd' fails to flush this
+ Q_UNUSED(notUsed);
+ QCOMPARE(d.cd(cdDir), successExpected);
+ if (successExpected)
+ QCOMPARE(d.absolutePath(), newDir);
+}
+
+void tst_QDir::setNameFilters_data()
+{
+ // Effectively copied from entryList2() test
+
+ QTest::addColumn<QString>("dirName"); // relative from current path or abs
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<QStringList>("expected");
+
+ QString appPath = SRCDIR;
+ if (appPath.isEmpty())
+ appPath = QCoreApplication::instance()->applicationDirPath();
+ if (!appPath.endsWith("/"))
+ appPath.append("/");
+
+ QTest::newRow("spaces1") << appPath + "testdir/spaces" << QStringList("*. bar")
+ << QStringList("foo. bar");
+ QTest::newRow("spaces2") << appPath + "testdir/spaces" << QStringList("*.bar")
+ << QStringList("foo.bar");
+ QTest::newRow("spaces3") << appPath + "testdir/spaces" << QStringList("foo.*")
+ << QString("foo. bar,foo.bar").split(",");
+ QTest::newRow("files1") << appPath + "testdir/dir" << QString("*r.cpp *.pro").split(" ")
+ << QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(",");
+ QTest::newRow("resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
+ << QString("file1.data,file2.data,file3.data").split(',');
+}
+
+void tst_QDir::setNameFilters()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(QStringList, expected);
+
+ QDir dir(dirName);
+ QVERIFY(dir.exists());
+
+ dir.setNameFilters(nameFilters);
+ QStringList actual = dir.entryList();
+ int max = qMin(actual.count(), expected.count());
+
+ for (int i=0; i<max; ++i)
+ QCOMPARE(actual[i], expected[i]);
+ QCOMPARE(actual.count(), expected.count());
+}
+
+void
+tst_QDir::cleanPath_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("data0") << "/Users/sam/troll/qt4.0//.." << "/Users/sam/troll";
+ QTest::newRow("data1") << "/Users/sam////troll/qt4.0//.." << "/Users/sam/troll";
+ QTest::newRow("data2") << "/" << "/";
+ QTest::newRow("data3") << QDir::cleanPath("../.") << "..";
+ QTest::newRow("data4") << QDir::cleanPath("../..") << "../..";
+#if !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("data5") << "d:\\a\\bc\\def\\.." << "d:/a/bc";
+ QTest::newRow("data6") << "d:\\a\\bc\\def\\../../.." << "d:/";
+#else
+ QTest::newRow("data5") << "d:\\a\\bc\\def\\.." << "d:\\a\\bc\\def\\..";
+ QTest::newRow("data6") << "d:\\a\\bc\\def\\../../.." << "d:\\a\\bc\\def\\../../..";
+#endif
+#endif
+ QTest::newRow("data7") << ".//file1.txt" << "file1.txt";
+ QTest::newRow("data8") << "/foo/bar/..//file1.txt" << "/foo/file1.txt";
+ QTest::newRow("data9") << "//" << "/";
+#if !defined(Q_OS_WINCE)
+#if defined Q_OS_WIN
+ QTest::newRow("data10") << "c:\\" << "c:/";
+#else
+ QTest::newRow("data10") << "/:/" << "/:";
+#endif
+#endif
+
+ QTest::newRow("resource0") << ":/prefix/foo.bar" << ":/prefix/foo.bar";
+ QTest::newRow("resource1") << "://prefix/..//prefix/foo.bar" << ":/prefix/foo.bar";
+}
+
+
+void
+tst_QDir::cleanPath()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, expected);
+ QString cleaned = QDir::cleanPath(path);
+ QCOMPARE(cleaned, expected);
+}
+
+void tst_QDir::absoluteFilePath_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedFilePath");
+
+ QTest::newRow("0") << "/etc" << "/passwd" << "/passwd";
+ QTest::newRow("1") << "/etc" << "passwd" << "/etc/passwd";
+ QTest::newRow("2") << "/" << "passwd" << "/passwd";
+ QTest::newRow("3") << "relative" << "path" << QDir::currentPath() + "/relative/path";
+ QTest::newRow("4") << "" << "" << QDir::currentPath();
+ QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
+}
+
+void tst_QDir::absoluteFilePath()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedFilePath);
+
+ QDir dir(path);
+ QString absFilePath = dir.absoluteFilePath(fileName);
+ QCOMPARE(absFilePath, expectedFilePath);
+}
+
+void tst_QDir::absolutePath_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("expectedPath");
+
+ QTest::newRow("0") << "/machine/share/dir1" << "/machine/share/dir1";
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("1") << "\\machine\\share\\dir1" << "/machine/share/dir1";
+# if !defined(Q_OS_SYMBIAN)
+ QTest::newRow("2") << "//machine/share/dir1" << "//machine/share/dir1";
+ QTest::newRow("3") << "\\\\machine\\share\\dir1" << "//machine/share/dir1";
+# endif
+ QTest::newRow("4") << "c:/machine/share/dir1" << "c:/machine/share/dir1";
+ QTest::newRow("5") << "c:\\machine\\share\\dir1" << "c:/machine/share/dir1";
+#endif
+ QTest::newRow("resource") << ":/prefix/foo.bar" << ":/prefix/foo.bar";
+}
+
+void tst_QDir::absolutePath()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, expectedPath);
+
+ QDir dir(path);
+ QCOMPARE(dir.absolutePath(), expectedPath);
+}
+
+void tst_QDir::relativeFilePath_data()
+{
+ QTest::addColumn<QString>("dir");
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("0") << "/foo/bar" << "ding.txt" << "ding.txt";
+ QTest::newRow("1") << "/foo/bar" << "ding/dong.txt" << "ding/dong.txt";
+ QTest::newRow("2") << "/foo/bar" << "../ding/dong.txt" << "../ding/dong.txt";
+
+ QTest::newRow("3") << "/foo/bar" << "/foo/bar/ding.txt" << "ding.txt";
+ QTest::newRow("4") << "/foo/bar/" << "/foo/bar/ding/dong.txt" << "ding/dong.txt";
+ QTest::newRow("5") << "/foo/bar/" << "/ding/dong.txt" << "../../ding/dong.txt";
+
+ QTest::newRow("6") << "/" << "/ding/dong.txt" << "ding/dong.txt";
+ QTest::newRow("7") << "/" << "/ding/" << "ding";
+ QTest::newRow("8") << "/" << "/ding//" << "ding";
+ QTest::newRow("9") << "/" << "/ding/../dong" << "dong";
+ QTest::newRow("10") << "/" << "/ding/../../../../dong" << "../../../dong";
+
+ QTest::newRow("11") << "" << "" << "";
+
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("12") << "C:/foo/bar" << "ding" << "ding";
+ QTest::newRow("13") << "C:/foo/bar" << "C:/ding/dong" << "../../ding/dong";
+ QTest::newRow("14") << "C:/foo/bar" << "/ding/dong" << "../../ding/dong";
+ QTest::newRow("15") << "C:/foo/bar" << "D:/ding/dong" << "D:/ding/dong";
+ QTest::newRow("16") << "C:" << "C:/ding/dong" << "ding/dong";
+ QTest::newRow("17") << "C:/" << "C:/ding/dong" << "ding/dong";
+ QTest::newRow("18") << "C:" << "C:" << "";
+ QTest::newRow("19") << "C:/" << "C:" << "";
+ QTest::newRow("20") << "C:" << "C:/" << "";
+ QTest::newRow("21") << "C:/" << "C:/" << "";
+ QTest::newRow("22") << "C:" << "C:file.txt" << "file.txt";
+ QTest::newRow("23") << "C:/" << "C:file.txt" << "file.txt";
+ QTest::newRow("24") << "C:" << "C:/file.txt" << "file.txt";
+ QTest::newRow("25") << "C:/" << "C:/file.txt" << "file.txt";
+ QTest::newRow("26") << "C:" << "D:" << "D:";
+ QTest::newRow("27") << "C:" << "D:/" << "D:/";
+ QTest::newRow("28") << "C:/" << "D:" << "D:";
+ QTest::newRow("29") << "C:/" << "D:/" << "D:/";
+# if !defined(Q_OS_SYMBIAN)
+ QTest::newRow("30") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar";
+ QTest::newRow("31") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar";
+ QTest::newRow("32") << "//anotherHost/foo" << "bar" << "bar";
+ QTest::newRow("33") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar";
+# endif
+#endif
+
+ QTest::newRow("resource0") << ":/prefix" << "foo.bar" << "foo.bar";
+ QTest::newRow("resource1") << ":/prefix" << ":/prefix/foo.bar" << "foo.bar";
+}
+
+void tst_QDir::relativeFilePath()
+{
+ QFETCH(QString, dir);
+ QFETCH(QString, path);
+ QFETCH(QString, expected);
+
+ QCOMPARE(QDir(dir).relativeFilePath(path), expected);
+}
+
+void tst_QDir::filePath_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedFilePath");
+
+ QTest::newRow("0") << "/etc" << "/passwd" << "/passwd";
+ QTest::newRow("1") << "/etc" << "passwd" << "/etc/passwd";
+ QTest::newRow("2") << "/" << "passwd" << "/passwd";
+ QTest::newRow("3") << "relative" << "path" << "relative/path";
+ QTest::newRow("4") << "" << "" << ".";
+ QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
+}
+
+void tst_QDir::filePath()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedFilePath);
+
+ QDir dir(path);
+ QString absFilePath = dir.filePath(fileName);
+ QCOMPARE(absFilePath, expectedFilePath);
+}
+
+void tst_QDir::remove()
+{
+ QFile f("remove-test");
+ f.open(QIODevice::WriteOnly);
+ f.close();
+ QDir dir;
+ QVERIFY(dir.remove("remove-test"));
+ QVERIFY(!dir.remove("/remove-test"));
+ QTest::ignoreMessage(QtWarningMsg, "QDir::remove: Empty or null file name");
+ QVERIFY(!dir.remove(""));
+}
+
+void tst_QDir::rename()
+{
+ QFile f("rename-test");
+ f.open(QIODevice::WriteOnly);
+ f.close();
+ QDir dir;
+ QVERIFY(dir.rename("rename-test", "rename-test-renamed"));
+ QVERIFY(dir.rename("rename-test-renamed", "rename-test"));
+#if defined(Q_OS_MAC)
+ QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed"));
+#elif defined(Q_OS_SYMBIAN)
+ QVERIFY(!dir.rename("rename-test", "/resource/rename-test-renamed"));
+#elif !defined(Q_OS_WIN)
+ // on windows this is possible - maybe make the test a bit better
+ QVERIFY(!dir.rename("rename-test", "/rename-test-renamed"));
+#endif
+ QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)");
+ QVERIFY(!dir.rename("rename-test", ""));
+ QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)");
+ QVERIFY(!dir.rename("", "rename-test-renamed"));
+ QVERIFY(!dir.rename("some-file-that-does-not-exist", "rename-test-renamed"));
+
+ QVERIFY(dir.remove("rename-test"));
+}
+
+void tst_QDir::exists2_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("exists");
+
+ QTest::newRow("0") << "." << true;
+ QTest::newRow("1") << "/" << true;
+ QTest::newRow("2") << "" << false;
+ QTest::newRow("3") << "testData" << true;
+ QTest::newRow("4") << "/testData" << false;
+ QTest::newRow("5") << "tst_qdir.cpp" << true;
+ QTest::newRow("6") << "/resources.cpp" << false;
+ QTest::newRow("resource0") << ":/prefix/foo.bar" << false;
+ QTest::newRow("resource1") << ":/tst_qdir/resources/entryList/file1.data" << true;
+}
+
+void tst_QDir::exists2()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, exists);
+
+ QString oldpwd = QDir::currentPath();
+ if (strlen(SRCDIR) > 0)
+ QDir::setCurrent(SRCDIR);
+
+ if (path.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, "QDir::exists: Empty or null file name");
+
+ QDir dir;
+ if (exists)
+ QVERIFY(dir.exists(path));
+ else
+ QVERIFY(!dir.exists(path));
+
+ QDir::setCurrent(oldpwd);
+}
+
+void tst_QDir::dirName_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("dirName");
+
+ QTest::newRow("slash0") << "c:/winnt/system32" << "system32";
+ QTest::newRow("slash1") << "/winnt/system32" << "system32";
+ QTest::newRow("slash2") << "c:/winnt/system32/kernel32.dll" << "kernel32.dll";
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("bslash0") << "c:\\winnt\\system32" << "system32";
+ QTest::newRow("bslash1") << "\\winnt\\system32" << "system32";
+ QTest::newRow("bslash2") << "c:\\winnt\\system32\\kernel32.dll" << "kernel32.dll";
+#endif
+
+ QTest::newRow("resource") << ":/prefix" << "prefix";
+}
+
+void tst_QDir::dirName()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, dirName);
+
+ QDir dir(path);
+ QCOMPARE(dir.dirName(), dirName);
+}
+
+void tst_QDir::operator_eq()
+{
+ QDir dir1(".");
+ dir1 = dir1;
+ dir1.setPath("..");
+}
+
+void tst_QDir::dotAndDotDot()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("WinCE and Symbian do not have . nor ..", SkipAll);
+#else
+ QDir dir(QString(SRCDIR "testdir/"));
+ QStringList entryList = dir.entryList(QDir::Dirs);
+ QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces"));
+ entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces"));
+#endif
+}
+
+void tst_QDir::homePath()
+{
+ QDir homeDir = QDir::home();
+ QString strHome = QDir::homePath();
+
+ // docs say that homePath() is an absolute path
+ QCOMPARE(strHome, homeDir.absolutePath());
+ QVERIFY(QDir::isAbsolutePath(strHome));
+
+#ifdef Q_OS_UNIX
+ if (strHome.length() > 1) // root dir = "/"
+ QVERIFY(!strHome.endsWith('/'));
+#elif defined(Q_OS_WIN)
+ if (strHome.length() > 3) // root dir = "c:/"; "//" is not really valid...
+ QVERIFY(!strHome.endsWith('/'));
+#endif
+
+ QStringList entries = homeDir.entryList();
+ for (int i = 0; i < entries.count(); ++i) {
+ QFileInfo fi(QDir::homePath() + "/" + entries[i]);
+ QCOMPARE(fi.exists(), true);
+ }
+}
+
+void tst_QDir::tempPath()
+{
+ QDir dir = QDir::temp();
+ QString path = QDir::tempPath();
+
+ // docs say that tempPath() is an absolute path
+ QCOMPARE(path, dir.absolutePath());
+ QVERIFY(QDir::isAbsolutePath(path));
+
+#ifdef Q_OS_UNIX
+ if (path.length() > 1) // root dir = "/"
+ QVERIFY(!path.endsWith('/'));
+#elif defined(Q_OS_WIN)
+ if (path.length() > 3) // root dir = "c:/"; "//" is not really valid...
+ QVERIFY(!path.endsWith('/'));
+#endif
+}
+
+void tst_QDir::rootPath()
+{
+ QDir dir = QDir::root();
+ QString path = QDir::rootPath();
+
+ // docs say that tempPath() is an absolute path
+ QCOMPARE(path, dir.absolutePath());
+ QVERIFY(QDir::isAbsolutePath(path));
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ QCOMPARE(path, QString("/"));
+#endif
+}
+
+void tst_QDir::nativeSeparators()
+{
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("\\"));
+ QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
+ QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/"));
+ QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/"));
+#else
+ QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/"));
+ QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
+ QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/"));
+ QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("\\"));
+#endif
+}
+
+void tst_QDir::searchPaths_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<QString>("searchPathPrefixes");
+ QTest::addColumn<QString>("searchPaths");
+ QTest::addColumn<QString>("expectedAbsolutePath");
+
+ QString srcdir = SRCDIR;
+ if (srcdir.isEmpty())
+ srcdir = QDir::currentPath();
+ else
+ srcdir.chop(1); // remove ending slash
+ QString searchDir = srcdir + "/searchdir";
+
+ // sanity
+ QTest::newRow("nopath") << "picker.png" << QString() << QString() << QString();
+ QTest::newRow("emptysearchpath") << "subdir1/picker.png" << QString() << QString() << QString();
+ QTest::newRow("searchpathwithoutprefix") << SRCDIR "searchdir/subdir1/picker.png" << QString("searchpath") << QString("searchdir") << (searchDir+"/subdir1/picker.png");
+
+ // new
+ QTest::newRow("novalidsearchpath") << "searchpath:subdir1/picker.png" << QString() << QString() << QString();
+ QTest::newRow("invalidsearchpath") << "searchpath:subdir1/picker.png" << QString("invalid") << QString("invalid") << QString();
+ QTest::newRow("onlyvalidsearchpath") << "searchpath:subdir1/picker.png" << QString("searchpath") << QString(SRCDIR "searchdir") << (searchDir+"/subdir1/picker.png");
+ QTest::newRow("validandinvalidsearchpath") << "searchpath:subdir1/picker.png" << QString("invalid;searchpath") << QString("invalid;" SRCDIR "searchdir") << (searchDir+"/subdir1/picker.png");
+ QTest::newRow("precedence1") << "searchpath:picker.png" << QString("invalid;searchpath") << QString("invalid;" SRCDIR "searchdir/subdir1," SRCDIR "searchdir/subdir2") << (searchDir+"/subdir1/picker.png");
+ QTest::newRow("precedence2") << "searchpath:picker.png" << QString("invalid;searchpath") << QString("invalid;" SRCDIR "searchdir/subdir2," SRCDIR "searchdir/subdir1") << (searchDir+"/subdir2/picker.png");
+ QTest::newRow("precedence3") << "searchpath2:picker.png" << QString("searchpath1;searchpath2") << QString(SRCDIR "searchdir/subdir1;" SRCDIR "searchdir/subdir2") << (searchDir+"/subdir2/picker.png");
+
+ // re
+}
+
+void tst_QDir::searchPaths()
+{
+ QFETCH(QString, filename);
+ QFETCH(QString, searchPathPrefixes);
+ QStringList searchPathPrefixList = searchPathPrefixes.split(";", QString::SkipEmptyParts);
+ QFETCH(QString, searchPaths);
+ QStringList searchPathsList = searchPaths.split(";", QString::SkipEmptyParts);
+ QFETCH(QString, expectedAbsolutePath);
+ bool exists = !expectedAbsolutePath.isEmpty();
+
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QDir::setSearchPaths(searchPathPrefixList.at(i), searchPathsList.at(i).split(","));
+ }
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)) == searchPathsList.at(i).split(","));
+ }
+
+ QCOMPARE(QFile(filename).exists(), exists);
+ QCOMPARE(QFileInfo(filename).exists(), exists);
+
+ if (exists) {
+ QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath);
+ }
+
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList());
+ }
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty());
+ }
+
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ foreach (QString path, searchPathsList.at(i).split(",")) {
+ QDir::addSearchPath(searchPathPrefixList.at(i), path);
+ }
+ }
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)) == searchPathsList.at(i).split(","));
+ }
+
+ QCOMPARE(QFile(filename).exists(), exists);
+ QCOMPARE(QFileInfo(filename).exists(), exists);
+
+ if (exists) {
+ QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath);
+ }
+
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList());
+ }
+ for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty());
+ }
+}
+
+void tst_QDir::entryListWithSearchPaths()
+{
+ QDir realDir(":/tst_qdir/resources/entryList");
+ QVERIFY(realDir.exists());
+ QVERIFY(!realDir.entryList().isEmpty());
+ QVERIFY(realDir.entryList().contains("file3.data"));
+
+ QDir::setSearchPaths("searchpath", QStringList(":/tst_qdir/resources"));
+ QDir dir("searchpath:entryList/");
+ QCOMPARE(dir.path(), QString(":/tst_qdir/resources/entryList"));
+ QVERIFY(dir.exists());
+ QStringList entryList = dir.entryList();
+ QVERIFY(entryList.contains("file3.data"));
+}
+
+void tst_QDir::longFileName_data()
+{
+ QTest::addColumn<int>("length");
+
+ QTest::newRow("128") << 128;
+ QTest::newRow("256") << 256;
+ QTest::newRow("512") << 512;
+ QTest::newRow("1024") << 1024;
+ QTest::newRow("2048") << 2048;
+ QTest::newRow("4096") << 4096;
+}
+
+void tst_QDir::longFileName()
+{
+ QFETCH(int, length);
+
+ QString fileName(length, QLatin1Char('a'));
+ fileName += QLatin1String(".txt");
+
+ QFile file(fileName);
+ if (!file.open(QFile::WriteOnly))
+ QSKIP("Cannot create long file names", SkipAll);
+
+ QFile file2(fileName);
+ QVERIFY(file2.open(QFile::ReadOnly));
+
+ QVERIFY(QDir().entryList().contains(fileName));
+
+ file.close();
+ file2.close();
+
+ QFile::remove(fileName);
+}
+
+void tst_QDir::updateFileLists()
+{
+ // Test setup
+
+ FileSystem fs;
+
+ QVERIFY( fs.createDirectory("update-file-lists") );
+ QVERIFY( fs.createFile("update-file-lists/file1.txt") );
+ QVERIFY( fs.createFile("update-file-lists/file2.doc") );
+
+ QVERIFY( fs.createDirectory("update-file-lists/sub-dir1") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir1/file3.txt") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir1/file4.doc") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir1/file5.txt") );
+
+ QVERIFY( fs.createDirectory("update-file-lists/sub-dir2") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file6.txt") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file7.txt") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file8.doc") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file9.doc") );
+
+ // Actual test
+
+ QDir dir("update-file-lists");
+
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE)
+ //no . and .. on these OS.
+ QCOMPARE(dir.count(), uint(4));
+ QCOMPARE(dir.entryList().size(), 4);
+ QCOMPARE(dir.entryInfoList().size(), 4);
+#else
+ QCOMPARE(dir.count(), uint(6));
+ QCOMPARE(dir.entryList().size(), 6);
+ QCOMPARE(dir.entryInfoList().size(), 6);
+#endif
+
+ dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
+
+ QCOMPARE(dir.entryList().size(), 4);
+ QCOMPARE(dir.count(), uint(4));
+ QCOMPARE(dir.entryInfoList().size(), 4);
+
+ dir.setPath("update-file-lists/sub-dir1");
+
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+
+ dir.setNameFilters(QStringList("*.txt"));
+
+ QCOMPARE(dir.entryInfoList().size(), 2);
+ QCOMPARE(dir.entryList().size(), 2);
+ QCOMPARE(dir.count(), uint(2));
+
+ dir.setPath("update-file-lists");
+ dir = QDir(dir.path(),
+ "*.txt",
+ QDir::Name | QDir::DirsLast,
+ QDir::AllEntries | QDir::AllDirs | QDir::NoDotAndDotDot);
+
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.entryList(), QStringList() << "file1.txt" << "sub-dir1" << "sub-dir2");
+
+ dir.setSorting(QDir::Name | QDir::DirsFirst);
+
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
+
+ {
+ QVERIFY( fs.createFile("update-file-lists/extra-file.txt") );
+
+ QDir dir2(dir);
+
+ QCOMPARE(dir2.count(), uint(3));
+ QCOMPARE(dir2.entryList().size(), 3);
+ QCOMPARE(dir2.entryInfoList().size(), 3);
+ QCOMPARE(dir2.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
+
+ dir2.refresh();
+
+ QCOMPARE(dir2.count(), uint(4));
+ QCOMPARE(dir2.entryList().size(), 4);
+ QCOMPARE(dir2.entryInfoList().size(), 4);
+ QCOMPARE(dir2.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "extra-file.txt" << "file1.txt");
+ }
+
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
+}
+
+void tst_QDir::detachingOperations()
+{
+ QString const defaultPath(".");
+ QStringList const defaultNameFilters = QStringList("*");
+ QDir::SortFlags const defaultSorting = QDir::Name | QDir::IgnoreCase;
+ QDir::Filters const defaultFilter = QDir::AllEntries;
+
+ QString const path1("..");
+ QString const path2("./foo");
+ QStringList const nameFilters = QStringList(QString("*.txt"));
+ QDir::SortFlags const sorting = QDir::Name | QDir::DirsLast | QDir::Reversed;
+ QDir::Filters const filter = QDir::Writable;
+
+ QDir dir1;
+
+ QCOMPARE(dir1.path(), defaultPath);
+ QCOMPARE(dir1.filter(), defaultFilter);
+ QCOMPARE(dir1.nameFilters(), defaultNameFilters);
+ QCOMPARE(dir1.sorting(), defaultSorting);
+
+ dir1.setPath(path1);
+ QCOMPARE(dir1.path(), path1);
+ QCOMPARE(dir1.filter(), defaultFilter);
+ QCOMPARE(dir1.nameFilters(), defaultNameFilters);
+ QCOMPARE(dir1.sorting(), defaultSorting);
+
+ dir1.setFilter(filter);
+ QCOMPARE(dir1.path(), path1);
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), defaultNameFilters);
+ QCOMPARE(dir1.sorting(), defaultSorting);
+
+ dir1.setNameFilters(nameFilters);
+ QCOMPARE(dir1.path(), path1);
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), nameFilters);
+ QCOMPARE(dir1.sorting(), defaultSorting);
+
+ dir1.setSorting(sorting);
+ QCOMPARE(dir1.path(), path1);
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), nameFilters);
+ QCOMPARE(dir1.sorting(), sorting);
+
+ dir1.setPath(path2);
+ QCOMPARE(dir1.path(), path2);
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), nameFilters);
+ QCOMPARE(dir1.sorting(), sorting);
+
+ {
+ QDir dir2(dir1);
+ QCOMPARE(dir2.path(), path2);
+ QCOMPARE(dir2.filter(), filter);
+ QCOMPARE(dir2.nameFilters(), nameFilters);
+ QCOMPARE(dir2.sorting(), sorting);
+ }
+
+ {
+ QDir dir2;
+ QCOMPARE(dir2.path(), defaultPath);
+ QCOMPARE(dir2.filter(), defaultFilter);
+ QCOMPARE(dir2.nameFilters(), defaultNameFilters);
+ QCOMPARE(dir2.sorting(), defaultSorting);
+
+ dir2 = dir1;
+ QCOMPARE(dir2.path(), path2);
+ QCOMPARE(dir2.filter(), filter);
+ QCOMPARE(dir2.nameFilters(), nameFilters);
+ QCOMPARE(dir2.sorting(), sorting);
+
+ dir2 = path1;
+ QCOMPARE(dir2.path(), path1);
+ QCOMPARE(dir2.filter(), filter);
+ QCOMPARE(dir2.nameFilters(), nameFilters);
+ QCOMPARE(dir2.sorting(), sorting);
+ }
+
+ dir1.refresh();
+ QCOMPARE(dir1.path(), path2);
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), nameFilters);
+ QCOMPARE(dir1.sorting(), sorting);
+
+ QString const currentPath = QDir::currentPath();
+ QVERIFY(dir1.cd(currentPath));
+ QCOMPARE(dir1.path(), currentPath);
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), nameFilters);
+ QCOMPARE(dir1.sorting(), sorting);
+
+ QVERIFY(dir1.cdUp());
+ QCOMPARE(dir1.filter(), filter);
+ QCOMPARE(dir1.nameFilters(), nameFilters);
+ QCOMPARE(dir1.sorting(), sorting);
+}
+
+void tst_QDir::testCaching()
+{
+ QString dirName = QString::fromLatin1("testCaching");
+ QDir::current().rmdir(dirName); // cleanup a previous run.
+ QDir dir(dirName);
+ QVERIFY(!dir.exists());
+ QDir::current().mkdir(dirName);
+ QVERIFY(QDir(dirName).exists()); // dir exists
+ QVERIFY(dir.exists()); // QDir doesn't cache the 'exist' between calls.
+}
+
+void tst_QDir::isRoot_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isRoot");
+
+ QString test = QDir::rootPath();
+ QTest::newRow(QString("rootPath " + test).toLatin1()) << test << true;
+ test = QDir::rootPath().append("./");
+ QTest::newRow(QString("./ appended " + test).toLatin1()) << test << false;
+
+ test = QDir(QDir::rootPath().append("./")).canonicalPath();
+#ifdef Q_OS_MAC
+ // On Mac OS X 10.5 and earlier, canonicalPath depends on cleanPath which
+ // is itself very broken and fundamentally wrong on "/./", which this would
+ // exercise
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6)
+#endif
+ QTest::newRow(QString("canonicalPath " + test).toLatin1()) << test << true;
+
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ test = QDir::rootPath().left(2);
+ QTest::newRow(QString("drive relative " + test).toLatin1()) << test << false;
+#endif
+
+ QTest::newRow("resources root") << ":/" << true;
+ QTest::newRow("resources nonroot") << ":/entrylist" << false;
+}
+
+void tst_QDir::isRoot()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isRoot);
+
+ QDir dir(path);
+ QCOMPARE(dir.isRoot(),isRoot);
+}
+
+#ifndef QT_NO_REGEXP
+void tst_QDir::match_data()
+{
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<bool>("match");
+
+ QTest::newRow("single, matching") << "*.cpp" << "tst_qdir.cpp" << true;
+ QTest::newRow("single, not matching") << "*.cpp" << "tst_qdir.h" << false;
+ QTest::newRow("multi, matching") << "*.cpp;*.h" << "tst_qdir.cpp" << true;
+ QTest::newRow("multi, matching2") << "*.cpp;*.h" << "tst_qdir.h" << true;
+ QTest::newRow("multi, not matching") << "*.cpp;*.h" << "readme.txt" << false;
+}
+
+void tst_QDir::match()
+{
+ QFETCH(QString, filter);
+ QFETCH(QString, filename);
+ QFETCH(bool, match);
+
+ QCOMPARE(QDir::match(filter, filename), match);
+ QCOMPARE(QDir::match(filter.split(QLatin1Char(';')), filename), match);
+}
+#endif
+
+void tst_QDir::drives()
+{
+ QFileInfoList list(QDir::drives());
+#if defined(Q_OS_WIN)
+ QVERIFY(list.count() >= 1); //system
+ QLatin1Char systemdrive('c');
+#elif defined(Q_OS_SYMBIAN)
+ QVERIFY(list.count() >= 2); //system, rom
+ QLatin1Char romdrive('z');
+ QLatin1Char systemdrive('a' + int(RFs::GetSystemDrive()));
+#endif
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QVERIFY(list.count() <= 26);
+ bool foundsystem = false;
+#ifdef Q_OS_SYMBIAN
+ bool foundrom = false;
+#endif
+ foreach (QFileInfo fi, list) {
+ QCOMPARE(fi.absolutePath().size(), 3); //"x:/"
+ QCOMPARE(fi.absolutePath().at(1), QChar(QLatin1Char(':')));
+ QCOMPARE(fi.absolutePath().at(2), QChar(QLatin1Char('/')));
+ if (fi.absolutePath().at(0).toLower() == systemdrive)
+ foundsystem = true;
+#ifdef Q_OS_SYMBIAN
+ if (fi.absolutePath().at(0).toLower() == romdrive)
+ foundrom = true;
+#endif
+ }
+ QCOMPARE(foundsystem, true);
+#ifdef Q_OS_SYMBIAN
+ QCOMPARE(foundrom, true);
+#endif
+#else
+ QCOMPARE(list.count(), 1); //root
+ QCOMPARE(list.at(0).absolutePath(), QLatin1String("/"));
+#endif
+}
+
+void tst_QDir::arrayOperator()
+{
+ QDir dir1(SRCDIR "entrylist/");
+ QDir dir2(SRCDIR "entrylist/");
+
+ QStringList entries(dir1.entryList());
+ int i = dir2.count();
+ QCOMPARE(i, entries.count());
+ --i;
+ for (;i>=0;--i) {
+ QCOMPARE(dir2[i], entries.at(i));
+ }
+}
+
+void tst_QDir::equalityOperator_data()
+{
+ QTest::addColumn<QString>("leftPath");
+ QTest::addColumn<QString>("leftNameFilters");
+ QTest::addColumn<int>("leftSort");
+ QTest::addColumn<int>("leftFilters");
+ QTest::addColumn<QString>("rightPath");
+ QTest::addColumn<QString>("rightNameFilters");
+ QTest::addColumn<int>("rightSort");
+ QTest::addColumn<int>("rightFilters");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("same") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << true;
+
+ QTest::newRow("relativepaths") << "entrylist/" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << true;
+
+ QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs)
+ << false;
+
+ QTest::newRow("diff-sort") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << SRCDIR << "*.cpp" << int(QDir::Time) << int(QDir::Files)
+ << false;
+
+ QTest::newRow("diff-namefilters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << SRCDIR << "*.jpg" << int(QDir::Name) << int(QDir::Files)
+ << false;
+}
+
+void tst_QDir::equalityOperator()
+{
+ QFETCH(QString, leftPath);
+ QFETCH(QString, leftNameFilters);
+ QFETCH(int, leftSort);
+ QFETCH(int, leftFilters);
+ QFETCH(QString, rightPath);
+ QFETCH(QString, rightNameFilters);
+ QFETCH(int, rightSort);
+ QFETCH(int, rightFilters);
+ QFETCH(bool, expected);
+
+ QDir dir1(leftPath, leftNameFilters, QDir::SortFlags(leftSort), QDir::Filters(leftFilters));
+ QDir dir2(rightPath, rightNameFilters, QDir::SortFlags(rightSort), QDir::Filters(rightFilters));
+
+ QCOMPARE((dir1 == dir2), expected);
+ QCOMPARE((dir2 == dir1), expected);
+ QCOMPARE((dir1 != dir2), !expected);
+ QCOMPARE((dir2 != dir1), !expected);
+}
+
+void tst_QDir::isRelative_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("relative");
+
+ QTest::newRow(".") << "./" << true;
+ QTest::newRow("..") << "../" << true;
+ QTest::newRow("content") << "entrylist/" << true;
+ QTest::newRow("current") << QDir::currentPath() << false;
+ QTest::newRow("homepath") << QDir::homePath() << false;
+ QTest::newRow("temppath") << QDir::tempPath() << false;
+ QTest::newRow("rootpath") << QDir::rootPath() << false;
+ foreach (QFileInfo root, QDir::drives()) {
+ QTest::newRow(root.absolutePath().toLocal8Bit()) << root.absolutePath() << false;
+ }
+
+ QTest::newRow("resource") << ":/prefix" << false;
+}
+
+void tst_QDir::isRelative()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, relative);
+
+ QCOMPARE(QDir(path).isRelative(), relative);
+}
+
+void tst_QDir::isReadable()
+{
+ QDir dir;
+
+ QVERIFY(dir.isReadable());
+#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)
+ QVERIFY(dir.mkdir("nonreadabledir"));
+ QVERIFY(0 == ::chmod("nonreadabledir", 0));
+ QVERIFY(!QDir("nonreadabledir").isReadable());
+ QVERIFY(0 == ::chmod("nonreadabledir", S_IRUSR | S_IWUSR | S_IXUSR));
+ QVERIFY(dir.rmdir("nonreadabledir"));
+#endif
+}
+
+QTEST_MAIN(tst_QDir)
+#include "tst_qdir.moc"
+
diff --git a/tests/auto/corelib/io/qdir/types/a b/tests/auto/corelib/io/qdir/types/a
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/a
diff --git a/tests/auto/corelib/io/qdir/types/a.a b/tests/auto/corelib/io/qdir/types/a.a
new file mode 100644
index 0000000000..7898192261
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/a.a
@@ -0,0 +1 @@
+a
diff --git a/tests/auto/corelib/io/qdir/types/a.b b/tests/auto/corelib/io/qdir/types/a.b
new file mode 100644
index 0000000000..e61ef7b965
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/a.b
@@ -0,0 +1 @@
+aa
diff --git a/tests/auto/corelib/io/qdir/types/a.c b/tests/auto/corelib/io/qdir/types/a.c
new file mode 100644
index 0000000000..72943a16fb
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/a.c
@@ -0,0 +1 @@
+aaa
diff --git a/tests/auto/corelib/io/qdir/types/b b/tests/auto/corelib/io/qdir/types/b
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/b
diff --git a/tests/auto/corelib/io/qdir/types/b.a b/tests/auto/corelib/io/qdir/types/b.a
new file mode 100644
index 0000000000..90b451628d
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/b.a
@@ -0,0 +1 @@
+aaaaaa
diff --git a/tests/auto/corelib/io/qdir/types/b.b b/tests/auto/corelib/io/qdir/types/b.b
new file mode 100644
index 0000000000..5d308e1d06
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/b.b
@@ -0,0 +1 @@
+aaaa
diff --git a/tests/auto/corelib/io/qdir/types/b.c b/tests/auto/corelib/io/qdir/types/b.c
new file mode 100644
index 0000000000..ccc3e7b48d
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/b.c
@@ -0,0 +1 @@
+aaaaa
diff --git a/tests/auto/corelib/io/qdir/types/c b/tests/auto/corelib/io/qdir/types/c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/c
diff --git a/tests/auto/corelib/io/qdir/types/c.a b/tests/auto/corelib/io/qdir/types/c.a
new file mode 100644
index 0000000000..2b932011c2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/c.a
@@ -0,0 +1 @@
+aaaaaaaaa
diff --git a/tests/auto/corelib/io/qdir/types/c.b b/tests/auto/corelib/io/qdir/types/c.b
new file mode 100644
index 0000000000..ea8f022358
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/c.b
@@ -0,0 +1 @@
+aaaaaaaa
diff --git a/tests/auto/corelib/io/qdir/types/c.c b/tests/auto/corelib/io/qdir/types/c.c
new file mode 100644
index 0000000000..e5a0c33b87
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/c.c
@@ -0,0 +1 @@
+aaaaaaa
diff --git a/tests/auto/corelib/io/qdir/types/d.a/dummy b/tests/auto/corelib/io/qdir/types/d.a/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/d.a/dummy
diff --git a/tests/auto/corelib/io/qdir/types/d.b/dummy b/tests/auto/corelib/io/qdir/types/d.b/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/d.b/dummy
diff --git a/tests/auto/corelib/io/qdir/types/d.c/dummy b/tests/auto/corelib/io/qdir/types/d.c/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/d.c/dummy
diff --git a/tests/auto/corelib/io/qdir/types/d/dummy b/tests/auto/corelib/io/qdir/types/d/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/d/dummy
diff --git a/tests/auto/corelib/io/qdir/types/e.a/dummy b/tests/auto/corelib/io/qdir/types/e.a/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/e.a/dummy
diff --git a/tests/auto/corelib/io/qdir/types/e.b/dummy b/tests/auto/corelib/io/qdir/types/e.b/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/e.b/dummy
diff --git a/tests/auto/corelib/io/qdir/types/e.c/dummy b/tests/auto/corelib/io/qdir/types/e.c/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/e.c/dummy
diff --git a/tests/auto/corelib/io/qdir/types/e/dummy b/tests/auto/corelib/io/qdir/types/e/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/e/dummy
diff --git a/tests/auto/corelib/io/qdir/types/f.a/dummy b/tests/auto/corelib/io/qdir/types/f.a/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/f.a/dummy
diff --git a/tests/auto/corelib/io/qdir/types/f.b/dummy b/tests/auto/corelib/io/qdir/types/f.b/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/f.b/dummy
diff --git a/tests/auto/corelib/io/qdir/types/f.c/dummy b/tests/auto/corelib/io/qdir/types/f.c/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/f.c/dummy
diff --git a/tests/auto/corelib/io/qdir/types/f/dummy b/tests/auto/corelib/io/qdir/types/f/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/types/f/dummy
diff --git a/tests/auto/corelib/io/qdiriterator/.gitignore b/tests/auto/corelib/io/qdiriterator/.gitignore
new file mode 100644
index 0000000000..cf5974f1a5
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/.gitignore
@@ -0,0 +1 @@
+tst_qdiriterator
diff --git a/tests/auto/corelib/io/qdiriterator/entrylist/directory/dummy b/tests/auto/corelib/io/qdiriterator/entrylist/directory/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/entrylist/directory/dummy
diff --git a/tests/auto/corelib/io/qdiriterator/entrylist/file b/tests/auto/corelib/io/qdiriterator/entrylist/file
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/entrylist/file
diff --git a/tests/auto/corelib/io/qdiriterator/qdiriterator.pro b/tests/auto/corelib/io/qdiriterator/qdiriterator.pro
new file mode 100644
index 0000000000..f9f5c8d664
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/qdiriterator.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+SOURCES += tst_qdiriterator.cpp
+RESOURCES += qdiriterator.qrc
+QT = core
+
+wince*mips*|wincewm50smart-msvc200*: DEFINES += WINCE_BROKEN_ITERATE=1
+
+CONFIG += parallel_test
+CONFIG += insignificant_test # QTBUG-21160
diff --git a/tests/auto/corelib/io/qdiriterator/qdiriterator.qrc b/tests/auto/corelib/io/qdiriterator/qdiriterator.qrc
new file mode 100644
index 0000000000..058d474780
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/qdiriterator.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>entrylist/file</file>
+ <file>entrylist/directory/dummy</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
new file mode 100644
index 0000000000..42ac065645
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
@@ -0,0 +1,639 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qdiriterator.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+#if defined(Q_OS_VXWORKS)
+#define Q_NO_SYMLINKS
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+#define Q_NO_SYMLINKS
+#define Q_NO_SYMLINKS_TO_DIRS
+#endif
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#include "../network-settings.h"
+#endif
+
+Q_DECLARE_METATYPE(QDirIterator::IteratorFlags)
+Q_DECLARE_METATYPE(QDir::Filters)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QDirIterator : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QDirIterator();
+ virtual ~tst_QDirIterator();
+
+private: // convenience functions
+ QStringList createdDirectories;
+ QStringList createdFiles;
+
+ QDir currentDir;
+ bool createDirectory(const QString &dirName)
+ {
+ if (currentDir.mkdir(dirName)) {
+ createdDirectories.prepend(dirName);
+ return true;
+ }
+ return false;
+ }
+
+ enum Cleanup { DoDelete, DontDelete };
+ bool createFile(const QString &fileName, Cleanup cleanup = DoDelete)
+ {
+ QFile file(fileName);
+ if (file.open(QIODevice::WriteOnly)) {
+ if (cleanup == DoDelete)
+ createdFiles << fileName;
+ return true;
+ }
+ return false;
+ }
+
+ bool createLink(const QString &destination, const QString &linkName)
+ {
+ if (QFile::link(destination, linkName)) {
+ createdFiles << linkName;
+ return true;
+ }
+ return false;
+ }
+
+private slots:
+ void iterateRelativeDirectory_data();
+ void iterateRelativeDirectory();
+ void iterateResource_data();
+ void iterateResource();
+ void stopLinkLoop();
+ void engineWithNoIterator();
+ void absoluteFilePathsFromRelativeIteratorPath();
+ void recurseWithFilters() const;
+ void longPath();
+ void task185502_dirorder();
+ void relativePaths();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void uncPaths_data();
+ void uncPaths();
+#endif
+ void qtbug15421_hiddenDirs_hiddenFiles();
+};
+
+tst_QDirIterator::tst_QDirIterator()
+{
+ QFile::remove("entrylist/entrylist1.lnk");
+ QFile::remove("entrylist/entrylist2.lnk");
+ QFile::remove("entrylist/entrylist3.lnk");
+ QFile::remove("entrylist/entrylist4.lnk");
+ QFile::remove("entrylist/directory/entrylist1.lnk");
+ QFile::remove("entrylist/directory/entrylist2.lnk");
+ QFile::remove("entrylist/directory/entrylist3.lnk");
+ QFile::remove("entrylist/directory/entrylist4.lnk");
+
+ createDirectory("entrylist");
+ createDirectory("entrylist/directory");
+ createFile("entrylist/file", DontDelete);
+ createFile("entrylist/writable");
+ createFile("entrylist/directory/dummy", DontDelete);
+
+ createDirectory("recursiveDirs");
+ createDirectory("recursiveDirs/dir1");
+ createFile("recursiveDirs/textFileA.txt");
+ createFile("recursiveDirs/dir1/aPage.html");
+ createFile("recursiveDirs/dir1/textFileB.txt");
+
+ createDirectory("foo");
+ createDirectory("foo/bar");
+ createFile("foo/bar/readme.txt");
+
+ createDirectory("empty");
+
+#ifndef Q_NO_SYMLINKS
+# if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ // ### Sadly, this is a platform difference right now.
+ createLink("entrylist/file", "entrylist/linktofile.lnk");
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ createLink("entrylist/directory", "entrylist/linktodirectory.lnk");
+# endif
+ createLink("entrylist/nothing", "entrylist/brokenlink.lnk");
+# else
+ createLink("file", "entrylist/linktofile.lnk");
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ createLink("directory", "entrylist/linktodirectory.lnk");
+# endif
+ createLink("nothing", "entrylist/brokenlink.lnk");
+# endif
+#endif
+
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/normalFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/.hiddenFile");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/normalFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/.hiddenFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/normalFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenFile");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/normalDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/.hiddenDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/normalDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenDirectory");
+}
+
+tst_QDirIterator::~tst_QDirIterator()
+{
+ Q_FOREACH(QString fileName, createdFiles)
+ QFile::remove(fileName);
+
+ Q_FOREACH(QString dirName, createdDirectories)
+ currentDir.rmdir(dirName);
+}
+
+void tst_QDirIterator::iterateRelativeDirectory_data()
+{
+ QTest::addColumn<QString>("dirName"); // relative from current path or abs
+ QTest::addColumn<QDirIterator::IteratorFlags>("flags");
+ QTest::addColumn<QDir::Filters>("filters");
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<QStringList>("entries");
+
+ QTest::newRow("no flags")
+ << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::NoFilter) << QStringList("*")
+ << QString(
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ "entrylist/.,"
+ "entrylist/..,"
+#endif
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("NoDot")
+ << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::AllEntries | QDir::NoDot) << QStringList("*")
+ << QString(
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ "entrylist/..,"
+#endif
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("NoDotDot")
+ << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::AllEntries | QDir::NoDotDot) << QStringList("*")
+ << QString(
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ "entrylist/.,"
+#endif
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("NoDotAndDotDot")
+ << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::AllEntries | QDir::NoDotAndDotDot) << QStringList("*")
+ << QString(
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks")
+ << QString("entrylist") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories | QDirIterator::FollowSymlinks)
+ << QDir::Filters(QDir::NoFilter) << QStringList("*")
+ << QString(
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ "entrylist/.,"
+ "entrylist/..,"
+ "entrylist/directory/.,"
+ "entrylist/directory/..,"
+#endif
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+ "entrylist/directory/dummy,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("QDir::Subdirectories / QDir::Files")
+ << QString("entrylist") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories)
+ << QDir::Filters(QDir::Files) << QStringList("*")
+ << QString("entrylist/directory/dummy,"
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks / QDir::Files")
+ << QString("entrylist") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories | QDirIterator::FollowSymlinks)
+ << QDir::Filters(QDir::Files) << QStringList("*")
+ << QString("entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory/dummy,"
+ "entrylist/writable").split(',');
+
+ QTest::newRow("empty, default")
+ << QString("empty") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::NoFilter) << QStringList("*")
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE)
+ << QStringList();
+#else
+ << QString("empty/.,empty/..").split(',');
+#endif
+
+ QTest::newRow("empty, QDir::NoDotAndDotDot")
+ << QString("empty") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*")
+ << QStringList();
+}
+
+void tst_QDirIterator::iterateRelativeDirectory()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QDirIterator::IteratorFlags, flags);
+ QFETCH(QDir::Filters, filters);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(QStringList, entries);
+
+ QDirIterator it(dirName, nameFilters, filters, flags);
+ QStringList list;
+ while (it.hasNext()) {
+ QString next = it.next();
+
+ QString fileName = it.fileName();
+ QString filePath = it.filePath();
+ QString path = it.path();
+
+ QFileInfo info = it.fileInfo();
+
+ QCOMPARE(path, dirName);
+ QCOMPARE(next, filePath);
+
+ QCOMPARE(info, QFileInfo(next));
+ QCOMPARE(fileName, info.fileName());
+ QCOMPARE(filePath, info.filePath());
+
+ // Using canonical file paths for final comparison
+ list << info.canonicalFilePath();
+ }
+
+ // The order of items returned by QDirIterator is not guaranteed.
+ list.sort();
+
+ QStringList sortedEntries;
+ foreach(QString item, entries)
+ sortedEntries.append(QFileInfo(item).canonicalFilePath());
+ sortedEntries.sort();
+
+ if (sortedEntries != list) {
+ qDebug() << "EXPECTED:" << sortedEntries;
+ qDebug() << "ACTUAL: " << list;
+ }
+
+ QCOMPARE(list, sortedEntries);
+}
+
+void tst_QDirIterator::iterateResource_data()
+{
+ QTest::addColumn<QString>("dirName"); // relative from current path or abs
+ QTest::addColumn<QDirIterator::IteratorFlags>("flags");
+ QTest::addColumn<QDir::Filters>("filters");
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<QStringList>("entries");
+
+ QTest::newRow("invalid") << QString::fromLatin1(":/burpaburpa") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QStringList();
+ QTest::newRow(":/") << QString::fromLatin1(":/") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QString::fromLatin1(":/entrylist").split(QLatin1String(","));
+ QTest::newRow(":/entrylist") << QString::fromLatin1(":/entrylist") << QDirIterator::IteratorFlags(0)
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QString::fromLatin1(":/entrylist/directory,:/entrylist/file").split(QLatin1String(","));
+ QTest::newRow(":/ recursive") << QString::fromLatin1(":/") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories)
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QString::fromLatin1(":/entrylist,:/entrylist/directory,:/entrylist/directory/dummy,:/entrylist/file").split(QLatin1String(","));
+}
+
+void tst_QDirIterator::iterateResource()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QDirIterator::IteratorFlags, flags);
+ QFETCH(QDir::Filters, filters);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(QStringList, entries);
+
+ QDirIterator it(dirName, nameFilters, filters, flags);
+ QStringList list;
+ while (it.hasNext())
+ list << it.next();
+
+ list.sort();
+ QStringList sortedEntries = entries;
+ sortedEntries.sort();
+
+ if (sortedEntries != list) {
+ qDebug() << "EXPECTED:" << sortedEntries;
+ qDebug() << "ACTUAL:" << list;
+ }
+
+ QCOMPARE(list, sortedEntries);
+}
+
+void tst_QDirIterator::stopLinkLoop()
+{
+#ifdef Q_OS_WIN
+ // ### Sadly, this is a platform difference right now.
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/entrylist1.lnk");
+ createLink("entrylist/.", "entrylist/entrylist2.lnk");
+ createLink("entrylist/../entrylist/.", "entrylist/entrylist3.lnk");
+ createLink("entrylist/..", "entrylist/entrylist4.lnk");
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/directory/entrylist1.lnk");
+ createLink("entrylist/.", "entrylist/directory/entrylist2.lnk");
+ createLink("entrylist/../directory/.", "entrylist/directory/entrylist3.lnk");
+ createLink("entrylist/..", "entrylist/directory/entrylist4.lnk");
+#else
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/entrylist1.lnk");
+ createLink(".", "entrylist/entrylist2.lnk");
+ createLink("../entrylist/.", "entrylist/entrylist3.lnk");
+ createLink("..", "entrylist/entrylist4.lnk");
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/directory/entrylist1.lnk");
+ createLink(".", "entrylist/directory/entrylist2.lnk");
+ createLink("../directory/.", "entrylist/directory/entrylist3.lnk");
+ createLink("..", "entrylist/directory/entrylist4.lnk");
+#endif
+
+ QDirIterator it(QLatin1String("entrylist"), QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
+ QStringList list;
+ int max = 200;
+ while (--max && it.hasNext())
+ it.next();
+ QVERIFY(max);
+
+ // The goal of this test is only to ensure that the test above don't malfunction
+}
+
+class EngineWithNoIterator : public QFSFileEngine
+{
+public:
+ EngineWithNoIterator(const QString &fileName)
+ : QFSFileEngine(fileName)
+ { }
+
+ QAbstractFileEngineIterator *beginEntryList(QDir::Filters, const QStringList &)
+ { return 0; }
+};
+
+class EngineWithNoIteratorHandler : public QAbstractFileEngineHandler
+{
+public:
+ QAbstractFileEngine *create(const QString &fileName) const
+ {
+ return new EngineWithNoIterator(fileName);
+ }
+};
+
+void tst_QDirIterator::engineWithNoIterator()
+{
+ EngineWithNoIteratorHandler handler;
+
+ QDir("entrylist").entryList();
+ QVERIFY(true); // test that the above line doesn't crash
+}
+
+void tst_QDirIterator::absoluteFilePathsFromRelativeIteratorPath()
+{
+ QDirIterator it("entrylist/", QDir::NoDotAndDotDot);
+ while (it.hasNext()) {
+ it.next();
+ QVERIFY(QFileInfo(it.filePath()).absoluteFilePath().contains("entrylist"));
+ }
+}
+
+void tst_QDirIterator::recurseWithFilters() const
+{
+ QStringList nameFilters;
+ nameFilters.append("*.txt");
+
+ QDirIterator it("recursiveDirs/", nameFilters, QDir::Files,
+ QDirIterator::Subdirectories);
+
+ QSet<QString> actualEntries;
+ QSet<QString> expectedEntries;
+ expectedEntries.insert(QString::fromLatin1("recursiveDirs/dir1/textFileB.txt"));
+ expectedEntries.insert(QString::fromLatin1("recursiveDirs/textFileA.txt"));
+
+ QVERIFY(it.hasNext());
+ it.next();
+ actualEntries.insert(it.fileInfo().filePath());
+ QVERIFY(it.hasNext());
+ it.next();
+ actualEntries.insert(it.fileInfo().filePath());
+ QVERIFY(actualEntries == expectedEntries);
+
+ QVERIFY(!it.hasNext());
+}
+
+void tst_QDirIterator::longPath()
+{
+ QDir dir;
+ dir.mkdir("longpaths");
+ dir.cd("longpaths");
+
+ QString dirName = "x";
+ int n = 0;
+ while (dir.exists(dirName) || dir.mkdir(dirName)) {
+ ++n;
+ dirName.append('x');
+#if defined(Q_OS_WINCE) && defined(WINCE_BROKEN_ITERATE)
+ // Some Windows CE devices/emulators are broken.
+ // though one can create directories of length <= 217,
+ // FindNextFile only reports entries until ~ 214.
+ if (n >= 210)
+ break;
+#endif
+ }
+
+ QDirIterator it(dir.absolutePath(), QDir::NoDotAndDotDot|QDir::Dirs, QDirIterator::Subdirectories);
+ int m = 0;
+ while (it.hasNext()) {
+ ++m;
+ it.next();
+ }
+
+ QCOMPARE(n, m);
+
+ dirName.chop(1);
+ while (dirName.length() > 0 && dir.exists(dirName) && dir.rmdir(dirName)) {
+ dirName.chop(1);
+ }
+ dir.cdUp();
+ dir.rmdir("longpaths");
+}
+
+void tst_QDirIterator::task185502_dirorder()
+{
+ QDirIterator iterator("foo", QDirIterator::Subdirectories);
+ while (iterator.hasNext() && iterator.next() != "foo/bar")
+ { }
+
+ QCOMPARE(iterator.filePath(), QString("foo/bar"));
+ QCOMPARE(iterator.fileInfo().filePath(), QString("foo/bar"));
+}
+
+void tst_QDirIterator::relativePaths()
+{
+ QDirIterator iterator("*", QDirIterator::Subdirectories);
+ while(iterator.hasNext()) {
+ QCOMPARE(iterator.filePath(), QDir::cleanPath(iterator.filePath()));
+ }
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QDirIterator::uncPaths_data()
+{
+ QTest::addColumn<QString>("dirName");
+ QTest::newRow("uncserver")
+ <<QString("//" + QtNetworkSettings::winServerName());
+ QTest::newRow("uncserver/testshare")
+ <<QString("//" + QtNetworkSettings::winServerName() + "/testshare");
+ QTest::newRow("uncserver/testshare/tmp")
+ <<QString("//" + QtNetworkSettings::winServerName() + "/testshare/tmp");
+}
+void tst_QDirIterator::uncPaths()
+{
+ QFETCH(QString, dirName);
+ QDirIterator iterator(dirName, QDir::AllEntries|QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while(iterator.hasNext()) {
+ iterator.next();
+ QCOMPARE(iterator.filePath(), QDir::cleanPath(iterator.filePath()));
+ }
+}
+#endif
+
+void tst_QDirIterator::qtbug15421_hiddenDirs_hiddenFiles()
+{
+ // In Unix it is easy to create hidden files, but in Windows it requires
+ // a special call since hidden files need to be "marked" while in Unix
+ // anything starting by a '.' is a hidden file.
+ // For that reason this test is not run in Windows.
+#if defined Q_OS_WIN || Q_OS_WINCE
+ QSKIP("To create hidden files a special call is required in Windows.", SkipAll);
+#else
+ // Only files
+ {
+ int matches = 0;
+ int failures = 0;
+ QDirIterator di("qtbug15421_hiddenDirs_hiddenFiles", QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while (di.hasNext()) {
+ ++matches;
+ QString filename = di.next();
+ if (QFileInfo(filename).isDir())
+ ++failures; // search was only supposed to find files
+ }
+ QCOMPARE(matches, 6);
+ QCOMPARE(failures, 0);
+ }
+ // Only directories
+ {
+ int matches = 0;
+ int failures = 0;
+ QDirIterator di("qtbug15421_hiddenDirs_hiddenFiles", QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while (di.hasNext()) {
+ ++matches;
+ QString filename = di.next();
+ if (!QFileInfo(filename).isDir())
+ ++failures; // search was only supposed to find files
+ }
+ QCOMPARE(matches, 6);
+ QCOMPARE(failures, 0);
+ }
+#endif // Q_OS_WIN || Q_OS_WINCE
+}
+
+QTEST_MAIN(tst_QDirIterator)
+
+#include "tst_qdiriterator.moc"
+
diff --git a/tests/auto/corelib/io/qfile/.gitattributes b/tests/auto/corelib/io/qfile/.gitattributes
new file mode 100644
index 0000000000..3be66dc5eb
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/.gitattributes
@@ -0,0 +1,2 @@
+dosfile.txt -crlf
+testfile.txt -crlf \ No newline at end of file
diff --git a/tests/auto/corelib/io/qfile/.gitignore b/tests/auto/corelib/io/qfile/.gitignore
new file mode 100644
index 0000000000..c508239722
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/.gitignore
@@ -0,0 +1,8 @@
+tst_qfile
+stdinprocess/stdinprocess
+stdinprocess/stdinprocess.exe
+readonlyfile
+newfile.txt
+appendfile.txt
+oldfile.txt
+simplefile.txt
diff --git a/tests/auto/corelib/io/qfile/copy-fallback.qrc b/tests/auto/corelib/io/qfile/copy-fallback.qrc
new file mode 100644
index 0000000000..864491f326
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/copy-fallback.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>copy-fallback.qrc</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qfile/dosfile.txt b/tests/auto/corelib/io/qfile/dosfile.txt
new file mode 100644
index 0000000000..47205062e1
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/dosfile.txt
@@ -0,0 +1,14 @@
+/dev/system/root / reiserfs acl,user_xattr 1 1
+/dev/sda1 /boot ext3 acl,user_xattr 1 2
+/dev/system/home /home reiserfs acl,user_xattr 1 2
+/dev/system/temp /tmp reiserfs acl,user_xattr 1 2
+/dev/sda2 swap swap pri=42 0 0
+devpts /dev/pts devpts mode=0620,gid=5 0 0
+proc /proc proc defaults 0 0
+usbfs /proc/bus/usb usbfs noauto 0 0
+sysfs /sys sysfs noauto 0 0
+/dev/dvd /media/dvd subfs noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec,iocharset=utf8 0 0
+/dev/fd0 /media/floppy subfs noauto,fs=floppyfss,procuid,nodev,nosuid,sync 0 0
+/dev/sdb2 /media/ipod subfs noauto,rw,noexec,nosuid,nodev,sync,procuid,user,iocharset=utf8 1 2
+/dev/sdc1 /media/usbkey vfat rw,nosuid,nodev,sync,procuid,user 1 2
+
diff --git a/tests/auto/corelib/io/qfile/forCopying.txt b/tests/auto/corelib/io/qfile/forCopying.txt
new file mode 100644
index 0000000000..d4143d5958
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/forCopying.txt
@@ -0,0 +1 @@
+A basic file for copying.
diff --git a/tests/auto/corelib/io/qfile/forRenaming.txt b/tests/auto/corelib/io/qfile/forRenaming.txt
new file mode 100644
index 0000000000..7032162406
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/forRenaming.txt
@@ -0,0 +1,7 @@
+----------------------------------------------------------
+DO NOT CHANGE ANY CONTENT OR ACCESS RIGHTS OF THIS FILE!!!
+----------------------------------------------------------
+
+This file is larger than QFile::rename()'s buffer, which is 4096 bytes. This means it is more than what is returned in its call to read().
+
+112345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890234567890
diff --git a/tests/auto/corelib/io/qfile/largefile/largefile.pro b/tests/auto/corelib/io/qfile/largefile/largefile.pro
new file mode 100644
index 0000000000..6407cb6b3e
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/largefile/largefile.pro
@@ -0,0 +1,8 @@
+load(qttest_p4)
+
+QT = core
+SOURCES += tst_largefile.cpp
+
+wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp b/tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp
new file mode 100644
index 0000000000..bf6cc688ba
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp
@@ -0,0 +1,538 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QTest>
+
+#include <QtAlgorithms>
+#include <QFile>
+#include <QFileInfo>
+#include <qplatformdefs.h>
+
+#include <QDebug>
+
+#include <cstdlib>
+#include <cstdio>
+
+#ifdef Q_OS_WIN
+
+#include <windows.h>
+
+#ifndef Q_OS_WINCE
+#include <io.h>
+#endif
+
+#ifndef FSCTL_SET_SPARSE
+// MinGW doesn't define this.
+#define FSCTL_SET_SPARSE (0x900C4)
+#endif
+
+#endif // Q_OS_WIN
+
+class tst_LargeFile
+ : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_LargeFile()
+ : blockSize(1 << 12)
+ , maxSizeBits()
+ , fd_(-1)
+ , stream_(0)
+ {
+ #if defined(QT_LARGEFILE_SUPPORT) && !defined(Q_OS_MAC)
+ maxSizeBits = 36; // 64 GiB
+ #elif defined(Q_OS_MAC)
+ // HFS+ does not support sparse files, so we limit file size for the test
+ // on Mac OS.
+ maxSizeBits = 32; // 4 GiB
+ #else
+ maxSizeBits = 24; // 16 MiB
+ #endif
+ }
+
+private:
+ void sparseFileData();
+ QByteArray const &getDataBlock(int index, qint64 position);
+
+private slots:
+ // The LargeFile test case was designed to be run in order as a single unit
+
+ void initTestCase();
+ void cleanupTestCase();
+
+ void init();
+ void cleanup();
+
+ // Create and fill large file
+ void createSparseFile();
+ void fillFileSparsely();
+ void closeSparseFile();
+
+ // Verify file was created
+ void fileCreated();
+
+ // Positioning in large files
+ void filePositioning();
+ void fdPositioning();
+ void streamPositioning();
+
+ // Read data from file
+ void openFileForReading();
+ void readFile();
+
+ // Map/unmap large file
+ void mapFile();
+ void mapOffsetOverflow();
+
+ void closeFile() { largeFile.close(); }
+
+ // Test data
+ void fillFileSparsely_data() { sparseFileData(); }
+ void filePositioning_data() { sparseFileData(); }
+ void fdPositioning_data() { sparseFileData(); }
+ void streamPositioning_data() { sparseFileData(); }
+ void readFile_data() { sparseFileData(); }
+ void mapFile_data() { sparseFileData(); }
+
+private:
+ const int blockSize;
+ int maxSizeBits;
+
+ QFile largeFile;
+
+ QVector<QByteArray> generatedBlocks;
+
+ int fd_;
+ FILE *stream_;
+};
+
+/*
+ Convenience function to hide reinterpret_cast when copying a POD directly
+ into a QByteArray.
+ */
+template <class T>
+static inline void appendRaw(QByteArray &array, T data)
+{
+ array.append(reinterpret_cast<char *>(&data), sizeof(T));
+}
+
+/*
+ Pad array with filler up to size. On return, array.size() returns size.
+ */
+static inline void topUpWith(QByteArray &array, QByteArray filler, int size)
+{
+ for (int i = (size - array.size()) / filler.size(); i > 0; --i)
+ array.append(filler);
+
+ if (array.size() < size) {
+ array.append(filler.left(size - array.size()));
+ }
+}
+
+/*
+ Generate a unique data block containing identifiable data. Unaligned,
+ overlapping and partial blocks should not compare equal.
+ */
+static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 userBits = -1)
+{
+ QByteArray block;
+ block.reserve(blockSize);
+
+ // Use of counter and randomBits means content of block will be dependent
+ // on the generation order. For (file-)systems that do not support sparse
+ // files, these can be removed so the test file can be reused and doesn't
+ // have to be generated for every run.
+
+ static qint64 counter = 0;
+
+ qint64 randomBits = ((qint64)qrand() << 32)
+ | ((qint64)qrand() & 0x00000000ffffffff);
+
+ appendRaw(block, randomBits);
+ appendRaw(block, userBits);
+ appendRaw(block, counter);
+ appendRaw(block, (qint32)0xdeadbeef);
+ appendRaw(block, blockSize);
+
+ QByteArray userContent = text.toUtf8();
+ appendRaw(block, userContent.size());
+ block.append(userContent);
+ appendRaw(block, (qint64)0);
+
+ // size, so far
+ appendRaw(block, block.size());
+
+ QByteArray filler("0123456789");
+ block.append(filler.right(10 - block.size() % 10));
+ topUpWith(block, filler, blockSize - 3 * sizeof(qint64));
+
+ appendRaw(block, counter);
+ appendRaw(block, userBits);
+ appendRaw(block, randomBits);
+
+ ++counter;
+ return block;
+}
+
+/*
+ Generates data blocks the first time they are requested. Keeps copies for reuse.
+ */
+QByteArray const &tst_LargeFile::getDataBlock(int index, qint64 position)
+{
+ if (index >= generatedBlocks.size())
+ generatedBlocks.resize(index + 1);
+
+ if (generatedBlocks[index].isNull()) {
+ QString text = QString("Current %1-byte block (index = %2) "
+ "starts %3 bytes into the file '%4'.")
+ .arg(blockSize)
+ .arg(index)
+ .arg(position)
+ .arg("qt_largefile.tmp");
+
+ generatedBlocks[index] = generateDataBlock(blockSize, text, (qint64)1 << index);
+ }
+
+ return generatedBlocks[index];
+}
+
+void tst_LargeFile::initTestCase()
+{
+ QFile file("qt_largefile.tmp");
+ QVERIFY( !file.exists() || file.remove() );
+}
+
+void tst_LargeFile::cleanupTestCase()
+{
+ if (largeFile.isOpen())
+ largeFile.close();
+
+ QFile file("qt_largefile.tmp");
+ QVERIFY( !file.exists() || file.remove() );
+}
+
+void tst_LargeFile::init()
+{
+ fd_ = -1;
+ stream_ = 0;
+}
+
+void tst_LargeFile::cleanup()
+{
+ if (-1 != fd_)
+ QT_CLOSE(fd_);
+ if (stream_)
+ ::fclose(stream_);
+}
+
+void tst_LargeFile::sparseFileData()
+{
+ QTest::addColumn<int>("index");
+ QTest::addColumn<qint64>("position");
+ QTest::addColumn<QByteArray>("block");
+
+ QTest::newRow(QString("block[%1] @%2)")
+ .arg(0).arg(0)
+ .toLocal8Bit().constData())
+ << 0 << (qint64)0 << getDataBlock(0, 0);
+
+ // While on Linux sparse files scale well, on Windows, testing at every
+ // power of 2 leads to very large files. i += 4 gives us a good coverage
+ // without taxing too much on resources.
+ for (int index = 12; index <= maxSizeBits; index += 4) {
+ qint64 position = (qint64)1 << index;
+ QByteArray block = getDataBlock(index, position);
+
+ QTest::newRow(
+ QString("block[%1] @%2)")
+ .arg(index).arg(position)
+ .toLocal8Bit().constData())
+ << index << position << block;
+ }
+}
+
+void tst_LargeFile::createSparseFile()
+{
+#if defined(Q_OS_WIN32)
+ // On Windows platforms, we must explicitly set the file to be sparse,
+ // so disk space is not allocated for the full file when writing to it.
+ HANDLE handle = ::CreateFileA("qt_largefile.tmp",
+ GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
+ QVERIFY( INVALID_HANDLE_VALUE != handle );
+
+ DWORD bytes;
+ if (!::DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0,
+ &bytes, NULL)) {
+ QWARN("Unable to set test file as sparse. "
+ "Limiting test file to 16MiB.");
+ maxSizeBits = 24;
+ }
+
+ int fd = ::_open_osfhandle((intptr_t)handle, 0);
+ QVERIFY( -1 != fd );
+ QVERIFY( largeFile.open(fd, QIODevice::WriteOnly | QIODevice::Unbuffered) );
+#else // !Q_OS_WIN32
+ largeFile.setFileName("qt_largefile.tmp");
+ QVERIFY( largeFile.open(QIODevice::WriteOnly | QIODevice::Unbuffered) );
+#endif
+}
+
+void tst_LargeFile::closeSparseFile()
+{
+#if defined(Q_OS_WIN32)
+ int fd = largeFile.handle();
+#endif
+
+ largeFile.close();
+
+#if defined(Q_OS_WIN32)
+ if (-1 != fd)
+ ::_close(fd);
+#endif
+}
+
+void tst_LargeFile::fillFileSparsely()
+{
+ QFETCH( qint64, position );
+ QFETCH( QByteArray, block );
+ QCOMPARE( block.size(), blockSize );
+
+ static int lastKnownGoodIndex = 0;
+ struct ScopeGuard {
+ ScopeGuard(tst_LargeFile* test)
+ : this_(test)
+ , failed(true)
+ {
+ QFETCH( int, index );
+ index_ = index;
+ }
+
+ ~ScopeGuard()
+ {
+ if (failed) {
+ this_->maxSizeBits = lastKnownGoodIndex;
+ QWARN( qPrintable(
+ QString("QFile::error %1: '%2'. Maximum size bits reset to %3.")
+ .arg(this_->largeFile.error())
+ .arg(this_->largeFile.errorString())
+ .arg(this_->maxSizeBits)) );
+ } else
+ lastKnownGoodIndex = qMax<int>(index_, lastKnownGoodIndex);
+ }
+
+ private:
+ tst_LargeFile * const this_;
+ int index_;
+
+ public:
+ bool failed;
+ };
+
+ ScopeGuard resetMaxSizeBitsOnFailure(this);
+
+ QVERIFY( largeFile.seek(position) );
+ QCOMPARE( largeFile.pos(), position );
+
+ QCOMPARE( largeFile.write(block), (qint64)blockSize );
+ QCOMPARE( largeFile.pos(), position + blockSize );
+ QVERIFY( largeFile.flush() );
+
+ resetMaxSizeBitsOnFailure.failed = false;
+}
+
+void tst_LargeFile::fileCreated()
+{
+ QFileInfo info("qt_largefile.tmp");
+
+ QVERIFY( info.exists() );
+ QVERIFY( info.isFile() );
+ QVERIFY( info.size() >= ((qint64)1 << maxSizeBits) + blockSize );
+}
+
+void tst_LargeFile::filePositioning()
+{
+ QFETCH( qint64, position );
+
+ QFile file("qt_largefile.tmp");
+ QVERIFY( file.open(QIODevice::ReadOnly) );
+
+ QVERIFY( file.seek(position) );
+ QCOMPARE( file.pos(), position );
+}
+
+void tst_LargeFile::fdPositioning()
+{
+ QFETCH( qint64, position );
+
+ fd_ = QT_OPEN("qt_largefile.tmp",
+ QT_OPEN_RDONLY | QT_OPEN_LARGEFILE);
+ QVERIFY( -1 != fd_ );
+
+ QFile file;
+ QVERIFY( file.open(fd_, QIODevice::ReadOnly) );
+ QCOMPARE( file.pos(), (qint64)0 );
+ QVERIFY( file.seek(position) );
+ QCOMPARE( file.pos(), position );
+
+ file.close();
+
+ QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(0), SEEK_SET), QT_OFF_T(0) );
+ QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(position), SEEK_SET), QT_OFF_T(position) );
+
+ QVERIFY( file.open(fd_, QIODevice::ReadOnly) );
+ QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(0), SEEK_CUR), QT_OFF_T(position) );
+ QCOMPARE( file.pos(), position );
+ QVERIFY( file.seek(0) );
+ QCOMPARE( file.pos(), (qint64)0 );
+
+ file.close();
+
+ QVERIFY( !QT_CLOSE(fd_) );
+ fd_ = -1;
+}
+
+void tst_LargeFile::streamPositioning()
+{
+ QFETCH( qint64, position );
+
+#if defined(QT_LARGEFILE_SUPPORT) && defined(Q_CC_MSVC) && _MSC_VER < 1400
+ if (position >= (qint64)1 << 31)
+ QSKIP("MSVC 2003 doesn't have 64 bit versions of fseek/ftell.", SkipSingle);
+#endif
+
+ stream_ = QT_FOPEN("qt_largefile.tmp", "rb");
+ QVERIFY( 0 != stream_ );
+
+ QFile file;
+ QVERIFY( file.open(stream_, QIODevice::ReadOnly) );
+ QCOMPARE( file.pos(), (qint64)0 );
+ QVERIFY( file.seek(position) );
+ QCOMPARE( file.pos(), position );
+
+ file.close();
+
+ QVERIFY( !QT_FSEEK(stream_, QT_OFF_T(0), SEEK_SET) );
+ QCOMPARE( QT_FTELL(stream_), QT_OFF_T(0) );
+ QVERIFY( !QT_FSEEK(stream_, QT_OFF_T(position), SEEK_SET) );
+ QCOMPARE( QT_FTELL(stream_), QT_OFF_T(position) );
+
+ QVERIFY( file.open(stream_, QIODevice::ReadOnly) );
+ QCOMPARE( QT_FTELL(stream_), QT_OFF_T(position) );
+ QCOMPARE( file.pos(), position );
+ QVERIFY( file.seek(0) );
+ QCOMPARE( file.pos(), (qint64)0 );
+
+ file.close();
+
+ QVERIFY( !::fclose(stream_) );
+ stream_ = 0;
+}
+
+void tst_LargeFile::openFileForReading()
+{
+ largeFile.setFileName("qt_largefile.tmp");
+ QVERIFY( largeFile.open(QIODevice::ReadOnly) );
+}
+
+void tst_LargeFile::readFile()
+{
+ QFETCH( qint64, position );
+ QFETCH( QByteArray, block );
+ QCOMPARE( block.size(), blockSize );
+
+ QVERIFY( largeFile.size() >= position + blockSize );
+
+ QVERIFY( largeFile.seek(position) );
+ QCOMPARE( largeFile.pos(), position );
+
+ QCOMPARE( largeFile.read(blockSize), block );
+ QCOMPARE( largeFile.pos(), position + blockSize );
+}
+
+void tst_LargeFile::mapFile()
+{
+ QFETCH( qint64, position );
+ QFETCH( QByteArray, block );
+ QCOMPARE( block.size(), blockSize );
+
+ // Keep full block mapped to facilitate OS and/or internal reuse by Qt.
+ uchar *baseAddress = largeFile.map(position, blockSize);
+ QVERIFY( baseAddress );
+ QVERIFY( qEqual(block.begin(), block.end(), reinterpret_cast<char*>(baseAddress)) );
+
+ for (int offset = 1; offset < blockSize; ++offset) {
+ uchar *address = largeFile.map(position + offset, blockSize - offset);
+
+ QVERIFY( address );
+ if ( !qEqual(block.begin() + offset, block.end(), reinterpret_cast<char*>(address)) ) {
+ qDebug() << "Expected:" << block.toHex();
+ qDebug() << "Actual :" << QByteArray(reinterpret_cast<char*>(address), blockSize).toHex();
+ QVERIFY(false);
+ }
+
+ QVERIFY( largeFile.unmap( address ) );
+ }
+
+ QVERIFY( largeFile.unmap( baseAddress ) );
+}
+
+void tst_LargeFile::mapOffsetOverflow()
+{
+#if defined(Q_OS_MAC)
+ QSKIP("mmap'ping beyond EOF may succeed; generate bus error on access", SkipAll);
+#endif
+
+ // Out-of-range mappings should fail, and not silently clip the offset
+ for (int i = 50; i < 63; ++i) {
+ uchar *address = 0;
+
+ address = largeFile.map(((qint64)1 << i), blockSize);
+ QVERIFY( !address );
+
+ address = largeFile.map(((qint64)1 << i) + blockSize, blockSize);
+ QVERIFY( !address );
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_LargeFile)
+#include "tst_largefile.moc"
+
diff --git a/tests/auto/corelib/io/qfile/noendofline.txt b/tests/auto/corelib/io/qfile/noendofline.txt
new file mode 100644
index 0000000000..e120842ad9
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/noendofline.txt
@@ -0,0 +1,3 @@
+Do not touch the content of this file.
+It shows a text file
+with no end-of-line-character on the last line \ No newline at end of file
diff --git a/tests/auto/corelib/io/qfile/qfile.pro b/tests/auto/corelib/io/qfile/qfile.pro
new file mode 100644
index 0000000000..f41d32789a
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/qfile.pro
@@ -0,0 +1,10 @@
+TEMPLATE = subdirs
+wince*|symbian:{
+ SUBDIRS = test
+} else {
+ SUBDIRS = test stdinprocess
+}
+
+!symbian:SUBDIRS += largefile
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qfile/qfile.qrc b/tests/auto/corelib/io/qfile/qfile.qrc
new file mode 100644
index 0000000000..2c63d8afeb
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/qfile.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/tst_qfileinfo/">
+ <file>resources/</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qfile/rename-fallback.qrc b/tests/auto/corelib/io/qfile/rename-fallback.qrc
new file mode 100644
index 0000000000..c8a894a61d
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/rename-fallback.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>rename-fallback.qrc</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qfile/resources/file1.ext1 b/tests/auto/corelib/io/qfile/resources/file1.ext1
new file mode 100644
index 0000000000..e56e15bb7d
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/resources/file1.ext1
@@ -0,0 +1 @@
+12345
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
new file mode 100644
index 0000000000..57a8d904f5
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore>
+
+int main(int argc, char *argv[])
+{
+ if (argc < 2) {
+ printf("usage: stdinprocess <all|line <0|1>>\n");
+ printf("echos all its input to its output.\n");
+ return 1;
+ }
+
+ QFile file;
+
+ if (strcmp(argv[1], "all") == 0) {
+ file.open(stdin, QFile::ReadWrite);
+ printf("%s", file.readAll().constData());
+ } else if (strcmp(argv[1], "line") == 0) {
+ if (strcmp(argv[2], "0") == 0) {
+ file.open(stdin, QFile::ReadWrite);
+ } else {
+ file.open(0, QFile::ReadWrite);
+ }
+
+ char line[1024];
+ while (file.readLine(line, sizeof(line)) > 0) {
+ printf("%s", line);
+ fflush(stdout);
+ }
+ }
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
new file mode 100644
index 0000000000..bf791ffc61
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
@@ -0,0 +1,6 @@
+SOURCES += main.cpp
+QT = core
+CONFIG -= app_bundle debug_and_release_target
+CONFIG += console
+
+
diff --git a/tests/auto/corelib/io/qfile/test/test.pro b/tests/auto/corelib/io/qfile/test/test.pro
new file mode 100644
index 0000000000..f4ec12f874
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/test/test.pro
@@ -0,0 +1,44 @@
+load(qttest_p4)
+SOURCES += ../tst_qfile.cpp
+
+wince*|symbian {
+ QT = core gui
+ files.files += ..\\dosfile.txt ..\\noendofline.txt ..\\testfile.txt \
+ ..\\testlog.txt ..\\two.dots.file ..\\tst_qfile.cpp \
+ ..\\Makefile ..\\forCopying.txt ..\\forRenaming.txt
+ files.path = .
+ resour.files += ..\\resources\\file1.ext1
+ resour.path = resources
+
+ DEPLOYMENT += files resour
+}
+
+wince* {
+ SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp # needed for QT_OPEN
+ DEFINES += SRCDIR=\\\"\\\"
+} else:symbian {
+ # do not define SRCDIR at all
+ TARGET.EPOCHEAPSIZE = 0x100000 0x3000000
+} else {
+ QT = core network
+ DEFINES += SRCDIR=\\\"$$PWD/../\\\"
+}
+
+RESOURCES += ../qfile.qrc ../rename-fallback.qrc ../copy-fallback.qrc
+
+TARGET = ../tst_qfile
+
+win32 {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qfile
+ } else {
+ TARGET = ../../release/tst_qfile
+ }
+ LIBS+=-lole32 -luuid
+}
+
+symbian {
+ LIBS+=-lefsrv
+}
+
+mac*:CONFIG+=insignificant_test
diff --git a/tests/auto/corelib/io/qfile/testfile.txt b/tests/auto/corelib/io/qfile/testfile.txt
new file mode 100644
index 0000000000..a5f25a118a
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/testfile.txt
@@ -0,0 +1,6 @@
+----------------------------------------------------------
+DO NOT CHANGE ANY CONTENT OR ACCESS RIGHTS OF THIS FILE!!!
+----------------------------------------------------------
+
+This demo file has only six lines
+and a size of exactly 245 Bytes.
diff --git a/tests/auto/corelib/io/qfile/testlog.txt b/tests/auto/corelib/io/qfile/testlog.txt
new file mode 100644
index 0000000000..bcc7222b2f
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/testlog.txt
@@ -0,0 +1,144 @@
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts
+2006-09-29 13:50:08.349: -- File log starts_
+2006-09-29 13:50:08.349: -- File log starts
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
new file mode 100644
index 0000000000..f2031497ed
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -0,0 +1,3406 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+#include <qplatformdefs.h>
+
+#include <QAbstractFileEngine>
+#include <QFSFileEngine>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+#include <QHostInfo>
+#endif
+#include <QProcess>
+#ifndef Q_OS_WIN
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+#ifdef Q_OS_MAC
+# include <sys/mount.h>
+#elif defined(Q_OS_LINUX)
+# include <sys/vfs.h>
+#elif defined(Q_OS_FREEBSD)
+# include <sys/param.h>
+# include <sys/mount.h>
+#elif defined(Q_OS_IRIX)
+# include <sys/statfs.h>
+#elif defined(Q_OS_WINCE)
+# include <qplatformdefs.h>
+# include <private/qfsfileengine_p.h>
+#elif defined(Q_OS_SYMBIAN)
+# include <f32file.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include "../../../network-settings.h"
+
+#if defined(Q_OS_SYMBIAN)
+# define SRCDIR ""
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef QT_OPEN_BINARY
+#define QT_OPEN_BINARY 0
+#endif
+
+Q_DECLARE_METATYPE(QFile::FileError)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QFile : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QFile();
+ virtual ~tst_QFile();
+
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void exists();
+ void open_data();
+ void open();
+ void openUnbuffered();
+ void size_data();
+ void size();
+ void sizeNoExist();
+ void seek();
+ void setSize();
+ void setSizeSeek();
+ void atEnd();
+ void readLine();
+ void readLine2();
+ void readLineNullInLine();
+ void readAll_data();
+ void readAll();
+ void readAllBuffer();
+ void readAllStdin();
+ void readLineStdin();
+ void readLineStdin_lineByLine();
+ void text();
+ void missingEndOfLine();
+ void readBlock();
+ void getch();
+ void ungetChar();
+ void createFile();
+ void append();
+ void permissions_data();
+ void permissions();
+ void setPermissions();
+ void copy();
+ void copyAfterFail();
+ void copyRemovesTemporaryFile() const;
+ void copyShouldntOverwrite();
+ void copyFallback();
+ void link();
+ void linkToDir();
+ void absolutePathLinkToRelativePath();
+ void readBrokenLink();
+ void readTextFile_data();
+ void readTextFile();
+ void readTextFile2();
+ void writeTextFile_data();
+ void writeTextFile();
+ /* void largeFileSupport(); */
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void largeUncFileSupport();
+#endif
+ void tailFile();
+ void flush();
+ void bufferedRead();
+ void isSequential();
+ void encodeName();
+ void truncate();
+ void seekToPos();
+ void seekAfterEndOfFile();
+ void FILEReadWrite();
+ void i18nFileName_data();
+ void i18nFileName();
+ void longFileName_data();
+ void longFileName();
+ void fileEngineHandler();
+ void useQFileInAFileHandler();
+ void getCharFF();
+ void remove_and_exists();
+ void removeOpenFile();
+ void fullDisk();
+ void writeLargeDataBlock_data();
+ void writeLargeDataBlock();
+ void readFromWriteOnlyFile();
+ void writeToReadOnlyFile();
+ void virtualFile();
+ void textFile();
+ void rename_data();
+ void rename();
+ void renameWithAtEndSpecialFile() const;
+ void renameFallback();
+ void renameMultiple();
+ void appendAndRead();
+ void miscWithUncPathAsCurrentDir();
+ void standarderror();
+ void handle();
+ void nativeHandleLeaks();
+
+ void readEof_data();
+ void readEof();
+
+ void map_data();
+ void map();
+ void mapResource_data();
+ void mapResource();
+ void mapOpenMode_data();
+ void mapOpenMode();
+
+ void openStandardStreams();
+
+ void resize_data();
+ void resize();
+
+ void objectConstructors();
+#ifdef Q_OS_SYMBIAN
+ void platformSecurity_data();
+ void platformSecurity();
+#endif
+ void caseSensitivity();
+
+ void autocloseHandle();
+
+ // --- Task related tests below this line
+ void task167217();
+
+ void openDirectory();
+ void writeNothing();
+
+public:
+// disabled this test for the moment... it hangs
+ void invalidFile_data();
+ void invalidFile();
+
+private:
+ enum FileType {
+ OpenQFile,
+ OpenFd,
+ OpenStream,
+#ifdef Q_OS_SYMBIAN
+ OpenRFile,
+#endif
+ NumberOfFileTypes
+ };
+
+ void openStandardStreamsFileDescriptors();
+ void openStandardStreamsBufferedStreams();
+
+ bool openFd(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags)
+ {
+ int fdMode = QT_OPEN_LARGEFILE | QT_OPEN_BINARY;
+
+ // File will be truncated if in Write mode.
+ if (mode & QIODevice::WriteOnly)
+ fdMode |= QT_OPEN_WRONLY | QT_OPEN_TRUNC;
+ if (mode & QIODevice::ReadOnly)
+ fdMode |= QT_OPEN_RDONLY;
+
+ fd_ = QT_OPEN(qPrintable(file.fileName()), fdMode);
+
+ return (-1 != fd_) && file.open(fd_, mode, handleFlags);
+ }
+
+ bool openStream(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags)
+ {
+ char const *streamMode = "";
+
+ // File will be truncated if in Write mode.
+ if (mode & QIODevice::WriteOnly)
+ streamMode = "wb+";
+ else if (mode & QIODevice::ReadOnly)
+ streamMode = "rb";
+
+ stream_ = QT_FOPEN(qPrintable(file.fileName()), streamMode);
+
+ return stream_ && file.open(stream_, mode, handleFlags);
+ }
+
+#ifdef Q_OS_SYMBIAN
+ bool openRFile(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags)
+ {
+ //connect file server first time
+ if (!rfs_.Handle() && rfs_.Connect() != KErrNone)
+ return false;
+ //symbian does not like ./ in filenames, so open by absolute path
+ QString fileName(QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath()));
+ TPtrC fn(fileName.utf16(), fileName.length());
+ TInt smode = 0;
+ if (mode & QIODevice::WriteOnly)
+ smode |= EFileWrite;
+ if (mode & QIODevice::ReadOnly)
+ smode |= EFileRead;
+ TInt r;
+ if ((mode & QIODevice::Truncate) || (!(mode & QIODevice::ReadOnly) && !(mode & QIODevice::Append))) {
+ r = rfile_.Replace(rfs_, fn, smode);
+ } else {
+ r = rfile_.Open(rfs_, fn, smode);
+ if (r == KErrNotFound && (mode & QIODevice::WriteOnly)) {
+ r = rfile_.Create(rfs_, fn, smode);
+ }
+ }
+ return (r == KErrNone) && file.open(rfile_, mode, handleFlags);
+ }
+#endif
+
+ bool openFile(QFile &file, QIODevice::OpenMode mode, FileType type = OpenQFile, QFile::FileHandleFlags handleFlags = QFile::DontCloseHandle)
+ {
+ if (mode & QIODevice::WriteOnly && !file.exists())
+ {
+ // Make sure the file exists
+ QFile createFile(file.fileName());
+ if (!createFile.open(QIODevice::ReadWrite))
+ return false;
+ }
+
+ // Note: openFd and openStream will truncate the file if write mode.
+ switch (type)
+ {
+ case OpenQFile:
+ return file.open(mode);
+
+ case OpenFd:
+ return openFd(file, mode, handleFlags);
+
+ case OpenStream:
+ return openStream(file, mode, handleFlags);
+#ifdef Q_OS_SYMBIAN
+ case OpenRFile:
+ return openRFile(file, mode, handleFlags);
+#endif
+ case NumberOfFileTypes:
+ break;
+ }
+
+ return false;
+ }
+
+ void closeFile(QFile &file)
+ {
+ file.close();
+
+ if (-1 != fd_)
+ QT_CLOSE(fd_);
+ if (stream_)
+ ::fclose(stream_);
+#ifdef Q_OS_SYMBIAN
+ if (rfile_.SubSessionHandle())
+ rfile_.Close();
+#endif
+
+ fd_ = -1;
+ stream_ = 0;
+ }
+
+ int fd_;
+ FILE *stream_;
+#ifdef Q_OS_SYMBIAN
+ RFs rfs_;
+ RFile rfile_;
+#endif
+};
+
+tst_QFile::tst_QFile()
+{
+}
+
+tst_QFile::~tst_QFile()
+{
+
+}
+
+void tst_QFile::init()
+{
+// TODO: Add initialization code here.
+// This will be executed immediately before each test is run.
+ fd_ = -1;
+ stream_ = 0;
+}
+
+void tst_QFile::cleanup()
+{
+// TODO: Add cleanup code here.
+// This will be executed immediately after each test is run.
+
+ // for copyFallback()
+ if (QFile::exists("file-copy-destination.txt")) {
+ QFile::setPermissions("file-copy-destination.txt",
+ QFile::ReadOwner | QFile::WriteOwner);
+ QFile::remove("file-copy-destination.txt");
+ }
+
+ // for renameFallback()
+ QFile::remove("file-rename-destination.txt");
+
+ // for copyAfterFail()
+ QFile::remove("file-to-be-copied.txt");
+ QFile::remove("existing-file.txt");
+ QFile::remove("copied-file-1.txt");
+ QFile::remove("copied-file-2.txt");
+
+ // for renameMultiple()
+ QFile::remove("file-to-be-renamed.txt");
+ QFile::remove("existing-file.txt");
+ QFile::remove("file-renamed-once.txt");
+ QFile::remove("file-renamed-twice.txt");
+
+ if (-1 != fd_)
+ QT_CLOSE(fd_);
+ if (stream_)
+ ::fclose(stream_);
+}
+
+void tst_QFile::initTestCase()
+{
+ QFile::remove("noreadfile");
+
+ // create a file and make it read-only
+ QFile file("readonlyfile");
+ file.open(QFile::WriteOnly);
+ file.write("a", 1);
+ file.close();
+ file.setPermissions(QFile::ReadOwner);
+
+ // create another file and make it not readable
+ file.setFileName("noreadfile");
+ file.open(QFile::WriteOnly);
+ file.write("b", 1);
+ file.close();
+ file.setPermissions(0);
+}
+
+void tst_QFile::cleanupTestCase()
+{
+ // clean up the files we created
+ QFile::remove("readonlyfile");
+ QFile::remove("noreadfile");
+ QFile::remove("myLink.lnk");
+ QFile::remove("appendme.txt");
+ QFile::remove("createme.txt");
+ QFile::remove("file.txt");
+ QFile::remove("genfile.txt");
+ QFile::remove("seekToPos.txt");
+ QFile::remove("setsizeseek.txt");
+ QFile::remove("stdfile.txt");
+ QFile::remove("textfile.txt");
+ QFile::remove("truncate.txt");
+ QFile::remove("winfile.txt");
+ QFile::remove("writeonlyfile");
+ QFile::remove("largeblockfile.txt");
+ QFile::remove("tst_qfile_copy.cpp");
+ QFile::remove("nullinline.txt");
+ QFile::remove("myLink2.lnk");
+ QFile::remove("resources");
+ QFile::remove("qfile_map_testfile");
+ QFile::remove("readAllBuffer.txt");
+ QFile::remove("qt_file.tmp");
+ QFile::remove("File.txt");
+}
+
+//------------------------------------------
+// The 'testfile' is currently just a
+// testfile. The path of this file, the
+// attributes and the contents itself
+// will be changed as far as we have a
+// proper way to handle files in the
+// testing environment.
+//------------------------------------------
+
+void tst_QFile::exists()
+{
+ QFile f( SRCDIR "testfile.txt" );
+ QCOMPARE( f.exists(), (bool)TRUE );
+
+ QFile file("nobodyhassuchafile");
+ file.remove();
+ QVERIFY(!file.exists());
+
+ QFile file2("nobodyhassuchafile");
+ QVERIFY(file2.open(QIODevice::WriteOnly));
+ file2.close();
+
+ QVERIFY(file.exists());
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.close();
+ QVERIFY(file.exists());
+
+ file.remove();
+ QVERIFY(!file.exists());
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QFile unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt");
+ QVERIFY(unc.exists());
+#endif
+}
+
+void tst_QFile::open_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<int>("mode");
+ QTest::addColumn<bool>("ok");
+ QTest::addColumn<QFile::FileError>("status");
+
+#ifdef Q_OS_MAC
+ static const QString denied("Operation not permitted");
+#else
+ static const QString denied("Permission denied");
+#endif
+ QTest::newRow( "exist_readOnly" )
+ << QString(SRCDIR "testfile.txt") << int(QIODevice::ReadOnly)
+ << (bool)TRUE << QFile::NoError;
+
+ QTest::newRow( "exist_writeOnly" )
+ << QString("readonlyfile")
+ << int(QIODevice::WriteOnly)
+ << (bool)FALSE
+ << QFile::OpenError;
+
+ QTest::newRow( "exist_append" )
+ << QString("readonlyfile") << int(QIODevice::Append)
+ << (bool)FALSE << QFile::OpenError;
+
+ QTest::newRow( "nonexist_readOnly" )
+ << QString("nonExist.txt") << int(QIODevice::ReadOnly)
+ << (bool)FALSE << QFile::OpenError;
+
+ QTest::newRow("emptyfile")
+ << QString("")
+ << int(QIODevice::ReadOnly)
+ << (bool)FALSE
+ << QFile::OpenError;
+
+ QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly) << (bool)FALSE
+ << QFile::OpenError;
+
+ QTest::newRow("two-dots") << QString(SRCDIR "two.dots.file") << int(QIODevice::ReadOnly) << (bool)TRUE
+ << QFile::NoError;
+
+ QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly)
+ << (bool)FALSE << QFile::OpenError;
+ QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly)
+ << (bool)FALSE << QFile::OpenError;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
+ << (bool)TRUE << QFile::NoError;
+ QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" << int(QIODevice::ReadOnly)
+ << true << QFile::NoError;
+#endif
+}
+
+void tst_QFile::open()
+{
+ QFETCH( QString, filename );
+ QFETCH( int, mode );
+
+ QFile f( filename );
+
+ QFETCH( bool, ok );
+
+#if defined(Q_OS_SYMBIAN)
+ if (qstrcmp(QTest::currentDataTag(), "noreadfile") == 0)
+ QSKIP("Symbian does not support non-readable files", SkipSingle);
+#elif defined(Q_OS_UNIX)
+ if (::getuid() == 0)
+ // root and Chuck Norris don't care for file permissions. Skip.
+ QSKIP("Running this test as root doesn't make sense", SkipAll);
+#endif
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort);
+#endif
+ if (filename.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
+
+ QCOMPARE(f.open( QIODevice::OpenMode(mode) ), ok);
+
+ QTEST( f.error(), "status" );
+}
+
+void tst_QFile::openUnbuffered()
+{
+ QFile file(SRCDIR "testfile.txt");
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
+ char c = '\0';
+ QVERIFY(file.seek(1));
+ QCOMPARE(file.pos(), qint64(1));
+ QVERIFY(file.getChar(&c));
+ QCOMPARE(file.pos(), qint64(2));
+ char d = '\0';
+ QVERIFY(file.seek(3));
+ QCOMPARE(file.pos(), qint64(3));
+ QVERIFY(file.getChar(&d));
+ QCOMPARE(file.pos(), qint64(4));
+ QVERIFY(file.seek(1));
+ QCOMPARE(file.pos(), qint64(1));
+ char c2 = '\0';
+ QVERIFY(file.getChar(&c2));
+ QCOMPARE(file.pos(), qint64(2));
+ QVERIFY(file.seek(3));
+ QCOMPARE(file.pos(), qint64(3));
+ char d2 = '\0';
+ QVERIFY(file.getChar(&d2));
+ QCOMPARE(file.pos(), qint64(4));
+ QCOMPARE(c, c2);
+ QCOMPARE(d, d2);
+ QCOMPARE(c, '-');
+ QCOMPARE(d, '-');
+}
+
+void tst_QFile::size_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<qint64>("size");
+
+ QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << (qint64)245;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // Only test UNC on Windows./
+ QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testshare/test.pri") << (qint64)34;
+#endif
+}
+
+void tst_QFile::size()
+{
+ QFETCH( QString, filename );
+ QFETCH( qint64, size );
+
+#ifdef Q_WS_WINCE
+ filename = QFileInfo(filename).absoluteFilePath();
+#endif
+
+ {
+ QFile f( filename );
+ QCOMPARE( f.size(), size );
+
+ QVERIFY( f.open(QIODevice::ReadOnly) );
+ QCOMPARE( f.size(), size );
+ }
+
+ {
+ QFile f;
+ FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb");
+ QVERIFY( stream );
+ QVERIFY( f.open(stream, QIODevice::ReadOnly) );
+ QCOMPARE( f.size(), size );
+
+ f.close();
+ fclose(stream);
+ }
+
+ {
+#ifdef Q_WS_WINCE
+ QSKIP("Currently low level file I/O not well supported on Windows CE", SkipSingle);
+#endif
+ QFile f;
+
+ int fd = QT_OPEN(filename.toLocal8Bit().constData(), QT_OPEN_RDONLY);
+
+ QVERIFY( fd != -1 );
+ QVERIFY( f.open(fd, QIODevice::ReadOnly) );
+ QCOMPARE( f.size(), size );
+
+ f.close();
+ QT_CLOSE(fd);
+ }
+}
+
+void tst_QFile::sizeNoExist()
+{
+ QFile file("nonexist01");
+ QVERIFY( !file.exists() );
+ QCOMPARE( file.size(), (qint64)0 );
+ QVERIFY( !file.open(QIODevice::ReadOnly) );
+}
+
+void tst_QFile::seek()
+{
+ QFile::remove("newfile.txt");
+ QFile file("newfile.txt");
+ file.open(QIODevice::WriteOnly);
+ QCOMPARE(file.size(), qint64(0));
+ QCOMPARE(file.pos(), qint64(0));
+ QVERIFY(file.seek(10));
+ QCOMPARE(file.pos(), qint64(10));
+ QCOMPARE(file.size(), qint64(0));
+ file.close();
+ QFile::remove("newfile.txt");
+}
+
+void tst_QFile::setSize()
+{
+ DEPENDS_ON( "size" );
+
+ if ( QFile::exists( "createme.txt" ) )
+ QFile::remove( "createme.txt" );
+ QVERIFY( !QFile::exists( "createme.txt" ) );
+
+ QFile f("createme.txt");
+ QVERIFY(f.open(QIODevice::Truncate | QIODevice::ReadWrite));
+ f.putChar('a');
+
+ f.seek(0);
+ char c = '\0';
+ f.getChar(&c);
+ QCOMPARE(c, 'a');
+
+ QCOMPARE(f.size(), (qlonglong)1);
+ bool ok = f.resize(99);
+ QVERIFY(ok);
+ QCOMPARE(f.size(), (qlonglong)99);
+
+ f.seek(0);
+ c = '\0';
+ f.getChar(&c);
+ QCOMPARE(c, 'a');
+
+ QVERIFY(f.resize(1));
+ QCOMPARE(f.size(), (qlonglong)1);
+
+ f.seek(0);
+ c = '\0';
+ f.getChar(&c);
+ QCOMPARE(c, 'a');
+
+ f.close();
+
+ QCOMPARE(f.size(), (qlonglong)1);
+ QVERIFY(f.resize(100));
+ QCOMPARE(f.size(), (qlonglong)100);
+ QVERIFY(f.resize(50));
+ QCOMPARE(f.size(), (qlonglong)50);
+}
+
+void tst_QFile::setSizeSeek()
+{
+ QFile::remove("setsizeseek.txt");
+ QFile f("setsizeseek.txt");
+ QVERIFY(f.open(QFile::WriteOnly));
+ f.write("ABCD");
+
+ QCOMPARE(f.pos(), qint64(4));
+ f.resize(2);
+ QCOMPARE(f.pos(), qint64(2));
+ f.resize(4);
+ QCOMPARE(f.pos(), qint64(2));
+ f.resize(0);
+ QCOMPARE(f.pos(), qint64(0));
+ f.resize(4);
+ QCOMPARE(f.pos(), qint64(0));
+
+ f.seek(3);
+ QCOMPARE(f.pos(), qint64(3));
+ f.resize(2);
+ QCOMPARE(f.pos(), qint64(2));
+}
+
+void tst_QFile::atEnd()
+{
+ QFile f( SRCDIR "testfile.txt" );
+ QVERIFY(f.open( QIODevice::ReadOnly ));
+
+ int size = f.size();
+ f.seek( size );
+
+ bool end = f.atEnd();
+ f.close();
+ QCOMPARE( end, (bool)TRUE );
+}
+
+void tst_QFile::readLine()
+{
+ QFile f( SRCDIR "testfile.txt" );
+ QVERIFY(f.open( QIODevice::ReadOnly ));
+
+ int i = 0;
+ char p[128];
+ int foo;
+ while ( (foo=f.readLine( p, 128 )) > 0 ) {
+ ++i;
+ if ( i == 5 ) {
+ QCOMPARE( p[0], 'T' );
+ QCOMPARE( p[3], 's' );
+ QCOMPARE( p[11], 'i' );
+ }
+ }
+ f.close();
+ QCOMPARE( i, 6 );
+}
+
+void tst_QFile::readLine2()
+{
+ QFile f( SRCDIR "testfile.txt" );
+ f.open( QIODevice::ReadOnly );
+
+ char p[128];
+ QCOMPARE(f.readLine(p, 60), qlonglong(59));
+ QCOMPARE(f.readLine(p, 60), qlonglong(59));
+ memset(p, '@', sizeof(p));
+ QCOMPARE(f.readLine(p, 60), qlonglong(59));
+
+ QCOMPARE(p[57], '-');
+ QCOMPARE(p[58], '\n');
+ QCOMPARE(p[59], '\0');
+ QCOMPARE(p[60], '@');
+}
+
+void tst_QFile::readLineNullInLine()
+{
+ QFile::remove("nullinline.txt");
+ QFile file("nullinline.txt");
+ QVERIFY(file.open(QIODevice::ReadWrite));
+ QVERIFY(file.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0);
+ QVERIFY(file.flush());
+ file.reset();
+
+ QCOMPARE(file.readLine(), QByteArray("linewith\0null\n", 14));
+ QCOMPARE(file.readLine(), QByteArray("anotherline\0withnull\n", 21));
+ QCOMPARE(file.readLine(), QByteArray("\0\n", 2));
+ QCOMPARE(file.readLine(), QByteArray("null\0", 5));
+ QCOMPARE(file.readLine(), QByteArray());
+}
+
+void tst_QFile::readAll_data()
+{
+ QTest::addColumn<bool>("textMode");
+ QTest::addColumn<QString>("fileName");
+ QTest::newRow( "TextMode unixfile" ) << true << SRCDIR "testfile.txt";
+ QTest::newRow( "BinaryMode unixfile" ) << false << SRCDIR "testfile.txt";
+ QTest::newRow( "TextMode dosfile" ) << true << SRCDIR "dosfile.txt";
+ QTest::newRow( "BinaryMode dosfile" ) << false << SRCDIR "dosfile.txt";
+ QTest::newRow( "TextMode bigfile" ) << true << SRCDIR "tst_qfile.cpp";
+ QTest::newRow( "BinaryMode bigfile" ) << false << SRCDIR "tst_qfile.cpp";
+ QVERIFY(QFile(SRCDIR "tst_qfile.cpp").size() > 64*1024);
+}
+
+void tst_QFile::readAll()
+{
+ QFETCH( bool, textMode );
+ QFETCH( QString, fileName );
+
+ QFile file(fileName);
+ if (textMode)
+ QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
+ else
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ QByteArray a = file.readAll();
+ file.reset();
+ QVERIFY(file.pos() == 0);
+
+ QVERIFY(file.bytesAvailable() > 7);
+ QByteArray b = file.read(1);
+ char x;
+ file.getChar(&x);
+ b.append(x);
+ b.append(file.read(5));
+ b.append(file.readAll());
+
+ QCOMPARE(a, b);
+}
+
+void tst_QFile::readAllBuffer()
+{
+ QString fileName = QLatin1String("readAllBuffer.txt");
+
+ QFile::remove(fileName);
+
+ QFile writer(fileName);
+ QFile reader(fileName);
+
+ QByteArray data1("This is arguably a very simple text.");
+ QByteArray data2("This is surely not as simple a test.");
+
+ QVERIFY( writer.open(QIODevice::ReadWrite | QIODevice::Unbuffered) );
+ QVERIFY( reader.open(QIODevice::ReadOnly) );
+
+ QCOMPARE( writer.write(data1), qint64(data1.size()) );
+ QVERIFY( writer.seek(0) );
+
+ QByteArray result;
+ result = reader.read(18);
+ QCOMPARE( result.size(), 18 );
+
+ QCOMPARE( writer.write(data2), qint64(data2.size()) ); // new data, old version buffered in reader
+ QCOMPARE( writer.write(data2), qint64(data2.size()) ); // new data, unbuffered in reader
+
+ result += reader.readAll();
+
+ QCOMPARE( result, data1 + data2 );
+
+ QFile::remove(fileName);
+}
+
+void tst_QFile::readAllStdin()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll);
+#endif
+#if defined(QT_NO_PROCESS)
+ QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
+#else
+ QByteArray lotsOfData(1024, '@'); // 10 megs
+
+ QProcess process;
+ process.start("stdinprocess/stdinprocess all");
+ QVERIFY( process.waitForStarted() );
+ for (int i = 0; i < 5; ++i) {
+ QTest::qWait(1000);
+ process.write(lotsOfData);
+ while (process.bytesToWrite() > 0) {
+ QVERIFY(process.waitForBytesWritten());
+ }
+ }
+
+ process.closeWriteChannel();
+ process.waitForFinished();
+ QCOMPARE(process.readAll().size(), lotsOfData.size() * 5);
+#endif
+}
+
+void tst_QFile::readLineStdin()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll);
+#endif
+#if defined(QT_NO_PROCESS)
+ QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
+#else
+
+ QByteArray lotsOfData(1024, '@'); // 10 megs
+ for (int i = 0; i < lotsOfData.size(); ++i) {
+ if ((i % 32) == 31)
+ lotsOfData[i] = '\n';
+ else
+ lotsOfData[i] = char('0' + i % 32);
+ }
+
+ for (int i = 0; i < 2; ++i) {
+ QProcess process;
+ process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
+ for (int i = 0; i < 5; ++i) {
+ QTest::qWait(1000);
+ process.write(lotsOfData);
+ while (process.bytesToWrite() > 0) {
+ QVERIFY(process.waitForBytesWritten());
+ }
+ }
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+
+ QByteArray array = process.readAll();
+ QCOMPARE(array.size(), lotsOfData.size() * 5);
+ for (int i = 0; i < array.size(); ++i) {
+ if ((i % 32) == 31)
+ QCOMPARE(char(array[i]), '\n');
+ else
+ QCOMPARE(char(array[i]), char('0' + i % 32));
+ }
+ }
+#endif
+}
+
+void tst_QFile::readLineStdin_lineByLine()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("Currently no stdin/out supported for Windows CE", SkipAll);
+#endif
+#if defined(QT_NO_PROCESS)
+ QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
+#else
+ for (int i = 0; i < 2; ++i) {
+ QProcess process;
+ process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
+ QVERIFY(process.waitForStarted());
+
+ for (int j = 0; j < 3; ++j) {
+ QByteArray line = "line " + QByteArray::number(j) + "\n";
+ QCOMPARE(process.write(line), qint64(line.size()));
+ QVERIFY(process.waitForBytesWritten(2000));
+ if (process.bytesAvailable() == 0)
+ QVERIFY(process.waitForReadyRead(2000));
+ QCOMPARE(process.readAll(), line);
+ }
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+ }
+#endif
+}
+
+void tst_QFile::text()
+{
+ // dosfile.txt is a binary CRLF file
+ QFile file(SRCDIR "dosfile.txt");
+ QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
+ QCOMPARE(file.readLine(),
+ QByteArray("/dev/system/root / reiserfs acl,user_xattr 1 1\n"));
+ QCOMPARE(file.readLine(),
+ QByteArray("/dev/sda1 /boot ext3 acl,user_xattr 1 2\n"));
+ file.ungetChar('\n');
+ file.ungetChar('2');
+ QCOMPARE(file.readLine().constData(), QByteArray("2\n").constData());
+}
+
+void tst_QFile::missingEndOfLine()
+{
+ QFile file(SRCDIR "noendofline.txt");
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ int nlines = 0;
+ while (!file.atEnd()) {
+ ++nlines;
+ file.readLine();
+ }
+
+ QCOMPARE(nlines, 3);
+}
+
+void tst_QFile::readBlock()
+{
+ QFile f( SRCDIR "testfile.txt" );
+ f.open( QIODevice::ReadOnly );
+
+ int length = 0;
+ char p[256];
+ length = f.read( p, 256 );
+ f.close();
+ QCOMPARE( length, 245 );
+ QCOMPARE( p[59], 'D' );
+ QCOMPARE( p[178], 'T' );
+ QCOMPARE( p[199], 'l' );
+}
+
+void tst_QFile::getch()
+{
+ QFile f( SRCDIR "testfile.txt" );
+ f.open( QIODevice::ReadOnly );
+
+ char c;
+ int i = 0;
+ while (f.getChar(&c)) {
+ QCOMPARE(f.pos(), qint64(i + 1));
+ if ( i == 59 )
+ QCOMPARE( c, 'D' );
+ ++i;
+ }
+ f.close();
+ QCOMPARE( i, 245 );
+}
+
+void tst_QFile::ungetChar()
+{
+ QFile f(SRCDIR "testfile.txt");
+ QVERIFY(f.open(QIODevice::ReadOnly));
+
+ QByteArray array = f.readLine();
+ QCOMPARE(array.constData(), "----------------------------------------------------------\n");
+ f.ungetChar('\n');
+
+ array = f.readLine();
+ QCOMPARE(array.constData(), "\n");
+
+ f.ungetChar('\n');
+ f.ungetChar('-');
+ f.ungetChar('-');
+
+ array = f.readLine();
+ QCOMPARE(array.constData(), "--\n");
+
+ QFile::remove("genfile.txt");
+ QFile out("genfile.txt");
+ QVERIFY(out.open(QIODevice::ReadWrite));
+ out.write("123");
+ out.seek(0);
+ QCOMPARE(out.readAll().constData(), "123");
+ out.ungetChar('3');
+ out.write("4");
+ out.seek(0);
+ QCOMPARE(out.readAll().constData(), "124");
+ out.ungetChar('4');
+ out.ungetChar('2');
+ out.ungetChar('1');
+ char buf[3];
+ QCOMPARE(out.read(buf, sizeof(buf)), qint64(3));
+ QCOMPARE(buf[0], '1');
+ QCOMPARE(buf[1], '2');
+ QCOMPARE(buf[2], '4');
+}
+
+void tst_QFile::invalidFile_data()
+{
+ QTest::addColumn<QString>("fileName");
+#if !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow( "x11" ) << QString( "qwe//" );
+#else
+ QTest::newRow( "colon1" ) << QString( "fail:invalid" );
+ QTest::newRow( "colon2" ) << QString( "f:ail:invalid" );
+ QTest::newRow( "colon3" ) << QString( ":failinvalid" );
+ QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
+ QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
+ QTest::newRow( "questionmark" ) << QString( "fail?invalid" );
+ QTest::newRow( "quote" ) << QString( "fail\"invalid" );
+ QTest::newRow( "lt" ) << QString( "fail<invalid" );
+ QTest::newRow( "gt" ) << QString( "fail>invalid" );
+ QTest::newRow( "pipe" ) << QString( "fail|invalid" );
+#endif
+}
+
+void tst_QFile::invalidFile()
+{
+ QFETCH( QString, fileName );
+ QFile f( fileName );
+ QVERIFY( !f.open( QIODevice::ReadWrite ) );
+}
+
+void tst_QFile::createFile()
+{
+ if ( QFile::exists( "createme.txt" ) )
+ QFile::remove( "createme.txt" );
+ QVERIFY( !QFile::exists( "createme.txt" ) );
+
+ QFile f( "createme.txt" );
+ QVERIFY( f.open( QIODevice::WriteOnly ) );
+ f.close();
+ QVERIFY( QFile::exists( "createme.txt" ) );
+}
+
+void tst_QFile::append()
+{
+ const QString name("appendme.txt");
+ if (QFile::exists(name))
+ QFile::remove(name);
+ QVERIFY(!QFile::exists(name));
+
+ QFile f(name);
+ QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ f.putChar('a');
+ f.close();
+
+ QVERIFY(f.open(QIODevice::Append));
+ QVERIFY(f.pos() == 1);
+ f.putChar('a');
+ f.close();
+ QCOMPARE(int(f.size()), 2);
+}
+
+void tst_QFile::permissions_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<uint>("perms");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true;
+ QTest::newRow("data1") << SRCDIR "tst_qfile.cpp" << uint(QFile::ReadUser) << true;
+// QTest::newRow("data2") << "tst_qfile.cpp" << int(QFile::WriteUser) << false;
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser) << true;
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser) << false;
+ QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser) << false;
+}
+
+void tst_QFile::permissions()
+{
+#if defined(Q_OS_SYMBIAN)
+ if (qstrcmp(QTest::currentDataTag(), "data0") == 0)
+ QSKIP("Symbian does not have execution permissions", SkipSingle);
+#endif
+ QFETCH(QString, file);
+ QFETCH(uint, perms);
+ QFETCH(bool, expected);
+ QFile f(file);
+ QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected);
+ QCOMPARE(((QFile::permissions(file) & perms) == QFile::Permissions(perms)), expected);
+}
+
+void tst_QFile::setPermissions()
+{
+ DEPENDS_ON( "permissions" ); //if that doesn't work...
+
+ if ( QFile::exists( "createme.txt" ) )
+ QFile::remove( "createme.txt" );
+ QVERIFY( !QFile::exists( "createme.txt" ) );
+
+ QFile f("createme.txt");
+ QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ f.putChar('a');
+ f.close();
+
+ QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser);
+ QVERIFY(f.setPermissions(perms));
+ QVERIFY((f.permissions() & perms) == perms);
+
+}
+
+void tst_QFile::copy()
+{
+ QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser);
+ QFile::remove("tst_qfile_copy.cpp");
+ QFile::remove("test2");
+ QVERIFY(QFile::copy(SRCDIR "tst_qfile.cpp", "tst_qfile_copy.cpp"));
+ QFile in1(SRCDIR "tst_qfile.cpp"), in2("tst_qfile_copy.cpp");
+ QVERIFY(in1.open(QFile::ReadOnly));
+ QVERIFY(in2.open(QFile::ReadOnly));
+ QByteArray data1 = in1.readAll(), data2 = in2.readAll();
+ QCOMPARE(data1, data2);
+ QFile::remove( "main_copy.cpp" );
+
+ QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2"));
+}
+
+void tst_QFile::copyAfterFail()
+{
+ QFile file1("file-to-be-copied.txt");
+ QFile file2("existing-file.txt");
+
+ QVERIFY(file1.open(QIODevice::ReadWrite) && "(test-precondition)");
+ QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
+ file2.close();
+ QVERIFY(!QFile::exists("copied-file-1.txt") && "(test-precondition)");
+ QVERIFY(!QFile::exists("copied-file-2.txt") && "(test-precondition)");
+
+ QVERIFY(!file1.copy("existing-file.txt"));
+ QCOMPARE(file1.error(), QFile::CopyError);
+
+ QVERIFY(file1.copy("copied-file-1.txt"));
+ QVERIFY(!file1.isOpen());
+ QCOMPARE(file1.error(), QFile::NoError);
+
+ QVERIFY(!file1.copy("existing-file.txt"));
+ QCOMPARE(file1.error(), QFile::CopyError);
+
+ QVERIFY(file1.copy("copied-file-2.txt"));
+ QVERIFY(!file1.isOpen());
+ QCOMPARE(file1.error(), QFile::NoError);
+
+ QVERIFY(QFile::exists("copied-file-1.txt"));
+ QVERIFY(QFile::exists("copied-file-2.txt"));
+
+ QVERIFY(QFile::remove("file-to-be-copied.txt") && "(test-cleanup)");
+ QVERIFY(QFile::remove("existing-file.txt") && "(test-cleanup)");
+ QVERIFY(QFile::remove("copied-file-1.txt") && "(test-cleanup)");
+ QVERIFY(QFile::remove("copied-file-2.txt") && "(test-cleanup)");
+}
+
+void tst_QFile::copyRemovesTemporaryFile() const
+{
+ const QString newName(QLatin1String("copyRemovesTemporaryFile"));
+ QVERIFY(QFile::copy(SRCDIR "forCopying.txt", newName));
+
+ QVERIFY(!QFile::exists(QLatin1String( SRCDIR "qt_temp.XXXXXX")));
+ QVERIFY(QFile::remove(newName));
+}
+
+void tst_QFile::copyShouldntOverwrite()
+{
+ // Copy should not overwrite existing files.
+ QFile::remove("tst_qfile.cpy");
+ QFile file(SRCDIR "tst_qfile.cpp");
+ QVERIFY(file.copy("tst_qfile.cpy"));
+#if defined(Q_OS_SYMBIAN)
+ bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteUser);
+#else
+ bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther);
+#endif
+ QVERIFY(ok);
+ QVERIFY(!file.copy("tst_qfile.cpy"));
+ QFile::remove("tst_qfile.cpy");
+}
+
+void tst_QFile::copyFallback()
+{
+ // Using a resource file to trigger QFile::copy's fallback handling
+ QFile file(":/copy-fallback.qrc");
+ QFile::remove("file-copy-destination.txt");
+
+ QVERIFY2(file.exists(), "test precondition");
+ QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition");
+
+ // Fallback copy of closed file.
+ QVERIFY(file.copy("file-copy-destination.txt"));
+ QVERIFY(QFile::exists("file-copy-destination.txt"));
+ QVERIFY(!file.isOpen());
+
+#ifdef Q_WS_WINCE
+ // Need to reset permissions on Windows to be able to delete
+ QVERIFY(QFile::setPermissions("file-copy-destination.txt",
+ QFile::WriteOther));
+#else
+ // Need to reset permissions on Windows to be able to delete
+ QVERIFY(QFile::setPermissions("file-copy-destination.txt",
+ QFile::ReadOwner | QFile::WriteOwner));
+#endif
+ QVERIFY(QFile::remove("file-copy-destination.txt"));
+
+ // Fallback copy of open file.
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QVERIFY(file.copy("file-copy-destination.txt"));
+ QVERIFY(QFile::exists("file-copy-destination.txt"));
+ QVERIFY(!file.isOpen());
+
+ file.close();
+ QFile::remove("file-copy-destination.txt");
+}
+
+#ifdef Q_OS_WIN
+#include <objbase.h>
+#include <shlobj.h>
+#endif
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+static QString getWorkingDirectoryForLink(const QString &linkFileName)
+{
+ bool neededCoInit = false;
+ QString ret;
+
+ IShellLink *psl;
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
+ neededCoInit = true;
+ CoInitialize(NULL);
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ }
+
+ if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
+ IPersistFile *ppf;
+ hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
+ if (SUCCEEDED(hres)) {
+ hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
+ //The original path of the link is retrieved. If the file/folder
+ //was moved, the return value still have the old path.
+ if(SUCCEEDED(hres)) {
+ wchar_t szGotPath[MAX_PATH];
+ if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
+ ret = QString::fromWCharArray(szGotPath);
+ }
+ ppf->Release();
+ }
+ psl->Release();
+ }
+
+ if (neededCoInit) {
+ CoUninitialize();
+ }
+
+ return ret;
+}
+#endif
+
+void tst_QFile::link()
+{
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Symbian does not support links", SkipAll);
+#endif
+ QFile::remove("myLink.lnk");
+
+ QFileInfo info1(SRCDIR "tst_qfile.cpp");
+ QString referenceTarget = QDir::cleanPath(info1.absoluteFilePath());
+
+ QVERIFY(QFile::link(SRCDIR "tst_qfile.cpp", "myLink.lnk"));
+
+ QFileInfo info2("myLink.lnk");
+ QVERIFY(info2.isSymLink());
+ QCOMPARE(info2.symLinkTarget(), referenceTarget);
+
+ QFile link("myLink.lnk");
+ QVERIFY(link.open(QIODevice::ReadOnly));
+ QCOMPARE(link.symLinkTarget(), referenceTarget);
+ link.close();
+
+ QCOMPARE(QFile::symLinkTarget("myLink.lnk"), referenceTarget);
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath());
+ QCOMPARE(QDir::fromNativeSeparators(wd), QDir::cleanPath(info1.absolutePath()));
+#endif
+
+ QVERIFY(QFile::remove(info2.absoluteFilePath()));
+}
+
+void tst_QFile::linkToDir()
+{
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Symbian does not support linking to directories", SkipAll);
+#endif
+ QFile::remove("myLinkToDir.lnk");
+ QDir dir;
+ dir.mkdir("myDir");
+ QFileInfo info1("myDir");
+ QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
+ QFileInfo info2("myLinkToDir.lnk");
+#if !(defined Q_OS_HPUX && defined(__ia64))
+ // absurd HP-UX filesystem bug on gravlaks - checking if a symlink
+ // resolves or not alters the file system to make the broken symlink
+ // later fail...
+ QVERIFY(info2.isSymLink());
+#endif
+ QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
+ QVERIFY(QFile::remove(info2.absoluteFilePath()));
+ QFile::remove("myLinkToDir.lnk");
+ dir.rmdir("myDir");
+}
+
+void tst_QFile::absolutePathLinkToRelativePath()
+{
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Symbian does not support links", SkipAll);
+#endif
+ QFile::remove("myDir/test.txt");
+ QFile::remove("myDir/myLink.lnk");
+ QDir dir;
+ dir.mkdir("myDir");
+ QFile("myDir/test.txt").open(QFile::WriteOnly);
+
+#ifdef Q_OS_WIN
+ QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
+#else
+ QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
+#endif
+ QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix/Symbian", Continue);
+ QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(),
+ QFileInfo("myDir/test.txt").absoluteFilePath());
+
+ QFile::remove("myDir/test.txt");
+ QFile::remove("myDir/myLink.lnk");
+ dir.rmdir("myDir");
+}
+
+void tst_QFile::readBrokenLink()
+{
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Symbian does not support links", SkipAll);
+#endif
+ QFile::remove("myLink2.lnk");
+ QFileInfo info1("file12");
+#if defined(Q_OS_SYMBIAN)
+ // In Symbian can't link to nonexisting file directly, so create the file temporarily
+ QFile tempFile("file12");
+ tempFile.open(QIODevice::WriteOnly);
+ tempFile.link("myLink2.lnk");
+ tempFile.remove();
+#else
+ QVERIFY(QFile::link("file12", "myLink2.lnk"));
+#endif
+ QFileInfo info2("myLink2.lnk");
+ QVERIFY(info2.isSymLink());
+ QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
+ QVERIFY(QFile::remove(info2.absoluteFilePath()));
+
+#if !defined(Q_OS_SYMBIAN)
+ QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
+ QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
+#endif
+}
+
+void tst_QFile::readTextFile_data()
+{
+ QTest::addColumn<QByteArray>("in");
+ QTest::addColumn<QByteArray>("out");
+
+ QTest::newRow("empty") << QByteArray() << QByteArray();
+ QTest::newRow("a") << QByteArray("a") << QByteArray("a");
+ QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab");
+ QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n");
+ QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n");
+ QTest::newRow("\\r") << QByteArray("\r") << QByteArray();
+ QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n");
+ QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld");
+}
+
+void tst_QFile::readTextFile()
+{
+ QFETCH(QByteArray, in);
+ QFETCH(QByteArray, out);
+
+ QFile winfile("winfile.txt");
+ QVERIFY(winfile.open(QFile::WriteOnly | QFile::Truncate));
+ winfile.write(in);
+ winfile.close();
+
+ QVERIFY(winfile.open(QFile::ReadOnly));
+ QCOMPARE(winfile.readAll(), in);
+ winfile.close();
+
+ QVERIFY(winfile.open(QFile::ReadOnly | QFile::Text));
+ QCOMPARE(winfile.readAll(), out);
+}
+
+void tst_QFile::readTextFile2()
+{
+ {
+ QFile file(SRCDIR "testlog.txt");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ file.read(4097);
+ }
+
+ {
+ QFile file(SRCDIR "testlog.txt");
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ file.read(4097);
+ }
+}
+
+void tst_QFile::writeTextFile_data()
+{
+ QTest::addColumn<QByteArray>("in");
+
+ QTest::newRow("empty") << QByteArray();
+ QTest::newRow("a") << QByteArray("a");
+ QTest::newRow("a\\rb") << QByteArray("a\rb");
+ QTest::newRow("\\n") << QByteArray("\n");
+ QTest::newRow("\\r\\n") << QByteArray("\r\n");
+ QTest::newRow("\\r") << QByteArray("\r");
+ QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n");
+ QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld");
+ QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n");
+ QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld");
+ QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n");
+}
+
+void tst_QFile::writeTextFile()
+{
+ QFETCH(QByteArray, in);
+
+ QFile file("textfile.txt");
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text));
+ QByteArray out = in;
+#ifdef Q_OS_WIN
+ out.replace('\n', "\r\n");
+#endif
+ QCOMPARE(file.write(in), qlonglong(in.size()));
+ file.close();
+
+ file.open(QFile::ReadOnly);
+ QCOMPARE(file.readAll(), out);
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QFile::largeUncFileSupport()
+{
+ qint64 size = Q_INT64_C(8589934592);
+ qint64 dataOffset = Q_INT64_C(8589914592);
+ QByteArray knownData("LargeFile content at offset 8589914592");
+ QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
+
+ {
+ // 1) Native file handling.
+ QFile file(largeFile);
+ QCOMPARE(file.size(), size);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QCOMPARE(file.size(), size);
+ QVERIFY(file.seek(dataOffset));
+ QCOMPARE(file.read(knownData.size()), knownData);
+ }
+ {
+ // 2) stdlib file handling.
+#if _MSC_VER <= 1310
+ QSKIP("platform SDK for MSVC 2003 does not support large files", SkipAll);
+#endif
+ QFile file;
+ FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
+ QVERIFY(file.open(fh, QIODevice::ReadOnly));
+ QCOMPARE(file.size(), size);
+ QVERIFY(file.seek(dataOffset));
+ QCOMPARE(file.read(knownData.size()), knownData);
+ fclose(fh);
+ }
+ {
+ // 3) stdio file handling.
+ QFile file;
+ FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
+ int fd = int(_fileno(fh));
+ QVERIFY(file.open(fd, QIODevice::ReadOnly));
+ QCOMPARE(file.size(), size);
+ QVERIFY(file.seek(dataOffset));
+ QCOMPARE(file.read(knownData.size()), knownData);
+ fclose(fh);
+ }
+}
+#endif
+
+void tst_QFile::tailFile()
+{
+ QSKIP("File change notifications are so far unsupported.", SkipAll);
+
+ QFile file("tail.txt");
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
+
+ QFile tailFile("tail.txt");
+ QVERIFY(tailFile.open(QFile::ReadOnly));
+ tailFile.seek(file.size());
+
+ QSignalSpy readSignal(&tailFile, SIGNAL(readyRead()));
+
+ file.write("", 1);
+
+ QTestEventLoop::instance().enterLoop(5);
+
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QCOMPARE(readSignal.count(), 1);
+}
+
+void tst_QFile::flush()
+{
+ QString fileName("stdfile.txt");
+
+ QFile::remove(fileName);
+
+ {
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::WriteOnly));
+ QCOMPARE(file.write("abc", 3),qint64(3));
+ }
+
+ {
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
+ QCOMPARE(file.pos(), qlonglong(3));
+ QCOMPARE(file.write("def", 3), qlonglong(3));
+ QCOMPARE(file.pos(), qlonglong(6));
+ }
+
+ {
+ QFile file("stdfile.txt");
+ QVERIFY(file.open(QFile::ReadOnly));
+ QCOMPARE(file.readAll(), QByteArray("abcdef"));
+ }
+
+ QFile::remove(fileName);
+}
+
+void tst_QFile::bufferedRead()
+{
+ QFile::remove("stdfile.txt");
+
+ QFile file("stdfile.txt");
+ QVERIFY(file.open(QFile::WriteOnly));
+ file.write("abcdef");
+ file.close();
+
+#if defined(Q_OS_WINCE)
+ FILE *stdFile = fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r");
+#else
+ FILE *stdFile = fopen("stdfile.txt", "r");
+#endif
+ QVERIFY(stdFile);
+ char c;
+ QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1);
+ QCOMPARE(c, 'a');
+ QCOMPARE(int(ftell(stdFile)), 1);
+
+ {
+ QFile file;
+ QVERIFY(file.open(stdFile, QFile::ReadOnly));
+ QCOMPARE(file.pos(), qlonglong(1));
+ QCOMPARE(file.read(&c, 1), qlonglong(1));
+ QCOMPARE(c, 'b');
+ QCOMPARE(file.pos(), qlonglong(2));
+ }
+
+ fclose(stdFile);
+}
+
+void tst_QFile::isSequential()
+{
+#if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QSKIP("Unix only test.", SkipAll);
+#endif
+
+ QFile zero("/dev/null");
+ QVERIFY(zero.open(QFile::ReadOnly));
+ QVERIFY(zero.isSequential());
+}
+
+void tst_QFile::encodeName()
+{
+ QCOMPARE(QFile::encodeName(QString::null), QByteArray());
+}
+
+void tst_QFile::truncate()
+{
+ for (int i = 0; i < 2; ++i) {
+ QFile file("truncate.txt");
+ QVERIFY(file.open(QFile::WriteOnly));
+ file.write(QByteArray(200, '@'));
+ file.close();
+
+ QVERIFY(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate));
+ file.write(QByteArray(100, '$'));
+ file.close();
+
+ QVERIFY(file.open(QFile::ReadOnly));
+ QCOMPARE(file.readAll(), QByteArray(100, '$'));
+ }
+}
+
+void tst_QFile::seekToPos()
+{
+ {
+ QFile file("seekToPos.txt");
+ QVERIFY(file.open(QFile::WriteOnly));
+ file.write("a\r\nb\r\nc\r\n");
+ file.flush();
+ }
+
+ QFile file("seekToPos.txt");
+ QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
+ file.seek(1);
+ char c;
+ QVERIFY(file.getChar(&c));
+ QCOMPARE(c, '\n');
+
+ QCOMPARE(file.pos(), qint64(3));
+ file.seek(file.pos());
+ QCOMPARE(file.pos(), qint64(3));
+
+ file.seek(1);
+ file.seek(file.pos());
+ QCOMPARE(file.pos(), qint64(1));
+
+}
+
+void tst_QFile::seekAfterEndOfFile()
+{
+ QLatin1String filename("seekAfterEof.dat");
+ QFile::remove(filename);
+ {
+ QFile file(filename);
+ QVERIFY(file.open(QFile::WriteOnly));
+ file.write("abcd");
+ QCOMPARE(file.size(), qint64(4));
+ file.seek(8);
+ file.write("ijkl");
+ QCOMPARE(file.size(), qint64(12));
+ file.seek(4);
+ file.write("efgh");
+ QCOMPARE(file.size(), qint64(12));
+ file.seek(16);
+ file.write("----");
+ QCOMPARE(file.size(), qint64(20));
+ file.flush();
+ }
+
+ QFile file(filename);
+ QVERIFY(file.open(QFile::ReadOnly));
+ QByteArray contents = file.readAll();
+ QCOMPARE(contents.left(12), QByteArray("abcdefghijkl", 12));
+ //bytes 12-15 are uninitialised so we don't care what they read as.
+ QCOMPARE(contents.mid(16), QByteArray("----", 4));
+ file.close();
+ QFile::remove(filename);
+}
+
+void tst_QFile::FILEReadWrite()
+{
+ // Tests modifying a file. First creates it then reads in 4 bytes and then overwrites these
+ // 4 bytes with new values. At the end check to see the file contains the new values.
+
+ QFile::remove("FILEReadWrite.txt");
+
+ // create test file
+ {
+ QFile f("FILEReadWrite.txt");
+ QVERIFY(f.open(QFile::WriteOnly));
+ QDataStream ds(&f);
+ qint8 c = 0;
+ ds << c;
+ c = 1;
+ ds << c;
+ c = 2;
+ ds << c;
+ c = 3;
+ ds << c;
+ c = 4;
+ ds << c;
+ c = 5;
+ ds << c;
+ c = 6;
+ ds << c;
+ c = 7;
+ ds << c;
+ c = 8;
+ ds << c;
+ c = 9;
+ ds << c;
+ c = 10;
+ ds << c;
+ c = 11;
+ ds << c;
+ f.close();
+ }
+
+#ifdef Q_OS_WINCE
+ FILE *fp = fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
+#else
+ FILE *fp = fopen("FILEReadWrite.txt", "r+b");
+#endif
+ QVERIFY(fp);
+ QFile file;
+ QVERIFY(file.open(fp, QFile::ReadWrite));
+ QDataStream sfile(&file) ;
+
+ qint8 var1,var2,var3,var4;
+ while (!sfile.atEnd())
+ {
+ qint64 base = file.pos();
+
+ QCOMPARE(file.pos(), base + 0);
+ sfile >> var1;
+ QCOMPARE(file.pos(), base + 1);
+ file.flush(); // flushing should not change the base
+ QCOMPARE(file.pos(), base + 1);
+ sfile >> var2;
+ QCOMPARE(file.pos(), base + 2);
+ sfile >> var3;
+ QCOMPARE(file.pos(), base + 3);
+ sfile >> var4;
+ QCOMPARE(file.pos(), base + 4);
+ file.seek(file.pos() - 4) ; // Move it back 4, for we are going to write new values based on old ones
+ QCOMPARE(file.pos(), base + 0);
+ sfile << qint8(var1 + 5);
+ QCOMPARE(file.pos(), base + 1);
+ sfile << qint8(var2 + 5);
+ QCOMPARE(file.pos(), base + 2);
+ sfile << qint8(var3 + 5);
+ QCOMPARE(file.pos(), base + 3);
+ sfile << qint8(var4 + 5);
+ QCOMPARE(file.pos(), base + 4);
+
+ }
+ file.close();
+ fclose(fp);
+
+ // check modified file
+ {
+ QFile f("FILEReadWrite.txt");
+ QVERIFY(f.open(QFile::ReadOnly));
+ QDataStream ds(&f);
+ qint8 c = 0;
+ ds >> c;
+ QCOMPARE(c, (qint8)5);
+ ds >> c;
+ QCOMPARE(c, (qint8)6);
+ ds >> c;
+ QCOMPARE(c, (qint8)7);
+ ds >> c;
+ QCOMPARE(c, (qint8)8);
+ ds >> c;
+ QCOMPARE(c, (qint8)9);
+ ds >> c;
+ QCOMPARE(c, (qint8)10);
+ ds >> c;
+ QCOMPARE(c, (qint8)11);
+ ds >> c;
+ QCOMPARE(c, (qint8)12);
+ ds >> c;
+ QCOMPARE(c, (qint8)13);
+ ds >> c;
+ QCOMPARE(c, (qint8)14);
+ ds >> c;
+ QCOMPARE(c, (qint8)15);
+ ds >> c;
+ QCOMPARE(c, (qint8)16);
+ f.close();
+ }
+
+ QFile::remove("FILEReadWrite.txt");
+}
+
+
+/*
+#include <qglobal.h>
+#define BUFFSIZE 1
+#define FILESIZE 0x10000000f
+void tst_QFile::largeFileSupport()
+{
+#ifdef Q_OS_SOLARIS
+ QSKIP("Solaris does not support statfs", SkipAll);
+#else
+ qlonglong sizeNeeded = 2147483647;
+ sizeNeeded *= 2;
+ sizeNeeded += 1024;
+ qlonglong freespace = qlonglong(0);
+#ifdef Q_WS_WIN
+ _ULARGE_INTEGER free;
+ if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0))
+ freespace = free.QuadPart;
+ if (freespace != 0) {
+#elif defined(Q_OS_IRIX)
+ struct statfs info;
+ if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
+ freespace = qlonglong(info.f_bfree * info.f_bsize);
+#else
+ struct statfs info;
+ if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
+ freespace = qlonglong(info.f_bavail * info.f_bsize);
+#endif
+ if (freespace > sizeNeeded) {
+ QFile bigFile("bigfile");
+ if (bigFile.open(QFile::ReadWrite)) {
+ char c[BUFFSIZE] = {'a'};
+ QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
+ qlonglong oldPos = bigFile.pos();
+ QVERIFY(bigFile.resize(sizeNeeded));
+ QCOMPARE(oldPos, bigFile.pos());
+ QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
+ QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
+
+ bigFile.close();
+ if (bigFile.open(QFile::ReadOnly)) {
+ QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
+ int i = 0;
+ for (i=0; i<BUFFSIZE; i++)
+ QCOMPARE(c[i], 'a');
+ QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
+ QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
+ for (i=0; i<BUFFSIZE; i++)
+ QCOMPARE(c[i], 'a');
+ bigFile.close();
+ QVERIFY(bigFile.remove());
+ } else {
+ QVERIFY(bigFile.remove());
+ QFAIL("Could not reopen file");
+ }
+ } else {
+ QFAIL("Could not open file");
+ }
+ } else {
+ QSKIP("Not enough space to run test", SkipSingle);
+ }
+ } else {
+ QFAIL("Could not determin disk space");
+ }
+#endif
+}
+*/
+
+void tst_QFile::i18nFileName_data()
+{
+ QTest::addColumn<QString>("fileName");
+
+ QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt");
+}
+
+void tst_QFile::i18nFileName()
+{
+ QFETCH(QString, fileName);
+ if (QFile::exists(fileName)) {
+ QVERIFY(QFile::remove(fileName));
+ }
+ {
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
+ QTextStream ts(&file);
+ ts.setCodec("UTF-8");
+ ts << fileName << endl;
+ }
+ {
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
+ QTextStream ts(&file);
+ ts.setCodec("UTF-8");
+ QString line = ts.readLine();
+ QCOMPARE(line, fileName);
+ }
+ QVERIFY(QFile::remove(fileName));
+}
+
+
+void tst_QFile::longFileName_data()
+{
+ QTest::addColumn<QString>("fileName");
+
+ QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt");
+ QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt");
+ QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName.txt");
+ QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName.txt");
+ QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
+ /* needs to be put on a windows 2000 > test machine
+ QTest::newRow( "244 chars on UNC" ) << QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName.txt");*/
+}
+
+void tst_QFile::longFileName()
+{
+ QFETCH(QString, fileName);
+ if (QFile::exists(fileName)) {
+ QVERIFY(QFile::remove(fileName));
+ }
+ {
+ QFile file(fileName);
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
+ QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
+#endif
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
+ QTextStream ts(&file);
+ ts << fileName << endl;
+ }
+ {
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
+ QTextStream ts(&file);
+ QString line = ts.readLine();
+ QCOMPARE(line, fileName);
+ }
+ QString newName = fileName + QLatin1String("1");
+ {
+ QVERIFY(QFile::copy(fileName, newName));
+ QFile file(newName);
+ QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
+ QTextStream ts(&file);
+ QString line = ts.readLine();
+ QCOMPARE(line, fileName);
+
+ }
+ QVERIFY(QFile::remove(newName));
+ {
+ QVERIFY(QFile::rename(fileName, newName));
+ QFile file(newName);
+ QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
+ QTextStream ts(&file);
+ QString line = ts.readLine();
+ QCOMPARE(line, fileName);
+ }
+ QVERIFY(QFile::exists(newName));
+ QVERIFY(QFile::remove(newName));
+}
+
+class MyEngine : public QAbstractFileEngine
+{
+public:
+ MyEngine(int n) { number = n; }
+ virtual ~MyEngine() {}
+
+ void setFileName(const QString &) {}
+ bool open(int ) { return false; }
+ bool close() { return false; }
+ bool flush() { return false; }
+ qint64 size() const { return 123 + number; }
+ qint64 at() const { return -1; }
+ bool seek(qint64) { return false; }
+ bool isSequential() const { return false; }
+ qint64 read(char *, qint64) { return -1; }
+ qint64 write(const char *, qint64) { return -1; }
+ bool remove() { return false; }
+ bool copy(const QString &) { return false; }
+ bool rename(const QString &) { return false; }
+ bool link(const QString &) { return false; }
+ bool mkdir(const QString &, bool) const { return false; }
+ bool rmdir(const QString &, bool) const { return false; }
+ bool setSize(qint64) { return false; }
+ QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); }
+ bool caseSensitive() const { return false; }
+ bool isRelativePath() const { return false; }
+ FileFlags fileFlags(FileFlags) const { return 0; }
+ bool chmod(uint) { return false; }
+ QString fileName(FileName) const { return name; }
+ uint ownerId(FileOwner) const { return 0; }
+ QString owner(FileOwner) const { return QString(); }
+ QDateTime fileTime(FileTime) const { return QDateTime(); }
+
+private:
+ int number;
+ QString name;
+};
+
+class MyHandler : public QAbstractFileEngineHandler
+{
+public:
+ inline QAbstractFileEngine *create(const QString &) const
+ {
+ return new MyEngine(1);
+ }
+};
+
+class MyHandler2 : public QAbstractFileEngineHandler
+{
+public:
+ inline QAbstractFileEngine *create(const QString &) const
+ {
+ return new MyEngine(2);
+ }
+};
+
+void tst_QFile::fileEngineHandler()
+{
+ // A file that does not exist has a size of 0.
+ QFile::remove("ole.bull");
+ QFile file("ole.bull");
+ QCOMPARE(file.size(), qint64(0));
+
+ // Instantiating our handler will enable the new engine.
+ MyHandler handler;
+ file.setFileName("ole.bull");
+ QCOMPARE(file.size(), qint64(124));
+
+ // A new, identical handler should take preference over the last one.
+ MyHandler2 handler2;
+ file.setFileName("ole.bull");
+ QCOMPARE(file.size(), qint64(125));
+
+}
+
+class MyRecursiveHandler : public QAbstractFileEngineHandler
+{
+public:
+ inline QAbstractFileEngine *create(const QString &fileName) const
+ {
+ if (fileName.startsWith(":!")) {
+ QDir dir;
+ QString realFile = SRCDIR + fileName.mid(2);
+ if (dir.exists(realFile))
+ return new QFSFileEngine(realFile);
+ }
+ return 0;
+ }
+};
+
+void tst_QFile::useQFileInAFileHandler()
+{
+ // This test should not dead-lock
+ MyRecursiveHandler handler;
+ QFile file(":!tst_qfile.cpp");
+ QVERIFY(file.exists());
+}
+
+void tst_QFile::getCharFF()
+{
+ QFile file("file.txt");
+ file.open(QFile::ReadWrite);
+ file.write("\xff\xff\xff");
+ file.flush();
+ file.seek(0);
+
+ char c;
+ QVERIFY(file.getChar(&c));
+ QVERIFY(file.getChar(&c));
+ QVERIFY(file.getChar(&c));
+}
+
+void tst_QFile::remove_and_exists()
+{
+ QFile::remove("tull_i_grunn.txt");
+ QFile f("tull_i_grunn.txt");
+
+ QVERIFY(!f.exists());
+
+ bool opened = f.open(QIODevice::WriteOnly);
+ QVERIFY(opened);
+
+ f.write(QString("testing that remove/exists work...").toLatin1());
+ f.close();
+
+ QVERIFY(f.exists());
+
+ f.remove();
+ QVERIFY(!f.exists());
+}
+
+void tst_QFile::removeOpenFile()
+{
+ {
+ // remove an opened, write-only file
+ QFile::remove("remove_unclosed.txt");
+ QFile f("remove_unclosed.txt");
+
+ QVERIFY(!f.exists());
+ bool opened = f.open(QIODevice::WriteOnly);
+ QVERIFY(opened);
+ f.write(QString("testing that remove closes the file first...").toLatin1());
+
+ bool removed = f.remove(); // remove should both close and remove the file
+ QVERIFY(removed);
+ QVERIFY(!f.isOpen());
+ QVERIFY(!f.exists());
+ QVERIFY(f.error() == QFile::NoError);
+ }
+
+ {
+ // remove an opened, read-only file
+ QFile::remove("remove_unclosed.txt");
+
+ // first, write a file that we can remove
+ {
+ QFile f("remove_unclosed.txt");
+ QVERIFY(!f.exists());
+ bool opened = f.open(QIODevice::WriteOnly);
+ QVERIFY(opened);
+ f.write(QString("testing that remove closes the file first...").toLatin1());
+ f.close();
+ }
+
+ QFile f("remove_unclosed.txt");
+ bool opened = f.open(QIODevice::ReadOnly);
+ QVERIFY(opened);
+ f.readAll();
+ // this used to only fail on FreeBSD (and Mac OS X)
+ QVERIFY(f.flush());
+ bool removed = f.remove(); // remove should both close and remove the file
+ QVERIFY(removed);
+ QVERIFY(!f.isOpen());
+ QVERIFY(!f.exists());
+ QVERIFY(f.error() == QFile::NoError);
+ }
+}
+
+void tst_QFile::fullDisk()
+{
+ QFile file("/dev/full");
+ if (!file.exists())
+ QSKIP("/dev/full doesn't exist on this system", SkipAll);
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.write("foobar", 6);
+
+ QVERIFY(!file.flush());
+ QCOMPARE(file.error(), QFile::ResourceError);
+ QVERIFY(!file.flush());
+ QCOMPARE(file.error(), QFile::ResourceError);
+
+ char c = 0;
+ file.write(&c, 0);
+ QVERIFY(!file.flush());
+ QCOMPARE(file.error(), QFile::ResourceError);
+ QCOMPARE(file.write(&c, 1), qint64(1));
+ QVERIFY(!file.flush());
+ QCOMPARE(file.error(), QFile::ResourceError);
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.error(), QFile::ResourceError);
+
+ file.open(QIODevice::WriteOnly);
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(file.flush()); // Shouldn't inherit write buffer
+ file.close();
+ QCOMPARE(file.error(), QFile::NoError);
+
+ // try again without flush:
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.write("foobar", 6);
+ file.close();
+ QVERIFY(file.error() != QFile::NoError);
+}
+
+void tst_QFile::writeLargeDataBlock_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<int>("type");
+
+ QTest::newRow("localfile-QFile") << "./largeblockfile.txt" << (int)OpenQFile;
+ QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd;
+ QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream;
+#ifdef Q_OS_SYMBIAN
+ QTest::newRow("localfile-RFile") << "./largeblockfile.txt" << (int)OpenRFile;
+#endif
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // Some semi-randomness to avoid collisions.
+ QTest::newRow("unc file")
+ << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
+ .arg(QHostInfo::localHostName())
+ .arg(QTime::currentTime().msec()) << (int)OpenQFile;
+#endif
+}
+
+static QByteArray getLargeDataBlock()
+{
+ static QByteArray array;
+
+ if (array.isNull())
+ {
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ int resizeSize = 1024 * 1024; // WinCE and Symbian do not have much space
+#else
+ int resizeSize = 64 * 1024 * 1024;
+#endif
+ array.resize(resizeSize);
+ for (int i = 0; i < array.size(); ++i)
+ array[i] = uchar(i);
+ }
+
+ return array;
+}
+
+void tst_QFile::writeLargeDataBlock()
+{
+ QFETCH(QString, fileName);
+ QFETCH( int, type );
+
+ QByteArray const originalData = getLargeDataBlock();
+
+ {
+ QFile file(fileName);
+
+ QVERIFY2( openFile(file, QIODevice::WriteOnly, (FileType)type),
+ qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName)) );
+ QCOMPARE( file.write(originalData), (qint64)originalData.size() );
+ QVERIFY( file.flush() );
+
+ closeFile(file);
+ }
+
+ QByteArray readData;
+
+ {
+ QFile file(fileName);
+
+ QVERIFY2( openFile(file, QIODevice::ReadOnly, (FileType)type),
+ qPrintable(QString("Couldn't open file for reading: [%1]").arg(fileName)) );
+ readData = file.readAll();
+ closeFile(file);
+ }
+
+ QCOMPARE( readData, originalData );
+ QVERIFY( QFile::remove(fileName) );
+}
+
+void tst_QFile::readFromWriteOnlyFile()
+{
+ QFile file("writeonlyfile");
+ QVERIFY(file.open(QFile::WriteOnly));
+ char c;
+ QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device");
+ QCOMPARE(file.read(&c, 1), qint64(-1));
+}
+
+void tst_QFile::writeToReadOnlyFile()
+{
+ QFile file("readonlyfile");
+ QVERIFY(file.open(QFile::ReadOnly));
+ char c = 0;
+ QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device");
+ QCOMPARE(file.write(&c, 1), qint64(-1));
+}
+
+void tst_QFile::virtualFile()
+{
+ // test if QFile works with virtual files
+ QString fname;
+#if defined(Q_OS_LINUX)
+ fname = "/proc/self/maps";
+#elif defined(Q_OS_AIX)
+ fname = QString("/proc/%1/map").arg(getpid());
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+ fname = "/proc/curproc/map";
+#else
+ QSKIP("This platform does not have 0-sized virtual files", SkipAll);
+#endif
+
+ // consistency check
+ QFileInfo fi(fname);
+ QVERIFY(fi.exists());
+ QVERIFY(fi.isFile());
+ QCOMPARE(fi.size(), Q_INT64_C(0));
+
+ // open the file
+ QFile f(fname);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ QCOMPARE(f.size(), Q_INT64_C(0));
+ QVERIFY(f.atEnd());
+
+ // read data
+ QByteArray data = f.read(16);
+ QCOMPARE(data.size(), 16);
+ QCOMPARE(f.pos(), Q_INT64_C(16));
+
+ // line-reading
+ data = f.readLine();
+ QVERIFY(!data.isEmpty());
+
+ // read all:
+ data = f.readAll();
+ QVERIFY(f.pos() != 0);
+ QVERIFY(!data.isEmpty());
+
+ // seeking
+ QVERIFY(f.seek(1));
+ QCOMPARE(f.pos(), Q_INT64_C(1));
+}
+
+void tst_QFile::textFile()
+{
+#if defined(Q_OS_WINCE)
+ FILE *fs = ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toAscii() , "wt");
+#elif defined(Q_OS_WIN)
+ FILE *fs = ::fopen("writeabletextfile", "wt");
+#else
+ FILE *fs = ::fopen("writeabletextfile", "w");
+#endif
+ QFile f;
+ QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n");
+ QByteArray part2("Add\nsome\nmore\nnewlines\n");
+
+ QVERIFY(f.open(fs, QIODevice::WriteOnly));
+ f.write(part1);
+ f.write(part2);
+ f.close();
+ ::fclose(fs);
+
+ QFile file("writeabletextfile");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+
+ QByteArray data = file.readAll();
+
+ QByteArray expected = part1 + part2;
+#ifdef Q_OS_WIN
+ expected.replace("\n", "\015\012");
+#endif
+ QCOMPARE(data, expected);
+ file.close();
+ file.remove();
+}
+
+void tst_QFile::rename_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<QString>("destination");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("a -> b") << QString("a") << QString("b") << false;
+ QTest::newRow("a -> .") << QString("a") << QString(".") << false;
+ QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
+ QTest::newRow("renamefile -> noreadfile") << QString("renamefile") << QString("noreadfile") << false;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
+#endif
+ QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true;
+ QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false;
+}
+
+void tst_QFile::rename()
+{
+ QFETCH(QString, source);
+ QFETCH(QString, destination);
+ QFETCH(bool, result);
+
+ QFile::remove("renamedfile");
+ QFile f("renamefile");
+ f.open(QFile::WriteOnly);
+ f.close();
+
+ QFile file(source);
+ QCOMPARE(file.rename(destination), result);
+
+ if (result)
+ QCOMPARE(file.error(), QFile::NoError);
+ else
+ QCOMPARE(file.error(), QFile::RenameError);
+
+ QFile::remove("renamefile");
+}
+
+/*!
+ \since 4.5
+
+ Some special files have QFile::atEnd() returning true, even though there is
+ more data available. True for corner cases, as well as some mounts on OS X.
+
+ Here, we reproduce that condition by having a QFile sub-class with this
+ peculiar atEnd() behavior.
+
+ See task 231583.
+ */
+void tst_QFile::renameWithAtEndSpecialFile() const
+{
+ class PeculiarAtEnd : public QFile
+ {
+ public:
+ virtual bool atEnd() const
+ {
+ return true;
+ }
+ };
+
+ const QString newName(QLatin1String("newName.txt"));
+ /* Cleanup, so we're a bit more robust. */
+ QFile::remove(newName);
+
+ const QString originalName(QString(SRCDIR "forRenaming.txt"));
+
+ PeculiarAtEnd file;
+ file.setFileName(originalName);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+
+ QVERIFY(file.rename(newName));
+
+ file.close();
+ /* Guess what, we have to rename it back, otherwise we'll fail on second
+ * invocation. */
+ QVERIFY(QFile::rename(newName, originalName));
+}
+
+void tst_QFile::renameFallback()
+{
+ // Using a resource file both to trigger QFile::rename's fallback handling
+ // and as a *read-only* source whose move should fail.
+ QFile file(":/rename-fallback.qrc");
+ QVERIFY(file.exists() && "(test-precondition)");
+ QFile::remove("file-rename-destination.txt");
+
+ QVERIFY(!file.rename("file-rename-destination.txt"));
+ QVERIFY(!QFile::exists("file-rename-destination.txt"));
+ QVERIFY(!file.isOpen());
+}
+
+void tst_QFile::renameMultiple()
+{
+ // create the file if it doesn't exist
+ QFile file("file-to-be-renamed.txt");
+ QFile file2("existing-file.txt");
+ QVERIFY(file.open(QIODevice::ReadWrite) && "(test-precondition)");
+ QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
+
+ // any stale files from previous test failures?
+ QFile::remove("file-renamed-once.txt");
+ QFile::remove("file-renamed-twice.txt");
+
+ // begin testing
+ QVERIFY(QFile::exists("existing-file.txt"));
+ QVERIFY(!file.rename("existing-file.txt"));
+ QCOMPARE(file.error(), QFile::RenameError);
+ QCOMPARE(file.fileName(), QString("file-to-be-renamed.txt"));
+
+ QVERIFY(file.rename("file-renamed-once.txt"));
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
+
+ QVERIFY(QFile::exists("existing-file.txt"));
+ QVERIFY(!file.rename("existing-file.txt"));
+ QCOMPARE(file.error(), QFile::RenameError);
+ QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
+
+ QVERIFY(file.rename("file-renamed-twice.txt"));
+ QVERIFY(!file.isOpen());
+ QCOMPARE(file.fileName(), QString("file-renamed-twice.txt"));
+
+ QVERIFY(QFile::exists("existing-file.txt"));
+ QVERIFY(!QFile::exists("file-to-be-renamed.txt"));
+ QVERIFY(!QFile::exists("file-renamed-once.txt"));
+ QVERIFY(QFile::exists("file-renamed-twice.txt"));
+
+ file.remove();
+ file2.remove();
+ QVERIFY(!QFile::exists("file-renamed-twice.txt"));
+ QVERIFY(!QFile::exists("existing-file.txt"));
+}
+
+void tst_QFile::appendAndRead()
+{
+ QFile writeFile(QLatin1String("appendfile.txt"));
+ QVERIFY(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+
+ QFile readFile(QLatin1String("appendfile.txt"));
+ QVERIFY(readFile.open(QIODevice::ReadOnly));
+
+ // Write to the end of the file, then read that character back, and so on.
+ for (int i = 0; i < 100; ++i) {
+ char c = '\0';
+ writeFile.putChar(char(i % 256));
+ writeFile.flush();
+ QVERIFY(readFile.getChar(&c));
+ QCOMPARE(c, char(i % 256));
+ QCOMPARE(readFile.pos(), writeFile.pos());
+ }
+
+ // Write blocks and read them back
+ for (int j = 0; j < 18; ++j) {
+ writeFile.write(QByteArray(1 << j, '@'));
+ writeFile.flush();
+ QCOMPARE(readFile.read(1 << j).size(), 1 << j);
+ }
+
+ readFile.close();
+ QFile::remove(QLatin1String("appendfile.txt"));
+}
+
+void tst_QFile::miscWithUncPathAsCurrentDir()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QString current = QDir::currentPath();
+ QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testshare"));
+ QFile file("test.pri");
+ QVERIFY(file.exists());
+ QCOMPARE(int(file.size()), 34);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QVERIFY(QDir::setCurrent(current));
+#endif
+}
+
+void tst_QFile::standarderror()
+{
+ QFile f;
+ bool ok = f.open(stderr, QFile::WriteOnly);
+ QVERIFY(ok);
+ f.close();
+}
+
+void tst_QFile::handle()
+{
+ int fd;
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QFile file(SRCDIR "tst_qfile.cpp");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ fd = int(file.handle());
+ QVERIFY(fd > 2);
+ QCOMPARE(int(file.handle()), fd);
+ char c = '\0';
+ QT_READ(int(file.handle()), &c, 1);
+ QCOMPARE(c, '/');
+
+ // test if the QFile and the handle remain in sync
+ QVERIFY(file.getChar(&c));
+ QCOMPARE(c, '*');
+
+ // same, but read from QFile first now
+ file.close();
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
+ fd = int(file.handle());
+ QVERIFY(fd > 2);
+ QVERIFY(file.getChar(&c));
+ QCOMPARE(c, '/');
+#ifdef Q_OS_UNIX
+ QCOMPARE(QT_READ(fd, &c, 1), ssize_t(1));
+#else
+ QCOMPARE(QT_READ(fd, &c, 1), 1);
+#endif
+
+ QCOMPARE(c, '*');
+#endif
+
+ //test round trip of adopted stdio file handle
+ QFile file2;
+ FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r");
+ file2.open(fp, QIODevice::ReadOnly);
+ QCOMPARE(int(file2.handle()), int(fileno(fp)));
+ QCOMPARE(int(file2.handle()), int(fileno(fp)));
+ fclose(fp);
+
+ //test round trip of adopted posix file handle
+#ifdef Q_OS_UNIX
+ QFile file3;
+ fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY);
+ file3.open(fd, QIODevice::ReadOnly);
+ QCOMPARE(int(file3.handle()), fd);
+ QT_CLOSE(fd);
+#endif
+}
+
+void tst_QFile::nativeHandleLeaks()
+{
+#ifdef Q_OS_SYMBIAN
+ QSKIP("test assumptions invalid for symbian", SkipAll);
+#else
+ int fd1, fd2;
+
+#ifdef Q_OS_WIN
+ HANDLE handle1, handle2;
+#endif
+
+ {
+ QFile file("qt_file.tmp");
+ QVERIFY( file.open(QIODevice::ReadWrite) );
+
+ fd1 = file.handle();
+ QVERIFY( -1 != fd1 );
+ }
+
+#ifdef Q_OS_WIN
+ handle1 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
+ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ QVERIFY( INVALID_HANDLE_VALUE != handle1 );
+ QVERIFY( ::CloseHandle(handle1) );
+#endif
+
+ {
+ QFile file("qt_file.tmp");
+ QVERIFY( file.open(QIODevice::ReadOnly) );
+
+ fd2 = file.handle();
+ QVERIFY( -1 != fd2 );
+ }
+
+#ifdef Q_OS_WIN
+ handle2 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
+ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ QVERIFY( INVALID_HANDLE_VALUE != handle2 );
+ QVERIFY( ::CloseHandle(handle2) );
+#endif
+
+ QCOMPARE( fd2, fd1 );
+
+#ifdef Q_OS_WIN
+ QCOMPARE( handle2, handle1 );
+#endif
+#endif
+}
+
+void tst_QFile::readEof_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<int>("imode");
+
+ QTest::newRow("buffered") << SRCDIR "testfile.txt" << 0;
+ QTest::newRow("unbuffered") << SRCDIR "testfile.txt" << int(QIODevice::Unbuffered);
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("sequential,buffered") << "/dev/null" << 0;
+ QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered);
+#endif
+}
+
+void tst_QFile::readEof()
+{
+ QFETCH(QString, filename);
+ QFETCH(int, imode);
+ QIODevice::OpenMode mode = QIODevice::OpenMode(imode);
+
+ {
+ QFile file(filename);
+ QVERIFY(file.open(QIODevice::ReadOnly | mode));
+ bool isSequential = file.isSequential();
+ if (!isSequential) {
+ QVERIFY(file.seek(245));
+ QVERIFY(file.atEnd());
+ }
+
+ char buf[10];
+ int ret = file.read(buf, sizeof buf);
+ QCOMPARE(ret, 0);
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+
+ // Do it again to ensure that we get the same result
+ ret = file.read(buf, sizeof buf);
+ QCOMPARE(ret, 0);
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+ }
+
+ {
+ QFile file(filename);
+ QVERIFY(file.open(QIODevice::ReadOnly | mode));
+ bool isSequential = file.isSequential();
+ if (!isSequential) {
+ QVERIFY(file.seek(245));
+ QVERIFY(file.atEnd());
+ }
+
+ QByteArray ret = file.read(10);
+ QVERIFY(ret.isEmpty());
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+
+ // Do it again to ensure that we get the same result
+ ret = file.read(10);
+ QVERIFY(ret.isEmpty());
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+ }
+
+ {
+ QFile file(filename);
+ QVERIFY(file.open(QIODevice::ReadOnly | mode));
+ bool isSequential = file.isSequential();
+ if (!isSequential) {
+ QVERIFY(file.seek(245));
+ QVERIFY(file.atEnd());
+ }
+
+ char buf[10];
+ int ret = file.readLine(buf, sizeof buf);
+ QCOMPARE(ret, -1);
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+
+ // Do it again to ensure that we get the same result
+ ret = file.readLine(buf, sizeof buf);
+ QCOMPARE(ret, -1);
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+ }
+
+ {
+ QFile file(filename);
+ QVERIFY(file.open(QIODevice::ReadOnly | mode));
+ bool isSequential = file.isSequential();
+ if (!isSequential) {
+ QVERIFY(file.seek(245));
+ QVERIFY(file.atEnd());
+ }
+
+ QByteArray ret = file.readLine();
+ QVERIFY(ret.isNull());
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+
+ // Do it again to ensure that we get the same result
+ ret = file.readLine();
+ QVERIFY(ret.isNull());
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+ }
+
+ {
+ QFile file(filename);
+ QVERIFY(file.open(QIODevice::ReadOnly | mode));
+ bool isSequential = file.isSequential();
+ if (!isSequential) {
+ QVERIFY(file.seek(245));
+ QVERIFY(file.atEnd());
+ }
+
+ char c;
+ QVERIFY(!file.getChar(&c));
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+
+ // Do it again to ensure that we get the same result
+ QVERIFY(!file.getChar(&c));
+ QVERIFY(file.error() == QFile::NoError);
+ QVERIFY(file.atEnd());
+ }
+}
+
+void tst_QFile::task167217()
+{
+ // Regression introduced in 4.3.0; after a failed stat, pos() could no
+ // longer be calculated correctly.
+ QFile::remove("tmp.txt");
+ QFile file("tmp.txt");
+ QVERIFY(!file.exists());
+ QVERIFY(file.open(QIODevice::Append));
+ QVERIFY(file.exists());
+ file.write("qt430", 5);
+ QVERIFY(!file.isSequential());
+ QCOMPARE(file.pos(), qint64(5));
+ file.remove();
+}
+
+#define FILESIZE 65536 * 3
+
+void tst_QFile::map_data()
+{
+ QTest::addColumn<int>("fileSize");
+ QTest::addColumn<int>("offset");
+ QTest::addColumn<int>("size");
+ QTest::addColumn<QFile::FileError>("error");
+
+ QTest::newRow("zero") << FILESIZE << 0 << FILESIZE << QFile::NoError;
+ QTest::newRow("small, but 0") << FILESIZE << 30 << FILESIZE - 30 << QFile::NoError;
+ QTest::newRow("a page") << FILESIZE << 4096 << FILESIZE - 4096 << QFile::NoError;
+ QTest::newRow("+page") << FILESIZE << 5000 << FILESIZE - 5000 << QFile::NoError;
+ QTest::newRow("++page") << FILESIZE << 65576 << FILESIZE - 65576 << QFile::NoError;
+ QTest::newRow("bad size") << FILESIZE << 0 << -1 << QFile::ResourceError;
+ QTest::newRow("bad offset") << FILESIZE << -1 << 1 << QFile::UnspecifiedError;
+ QTest::newRow("zerozero") << FILESIZE << 0 << 0 << QFile::UnspecifiedError;
+}
+
+void tst_QFile::map()
+{
+ QFETCH(int, fileSize);
+ QFETCH(int, offset);
+ QFETCH(int, size);
+ QFETCH(QFile::FileError, error);
+
+ QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
+
+#ifdef Q_WS_WINCE
+ fileName = QFileInfo(fileName).absoluteFilePath();
+#endif
+
+ if (QFile::exists(fileName)) {
+ QVERIFY(QFile::setPermissions(fileName,
+ QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
+ QFile::remove(fileName);
+ }
+ QFile file(fileName);
+
+ // invalid, not open
+ uchar *memory = file.map(0, size);
+ QVERIFY(!memory);
+ QCOMPARE(file.error(), QFile::PermissionsError);
+ QVERIFY(!file.unmap(memory));
+ QCOMPARE(file.error(), QFile::PermissionsError);
+
+ // make a file
+ QVERIFY(file.open(QFile::ReadWrite));
+ QVERIFY(file.resize(fileSize));
+ QVERIFY(file.flush());
+ file.close();
+ QVERIFY(file.open(QFile::ReadWrite));
+ memory = file.map(offset, size);
+ if (error != QFile::NoError) {
+
+ QVERIFY(file.error() != QFile::NoError);
+ return;
+ }
+
+ QCOMPARE(file.error(), error);
+ QVERIFY(memory);
+ memory[0] = 'Q';
+ QVERIFY(file.unmap(memory));
+ QCOMPARE(file.error(), QFile::NoError);
+
+ // Verify changes were saved
+ memory = file.map(offset, size);
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(memory);
+ QVERIFY(memory[0] == 'Q');
+ QVERIFY(file.unmap(memory));
+ QCOMPARE(file.error(), QFile::NoError);
+
+ // hpux wont let you map multiple times.
+#if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API) && !defined(Q_OS_WINCE)
+ // exotic test to make sure that multiple maps work
+
+ // note: windows ce does not reference count mutliple maps
+ // it's essentially just the same reference but it
+ // cause a resource lock on the file which prevents it
+ // from being removed uchar *memory1 = file.map(0, file.size());
+ uchar *memory1 = file.map(0, file.size());
+ QCOMPARE(file.error(), QFile::NoError);
+ uchar *memory2 = file.map(0, file.size());
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(memory1);
+ QVERIFY(memory2);
+ QVERIFY(file.unmap(memory1));
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(file.unmap(memory2));
+ QCOMPARE(file.error(), QFile::NoError);
+ memory1 = file.map(0, file.size());
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(memory1);
+ QVERIFY(file.unmap(memory1));
+ QCOMPARE(file.error(), QFile::NoError);
+#endif
+
+ file.close();
+
+#if defined(Q_OS_SYMBIAN)
+ if (false) // No permissions for user makes no sense in Symbian
+#elif defined(Q_OS_UNIX)
+ if (::getuid() != 0)
+ // root always has permissions
+#endif
+ {
+ // Change permissions on a file, just to confirm it would fail
+ QFile::Permissions originalPermissions = file.permissions();
+ QVERIFY(file.setPermissions(QFile::ReadOther));
+ QVERIFY(!file.open(QFile::ReadWrite));
+ memory = file.map(offset, size);
+ QCOMPARE(file.error(), QFile::PermissionsError);
+ QVERIFY(!memory);
+ QVERIFY(file.setPermissions(originalPermissions));
+ }
+ QVERIFY(file.remove());
+}
+
+void tst_QFile::mapResource_data()
+{
+ QTest::addColumn<int>("offset");
+ QTest::addColumn<int>("size");
+ QTest::addColumn<QFile::FileError>("error");
+ QTest::addColumn<QString>("fileName");
+
+ QString validFile = ":/tst_qfileinfo/resources/file1.ext1";
+ QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1";
+
+ for (int i = 0; i < 2; ++i) {
+ QString file = (i == 0) ? validFile : invalidFile;
+ QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file;
+ QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file;
+ QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file;
+ QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file;
+ }
+
+ QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile;
+}
+
+void tst_QFile::mapResource()
+{
+ QFETCH(QString, fileName);
+ QFETCH(int, offset);
+ QFETCH(int, size);
+ QFETCH(QFile::FileError, error);
+
+ QFile file(fileName);
+ uchar *memory = file.map(offset, size);
+ QCOMPARE(file.error(), error);
+ QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0));
+ if (error == QFile::NoError)
+ QCOMPARE(QString(memory[0]), QString::number(offset + 1));
+ QVERIFY(file.unmap(memory));
+}
+
+void tst_QFile::mapOpenMode_data()
+{
+ QTest::addColumn<int>("openMode");
+
+ QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly);
+ //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense
+ QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite);
+ QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly | QIODevice::Unbuffered);
+ QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite | QIODevice::Unbuffered);
+}
+
+void tst_QFile::mapOpenMode()
+{
+ QFETCH(int, openMode);
+ static const qint64 fileSize = 4096;
+
+ QByteArray pattern(fileSize, 'A');
+
+ QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
+ if (QFile::exists(fileName)) {
+ QVERIFY(QFile::setPermissions(fileName,
+ QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
+ QFile::remove(fileName);
+ }
+ QFile file(fileName);
+
+ // make a file
+ QVERIFY(file.open(QFile::ReadWrite));
+ QVERIFY(file.write(pattern));
+ QVERIFY(file.flush());
+ file.close();
+
+ // open according to our mode
+ QVERIFY(file.open(QIODevice::OpenMode(openMode)));
+
+ uchar *memory = file.map(0, fileSize);
+ QVERIFY(memory);
+ QVERIFY(memcmp(memory, pattern, fileSize) == 0);
+
+ if (openMode & QIODevice::WriteOnly) {
+ // try to write to the file
+ *memory = 'a';
+ file.unmap(memory);
+ file.close();
+ file.open(QIODevice::OpenMode(openMode));
+ file.seek(0);
+ char c;
+ QVERIFY(file.getChar(&c));
+ QCOMPARE(c, 'a');
+ }
+
+ file.close();
+}
+
+void tst_QFile::openDirectory()
+{
+ QFile f1(SRCDIR "resources");
+ // it's a directory, it must exist
+ QVERIFY(f1.exists());
+
+ // ...but not be openable
+ QVERIFY(!f1.open(QIODevice::ReadOnly));
+ f1.close();
+ QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered));
+ f1.close();
+ QVERIFY(!f1.open(QIODevice::ReadWrite));
+ f1.close();
+ QVERIFY(!f1.open(QIODevice::WriteOnly));
+ f1.close();
+ QVERIFY(!f1.open(QIODevice::WriteOnly|QIODevice::Unbuffered));
+ f1.close();
+}
+
+void tst_QFile::openStandardStreamsFileDescriptors()
+{
+#ifdef Q_WS_WINCE
+ //allthough Windows CE (not mobile!) has functions that allow redirecting
+ //the standard file descriptors to a file (see SetStdioPathW/GetStdioPathW)
+ //it does not have functions to simply open them like below .
+ QSKIP("Opening standard streams on Windows CE via descriptor not implemented", SkipAll);
+#endif
+ // Using file descriptors
+ {
+ QFile in;
+ in.open(STDIN_FILENO, QIODevice::ReadOnly);
+ QCOMPARE( in.pos(), (qint64)0 );
+ QCOMPARE( in.size(), (qint64)0 );
+ QVERIFY( in.isSequential() );
+ }
+
+ {
+ QFile out;
+ out.open(STDOUT_FILENO, QIODevice::WriteOnly);
+ QCOMPARE( out.pos(), (qint64)0 );
+ QCOMPARE( out.size(), (qint64)0 );
+ QVERIFY( out.isSequential() );
+ }
+
+ {
+ QFile err;
+ err.open(STDERR_FILENO, QIODevice::WriteOnly);
+ QCOMPARE( err.pos(), (qint64)0 );
+ QCOMPARE( err.size(), (qint64)0 );
+ QVERIFY( err.isSequential() );
+ }
+}
+
+void tst_QFile::openStandardStreamsBufferedStreams()
+{
+#if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QSKIP("Unix only test.", SkipAll);
+#endif
+ // Using streams
+ {
+ QFile in;
+ in.open(stdin, QIODevice::ReadOnly);
+ QCOMPARE( in.pos(), (qint64)0 );
+ QCOMPARE( in.size(), (qint64)0 );
+ QVERIFY( in.isSequential() );
+ }
+
+ {
+ QFile out;
+ out.open(stdout, QIODevice::WriteOnly);
+ QCOMPARE( out.pos(), (qint64)0 );
+ QCOMPARE( out.size(), (qint64)0 );
+ QVERIFY( out.isSequential() );
+ }
+
+ {
+ QFile err;
+ err.open(stderr, QIODevice::WriteOnly);
+ QCOMPARE( err.pos(), (qint64)0 );
+ QCOMPARE( err.size(), (qint64)0 );
+ QVERIFY( err.isSequential() );
+ }
+}
+
+void tst_QFile::openStandardStreams()
+{
+ openStandardStreamsFileDescriptors();
+ openStandardStreamsBufferedStreams();
+}
+
+void tst_QFile::writeNothing()
+{
+ for (int i = 0; i < NumberOfFileTypes; ++i) {
+ QFile file("file.txt");
+ QVERIFY( openFile(file, QIODevice::WriteOnly | QIODevice::Unbuffered, FileType(i)) );
+ QVERIFY( 0 == file.write((char *)0, 0) );
+ QCOMPARE( file.error(), QFile::NoError );
+ closeFile(file);
+ }
+}
+
+void tst_QFile::resize_data()
+{
+ QTest::addColumn<int>("filetype");
+
+ QTest::newRow("native") << int(OpenQFile);
+ QTest::newRow("fileno") << int(OpenFd);
+ QTest::newRow("stream") << int(OpenStream);
+#ifdef Q_OS_SYMBIAN
+ QTest::newRow("rfile") << int(OpenRFile);
+#endif
+}
+
+void tst_QFile::resize()
+{
+ QFETCH(int, filetype);
+ QString filename(QLatin1String("file.txt"));
+ QFile file(filename);
+ QVERIFY(openFile(file, QIODevice::ReadWrite, FileType(filetype)));
+ QVERIFY(file.resize(8));
+ QCOMPARE(file.size(), qint64(8));
+ closeFile(file);
+ QFile::resize(filename, 4);
+ QCOMPARE(QFileInfo(filename).size(), qint64(4));
+ QVERIFY(QFile::remove(filename));
+}
+
+void tst_QFile::objectConstructors()
+{
+ QObject ob;
+ QFile* file1 = new QFile(SRCDIR "testfile.txt", &ob);
+ QFile* file2 = new QFile(&ob);
+ QVERIFY(file1->exists());
+ QVERIFY(!file2->exists());
+}
+
+#ifdef Q_OS_SYMBIAN
+void tst_QFile::platformSecurity_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<bool>("readable");
+ QTest::addColumn<bool>("writable");
+
+ QString selfname = QCoreApplication::applicationFilePath();
+ QString ownprivate = QCoreApplication::applicationDirPath();
+ QString owndrive = selfname.left(2);
+ bool amiprivileged = RProcess().HasCapability(ECapabilityAllFiles);
+ QTest::newRow("resource") << owndrive + "/resource/apps/tst_qfile.rsc" << true << amiprivileged;
+ QTest::newRow("sys") << selfname << amiprivileged << false;
+ QTest::newRow("own private") << ownprivate + "/testfile.txt" << true << true;
+ QTest::newRow("other private") << owndrive + "/private/10003a3f/import/apps/tst_qfile_reg.rsc" << amiprivileged << amiprivileged;
+}
+
+void tst_QFile::platformSecurity()
+{
+ QFETCH(QString,file);
+ QFETCH(bool,readable);
+ QFETCH(bool,writable);
+
+ {
+ QFile f(file);
+ QCOMPARE(f.open(QIODevice::ReadOnly), readable);
+ }
+
+ {
+ QFile f(file);
+ QCOMPARE(f.open(QIODevice::ReadOnly | QIODevice::Unbuffered), readable);
+ }
+
+ //append mode used to avoid truncating the files.
+ {
+ QFile f(file);
+ QCOMPARE(f.open(QIODevice::WriteOnly | QIODevice::Append), writable);
+ }
+
+ {
+ QFile f(file);
+ QCOMPARE(f.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered), writable);
+ }
+
+ {
+ QFile f(file);
+ QCOMPARE(f.open(QIODevice::ReadWrite), writable);
+ }
+
+ {
+ QFile f(file);
+ QCOMPARE(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered), writable);
+ }
+}
+#endif
+
+void tst_QFile::caseSensitivity()
+{
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) || defined(Q_OS_MAC)
+ const bool caseSensitive = false;
+#else
+ const bool caseSensitive = true;
+#endif
+ QByteArray testData("a little test");
+ QString filename("File.txt");
+ {
+ QFile f(filename);
+ QVERIFY(f.open(QIODevice::WriteOnly));
+ QVERIFY(f.write(testData));
+ f.close();
+ }
+ QStringList alternates;
+ QFileInfo fi(filename);
+ QVERIFY(fi.exists());
+ alternates << "file.txt" << "File.TXT" << "fIlE.TxT" << fi.absoluteFilePath().toUpper() << fi.absoluteFilePath().toLower();
+ foreach (QString alt, alternates) {
+ QFileInfo fi2(alt);
+ QCOMPARE(fi2.exists(), !caseSensitive);
+ QCOMPARE(fi.size() == fi2.size(), !caseSensitive);
+ QFile f2(alt);
+ QCOMPARE(f2.open(QIODevice::ReadOnly), !caseSensitive);
+ if (!caseSensitive)
+ QCOMPARE(f2.readAll(), testData);
+ }
+}
+
+//MSVCRT asserts when any function is called with a closed file handle.
+//This replaces the default crashing error handler with one that ignores the error (allowing EBADF to be returned)
+class AutoIgnoreInvalidParameter
+{
+public:
+#if defined(Q_OS_WIN) && defined (Q_CC_MSVC)
+ static void ignore_invalid_parameter(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t) {}
+ AutoIgnoreInvalidParameter()
+ {
+ oldHandler = _set_invalid_parameter_handler(ignore_invalid_parameter);
+ //also disable the abort/retry/ignore popup
+ oldReportMode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+ }
+ ~AutoIgnoreInvalidParameter()
+ {
+ //restore previous settings
+ _set_invalid_parameter_handler(oldHandler);
+ _CrtSetReportMode(_CRT_ASSERT, oldReportMode);
+ }
+ _invalid_parameter_handler oldHandler;
+ int oldReportMode;
+#endif
+};
+
+void tst_QFile::autocloseHandle()
+{
+#ifdef Q_OS_SYMBIAN
+ // these tests are a bit different, because using a closed file handle results in a panic rather than error
+ {
+ QFile file("readonlyfile");
+ QFile file2("readonlyfile");
+ QVERIFY(openFile(file, QIODevice::ReadOnly, OpenRFile, QFile::AutoCloseHandle));
+ // file is opened with mandatory lock, so opening again should fail
+ QVERIFY(!file2.open(QIODevice::ReadOnly));
+
+ file.close();
+ // opening again should now succeed (because handle is closed)
+ QVERIFY(file2.open(QIODevice::ReadOnly));
+ }
+
+ {
+ QFile file("readonlyfile");
+ QFile file2("readonlyfile");
+ QVERIFY(openFile(file, QIODevice::ReadOnly, OpenRFile, QFile::DontCloseHandle));
+ // file is opened with mandatory lock, so opening again should fail
+ QVERIFY(!file2.open(QIODevice::ReadOnly));
+
+ file.close();
+ // opening again should still fail (because handle is not auto closed)
+ QVERIFY(!file2.open(QIODevice::ReadOnly));
+
+ rfile_.Close();
+ // now it should succeed
+ QVERIFY(file2.open(QIODevice::ReadOnly));
+ }
+#endif
+
+ {
+ QFile file("readonlyfile");
+ QVERIFY(openFile(file, QIODevice::ReadOnly, OpenFd, QFile::AutoCloseHandle));
+ int fd = fd_;
+ QCOMPARE(file.handle(), fd);
+ file.close();
+ fd_ = -1;
+ QCOMPARE(file.handle(), -1);
+ AutoIgnoreInvalidParameter a;
+ Q_UNUSED(a);
+ //file is closed, read should fail
+ char buf;
+ QCOMPARE((int)QT_READ(fd, &buf, 1), -1);
+ QVERIFY(errno = EBADF);
+ }
+
+ {
+ QFile file("readonlyfile");
+ QVERIFY(openFile(file, QIODevice::ReadOnly, OpenFd, QFile::DontCloseHandle));
+ QCOMPARE(file.handle(), fd_);
+ file.close();
+ QCOMPARE(file.handle(), -1);
+ //file is not closed, read should succeed
+ char buf;
+ QCOMPARE((int)QT_READ(fd_, &buf, 1), 1);
+ ::close(fd_);
+ fd_ = -1;
+ }
+
+ {
+ QFile file("readonlyfile");
+ QVERIFY(openFile(file, QIODevice::ReadOnly, OpenStream, QFile::AutoCloseHandle));
+ int fd = fileno(stream_);
+ QCOMPARE(file.handle(), fd);
+ file.close();
+ stream_ = 0;
+ QCOMPARE(file.handle(), -1);
+ AutoIgnoreInvalidParameter a;
+ Q_UNUSED(a);
+ //file is closed, read should fail
+ char buf;
+ QCOMPARE((int)QT_READ(fd, &buf, 1), -1); //not using fread because the FILE* was freed by fclose
+ }
+
+ {
+ QFile file("readonlyfile");
+ QVERIFY(openFile(file, QIODevice::ReadOnly, OpenStream, QFile::DontCloseHandle));
+ QCOMPARE(file.handle(), fileno(stream_));
+ file.close();
+ QCOMPARE(file.handle(), -1);
+ //file is not closed, read should succeed
+ char buf;
+ QCOMPARE(int(::fread(&buf, 1, 1, stream_)), 1);
+ ::fclose(stream_);
+ stream_ = 0;
+ }
+}
+
+QTEST_MAIN(tst_QFile)
+#include "tst_qfile.moc"
diff --git a/tests/auto/corelib/io/qfile/two.dots.file b/tests/auto/corelib/io/qfile/two.dots.file
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/two.dots.file
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qfileinfo/.gitignore b/tests/auto/corelib/io/qfileinfo/.gitignore
new file mode 100644
index 0000000000..fc1a8906af
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/.gitignore
@@ -0,0 +1 @@
+tst_qfileinfo
diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
new file mode 100644
index 0000000000..2fd626a57e
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
@@ -0,0 +1,33 @@
+load(qttest_p4)
+SOURCES += tst_qfileinfo.cpp
+
+QT = core-private
+
+
+RESOURCES += qfileinfo.qrc
+
+wince*:|symbian: {
+ deploy.files += qfileinfo.qrc tst_qfileinfo.cpp
+ res.files = resources\\file1 resources\\file1.ext1 resources\\file1.ext1.ext2
+ res.path = resources
+ DEPLOYMENT += deploy res
+}
+
+win32*:LIBS += -ladvapi32 -lnetapi32
+
+symbian {
+ TARGET.CAPABILITY=AllFiles
+ LIBS *= -lefsrv
+ INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs
+ }
+
+# support for running test from shadow build directory
+wince* {
+ DEFINES += SRCDIR=\\\"\\\"
+} else:symbian {
+ # do not define SRCDIR at all
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.qrc b/tests/auto/corelib/io/qfileinfo/qfileinfo.qrc
new file mode 100644
index 0000000000..2c63d8afeb
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/qfileinfo.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/tst_qfileinfo/">
+ <file>resources/</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qfileinfo/resources/file1 b/tests/auto/corelib/io/qfileinfo/resources/file1
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/resources/file1
diff --git a/tests/auto/corelib/io/qfileinfo/resources/file1.ext1 b/tests/auto/corelib/io/qfileinfo/resources/file1.ext1
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/resources/file1.ext1
diff --git a/tests/auto/corelib/io/qfileinfo/resources/file1.ext1.ext2 b/tests/auto/corelib/io/qfileinfo/resources/file1.ext1.ext2
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/resources/file1.ext1.ext2
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
new file mode 100644
index 0000000000..c3d106d2fd
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -0,0 +1,1803 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+
+#include <qfile.h>
+#include <qdir.h>
+#include <qcoreapplication.h>
+#include <qlibrary.h>
+#include <qtemporaryfile.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#ifdef Q_OS_UNIX
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <pwd.h>
+#endif
+#ifdef Q_OS_WIN
+#define _WIN32_WINNT 0x500
+#include <qt_windows.h>
+#include <qlibrary.h>
+#include <lm.h>
+#endif
+#include <qplatformdefs.h>
+#include <qdebug.h>
+#ifdef Q_OS_SYMBIAN
+#include <f32file.h>
+#include <private/qcore_symbian_p.h>
+#endif
+#include "../../../network-settings.h"
+#include <private/qfileinfo_p.h>
+#include "../../../../shared/filesystem.h"
+
+#if defined(Q_OS_SYMBIAN)
+# define SRCDIR ""
+# define NO_SYMLINKS
+#endif
+
+QT_BEGIN_NAMESPACE
+extern Q_AUTOTEST_EXPORT bool qIsLikelyToBeNfs(int /* handle */);
+QT_END_NAMESPACE
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QFileInfo : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QFileInfo();
+ ~tst_QFileInfo();
+
+private slots:
+ void getSetCheck();
+
+ void copy();
+
+ void isFile_data();
+ void isFile();
+
+ void isDir_data();
+ void isDir();
+
+ void isRoot_data();
+ void isRoot();
+
+ void exists_data();
+ void exists();
+
+ void absolutePath_data();
+ void absolutePath();
+
+ void absFilePath_data();
+ void absFilePath();
+
+ void canonicalPath();
+ void canonicalFilePath();
+
+ void fileName_data();
+ void fileName();
+
+ void bundleName_data();
+ void bundleName();
+
+ void dir_data();
+ void dir();
+
+ void suffix_data();
+ void suffix();
+
+ void completeSuffix_data();
+ void completeSuffix();
+
+ void baseName_data();
+ void baseName();
+
+ void completeBaseName_data();
+ void completeBaseName();
+
+ void permission_data();
+ void permission();
+
+ void size_data();
+ void size();
+
+ void systemFiles();
+
+ void compare_data();
+ void compare();
+
+ void consistent_data();
+ void consistent();
+
+ void fileTimes_data();
+ void fileTimes();
+ void fileTimes_oldFile();
+
+ void isSymLink_data();
+ void isSymLink();
+
+ void isHidden_data();
+ void isHidden();
+#if defined(Q_OS_MAC)
+ void isHiddenFromFinder();
+#endif
+
+ void isBundle_data();
+ void isBundle();
+
+ void isLocalFs_data();
+ void isLocalFs();
+
+ void refresh();
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void ntfsJunctionPointsAndSymlinks_data();
+ void ntfsJunctionPointsAndSymlinks();
+ void brokenShortcut();
+#endif
+
+ void isWritable();
+ void isExecutable();
+ void testDecomposedUnicodeNames_data();
+ void testDecomposedUnicodeNames();
+
+ void equalOperator() const;
+ void equalOperatorWithDifferentSlashes() const;
+ void notEqualOperator() const;
+
+ void detachingOperations();
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ void owner();
+#endif
+ void group();
+
+ void invalidState();
+};
+
+tst_QFileInfo::tst_QFileInfo()
+{
+}
+
+tst_QFileInfo::~tst_QFileInfo()
+{
+ QFile::remove("brokenlink.lnk");
+ QFile::remove("link.lnk");
+ QFile::remove("file1");
+ QFile::remove("dummyfile");
+ QFile::remove("simplefile.txt");
+ QFile::remove("longFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileName.txt");
+#ifdef Q_OS_SYMBIAN
+ QFile::remove("hidden.txt");
+ QFile::remove("nothidden.txt");
+#else
+ QFile::remove("tempfile.txt");
+#endif
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ QDir().rmdir("./.hidden-directory");
+ QFile::remove("link_to_tst_qfileinfo");
+#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QDir().rmdir("./hidden-directory");
+ QDir().rmdir("abs_symlink");
+ QDir().rmdir("rel_symlink");
+ QDir().rmdir("junction_pwd");
+ QDir().rmdir("junction_root");
+ QDir().rmdir("mountpoint");
+ QFile::remove("abs_symlink.cpp");
+ QFile::remove("rel_symlink.cpp");
+#endif
+}
+
+// Testing get/set functions
+void tst_QFileInfo::getSetCheck()
+{
+ QFileInfo obj1;
+ // bool QFileInfo::caching()
+ // void QFileInfo::setCaching(bool)
+ obj1.setCaching(false);
+ QCOMPARE(false, obj1.caching());
+ obj1.setCaching(true);
+ QCOMPARE(true, obj1.caching());
+}
+
+static QFileInfoPrivate* getPrivate(QFileInfo &info)
+{
+ return (*reinterpret_cast<QFileInfoPrivate**>(&info));
+}
+
+void tst_QFileInfo::copy()
+{
+ QTemporaryFile *t;
+ t = new QTemporaryFile;
+ t->open();
+ QFileInfo info(t->fileName());
+ QVERIFY(info.exists());
+
+ //copy constructor
+ QFileInfo info2(info);
+ QFileInfoPrivate *privateInfo = getPrivate(info);
+ QFileInfoPrivate *privateInfo2 = getPrivate(info2);
+ QCOMPARE(privateInfo, privateInfo2);
+
+ //operator =
+ QFileInfo info3 = info;
+ QFileInfoPrivate *privateInfo3 = getPrivate(info3);
+ QCOMPARE(privateInfo, privateInfo3);
+ QCOMPARE(privateInfo2, privateInfo3);
+
+ //refreshing info3 will detach it
+ QFile file(info.absoluteFilePath());
+ QVERIFY(file.open(QFile::WriteOnly));
+ QCOMPARE(file.write("JAJAJAA"), qint64(7));
+ file.flush();
+
+ QTest::qWait(250);
+#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
+ if (QSysInfo::windowsVersion() & QSysInfo::WV_VISTA ||
+ QSysInfo::windowsVersion() & QSysInfo::WV_CE_based)
+ file.close();
+#endif
+#if defined(Q_OS_WINCE)
+ // On Windows CE we need to close the file.
+ // Otherwise the content will be cached and not
+ // flushed to the storage, although we flushed it
+ // manually!!! CE has interim cache, we cannot influence.
+ QTest::qWait(5000);
+#endif
+ info3.refresh();
+ privateInfo3 = getPrivate(info3);
+ QVERIFY(privateInfo != privateInfo3);
+ QVERIFY(privateInfo2 != privateInfo3);
+ QCOMPARE(privateInfo, privateInfo2);
+}
+
+void tst_QFileInfo::isFile_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("data0") << QDir::currentPath() << false;
+ QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << true;
+ QTest::newRow("data2") << ":/tst_qfileinfo/resources/" << false;
+ QTest::newRow("data3") << ":/tst_qfileinfo/resources/file1" << true;
+ QTest::newRow("data4") << ":/tst_qfileinfo/resources/afilethatshouldnotexist" << false;
+}
+
+void tst_QFileInfo::isFile()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, expected);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isFile(), expected);
+}
+
+
+void tst_QFileInfo::isDir_data()
+{
+ // create a broken symlink
+ QFile::remove("brokenlink.lnk");
+ QFile::remove("dummyfile");
+ QFile file3("dummyfile");
+ file3.open(QIODevice::WriteOnly);
+ if (file3.link("brokenlink.lnk")) {
+ file3.remove();
+ QFileInfo info3("brokenlink.lnk");
+ QVERIFY( info3.isSymLink() );
+ }
+
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("data0") << QDir::currentPath() << true;
+ QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << false;
+ QTest::newRow("data2") << ":/tst_qfileinfo/resources/" << true;
+ QTest::newRow("data3") << ":/tst_qfileinfo/resources/file1" << false;
+ QTest::newRow("data4") << ":/tst_qfileinfo/resources/afilethatshouldnotexist" << false;
+
+ QTest::newRow("simple dir") << SRCDIR "resources" << true;
+ QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true;
+
+ QTest::newRow("broken link") << "brokenlink.lnk" << false;
+
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("drive 1") << "c:" << true;
+ QTest::newRow("drive 2") << "c:/" << true;
+ //QTest::newRow("drive 2") << "t:s" << false;
+#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QTest::newRow("unc 1") << "//" + QtNetworkSettings::winServerName() << true;
+ QTest::newRow("unc 2") << "//" + QtNetworkSettings::winServerName() + "/" << true;
+ QTest::newRow("unc 3") << "//" + QtNetworkSettings::winServerName() + "/testshare" << true;
+ QTest::newRow("unc 4") << "//" + QtNetworkSettings::winServerName() + "/testshare/" << true;
+ QTest::newRow("unc 5") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp" << true;
+ QTest::newRow("unc 6") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp/" << true;
+ QTest::newRow("unc 7") << "//" + QtNetworkSettings::winServerName() + "/testshare/adirthatshouldnotexist" << false;
+#endif
+}
+
+void tst_QFileInfo::isDir()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, expected);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isDir(), expected);
+}
+
+void tst_QFileInfo::isRoot_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("expected");
+ QTest::newRow("data0") << QDir::currentPath() << false;
+ QTest::newRow("data1") << "/" << true;
+ QTest::newRow("data2") << "*" << false;
+ QTest::newRow("data3") << "/*" << false;
+ QTest::newRow("data4") << ":/tst_qfileinfo/resources/" << false;
+ QTest::newRow("data5") << ":/" << true;
+
+ QTest::newRow("simple dir") << SRCDIR "resources" << false;
+ QTest::newRow("simple dir with slash") << SRCDIR "resources/" << false;
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("drive 1") << "c:" << false;
+ QTest::newRow("drive 2") << "c:/" << true;
+ QTest::newRow("drive 3") << "p:/" << false;
+#endif
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QTest::newRow("unc 1") << "//" + QtNetworkSettings::winServerName() << true;
+ QTest::newRow("unc 2") << "//" + QtNetworkSettings::winServerName() + "/" << true;
+ QTest::newRow("unc 3") << "//" + QtNetworkSettings::winServerName() + "/testshare" << false;
+ QTest::newRow("unc 4") << "//" + QtNetworkSettings::winServerName() + "/testshare/" << false;
+ QTest::newRow("unc 7") << "//ahostthatshouldnotexist" << false;
+#endif
+}
+
+void tst_QFileInfo::isRoot()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, expected);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isRoot(), expected);
+}
+
+void tst_QFileInfo::exists_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("data0") << QDir::currentPath() << true;
+ QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << true;
+ QTest::newRow("data2") << "/I/do_not_expect_this_path_to_exist/" << false;
+ QTest::newRow("data3") << ":/tst_qfileinfo/resources/" << true;
+ QTest::newRow("data4") << ":/tst_qfileinfo/resources/file1" << true;
+ QTest::newRow("data5") << ":/I/do_not_expect_this_path_to_exist/" << false;
+ QTest::newRow("data6") << SRCDIR "resources/*" << false;
+ QTest::newRow("data7") << SRCDIR "resources/*.foo" << false;
+ QTest::newRow("data8") << SRCDIR "resources/*.ext1" << false;
+ QTest::newRow("data9") << SRCDIR "resources/file?.ext1" << false;
+ QTest::newRow("data10") << "." << true;
+ QTest::newRow("data11") << ". " << false;
+ QTest::newRow("empty") << "" << false;
+
+ QTest::newRow("simple dir") << SRCDIR "resources" << true;
+ QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true;
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QTest::newRow("unc 1") << "//" + QtNetworkSettings::winServerName() << true;
+ QTest::newRow("unc 2") << "//" + QtNetworkSettings::winServerName() + "/" << true;
+ QTest::newRow("unc 3") << "//" + QtNetworkSettings::winServerName() + "/testshare" << true;
+ QTest::newRow("unc 4") << "//" + QtNetworkSettings::winServerName() + "/testshare/" << true;
+ QTest::newRow("unc 5") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp" << true;
+ QTest::newRow("unc 6") << "//" + QtNetworkSettings::winServerName() + "/testshare/tmp/" << true;
+ QTest::newRow("unc 7") << "//" + QtNetworkSettings::winServerName() + "/testshare/adirthatshouldnotexist" << false;
+ QTest::newRow("unc 8") << "//" + QtNetworkSettings::winServerName() + "/asharethatshouldnotexist" << false;
+ QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << false;
+#endif
+}
+
+void tst_QFileInfo::exists()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, expected);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.exists(), expected);
+}
+
+void tst_QFileInfo::absolutePath_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("filename");
+
+ QString drivePrefix;
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ drivePrefix = QDir::currentPath().left(2);
+ QString nonCurrentDrivePrefix =
+ drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:");
+
+ // Make sure drive-relative paths return correct absolute paths (task 255326)
+ QTest::newRow("<current drive>:my.dll") << drivePrefix + "my.dll" << QDir::currentPath() << "my.dll";
+ QTest::newRow("<not current drive>:my.dll") << nonCurrentDrivePrefix + "my.dll"
+ << nonCurrentDrivePrefix + "/"
+ << "my.dll";
+#endif
+ QTest::newRow("0") << "/machine/share/dir1/" << drivePrefix + "/machine/share/dir1" << "";
+ QTest::newRow("1") << "/machine/share/dir1" << drivePrefix + "/machine/share" << "dir1";
+ QTest::newRow("2") << "/usr/local/bin" << drivePrefix + "/usr/local" << "bin";
+ QTest::newRow("3") << "/usr/local/bin/" << drivePrefix + "/usr/local/bin" << "";
+ QTest::newRow("/test") << "/test" << drivePrefix + "/" << "test";
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // see task 102898
+ QTest::newRow("c:\\autoexec.bat") << "c:\\autoexec.bat" << "C:/"
+ << "autoexec.bat";
+#endif
+}
+
+void tst_QFileInfo::absolutePath()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, path);
+ QFETCH(QString, filename);
+
+ QFileInfo fi(file);
+
+ QCOMPARE(fi.absolutePath(), path);
+ QCOMPARE(fi.fileName(), filename);
+}
+
+void tst_QFileInfo::absFilePath_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("relativeFile") << "tmp.txt" << QDir::currentPath() + "/tmp.txt";
+ QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << QDir::currentPath() + "/" + "temp/tmp.txt";
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QString curr = QDir::currentPath();
+
+ curr.remove(0, 2); // Make it a absolute path with no drive specifier: \depot\qt-4.2\tests\auto\qfileinfo
+ QTest::newRow(".") << curr << QDir::currentPath();
+ QTest::newRow("absFilePath") << "c:\\home\\andy\\tmp.txt" << "C:/home/andy/tmp.txt";
+
+ // Make sure drive-relative paths return correct absolute paths (task 255326)
+ QString drivePrefix = QDir::currentPath().left(2);
+ QString nonCurrentDrivePrefix =
+ drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:");
+
+ QTest::newRow("<current drive>:my.dll") << drivePrefix + "temp/my.dll" << QDir::currentPath() + "/temp/my.dll";
+ QTest::newRow("<not current drive>:my.dll") << nonCurrentDrivePrefix + "temp/my.dll"
+ << nonCurrentDrivePrefix + "/temp/my.dll";
+#else
+ QTest::newRow("absFilePath") << "/home/andy/tmp.txt" << "/home/andy/tmp.txt";
+#endif
+}
+
+void tst_QFileInfo::absFilePath()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QVERIFY(QString::compare(fi.absoluteFilePath(), expected, Qt::CaseInsensitive) == 0);
+#else
+ QCOMPARE(fi.absoluteFilePath(), expected);
+#endif
+}
+
+void tst_QFileInfo::canonicalPath()
+{
+ QTemporaryFile tempFile;
+ tempFile.setAutoRemove(true);
+ tempFile.open();
+ QFileInfo fi(tempFile.fileName());
+ QCOMPARE(fi.canonicalPath(), QFileInfo(QDir::tempPath()).canonicalFilePath());
+}
+
+void tst_QFileInfo::canonicalFilePath()
+{
+ const QString fileName("tmp.canon");
+ QFile tempFile(fileName);
+ QVERIFY(tempFile.open(QFile::WriteOnly));
+ QFileInfo fi(tempFile.fileName());
+ QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName);
+ tempFile.remove();
+
+ // This used to crash on Mac, verify that it doesn't anymore.
+ QFileInfo info("/tmp/../../../../../../../../../../../../../../../../../");
+ info.canonicalFilePath();
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ // This used to crash on Mac
+ QFileInfo dontCrash(QLatin1String("/"));
+ QCOMPARE(dontCrash.canonicalFilePath(), QLatin1String("/"));
+#endif
+
+#ifndef Q_OS_WIN
+ // test symlinks
+ QFile::remove("link.lnk");
+ {
+ QFile file(SRCDIR "tst_qfileinfo.cpp");
+ if (file.link("link.lnk")) {
+ QFileInfo info1(file);
+ QFileInfo info2("link.lnk");
+ QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
+ }
+ }
+# if !defined(Q_OS_SYMBIAN)
+ // Symbian doesn't support links to directories
+ {
+ const QString link(QDir::tempPath() + QDir::separator() + "tst_qfileinfo");
+ QFile::remove(link);
+ QFile file(QDir::currentPath());
+ if (file.link(link)) {
+ QFile tempfile("tempfile.txt");
+ tempfile.open(QIODevice::ReadWrite);
+ tempfile.write("This file is generated by the QFileInfo autotest.");
+ QVERIFY(tempfile.flush());
+ tempfile.close();
+
+ QFileInfo info1("tempfile.txt");
+ QFileInfo info2(link + QDir::separator() + "tempfile.txt");
+
+ QVERIFY(info1.exists());
+ QVERIFY(info2.exists());
+ QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
+
+ QFileInfo info3(link + QDir::separator() + "link.lnk");
+ QFileInfo info4(SRCDIR "tst_qfileinfo.cpp");
+ QVERIFY(!info3.canonicalFilePath().isEmpty());
+ QCOMPARE(info4.canonicalFilePath(), info3.canonicalFilePath());
+
+ tempfile.remove();
+ }
+ }
+ {
+ QString link(QDir::tempPath() + QDir::separator() + "tst_qfileinfo"
+ + QDir::separator() + "link_to_tst_qfileinfo");
+ QFile::remove(link);
+
+ QFile file(QDir::tempPath() + QDir::separator() + "tst_qfileinfo"
+ + QDir::separator() + "tst_qfileinfo.cpp");
+ if (file.link(link))
+ {
+ QFileInfo info1("tst_qfileinfo.cpp");
+ QFileInfo info2(link);
+ QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
+ }
+ }
+# endif
+#endif
+
+#ifdef Q_OS_WIN
+ typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD);
+ PtrCreateSymbolicLink ptrCreateSymbolicLink =
+ (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLinkW");
+
+ if (!ptrCreateSymbolicLink) {
+ QSKIP("Symbolic links aren't supported by FS", SkipAll);
+ } else {
+ // CreateSymbolicLink can return TRUE & still fail to create the link,
+ // the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314)
+ SetLastError(0);
+ BOOL ret = ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1);
+ DWORD dwErr = GetLastError();
+ if (!ret)
+ QSKIP("Symbolic links aren't supported by FS", SkipAll);
+ QString currentPath = QDir::currentPath();
+ bool is_res_Current = QDir::setCurrent("res");
+ if (!is_res_Current && dwErr == 1314)
+ QSKIP("Not enough privilages to create Symbolic links", SkipAll);
+ QCOMPARE(is_res_Current, true);
+
+ QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1");
+
+ QCOMPARE(QDir::setCurrent(currentPath), true);
+ QDir::current().rmdir("res");
+ }
+#endif
+}
+
+void tst_QFileInfo::fileName_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("relativeFile") << "tmp.txt" << "tmp.txt";
+ QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << "tmp.txt";
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("absFilePath") << "c:\\home\\andy\\tmp.txt" << "tmp.txt";
+#else
+ QTest::newRow("absFilePath") << "/home/andy/tmp.txt" << "tmp.txt";
+#endif
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "file1.ext1";
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "file1.ext1.ext2";
+
+ QTest::newRow("ending slash [small]") << QString::fromLatin1("/a/") << QString::fromLatin1("");
+ QTest::newRow("no ending slash [small]") << QString::fromLatin1("/a") << QString::fromLatin1("a");
+
+ QTest::newRow("ending slash") << QString::fromLatin1("/somedir/") << QString::fromLatin1("");
+ QTest::newRow("no ending slash") << QString::fromLatin1("/somedir") << QString::fromLatin1("somedir");
+}
+
+void tst_QFileInfo::fileName()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.fileName(), expected);
+}
+
+void tst_QFileInfo::bundleName_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("root") << "/" << "";
+ QTest::newRow("etc") << "/etc" << "";
+#ifdef Q_OS_MAC
+ QTest::newRow("safari") << "/Applications/Safari.app" << "Safari";
+#endif
+}
+
+void tst_QFileInfo::bundleName()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.bundleName(), expected);
+}
+
+void tst_QFileInfo::dir_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<bool>("absPath");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("relativeFile") << "tmp.txt" << false << ".";
+ QTest::newRow("relativeFileAbsPath") << "tmp.txt" << true << QDir::currentPath();
+ QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << false << "temp";
+ QTest::newRow("relativeFileInSubDirAbsPath") << "temp/tmp.txt" << true << QDir::currentPath() + "/temp";
+ QTest::newRow("absFilePath") << QDir::currentPath() + "/tmp.txt" << false << QDir::currentPath();
+ QTest::newRow("absFilePathAbsPath") << QDir::currentPath() + "/tmp.txt" << true << QDir::currentPath();
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << true << ":/tst_qfileinfo/resources";
+}
+
+void tst_QFileInfo::dir()
+{
+ QFETCH(QString, file);
+ QFETCH(bool, absPath);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ if (absPath) {
+ QCOMPARE(fi.absolutePath(), expected);
+ QCOMPARE(fi.absoluteDir().path(), expected);
+ } else {
+ QCOMPARE(fi.path(), expected);
+ QCOMPARE(fi.dir().path(), expected);
+ }
+}
+
+
+void tst_QFileInfo::suffix_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("noextension0") << "file" << "";
+ QTest::newRow("noextension1") << "/path/to/file" << "";
+ QTest::newRow("data0") << "file.tar" << "tar";
+ QTest::newRow("data1") << "file.tar.gz" << "gz";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "gz";
+ QTest::newRow("data3") << "/path/file.tar" << "tar";
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "ext1";
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "ext2";
+ QTest::newRow("hidden1") << ".ext1" << "ext1";
+ QTest::newRow("hidden1") << ".ext" << "ext";
+ QTest::newRow("hidden1") << ".ex" << "ex";
+ QTest::newRow("hidden1") << ".e" << "e";
+ QTest::newRow("hidden2") << ".ext1.ext2" << "ext2";
+ QTest::newRow("hidden2") << ".ext.ext2" << "ext2";
+ QTest::newRow("hidden2") << ".ex.ext2" << "ext2";
+ QTest::newRow("hidden2") << ".e.ext2" << "ext2";
+ QTest::newRow("hidden2") << "..ext2" << "ext2";
+}
+
+void tst_QFileInfo::suffix()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.suffix(), expected);
+}
+
+
+void tst_QFileInfo::completeSuffix_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("noextension0") << "file" << "";
+ QTest::newRow("noextension1") << "/path/to/file" << "";
+ QTest::newRow("data0") << "file.tar" << "tar";
+ QTest::newRow("data1") << "file.tar.gz" << "tar.gz";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "tar.gz";
+ QTest::newRow("data3") << "/path/file.tar" << "tar";
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "ext1";
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "ext1.ext2";
+}
+
+void tst_QFileInfo::completeSuffix()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.completeSuffix(), expected);
+}
+
+void tst_QFileInfo::baseName_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("data0") << "file.tar" << "file";
+ QTest::newRow("data1") << "file.tar.gz" << "file";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "file";
+ QTest::newRow("data3") << "/path/file.tar" << "file";
+ QTest::newRow("data4") << "/path/file" << "file";
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "file1";
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "file1";
+}
+
+void tst_QFileInfo::baseName()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.baseName(), expected);
+}
+
+void tst_QFileInfo::completeBaseName_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("data0") << "file.tar" << "file";
+ QTest::newRow("data1") << "file.tar.gz" << "file.tar";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "file.tar";
+ QTest::newRow("data3") << "/path/file.tar" << "file";
+ QTest::newRow("data4") << "/path/file" << "file";
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "file1";
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "file1.ext1";
+}
+
+void tst_QFileInfo::completeBaseName()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.completeBaseName(), expected);
+}
+
+void tst_QFileInfo::permission_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<int>("perms");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << int(QFile::ExeUser) << true;
+ QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << int(QFile::ReadUser) << true;
+// QTest::newRow("data2") << "tst_qfileinfo.cpp" << int(QFile::WriteUser) << false;
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ReadUser) << true;
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::WriteUser) << false;
+ QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ExeUser) << false;
+}
+
+void tst_QFileInfo::permission()
+{
+ QFETCH(QString, file);
+ QFETCH(int, perms);
+ QFETCH(bool, expected);
+#ifdef Q_OS_SYMBIAN
+ QSKIP("No user based rights in Symbian OS - SOS needs platform security tests instead", SkipAll);
+#endif
+ QFileInfo fi(file);
+ QCOMPARE(fi.permission(QFile::Permissions(perms)), expected);
+}
+
+void tst_QFileInfo::size_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<int>("size");
+
+ QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << 0;
+ QFile::remove("file1");
+ QFile file("file1");
+ QVERIFY(file.open(QFile::WriteOnly));
+ QCOMPARE(file.write("JAJAJAA"), qint64(7));
+ QTest::newRow("created-file") << "file1" << 7;
+
+ QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << 0;
+}
+
+void tst_QFileInfo::size()
+{
+ QFETCH(QString, file);
+
+ QFileInfo fi(file);
+ (void)fi.permissions(); // see task 104198
+ QTEST(int(fi.size()), "size");
+}
+
+void tst_QFileInfo::systemFiles()
+{
+#if !defined(Q_OS_WIN) || defined(Q_OS_WINCE)
+ QSKIP("This is a Windows only test", SkipAll);
+#endif
+ QFileInfo fi("c:\\pagefile.sys");
+ QVERIFY(fi.exists()); // task 167099
+ QVERIFY(fi.size() > 0); // task 189202
+ QVERIFY(fi.lastModified().isValid());
+}
+
+void tst_QFileInfo::compare_data()
+{
+ QTest::addColumn<QString>("file1");
+ QTest::addColumn<QString>("file2");
+ QTest::addColumn<bool>("same");
+
+#if defined(Q_OS_MAC)
+ // Since 10.6 we use realpath() in qfsfileengine, and it properly handles
+ // file system case sensitivity. However here in the autotest we don't
+ // check if the file system is case sensitive, so to make it pass in the
+ // default OS X installation we assume we are running on a case insensitive
+ // file system if on 10.6 and on a case sensitive file system if on 10.5
+ bool caseSensitiveOnMac = true;
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6)
+ caseSensitiveOnMac = false;
+#endif
+
+ QTest::newRow("data0")
+ << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
+ << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
+ << true;
+ QTest::newRow("data1")
+ << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
+ << QString::fromLatin1("/tst_qfileinfo.cpp")
+ << false;
+ QTest::newRow("data2")
+ << QString::fromLatin1("tst_qfileinfo.cpp")
+ << QDir::currentPath() + QString::fromLatin1("/tst_qfileinfo.cpp")
+ << true;
+ QTest::newRow("casesense1")
+ << QString::fromLatin1(SRCDIR "tst_qfileInfo.cpp")
+ << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ << true;
+#elif defined(Q_OS_MAC)
+ << !caseSensitiveOnMac;
+#else
+ << false;
+#endif
+}
+
+void tst_QFileInfo::compare()
+{
+ QFETCH(QString, file1);
+ QFETCH(QString, file2);
+ QFETCH(bool, same);
+ QFileInfo fi1(file1), fi2(file2);
+ QCOMPARE(fi1 == fi2, same);
+}
+
+void tst_QFileInfo::consistent_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ QTest::newRow("slashes") << QString::fromLatin1("\\a\\a\\a\\a") << QString::fromLatin1("/a/a/a/a");
+#endif
+ QTest::newRow("ending slash") << QString::fromLatin1("/a/somedir/") << QString::fromLatin1("/a/somedir/");
+ QTest::newRow("no ending slash") << QString::fromLatin1("/a/somedir") << QString::fromLatin1("/a/somedir");
+}
+
+void tst_QFileInfo::consistent()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileInfo fi(file);
+ QCOMPARE(fi.filePath(), expected);
+ QCOMPARE(fi.dir().path() + "/" + fi.fileName(), expected);
+}
+
+
+void tst_QFileInfo::fileTimes_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::newRow("simple") << QString::fromLatin1("simplefile.txt");
+ QTest::newRow( "longfile" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName.txt");
+ QTest::newRow( "longfile absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName"
+ "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
+}
+
+void tst_QFileInfo::fileTimes()
+{
+#if defined(Q_OS_WINCE)
+ int sleepTime = 3000;
+#else
+ int sleepTime = 2000;
+#endif
+ QFETCH(QString, fileName);
+ if (QFile::exists(fileName)) {
+ QVERIFY(QFile::remove(fileName));
+ }
+ QTest::qSleep(sleepTime);
+ {
+ QFile file(fileName);
+#if defined(Q_OS_WINCE)
+ QEXPECT_FAIL("longfile", "No long filenames on WinCE", Abort);
+ QEXPECT_FAIL("longfile absolutepath", "No long filenames on WinCE", Abort);
+#elif defined(Q_OS_SYMBIAN)
+ QEXPECT_FAIL("longfile", "Maximum total filepath cannot exceed 256 characters in Symbian", Abort);
+ QEXPECT_FAIL("longfile absolutepath", "Maximum total filepath cannot exceed 256 characters in Symbian", Abort);
+#endif
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
+#ifdef Q_OS_UNIX
+ if (qIsLikelyToBeNfs(file.handle()))
+ QSKIP("This Test doesn't work on NFS", SkipAll);
+#endif
+ QTextStream ts(&file);
+ ts << fileName << endl;
+ }
+ QTest::qSleep(sleepTime);
+ QDateTime beforeWrite = QDateTime::currentDateTime();
+ QTest::qSleep(sleepTime);
+ {
+ QFileInfo fileInfo(fileName);
+ QVERIFY(fileInfo.created() < beforeWrite);
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::ReadWrite | QFile::Text));
+ QTextStream ts(&file);
+ ts << fileName << endl;
+ }
+ QTest::qSleep(sleepTime);
+ QDateTime beforeRead = QDateTime::currentDateTime();
+ QTest::qSleep(sleepTime);
+ {
+ QFileInfo fileInfo(fileName);
+// On unix created() returns the same as lastModified().
+#if !defined(Q_OS_UNIX) && !defined(Q_OS_WINCE)
+ QVERIFY(fileInfo.created() < beforeWrite);
+#endif
+ QVERIFY(fileInfo.lastModified() > beforeWrite);
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
+ QTextStream ts(&file);
+ QString line = ts.readLine();
+ QCOMPARE(line, fileName);
+ }
+
+ QFileInfo fileInfo(fileName);
+#if !defined(Q_OS_UNIX) && !defined(Q_OS_WINCE)
+ QVERIFY(fileInfo.created() < beforeWrite);
+#endif
+ //In Vista the last-access timestamp is not updated when the file is accessed/touched (by default).
+ //To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
+ //is set to 0, in the test machine.
+#ifdef Q_OS_WINCE
+ QEXPECT_FAIL("simple", "WinCE only stores date of access data, not the time", Continue);
+#endif
+#ifdef Q_OS_SYMBIAN
+ QEXPECT_FAIL("simple", "Symbian implementation of stat doesn't return read time right", Abort);
+#endif
+ QVERIFY(fileInfo.lastRead() > beforeRead);
+ QVERIFY(fileInfo.lastModified() > beforeWrite);
+ QVERIFY(fileInfo.lastModified() < beforeRead);
+}
+
+void tst_QFileInfo::fileTimes_oldFile()
+{
+ // This is not supported on WinCE
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // All files are opened in share mode (both read and write).
+ DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+
+ // All files on Windows can be read; there's no such thing as an
+ // unreadable file. Add GENERIC_WRITE if WriteOnly is passed.
+ int accessRights = GENERIC_READ | GENERIC_WRITE;
+
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+
+ // Regular file mode. In Unbuffered mode, pass the no-buffering flag.
+ DWORD flagsAndAtts = FILE_ATTRIBUTE_NORMAL;
+
+ // WriteOnly can create files, ReadOnly cannot.
+ DWORD creationDisp = OPEN_ALWAYS;
+
+ // Create the file handle.
+ HANDLE fileHandle = CreateFile(L"oldfile.txt",
+ accessRights,
+ shareMode,
+ &securityAtts,
+ creationDisp,
+ flagsAndAtts,
+ NULL);
+
+ // Set file times back to 1601.
+ SYSTEMTIME stime;
+ stime.wYear = 1601;
+ stime.wMonth = 1;
+ stime.wDayOfWeek = 1;
+ stime.wDay = 1;
+ stime.wHour = 1;
+ stime.wMinute = 0;
+ stime.wSecond = 0;
+ stime.wMilliseconds = 0;
+
+ FILETIME ctime;
+ QVERIFY(SystemTimeToFileTime(&stime, &ctime));
+ FILETIME atime = ctime;
+ FILETIME mtime = atime;
+ QVERIFY(fileHandle);
+ QVERIFY(SetFileTime(fileHandle, &ctime, &atime, &mtime) != 0);
+
+ CloseHandle(fileHandle);
+
+ QFileInfo info("oldfile.txt");
+ QCOMPARE(info.lastModified(), QDateTime(QDate(1601, 1, 1), QTime(1, 0), Qt::UTC).toLocalTime());
+#endif
+}
+
+void tst_QFileInfo::isSymLink_data()
+{
+#ifndef NO_SYMLINKS
+ QFile::remove("link.lnk");
+ QFile::remove("brokenlink.lnk");
+ QFile::remove("dummyfile");
+
+ QFile file1(SRCDIR "tst_qfileinfo.cpp");
+ QVERIFY(file1.link("link.lnk"));
+
+ QFile file2("dummyfile");
+ file2.open(QIODevice::WriteOnly);
+ QVERIFY(file2.link("brokenlink.lnk"));
+ file2.remove();
+
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isSymLink");
+ QTest::addColumn<QString>("linkTarget");
+
+ QTest::newRow("existent file") << SRCDIR "tst_qfileinfo.cpp" << false << "";
+ QTest::newRow("link") << "link.lnk" << true << QFileInfo(SRCDIR "tst_qfileinfo.cpp").absoluteFilePath();
+ QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath();
+#endif
+}
+
+void tst_QFileInfo::isSymLink()
+{
+#ifndef NO_SYMLINKS
+ QFETCH(QString, path);
+ QFETCH(bool, isSymLink);
+ QFETCH(QString, linkTarget);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isSymLink(), isSymLink);
+ QCOMPARE(fi.symLinkTarget(), linkTarget);
+#else
+ QSKIP("no symbolic link support on this platform", SkipAll);
+#endif
+}
+
+void tst_QFileInfo::isHidden_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isHidden");
+ foreach (const QFileInfo& info, QDir::drives()) {
+ QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false;
+ }
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QVERIFY(QDir("./hidden-directory").exists() || QDir().mkdir("./hidden-directory"));
+ QVERIFY(SetFileAttributesW(reinterpret_cast<LPCWSTR>(QString("./hidden-directory").utf16()),FILE_ATTRIBUTE_HIDDEN));
+ QTest::newRow("C:/path/to/hidden-directory") << QDir::currentPath() + QString::fromLatin1("/hidden-directory") << true;
+ QTest::newRow("C:/path/to/hidden-directory/.") << QDir::currentPath() + QString::fromLatin1("/hidden-directory/.") << true;
+#endif
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ QVERIFY(QDir("./.hidden-directory").exists() || QDir().mkdir("./.hidden-directory"));
+ QTest::newRow("/path/to/.hidden-directory") << QDir::currentPath() + QString("/.hidden-directory") << true;
+ QTest::newRow("/path/to/.hidden-directory/.") << QDir::currentPath() + QString("/.hidden-directory/.") << true;
+ QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << true;
+#endif
+
+#if defined(Q_OS_MAC)
+ // /bin has the hidden attribute on Mac OS X
+ QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << true;
+#elif !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+ QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false;
+#endif
+
+#ifdef Q_OS_MAC
+ QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true;
+ QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false;
+ QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false;
+#endif
+
+#ifdef Q_OS_SYMBIAN
+ // No guaranteed hidden file knows to exist in Symbian filesystem, so make one.
+ QString hiddenFileName("hidden.txt");
+ QString notHiddenFileName("nothidden.txt");
+ QTest::newRow("hidden file") << hiddenFileName << true;
+ QTest::newRow("non-hidden file") << notHiddenFileName << false;
+
+ {
+ QFile file(hiddenFileName);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QTextStream t(&file);
+ t << "foobar";
+
+ QFile file2(notHiddenFileName);
+ QVERIFY(file2.open(QIODevice::WriteOnly));
+ QTextStream t2(&file2);
+ t2 << "foobar";
+ }
+
+ RFs rfs;
+ TInt err = rfs.Connect();
+ QCOMPARE(err, KErrNone);
+ HBufC* symFile = qt_QString2HBufC(hiddenFileName);
+ err = rfs.SetAtt(*symFile, KEntryAttHidden, 0);
+ rfs.Close();
+ delete symFile;
+ QCOMPARE(err, KErrNone);
+#endif
+}
+
+void tst_QFileInfo::isHidden()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isHidden);
+ QFileInfo fi(path);
+
+ QCOMPARE(fi.isHidden(), isHidden);
+}
+
+#if defined(Q_OS_MAC)
+void tst_QFileInfo::isHiddenFromFinder()
+{
+ const char *filename = "test_foobar.txt";
+
+ QFile testFile(filename);
+ testFile.open(QIODevice::WriteOnly | QIODevice::Append);
+ testFile.write(QByteArray("world"));
+ testFile.close();
+
+ struct stat buf;
+ stat(filename, &buf);
+ chflags(filename, buf.st_flags | UF_HIDDEN);
+
+ QFileInfo fi(filename);
+ QCOMPARE(fi.isHidden(), true);
+
+ testFile.remove();
+}
+#endif
+
+void tst_QFileInfo::isBundle_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isBundle");
+ QTest::newRow("root") << QString::fromLatin1("/") << false;
+#ifdef Q_OS_MAC
+ QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false;
+ QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications/Safari.app") << true;
+#endif
+}
+
+void tst_QFileInfo::isBundle()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isBundle);
+ QFileInfo fi(path);
+ QCOMPARE(fi.isBundle(), isBundle);
+}
+
+void tst_QFileInfo::isLocalFs_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isLocalFs");
+
+ QTest::newRow("local root") << QString::fromLatin1("/") << true;
+ QTest::newRow("local non-existent file") << QString::fromLatin1("/abrakadabra.boo") << true;
+
+ QTest::newRow("qresource root") << QString::fromLatin1(":/") << false;
+}
+
+void tst_QFileInfo::isLocalFs()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isLocalFs);
+
+ QFileInfo info(path);
+ QFileInfoPrivate *privateInfo = getPrivate(info);
+ QCOMPARE((privateInfo->fileEngine == 0), isLocalFs);
+ if (privateInfo->fileEngine)
+ QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag)
+ & QAbstractFileEngine::LocalDiskFlag), isLocalFs);
+}
+
+void tst_QFileInfo::refresh()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_WIN)
+ int sleepTime = 3000;
+#else
+ int sleepTime = 2000;
+#endif
+
+ QFile::remove("file1");
+ QFile file("file1");
+ QVERIFY(file.open(QFile::WriteOnly));
+ QCOMPARE(file.write("JAJAJAA"), qint64(7));
+ file.flush();
+
+ QFileInfo info(file);
+ QDateTime lastModified = info.lastModified();
+ QCOMPARE(info.size(), qint64(7));
+
+ QTest::qSleep(sleepTime);
+
+ QCOMPARE(file.write("JOJOJO"), qint64(6));
+ file.flush();
+ QVERIFY(info.lastModified() == lastModified);
+
+ QCOMPARE(info.size(), qint64(7));
+#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
+ if (QSysInfo::windowsVersion() & QSysInfo::WV_VISTA ||
+ QSysInfo::windowsVersion() & QSysInfo::WV_CE_based)
+ file.close();
+#endif
+#if defined(Q_OS_WINCE)
+ // On Windows CE we need to close the file.
+ // Otherwise the content will be cached and not
+ // flushed to the storage, although we flushed it
+ // manually!!! CE has interim cache, we cannot influence.
+ QTest::qWait(5000);
+#endif
+ info.refresh();
+ QCOMPARE(info.size(), qint64(13));
+ QVERIFY(info.lastModified() > lastModified);
+
+ QFileInfo info2 = info;
+ QCOMPARE(info2.size(), info.size());
+
+ info2.refresh();
+ QCOMPARE(info2.size(), info.size());
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isSymLink");
+ QTest::addColumn<QString>("linkTarget");
+ QTest::addColumn<QString>("canonicalFilePath");
+
+ QDir pwd;
+ pwd.mkdir("target");
+
+ QLibrary kernel32("kernel32");
+ typedef BOOLEAN (WINAPI *PtrCreateSymbolicLink)(LPCWSTR, LPCWSTR, DWORD);
+ PtrCreateSymbolicLink createSymbolicLinkW = 0;
+ createSymbolicLinkW = (PtrCreateSymbolicLink) kernel32.resolve("CreateSymbolicLinkW");
+ if (!createSymbolicLinkW) {
+ //we need at least one data set for the test not to fail when skipping _data function
+ QDir target("target");
+ QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath();
+ QSKIP("symbolic links not supported by operating system",SkipSingle);
+ }
+ {
+ //Directory symlinks
+ QDir target("target");
+ QVERIFY(target.exists());
+
+ QString absTarget = QDir::toNativeSeparators(target.absolutePath());
+ QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink");
+ QString relTarget = "target";
+ QString relSymlink = "rel_symlink";
+ QString fileInTarget(absTarget);
+ fileInTarget.append("\\file");
+ QString fileInSymlink(absSymlink);
+ fileInSymlink.append("\\file");
+ QFile file(fileInTarget);
+ file.open(QIODevice::ReadWrite);
+ file.close();
+
+ DWORD err = ERROR_SUCCESS ;
+ if (!pwd.exists("abs_symlink"))
+ if (!createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1))
+ err = GetLastError();
+ if (err == ERROR_SUCCESS && !pwd.exists(relSymlink))
+ if (!createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1))
+ err = GetLastError();
+ if (err != ERROR_SUCCESS) {
+ wchar_t errstr[0x100];
+ DWORD count = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, err, 0, errstr, 0x100, 0);
+ QString error(QString::fromUtf16(errstr, count));
+ qWarning() << error;
+ //we need at least one data set for the test not to assert fail when skipping _data function
+ QDir target("target");
+ QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath();
+ QSKIP("link not supported by FS or insufficient privilege", SkipSingle);
+ }
+ QVERIFY(file.exists());
+
+ QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
+ QTest::newRow("relative dir symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalPath();
+ QTest::newRow("file in symlink dir") << fileInSymlink << false << "" << target.canonicalPath().append("/file");
+ }
+ {
+ //File symlinks
+ QFileInfo target(SRCDIR "tst_qfileinfo.cpp");
+ QString absTarget = QDir::toNativeSeparators(target.absoluteFilePath());
+ QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink.cpp");
+ QString relTarget = QDir::toNativeSeparators(pwd.relativeFilePath(target.absoluteFilePath()));
+ QString relSymlink = "rel_symlink.cpp";
+ QVERIFY(pwd.exists("abs_symlink.cpp") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0));
+ QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0));
+
+ QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+ QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalFilePath();
+ }
+
+ //Junctions
+ QString target = "target";
+ QString junction = "junction_pwd";
+ FileSystem::createNtfsJunction(target, junction);
+ QFileInfo targetInfo(target);
+ QTest::newRow("junction_pwd") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath();
+
+ QFileInfo fileInJunction(targetInfo.absoluteFilePath().append("/file"));
+ QFile file(fileInJunction.absoluteFilePath());
+ file.open(QIODevice::ReadWrite);
+ file.close();
+ QVERIFY(file.exists());
+ QTest::newRow("file in junction") << fileInJunction.absoluteFilePath() << false << "" << fileInJunction.canonicalFilePath();
+
+ target = QDir::rootPath();
+ junction = "junction_root";
+ FileSystem::createNtfsJunction(target, junction);
+ targetInfo.setFile(target);
+ QTest::newRow("junction_root") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath();
+
+ //Mountpoint
+ typedef BOOLEAN (WINAPI *PtrGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD);
+ PtrGetVolumeNameForVolumeMountPointW getVolumeNameForVolumeMountPointW = 0;
+ getVolumeNameForVolumeMountPointW = (PtrGetVolumeNameForVolumeMountPointW) kernel32.resolve("GetVolumeNameForVolumeMountPointW");
+ if(getVolumeNameForVolumeMountPointW)
+ {
+ wchar_t buffer[MAX_PATH];
+ QString rootPath = QDir::toNativeSeparators(QDir::rootPath());
+ QVERIFY(getVolumeNameForVolumeMountPointW((wchar_t*)rootPath.utf16(), buffer, MAX_PATH));
+ QString rootVolume = QString::fromWCharArray(buffer);
+ junction = "mountpoint";
+ rootVolume.replace("\\\\?\\","\\??\\");
+ FileSystem::createNtfsJunction(rootVolume, junction);
+ QTest::newRow("mountpoint") << junction << true << QDir::fromNativeSeparators(rootPath) << QDir::rootPath();
+ }
+}
+
+void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isSymLink);
+ QFETCH(QString, linkTarget);
+ QFETCH(QString, canonicalFilePath);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isSymLink(), isSymLink);
+ QCOMPARE(fi.symLinkTarget(), linkTarget);
+ QCOMPARE(fi.canonicalFilePath(), canonicalFilePath);
+}
+
+void tst_QFileInfo::brokenShortcut()
+{
+ QString linkName("borkenlink.lnk");
+ QFile::remove(linkName);
+ QFile file(linkName);
+ file.open(QFile::WriteOnly);
+ file.write("b0rk");
+ file.close();
+
+ QFileInfo info(linkName);
+ QVERIFY(info.isSymLink());
+ QVERIFY(!info.exists());
+ QFile::remove(linkName);
+}
+#endif
+
+void tst_QFileInfo::isWritable()
+{
+ QFile tempfile("tempfile.txt");
+ tempfile.open(QIODevice::WriteOnly);
+ tempfile.write("This file is generated by the QFileInfo autotest.");
+ tempfile.close();
+
+ QVERIFY(QFileInfo("tempfile.txt").isWritable());
+ tempfile.remove();
+
+#ifdef Q_OS_WIN
+#ifdef Q_OS_WINCE
+ QFileInfo fi("\\Windows\\wince.nls");
+#else
+ QFileInfo fi("c:\\pagefile.sys");
+#endif
+ QVERIFY(fi.exists());
+ QVERIFY(!fi.isWritable());
+#endif
+#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)
+ if (::getuid() == 0)
+ QVERIFY(QFileInfo("/etc/passwd").isWritable());
+ else
+ QVERIFY(!QFileInfo("/etc/passwd").isWritable());
+#endif
+}
+
+void tst_QFileInfo::isExecutable()
+{
+#ifdef Q_OS_SYMBIAN
+ QString appPath = "c:/sys/bin/tst_qfileinfo.exe";
+#else
+ QString appPath = QCoreApplication::applicationDirPath();
+ appPath += "/tst_qfileinfo";
+# if defined(Q_OS_WIN)
+ appPath += ".exe";
+# endif
+#endif
+ QFileInfo fi(appPath);
+ QCOMPARE(fi.isExecutable(), true);
+
+ QCOMPARE(QFileInfo("qfileinfo.pro").isExecutable(), false);
+}
+
+
+void tst_QFileInfo::testDecomposedUnicodeNames_data()
+{
+ QTest::addColumn<QString>("filePath");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<bool>("exists");
+ QString currPath = QDir::currentPath();
+ QTest::newRow("latin-only") << currPath + "/4.pdf" << "4.pdf" << true;
+ QTest::newRow("one-decomposed uni") << currPath + QString::fromUtf8("/4 À.pdf") << QString::fromUtf8("4 À.pdf") << true;
+ QTest::newRow("many-decomposed uni") << currPath + QString::fromUtf8("/4 ÀÀÀcopy.pdf") << QString::fromUtf8("4 ÀÀÀcopy.pdf") << true;
+ QTest::newRow("no decomposed") << currPath + QString::fromUtf8("/4 ÞÞÞcopy.pdf") << QString::fromUtf8("4 ÞÞÞcopy.pdf") << true;
+}
+
+static void createFileNative(const QString &filePath)
+{
+#ifdef Q_OS_UNIX
+ int fd = open(filePath.normalized(QString::NormalizationForm_D).toUtf8().constData(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ QFAIL("couldn't create file");
+ } else {
+ close(fd);
+ }
+#else
+ Q_UNUSED(filePath);
+#endif
+}
+
+static void removeFileNative(const QString &filePath)
+{
+#ifdef Q_OS_UNIX
+ unlink(filePath.normalized(QString::NormalizationForm_D).toUtf8().constData());
+#else
+ Q_UNUSED(filePath);
+#endif
+}
+
+void tst_QFileInfo::testDecomposedUnicodeNames()
+{
+#ifndef Q_OS_MAC
+ QSKIP("This is a OS X only test (unless you know more about filesystems, then maybe you should try it ;)", SkipAll);
+#endif
+ QFETCH(QString, filePath);
+ createFileNative(filePath);
+
+ QFileInfo file(filePath);
+ QTEST(file.fileName(), "fileName");
+ QTEST(file.exists(), "exists");
+ removeFileNative(filePath);
+}
+
+void tst_QFileInfo::equalOperator() const
+{
+ /* Compare two default constructed values. Yes, to me it seems it should be the opposite too, but
+ * this is how the code was written. */
+ QVERIFY(!(QFileInfo() == QFileInfo()));
+}
+
+
+void tst_QFileInfo::equalOperatorWithDifferentSlashes() const
+{
+ const QFileInfo fi1("/usr");
+ const QFileInfo fi2("/usr/");
+
+ QCOMPARE(fi1, fi2);
+}
+
+void tst_QFileInfo::notEqualOperator() const
+{
+ /* Compare two default constructed values. Yes, to me it seems it should be the opposite too, but
+ * this is how the code was written. */
+ QVERIFY(QFileInfo() != QFileInfo());
+}
+
+void tst_QFileInfo::detachingOperations()
+{
+ QFileInfo info1;
+ QVERIFY(info1.caching());
+ info1.setCaching(false);
+
+ {
+ QFileInfo info2 = info1;
+
+ QVERIFY(!info1.caching());
+ QVERIFY(!info2.caching());
+
+ info2.setCaching(true);
+ QVERIFY(info2.caching());
+
+ info1.setFile("foo");
+ QVERIFY(!info1.caching());
+ }
+
+ {
+ QFile file("foo");
+ info1.setFile(file);
+ QVERIFY(!info1.caching());
+ }
+
+ info1.setFile(QDir(), "foo");
+ QVERIFY(!info1.caching());
+
+ {
+ QFileInfo info3;
+ QVERIFY(info3.caching());
+
+ info3 = info1;
+ QVERIFY(!info3.caching());
+ }
+
+ info1.refresh();
+ QVERIFY(!info1.caching());
+
+ QVERIFY(info1.makeAbsolute());
+ QVERIFY(!info1.caching());
+
+ info1.detach();
+ QVERIFY(!info1.caching());
+}
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+#if defined (Q_OS_WIN)
+BOOL IsUserAdmin()
+{
+ BOOL b;
+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+ PSID AdministratorsGroup;
+ b = AllocateAndInitializeSid(
+ &NtAuthority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &AdministratorsGroup);
+ if (b) {
+ if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
+ b = FALSE;
+ FreeSid(AdministratorsGroup);
+ }
+
+ return(b);
+}
+#endif
+
+void tst_QFileInfo::owner()
+{
+ QString userName;
+#if defined(Q_OS_UNIX)
+ {
+ passwd *user = getpwuid(geteuid());
+ QVERIFY(user);
+ char *usernameBuf = user->pw_name;
+ userName = QString::fromLocal8Bit(usernameBuf);
+ }
+#endif
+#if defined(Q_OS_WIN)
+ wchar_t usernameBuf[1024];
+ DWORD bufSize = 1024;
+ if (GetUserNameW(usernameBuf, &bufSize)) {
+ userName = QString::fromWCharArray(usernameBuf);
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && IsUserAdmin()) {
+ // Special case : If the user is a member of Administrators group, all files
+ // created by the current user are owned by the Administrators group.
+ LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
+ DWORD dwLevel = 0;
+ DWORD dwFlags = LG_INCLUDE_INDIRECT ;
+ DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
+ DWORD dwEntriesRead = 0;
+ DWORD dwTotalEntries = 0;
+ NET_API_STATUS nStatus;
+ nStatus = NetUserGetLocalGroups(0, usernameBuf, dwLevel, dwFlags, (LPBYTE *) &pBuf,
+ dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries);
+ // Check if the current user is a member of Administrators group
+ if (nStatus == NERR_Success && pBuf){
+ for (int i = 0; i < dwEntriesRead; i++) {
+ QString groupName = QString::fromWCharArray(pBuf[i].lgrui0_name);
+ if (!groupName.compare(QLatin1String("Administrators")))
+ userName = groupName;
+ }
+ }
+ if (pBuf != NULL)
+ NetApiBufferFree(pBuf);
+ }
+ }
+ extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
+ qt_ntfs_permission_lookup = 1;
+#endif
+ if (userName.isEmpty())
+ QSKIP("Can't retrieve the user name", SkipAll);
+ QString fileName("ownertest.txt");
+ QVERIFY(!QFile::exists(fileName) || QFile::remove(fileName));
+ {
+ QFile testFile(fileName);
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text));
+ QByteArray testData("testfile");
+ QVERIFY(testFile.write(testData) != -1);
+ }
+ QFileInfo fi(fileName);
+ QVERIFY(fi.exists());
+ QCOMPARE(fi.owner(), userName);
+
+ QFile::remove(fileName);
+#if defined(Q_OS_WIN)
+ qt_ntfs_permission_lookup = 0;
+#endif
+}
+#endif
+
+void tst_QFileInfo::group()
+{
+ QString expected;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ struct group *gr;
+ gid_t gid = getegid();
+ gr = getgrgid(gid);
+ expected = QString::fromLocal8Bit(gr->gr_name);
+#endif
+
+ QString fileName("ownertest.txt");
+ if (QFile::exists(fileName))
+ QFile::remove(fileName);
+ QFile testFile(fileName);
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text));
+ QByteArray testData("testfile");
+ QVERIFY(testFile.write(testData) != -1);
+ testFile.close();
+ QFileInfo fi(fileName);
+ QVERIFY(fi.exists());
+
+ QCOMPARE(fi.group(), expected);
+}
+
+void tst_QFileInfo::invalidState()
+{
+ // Shouldn't crash;
+
+ {
+ QFileInfo info;
+ QCOMPARE(info.size(), qint64(0));
+ QVERIFY(!info.exists());
+
+ info.setCaching(false);
+
+ info.created();
+ info.lastRead();
+ info.lastModified();
+ }
+
+ {
+ QFileInfo info("");
+ QCOMPARE(info.size(), qint64(0));
+ QVERIFY(!info.exists());
+
+ info.setCaching(false);
+
+ info.created();
+ info.lastRead();
+ info.lastModified();
+ }
+
+ {
+ QFileInfo info("file-doesn't-really-exist.txt");
+ QCOMPARE(info.size(), qint64(0));
+ QVERIFY(!info.exists());
+
+ info.setCaching(false);
+
+ info.created();
+ info.lastRead();
+ info.lastModified();
+ }
+
+ QVERIFY(true);
+}
+
+QTEST_MAIN(tst_QFileInfo)
+#include "tst_qfileinfo.moc"
diff --git a/tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro b/tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro
new file mode 100644
index 0000000000..992c90cfcc
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro
@@ -0,0 +1,8 @@
+load(qttest_p4)
+
+SOURCES += tst_qfilesystementry.cpp \
+ $${QT.core.sources}/io/qfilesystementry.cpp
+HEADERS += $${QT.core.sources}/io/qfilesystementry_p.h
+QT = core core-private
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
new file mode 100644
index 0000000000..016bcbfe8a
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
@@ -0,0 +1,387 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+
+#include <QtCore/private/qfilesystementry_p.h>
+
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+# define WIN_STUFF
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QFileSystemEntry : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void getSetCheck_data();
+ void getSetCheck();
+ void suffix_data();
+ void suffix();
+ void completeSuffix_data();
+ void completeSuffix();
+ void baseName_data();
+ void baseName();
+ void completeBaseName_data();
+ void completeBaseName();
+#if defined(WIN_STUFF)
+ void absoluteOrRelative_data();
+ void absoluteOrRelative();
+#endif
+};
+
+#if defined(WIN_STUFF)
+void tst_QFileSystemEntry::getSetCheck_data()
+{
+ QTest::addColumn<QString>("nativeFilePath");
+ QTest::addColumn<QString>("internalnativeFilePath");
+ QTest::addColumn<QString>("filepath");
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<QString>("baseName");
+ QTest::addColumn<QString>("completeBasename");
+ QTest::addColumn<QString>("suffix");
+ QTest::addColumn<QString>("completeSuffix");
+ QTest::addColumn<bool>("absolute");
+ QTest::addColumn<bool>("relative");
+
+ QString absPrefix = QLatin1String("\\\\?\\");
+ QString relPrefix = absPrefix
+ + QDir::toNativeSeparators(QDir::currentPath())
+ + QLatin1String("\\");
+
+ QTest::newRow("simple")
+ << QString("A:\\home\\qt\\in\\a\\dir.tar.gz")
+ << absPrefix + QString("A:\\home\\qt\\in\\a\\dir.tar.gz")
+ << "A:/home/qt/in/a/dir.tar.gz"
+ << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true << false;
+
+ QTest::newRow("relative")
+ << QString("in\\a\\dir.tar.gz")
+ << relPrefix + QString("in\\a\\dir.tar.gz")
+ << "in/a/dir.tar.gz"
+ << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false <<true;
+
+ QTest::newRow("noSuffix")
+ << QString("myDir\\myfile")
+ << relPrefix + QString("myDir\\myfile")
+ << "myDir/myfile" << "myfile" << "myfile" << "myfile" << "" << "" << false <<true;
+
+ QTest::newRow("noLongSuffix")
+ << QString("myDir\\myfile.txt")
+ << relPrefix + QString("myDir\\myfile.txt")
+ << "myDir/myfile.txt" << "myfile.txt" << "myfile" << "myfile" << "txt" << "txt" << false << true;
+
+ QTest::newRow("endingSlash")
+ << QString("myDir\\myfile.bla\\")
+ << relPrefix + QString("myDir\\myfile.bla\\")
+ << "myDir/myfile.bla/" << "" << "" << "" << "" << "" << false << true;
+
+ QTest::newRow("absolutePath")
+ << QString("A:dir\\without\\leading\\backslash.bat")
+ << absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat")
+ << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false << false;
+}
+
+void tst_QFileSystemEntry::getSetCheck()
+{
+ QFETCH(QString, nativeFilePath);
+ QFETCH(QString, internalnativeFilePath);
+ QFETCH(QString, filepath);
+ QFETCH(QString, filename);
+ QFETCH(QString, baseName);
+ QFETCH(QString, completeBasename);
+ QFETCH(QString, suffix);
+ QFETCH(QString, completeSuffix);
+ QFETCH(bool, absolute);
+ QFETCH(bool, relative);
+
+ QFileSystemEntry entry1(filepath);
+ QCOMPARE(entry1.filePath(), filepath);
+ QCOMPARE(entry1.nativeFilePath().toLower(), internalnativeFilePath.toLower());
+ QCOMPARE(entry1.fileName(), filename);
+ QCOMPARE(entry1.suffix(), suffix);
+ QCOMPARE(entry1.completeSuffix(), completeSuffix);
+ QCOMPARE(entry1.isAbsolute(), absolute);
+ QCOMPARE(entry1.isRelative(), relative);
+ QCOMPARE(entry1.baseName(), baseName);
+ QCOMPARE(entry1.completeBaseName(), completeBasename);
+
+ QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath());
+ QCOMPARE(entry2.suffix(), suffix);
+ QCOMPARE(entry2.completeSuffix(), completeSuffix);
+ QCOMPARE(entry2.isAbsolute(), absolute);
+ QCOMPARE(entry2.isRelative(), relative);
+ QCOMPARE(entry2.filePath(), filepath);
+ // Since this entry was created using the native path,
+ // the object shouldnot change nativeFilePath.
+ QCOMPARE(entry2.nativeFilePath(), nativeFilePath);
+ QCOMPARE(entry2.fileName(), filename);
+ QCOMPARE(entry2.baseName(), baseName);
+ QCOMPARE(entry2.completeBaseName(), completeBasename);
+}
+
+#else
+
+void tst_QFileSystemEntry::getSetCheck_data()
+{
+ QTest::addColumn<QByteArray>("nativeFilePath");
+ QTest::addColumn<QString>("filepath");
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<QString>("basename");
+ QTest::addColumn<QString>("completeBasename");
+ QTest::addColumn<QString>("suffix");
+ QTest::addColumn<QString>("completeSuffix");
+ QTest::addColumn<bool>("absolute");
+
+ QTest::newRow("simple")
+ << QByteArray("/home/qt/in/a/dir.tar.gz")
+ << "/home/qt/in/a/dir.tar.gz"
+ << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true;
+ QTest::newRow("relative")
+ << QByteArray("in/a/dir.tar.gz")
+ << "in/a/dir.tar.gz"
+ << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false;
+
+ QTest::newRow("noSuffix")
+ << QByteArray("myDir/myfile")
+ << "myDir/myfile" << "myfile" << "myfile" << "myfile" << "" << "" << false;
+
+ QTest::newRow("noLongSuffix")
+ << QByteArray("myDir/myfile.txt")
+ << "myDir/myfile.txt" << "myfile.txt" << "myfile" << "myfile" << "txt" << "txt" << false;
+
+ QTest::newRow("endingSlash")
+ << QByteArray("myDir/myfile.bla/")
+ << "myDir/myfile.bla/" << "" << "" << "" << "" << "" << false;
+
+ QTest::newRow("relativePath")
+ << QByteArray("A:dir/without/leading/backslash.bat")
+ << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false;
+}
+
+void tst_QFileSystemEntry::getSetCheck()
+{
+ QFETCH(QByteArray, nativeFilePath);
+ QFETCH(QString, filepath);
+ QFETCH(QString, filename);
+ QFETCH(QString, basename);
+ QFETCH(QString, completeBasename);
+ QFETCH(QString, suffix);
+ QFETCH(QString, completeSuffix);
+ QFETCH(bool, absolute);
+
+ QFileSystemEntry entry1(filepath);
+ QCOMPARE(entry1.filePath(), filepath);
+ QCOMPARE(entry1.nativeFilePath(), nativeFilePath);
+ QCOMPARE(entry1.fileName(), filename);
+ QCOMPARE(entry1.suffix(), suffix);
+ QCOMPARE(entry1.completeSuffix(), completeSuffix);
+ QCOMPARE(entry1.isAbsolute(), absolute);
+ QCOMPARE(entry1.isRelative(), !absolute);
+ QCOMPARE(entry1.baseName(), basename);
+ QCOMPARE(entry1.completeBaseName(), completeBasename);
+
+ QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath());
+ QCOMPARE(entry2.suffix(), suffix);
+ QCOMPARE(entry2.completeSuffix(), completeSuffix);
+ QCOMPARE(entry2.isAbsolute(), absolute);
+ QCOMPARE(entry2.isRelative(), !absolute);
+ QCOMPARE(entry2.filePath(), filepath);
+ QCOMPARE(entry2.nativeFilePath(), nativeFilePath);
+ QCOMPARE(entry2.fileName(), filename);
+ QCOMPARE(entry2.baseName(), basename);
+ QCOMPARE(entry2.completeBaseName(), completeBasename);
+}
+#endif
+
+void tst_QFileSystemEntry::suffix_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("noextension0") << "file" << "";
+ QTest::newRow("noextension1") << "/path/to/file" << "";
+ QTest::newRow("data0") << "file.tar" << "tar";
+ QTest::newRow("data1") << "file.tar.gz" << "gz";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "gz";
+ QTest::newRow("data3") << "/path/file.tar" << "tar";
+ QTest::newRow("hidden1") << ".ext1" << "ext1";
+ QTest::newRow("hidden1") << ".ext" << "ext";
+ QTest::newRow("hidden1") << ".ex" << "ex";
+ QTest::newRow("hidden1") << ".e" << "e";
+ QTest::newRow("hidden2") << ".ext1.ext2" << "ext2";
+ QTest::newRow("hidden2") << ".ext.ext2" << "ext2";
+ QTest::newRow("hidden2") << ".ex.ext2" << "ext2";
+ QTest::newRow("hidden2") << ".e.ext2" << "ext2";
+ QTest::newRow("hidden2") << "..ext2" << "ext2";
+ QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "ext2";
+ QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "ext2";
+}
+
+void tst_QFileSystemEntry::suffix()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileSystemEntry fe(file);
+ QCOMPARE(fe.suffix(), expected);
+
+ QFileSystemEntry fi2(file);
+ // first resolve the last slash
+ (void) fi2.path();
+ QCOMPARE(fi2.suffix(), expected);
+}
+
+void tst_QFileSystemEntry::completeSuffix_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("noextension0") << "file" << "";
+ QTest::newRow("noextension1") << "/path/to/file" << "";
+ QTest::newRow("data0") << "file.tar" << "tar";
+ QTest::newRow("data1") << "file.tar.gz" << "tar.gz";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "tar.gz";
+ QTest::newRow("data3") << "/path/file.tar" << "tar";
+ QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << ".ext2";
+ QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "file..ext2";
+}
+
+void tst_QFileSystemEntry::completeSuffix()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileSystemEntry fi(file);
+ QCOMPARE(fi.completeSuffix(), expected);
+
+ QFileSystemEntry fi2(file);
+ // first resolve the last slash
+ (void) fi2.path();
+ QCOMPARE(fi2.completeSuffix(), expected);
+}
+
+void tst_QFileSystemEntry::baseName_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("data0") << "file.tar" << "file";
+ QTest::newRow("data1") << "file.tar.gz" << "file";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "file";
+ QTest::newRow("data3") << "/path/file.tar" << "file";
+ QTest::newRow("data4") << "/path/file" << "file";
+ QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "file";
+ QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "";
+}
+
+void tst_QFileSystemEntry::baseName()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileSystemEntry fi(file);
+ QCOMPARE(fi.baseName(), expected);
+
+ QFileSystemEntry fi2(file);
+ // first resolve the last slash
+ (void) fi2.path();
+ QCOMPARE(fi2.baseName(), expected);
+}
+
+void tst_QFileSystemEntry::completeBaseName_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("data0") << "file.tar" << "file";
+ QTest::newRow("data1") << "file.tar.gz" << "file.tar";
+ QTest::newRow("data2") << "/path/file/file.tar.gz" << "file.tar";
+ QTest::newRow("data3") << "/path/file.tar" << "file";
+ QTest::newRow("data4") << "/path/file" << "file";
+ QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "file.";
+ QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << ".file.";
+}
+
+void tst_QFileSystemEntry::completeBaseName()
+{
+ QFETCH(QString, file);
+ QFETCH(QString, expected);
+
+ QFileSystemEntry fi(file);
+ QCOMPARE(fi.completeBaseName(), expected);
+
+ QFileSystemEntry fi2(file);
+ // first resolve the last slash
+ (void) fi2.path();
+ QCOMPARE(fi2.completeBaseName(), expected);
+}
+
+#if defined(WIN_STUFF)
+void tst_QFileSystemEntry::absoluteOrRelative_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isAbsolute");
+ QTest::addColumn<bool>("isRelative");
+
+ QTest::newRow("data0") << "file.tar" << false << true;
+ QTest::newRow("data1") << "/path/file/file.tar.gz" << false << false;
+ QTest::newRow("data1") << "C:path/file/file.tar.gz" << false << false;
+ QTest::newRow("data3") << "C:/path/file" << true << false;
+ QTest::newRow("data3") << "//machine/share" << true << false;
+}
+
+void tst_QFileSystemEntry::absoluteOrRelative()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isAbsolute);
+ QFETCH(bool, isRelative);
+
+ QFileSystemEntry fi(path);
+ QCOMPARE(fi.isAbsolute(), isAbsolute);
+ QCOMPARE(fi.isRelative(), isRelative);
+}
+#endif
+
+QTEST_MAIN(tst_QFileSystemEntry)
+#include <tst_qfilesystementry.moc>
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/.gitignore b/tests/auto/corelib/io/qfilesystemwatcher/.gitignore
new file mode 100644
index 0000000000..19c6c08e03
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystemwatcher/.gitignore
@@ -0,0 +1 @@
+tst_qfilesystemwatcher
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
new file mode 100644
index 0000000000..d3549b2f05
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+SOURCES += tst_qfilesystemwatcher.cpp
+QT = core
+
+CONFIG += parallel_test
+CONFIG += insignificant_test
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
new file mode 100644
index 0000000000..9d46a8d863
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -0,0 +1,574 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+
+#include <QCoreApplication>
+
+#include <QFileSystemWatcher>
+
+#ifdef Q_OS_LINUX
+# ifdef QT_NO_INOTIFY
+# include <linux/version.h>
+# else
+# include <sys/inotify.h>
+# endif
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QFileSystemWatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QFileSystemWatcher();
+
+private slots:
+ void basicTest_data();
+ void basicTest();
+
+ void watchDirectory_data() { basicTest_data(); }
+ void watchDirectory();
+
+ void addPath();
+ void removePath();
+ void addPaths();
+ void removePaths();
+
+ void watchFileAndItsDirectory_data() { basicTest_data(); }
+ void watchFileAndItsDirectory();
+
+ void nonExistingFile();
+
+ void removeFileAndUnWatch();
+
+ void cleanup();
+
+ void QTBUG15255_deadlock();
+private:
+ QStringList do_force_engines;
+ bool do_force_native;
+};
+
+tst_QFileSystemWatcher::tst_QFileSystemWatcher()
+ : do_force_native(false)
+{
+#ifdef Q_OS_LINUX
+ // the inotify implementation in the kernel is known to be buggy in certain versions of the linux kernel
+ do_force_engines << "native";
+ do_force_engines << "dnotify";
+
+#ifdef QT_NO_INOTIFY
+ if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
+ do_force_engines << "inotify";
+#else
+ if (inotify_init() != -1)
+ do_force_engines << "inotify";
+#endif
+#elif defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_FREEBSD) || defined(Q_OS_SYMBIAN)
+ // we have native engines for win32, macosx and freebsd
+ do_force_engines << "native";
+#endif
+}
+
+void tst_QFileSystemWatcher::basicTest_data()
+{
+ QTest::addColumn<QString>("backend");
+ foreach(QString engine, do_force_engines)
+ QTest::newRow(engine.toLatin1().constData()) << engine;
+ QTest::newRow("poller") << "poller";
+}
+
+void tst_QFileSystemWatcher::basicTest()
+{
+ QFETCH(QString, backend);
+ qDebug() << "Testing" << backend << "engine";
+
+ // create test file
+ QFile testFile("testfile.txt");
+ testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
+ testFile.remove();
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.write(QByteArray("hello"));
+ testFile.close();
+
+ // set some file permissions
+ testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
+
+ // create watcher, forcing it to use a specific backend
+ QFileSystemWatcher watcher;
+ watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
+ watcher.removePath(testFile.fileName());
+ watcher.addPath(testFile.fileName());
+
+ QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
+ QEventLoop eventLoop;
+ QTimer timer;
+ connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+
+ // modify the file, should get a signal from the watcher
+
+ // resolution of the modification time is system dependent, but it's at most 1 second when using
+ // the polling engine. I've heard rumors that FAT32 has a 2 second resolution. So, we have to
+ // wait a bit before we can modify the file (hrmph)...
+#ifndef Q_OS_WINCE
+ QTest::qWait(2000);
+#else
+ // WinCE is always a little bit slower. Give it a little bit more time
+ QTest::qWait(5000);
+#endif
+
+ testFile.open(QIODevice::WriteOnly | QIODevice::Append);
+ testFile.write(QByteArray("world"));
+ testFile.close();
+
+ // qDebug() << "waiting max 5 seconds for notification for file modification to trigger(1)";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 1);
+ QCOMPARE(changedSpy.at(0).count(), 1);
+
+ QString fileName = changedSpy.at(0).at(0).toString();
+ QCOMPARE(fileName, testFile.fileName());
+
+ changedSpy.clear();
+
+ // remove the watch and modify the file, should not get a signal from the watcher
+ watcher.removePath(testFile.fileName());
+ testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ testFile.write(QByteArray("hello universe!"));
+ testFile.close();
+
+ // qDebug() << "waiting max 5 seconds for notification for file modification to trigger (2)";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 0);
+
+ // readd the file watch with a relative path
+ watcher.addPath(testFile.fileName().prepend("./"));
+ testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ testFile.write(QByteArray("hello multiverse!"));
+ testFile.close();
+
+ timer.start(5000);
+ eventLoop.exec();
+
+ QVERIFY(changedSpy.count() > 0);
+
+ watcher.removePath(testFile.fileName().prepend("./"));
+
+ changedSpy.clear();
+
+ // readd the file watch
+ watcher.addPath(testFile.fileName());
+
+ // change the permissions, should get a signal from the watcher
+ testFile.setPermissions(QFile::ReadOwner);
+
+ // qDebug() << "waiting max 5 seconds for notification for file permission modification to trigger(1)";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 1);
+ QCOMPARE(changedSpy.at(0).count(), 1);
+
+ fileName = changedSpy.at(0).at(0).toString();
+ QCOMPARE(fileName, testFile.fileName());
+
+ changedSpy.clear();
+
+ // remove the watch and modify file permissions, should not get a signal from the watcher
+ watcher.removePath(testFile.fileName());
+ testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOther);
+
+ // qDebug() << "waiting max 5 seconds for notification for file modification to trigger (2)";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 0);
+
+ // readd the file watch
+ watcher.addPath(testFile.fileName());
+
+ // remove the file, should get a signal from the watcher
+ QVERIFY(testFile.remove());
+
+ // qDebug() << "waiting max 5 seconds for notification for file removal to trigger";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QVERIFY(changedSpy.count() == 1 || changedSpy.count() == 2); // removing a file on some filesystems seems to deliver 2 notifications
+ QCOMPARE(changedSpy.at(0).count(), 1);
+
+ fileName = changedSpy.at(0).at(0).toString();
+ QCOMPARE(fileName, testFile.fileName());
+
+ changedSpy.clear();
+
+ // recreate the file, we should not get any notification
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.write(QByteArray("hello"));
+ testFile.close();
+
+ // qDebug() << "waiting max 5 seconds for notification for file recreation to trigger";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 0);
+
+ QVERIFY(testFile.remove());
+}
+
+void tst_QFileSystemWatcher::watchDirectory()
+{
+ QFETCH(QString, backend);
+ qDebug() << "Testing" << backend << "engine";
+
+ QDir().mkdir("testDir");
+ QDir testDir("testDir");
+
+ QString testFileName = testDir.filePath("testFile.txt");
+ QFile::remove(testFileName);
+
+ QFileSystemWatcher watcher;
+ watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
+ watcher.addPath(testDir.dirName());
+
+ QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
+ QEventLoop eventLoop;
+ QTimer timer;
+ connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+
+ // resolution of the modification time is system dependent, but it's at most 1 second when using
+ // the polling engine. From what I know, FAT32 has a 2 second resolution. So we have to
+ // wait before modifying the directory...
+ QTest::qWait(2000);
+ QFile testFile(testFileName);
+ QString fileName;
+
+ // remove the watch, should not get notification of a new file
+ watcher.removePath(testDir.dirName());
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.close();
+
+ // qDebug() << "waiting max 5 seconds for notification for file recreationg to trigger";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 0);
+
+ watcher.addPath(testDir.dirName());
+
+ // remove the file again, should get a signal from the watcher
+ QVERIFY(testFile.remove());
+
+ timer.start(5000);
+ eventLoop.exec();
+
+ // remove the directory, should get a signal from the watcher
+ QVERIFY(QDir().rmdir("testDir"));
+
+ // qDebug() << "waiting max 5 seconds for notification for directory removal to trigger";
+ timer.start(5000);
+ eventLoop.exec();
+
+#ifdef Q_OS_WINCE
+ QEXPECT_FAIL("poller", "Directory does not get updated on file removal(See #137910)", Abort);
+#endif
+ QCOMPARE(changedSpy.count(), 2);
+ QCOMPARE(changedSpy.at(0).count(), 1);
+ QCOMPARE(changedSpy.at(1).count(), 1);
+
+ fileName = changedSpy.at(0).at(0).toString();
+ QCOMPARE(fileName, testDir.dirName());
+ fileName = changedSpy.at(1).at(0).toString();
+ QCOMPARE(fileName, testDir.dirName());
+
+ changedSpy.clear();
+
+ // recreate the file, we should not get any notification
+ if (!QDir().mkdir("testDir"))
+ QSKIP("Failed to recreate directory, skipping final test.", SkipSingle);
+
+ // qDebug() << "waiting max 5 seconds for notification for dir recreation to trigger";
+ timer.start(5000);
+ eventLoop.exec();
+
+ QCOMPARE(changedSpy.count(), 0);
+
+ QVERIFY(QDir().rmdir("testDir"));
+}
+
+void tst_QFileSystemWatcher::addPath()
+{
+ QFileSystemWatcher watcher;
+ QString home = QDir::homePath();
+ watcher.addPath(home);
+ QCOMPARE(watcher.directories().count(), 1);
+ QCOMPARE(watcher.directories().first(), home);
+ watcher.addPath(home);
+ QCOMPARE(watcher.directories().count(), 1);
+
+ // With empty string
+ QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::addPath: path is empty");
+ watcher.addPath(QString());
+}
+
+void tst_QFileSystemWatcher::removePath()
+{
+ QFileSystemWatcher watcher;
+ QString home = QDir::homePath();
+ watcher.addPath(home);
+ watcher.removePath(home);
+ QCOMPARE(watcher.directories().count(), 0);
+ watcher.removePath(home);
+ QCOMPARE(watcher.directories().count(), 0);
+
+ // With empty string
+ QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::removePath: path is empty");
+ watcher.removePath(QString());
+}
+
+void tst_QFileSystemWatcher::addPaths()
+{
+ QFileSystemWatcher watcher;
+ QStringList paths;
+ paths << QDir::homePath() << QDir::currentPath();
+ watcher.addPaths(paths);
+ QCOMPARE(watcher.directories().count(), 2);
+
+ // With empty list
+ paths.clear();
+ QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::addPaths: list is empty");
+ watcher.addPaths(paths);
+}
+
+void tst_QFileSystemWatcher::removePaths()
+{
+ QFileSystemWatcher watcher;
+ QStringList paths;
+ paths << QDir::homePath() << QDir::currentPath();
+ watcher.addPaths(paths);
+ QCOMPARE(watcher.directories().count(), 2);
+ watcher.removePaths(paths);
+ QCOMPARE(watcher.directories().count(), 0);
+
+ //With empty list
+ paths.clear();
+ QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::removePaths: list is empty");
+ watcher.removePaths(paths);
+}
+
+#if 0
+class SignalTest : public QObject {
+ Q_OBJECT
+ public slots:
+ void fileSlot(const QString &file) { qDebug() << "file " << file;}
+ void dirSlot(const QString &dir) { qDebug() << "dir" << dir;}
+};
+#endif
+
+void tst_QFileSystemWatcher::watchFileAndItsDirectory()
+{
+ QFETCH(QString, backend);
+ QDir().mkdir("testDir");
+ QDir testDir("testDir");
+
+ QString testFileName = testDir.filePath("testFile.txt");
+ QString secondFileName = testDir.filePath("testFile2.txt");
+ QFile::remove(secondFileName);
+
+ QFile testFile(testFileName);
+ testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
+ testFile.remove();
+
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.write(QByteArray("hello"));
+ testFile.close();
+
+ QFileSystemWatcher watcher;
+ watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
+
+ watcher.addPath(testDir.dirName());
+ watcher.addPath(testFileName);
+
+ /*
+ SignalTest signalTest;
+ QObject::connect(&watcher, SIGNAL(fileChanged(const QString &)), &signalTest, SLOT(fileSlot(const QString &)));
+ QObject::connect(&watcher, SIGNAL(directoryChanged(const QString &)), &signalTest, SLOT(dirSlot(const QString &)));
+ */
+
+ QSignalSpy fileChangedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
+ QSignalSpy dirChangedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
+ QEventLoop eventLoop;
+ QTimer timer;
+ connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+
+ // resolution of the modification time is system dependent, but it's at most 1 second when using
+ // the polling engine. From what I know, FAT32 has a 2 second resolution. So we have to
+ // wait before modifying the directory...
+ QTest::qWait(2000);
+
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
+ testFile.write(QByteArray("hello again"));
+ testFile.close();
+
+ timer.start(3000);
+ eventLoop.exec();
+ QVERIFY(fileChangedSpy.count() > 0);
+ //according to Qt 4 documentation:
+ //void QFileSystemWatcher::directoryChanged ( const QString & path ) [signal]
+ //This signal is emitted when the directory at a specified path, is modified
+ //(e.g., when a file is added, -->modified<-- or deleted) or removed from disk.
+ //Note that if there are several changes during a short period of time, some
+ //of the changes might not emit this signal. However, the last change in the
+ //sequence of changes will always generate this signal.
+ //Symbian behaves as documented (and can't be filtered), but the other platforms don't
+ //so test should not assert this
+ QVERIFY(dirChangedSpy.count() < 2);
+
+ if (backend == "dnotify")
+ QSKIP("dnotify is broken, skipping the rest of the test.", SkipSingle);
+
+ fileChangedSpy.clear();
+ dirChangedSpy.clear();
+ QFile secondFile(secondFileName);
+ secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ secondFile.write("Foo");
+ secondFile.close();
+
+ timer.start(3000);
+ eventLoop.exec();
+ QCOMPARE(fileChangedSpy.count(), 0);
+#ifdef Q_OS_WINCE
+ QEXPECT_FAIL("poller", "Directory does not get updated on file removal(See #137910)", Abort);
+#endif
+ QCOMPARE(dirChangedSpy.count(), 1);
+
+ dirChangedSpy.clear();
+
+ QFile::remove(testFileName);
+
+ timer.start(3000);
+ eventLoop.exec();
+ QVERIFY(fileChangedSpy.count() > 0);
+ QCOMPARE(dirChangedSpy.count(), 1);
+
+ fileChangedSpy.clear();
+ dirChangedSpy.clear();
+
+ watcher.removePath(testFileName);
+ QFile::remove(secondFileName);
+
+ timer.start(3000);
+ eventLoop.exec();
+ QCOMPARE(fileChangedSpy.count(), 0);
+ // polling watcher has generated separate events for content and time change
+ // on Symbian emulator, so allow possibility of 2 events
+ QVERIFY(dirChangedSpy.count() == 1 || dirChangedSpy.count() == 2);
+
+ QVERIFY(QDir().rmdir("testDir"));
+}
+
+void tst_QFileSystemWatcher::cleanup()
+{
+ QDir testDir("testDir");
+ QString testFileName = testDir.filePath("testFile.txt");
+ QString secondFileName = testDir.filePath("testFile2.txt");
+ QFile::remove(testFileName);
+ QFile::remove(secondFileName);
+ QDir().rmdir("testDir");
+}
+
+void tst_QFileSystemWatcher::nonExistingFile()
+{
+ // Don't crash...
+ QFileSystemWatcher watcher;
+ watcher.addPath("file_that_does_not_exist.txt");
+ QVERIFY(true);
+}
+
+void tst_QFileSystemWatcher::removeFileAndUnWatch()
+{
+ static const char * const filename = "foo.txt";
+ QFileSystemWatcher watcher;
+
+ {
+ QFile testFile(filename);
+ testFile.open(QIODevice::WriteOnly);
+ testFile.close();
+ }
+ watcher.addPath(filename);
+
+ QFile::remove(filename);
+ watcher.removePath(filename);
+
+ {
+ QFile testFile(filename);
+ testFile.open(QIODevice::WriteOnly);
+ testFile.close();
+ }
+ watcher.addPath(filename);
+}
+
+class SomeSingleton : public QObject
+{
+public:
+ SomeSingleton() : mFsWatcher(new QFileSystemWatcher(this)) { mFsWatcher->addPath(QLatin1String("/usr/lib"));}
+ void bla() const {}
+ QFileSystemWatcher* mFsWatcher;
+};
+
+Q_GLOBAL_STATIC(SomeSingleton, someSingleton)
+
+void tst_QFileSystemWatcher::QTBUG15255_deadlock()
+{
+ someSingleton()->bla();
+ //the test must still finish
+ QTest::qWait(30);
+}
+
+
+QTEST_MAIN(tst_QFileSystemWatcher)
+#include "tst_qfilesystemwatcher.moc"
diff --git a/tests/auto/corelib/io/qiodevice/.gitignore b/tests/auto/corelib/io/qiodevice/.gitignore
new file mode 100644
index 0000000000..e503843519
--- /dev/null
+++ b/tests/auto/corelib/io/qiodevice/.gitignore
@@ -0,0 +1,2 @@
+tst_qiodevice
+peektestfile
diff --git a/tests/auto/corelib/io/qiodevice/qiodevice.pro b/tests/auto/corelib/io/qiodevice/qiodevice.pro
new file mode 100644
index 0000000000..08996e8cd4
--- /dev/null
+++ b/tests/auto/corelib/io/qiodevice/qiodevice.pro
@@ -0,0 +1,23 @@
+load(qttest_p4)
+SOURCES += tst_qiodevice.cpp
+
+QT = core network
+
+wince*: {
+ addFiles.files = tst_qiodevice.cpp
+ addFiles.path = .
+ DEPLOYMENT += addFiles
+ DEFINES += SRCDIR=\\\"\\\"
+ !wince50standard-x86-msvc2005: DEFINES += WINCE_EMULATOR_TEST=1
+} else:symbian {
+ # SRCDIR defined in code in symbian
+ addFiles.files = tst_qiodevice.cpp
+ addFiles.path = .
+ DEPLOYMENT += addFiles
+ TARGET.CAPABILITY = NetworkServices
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+MOC_DIR=tmp
+
+
diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
new file mode 100644
index 0000000000..425b3b6bd1
--- /dev/null
+++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
@@ -0,0 +1,611 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore/QtCore>
+#include <QtNetwork/QtNetwork>
+#include <QtTest/QtTest>
+
+#include "../../../network-settings.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#ifdef Q_OS_SYMBIAN
+#define SRCDIR ""
+#endif
+
+class tst_QIODevice : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QIODevice();
+ virtual ~tst_QIODevice();
+
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void getSetCheck();
+ void constructing_QTcpSocket();
+ void constructing_QFile();
+ void read_QByteArray();
+ void unget();
+ void peek();
+ void peekAndRead();
+
+ void readLine_data();
+ void readLine();
+
+ void readLine2_data();
+ void readLine2();
+
+ void peekBug();
+};
+
+// Testing get/set functions
+void tst_QIODevice::getSetCheck()
+{
+ // OpenMode QIODevice::openMode()
+ // void QIODevice::setOpenMode(OpenMode)
+ class MyIODevice : public QIODevice {
+ public:
+ void setOpenMode(OpenMode openMode) { QIODevice::setOpenMode(openMode); }
+ };
+ QTcpSocket var1;
+ MyIODevice *obj1 = reinterpret_cast<MyIODevice*>(&var1);
+ obj1->setOpenMode(QIODevice::OpenMode(QIODevice::NotOpen));
+ QCOMPARE(QIODevice::OpenMode(QIODevice::NotOpen), obj1->openMode());
+ obj1->setOpenMode(QIODevice::OpenMode(QIODevice::ReadWrite));
+ QCOMPARE(QIODevice::OpenMode(QIODevice::ReadWrite), obj1->openMode());
+}
+
+tst_QIODevice::tst_QIODevice()
+{
+ Q_SET_DEFAULT_IAP
+}
+
+tst_QIODevice::~tst_QIODevice()
+{
+}
+
+void tst_QIODevice::init()
+{
+}
+
+void tst_QIODevice::cleanup()
+{
+}
+
+//----------------------------------------------------------------------------------
+void tst_QIODevice::constructing_QTcpSocket()
+{
+#if defined(Q_OS_WINCE) && defined(WINCE_EMULATOR_TEST)
+ QSKIP("Networking tests in a WinCE emulator are unstable", SkipAll);
+#endif
+ QTcpSocket socket;
+ QIODevice *device = &socket;
+
+ QVERIFY(!device->isOpen());
+
+ socket.connectToHost(QtNetworkSettings::serverName(), 143);
+ QVERIFY(socket.waitForConnected(30000));
+ QVERIFY(device->isOpen());
+
+ while (!device->canReadLine())
+ QVERIFY(device->waitForReadyRead(30000));
+
+ char buf[1024];
+ memset(buf, 0, sizeof(buf));
+ qlonglong lineLength = device->readLine(buf, sizeof(buf));
+ QVERIFY(lineLength > 0);
+ QCOMPARE(socket.pos(), qlonglong(0));
+
+ socket.close();
+ socket.connectToHost(QtNetworkSettings::serverName(), 143);
+ QVERIFY(socket.waitForConnected(30000));
+ QVERIFY(device->isOpen());
+
+ while (!device->canReadLine())
+ QVERIFY(device->waitForReadyRead(30000));
+
+ char buf2[1024];
+ memset(buf2, 0, sizeof(buf2));
+ QCOMPARE(socket.readLine(buf2, sizeof(buf2)), lineLength);
+
+ char *c1 = buf;
+ char *c2 = buf2;
+ while (*c1 && *c2) {
+ QCOMPARE(*c1, *c2);
+ ++c1;
+ ++c2;
+ }
+ QCOMPARE(*c1, *c2);
+}
+
+//----------------------------------------------------------------------------------
+void tst_QIODevice::constructing_QFile()
+{
+ QFile file;
+ QIODevice *device = &file;
+
+ QVERIFY(!device->isOpen());
+
+ file.setFileName(SRCDIR "tst_qiodevice.cpp");
+ QVERIFY(file.open(QFile::ReadOnly));
+ QVERIFY(device->isOpen());
+ QCOMPARE((int) device->openMode(), (int) QFile::ReadOnly);
+
+ char buf[1024];
+ memset(buf, 0, sizeof(buf));
+ qlonglong lineLength = device->readLine(buf, sizeof(buf));
+ QVERIFY(lineLength > 0);
+ QCOMPARE(file.pos(), lineLength);
+
+ file.seek(0);
+ char buf2[1024];
+ memset(buf2, 0, sizeof(buf2));
+ QCOMPARE(file.readLine(buf2, sizeof(buf2)), lineLength);
+
+ char *c1 = buf;
+ char *c2 = buf2;
+ while (*c1 && *c2) {
+ QCOMPARE(*c1, *c2);
+ ++c1;
+ ++c2;
+ }
+ QCOMPARE(*c1, *c2);
+}
+
+
+void tst_QIODevice::read_QByteArray()
+{
+ QFile f(SRCDIR "tst_qiodevice.cpp");
+ f.open(QIODevice::ReadOnly);
+
+ QByteArray b = f.read(10);
+ QCOMPARE(b.length(), 10);
+
+ b = f.read(256);
+ QCOMPARE(b.length(), 256);
+
+ b = f.read(0);
+ QCOMPARE(b.length(), 0);
+}
+
+//--------------------------------------------------------------------
+void tst_QIODevice::unget()
+{
+#if defined(Q_OS_WINCE) && defined(WINCE_EMULATOR_TEST)
+ QSKIP("Networking tests in a WinCE emulator are unstable", SkipAll);
+#endif
+ QBuffer buffer;
+ buffer.open(QBuffer::ReadWrite);
+ buffer.write("ZXCV");
+ buffer.seek(0);
+ QCOMPARE(buffer.read(4), QByteArray("ZXCV"));
+ QCOMPARE(buffer.pos(), qint64(4));
+
+ buffer.ungetChar('a');
+ buffer.ungetChar('b');
+ buffer.ungetChar('c');
+ buffer.ungetChar('d');
+
+ QCOMPARE(buffer.pos(), qint64(0));
+
+ char buf[6];
+ QCOMPARE(buffer.readLine(buf, 5), qint64(4));
+ QCOMPARE(buffer.pos(), qint64(4));
+ QCOMPARE(static_cast<const char*>(buf), "dcba");
+
+ buffer.ungetChar('a');
+ buffer.ungetChar('b');
+ buffer.ungetChar('c');
+ buffer.ungetChar('d');
+
+ QCOMPARE(buffer.pos(), qint64(0));
+
+ for (int i = 0; i < 5; ++i) {
+ buf[0] = '@';
+ buf[1] = '@';
+ QTest::ignoreMessage(QtWarningMsg,
+ "QIODevice::readLine: Called with maxSize < 2");
+ QCOMPARE(buffer.readLine(buf, 1), qint64(-1));
+ QCOMPARE(buffer.readLine(buf, 2), qint64(i < 4 ? 1 : -1));
+ switch (i) {
+ case 0: QCOMPARE(buf[0], 'd'); break;
+ case 1: QCOMPARE(buf[0], 'c'); break;
+ case 2: QCOMPARE(buf[0], 'b'); break;
+ case 3: QCOMPARE(buf[0], 'a'); break;
+ case 4: QCOMPARE(buf[0], '\0'); break;
+ }
+ QCOMPARE(buf[1], i < 4 ? '\0' : '@');
+ }
+
+ buffer.ungetChar('\n');
+ QCOMPARE(buffer.readLine(), QByteArray("\n"));
+
+ buffer.seek(1);
+ buffer.readLine(buf, 3);
+ QCOMPARE(static_cast<const char*>(buf), "XC");
+
+ buffer.seek(4);
+ buffer.ungetChar('Q');
+ QCOMPARE(buffer.readLine(buf, 3), qint64(1));
+
+ for (int i = 0; i < 2; ++i) {
+ QTcpSocket socket;
+ QIODevice *dev;
+ QByteArray result;
+ const char *lineResult;
+ if (i == 0) {
+ dev = &buffer;
+ result = QByteArray("ZXCV");
+ lineResult = "ZXCV";
+ } else {
+ socket.connectToHost(QtNetworkSettings::serverName(), 80);
+ socket.write("GET / HTTP/1.0\r\n\r\n");
+ QVERIFY(socket.waitForReadyRead());
+ dev = &socket;
+ result = QByteArray("HTTP");
+ lineResult = "Date";
+ }
+ char ch, ch2;
+ dev->seek(0);
+ dev->getChar(&ch);
+ dev->ungetChar(ch);
+ QCOMPARE(dev->peek(4), result);
+ dev->getChar(&ch);
+ dev->getChar(&ch2);
+ dev->ungetChar(ch2);
+ dev->ungetChar(ch);
+ QCOMPARE(dev->read(1), result.left(1));
+ QCOMPARE(dev->read(3), result.right(3));
+
+ if (i == 0)
+ dev->seek(0);
+ else
+ dev->readLine();
+ dev->getChar(&ch);
+ dev->ungetChar(ch);
+ dev->readLine(buf, 5);
+ QCOMPARE(static_cast<const char*>(buf), lineResult);
+
+ if (i == 1)
+ socket.close();
+ }
+}
+
+//--------------------------------------------------------------------
+void tst_QIODevice::peek()
+{
+ QBuffer buffer;
+ QFile::remove("peektestfile");
+ QFile file("peektestfile");
+
+ for (int i = 0; i < 2; ++i) {
+ QIODevice *device = i ? (QIODevice *)&file : (QIODevice *)&buffer;
+
+ device->open(QBuffer::ReadWrite);
+ device->write("ZXCV");
+
+ device->seek(0);
+ QCOMPARE(device->peek(4), QByteArray("ZXCV"));
+ QCOMPARE(device->pos(), qint64(0));
+ device->write("ABCDE");
+ device->seek(3);
+ QCOMPARE(device->peek(1), QByteArray("D"));
+ QCOMPARE(device->peek(5), QByteArray("DE"));
+ device->seek(0);
+ QCOMPARE(device->read(4), QByteArray("ABCD"));
+ QCOMPARE(device->pos(), qint64(4));
+
+ device->seek(0);
+ device->write("ZXCV");
+ device->seek(0);
+ char buf[5];
+ buf[4] = 0;
+ device->peek(buf, 4);
+ QCOMPARE(static_cast<const char *>(buf), "ZXCV");
+ QCOMPARE(device->pos(), qint64(0));
+ device->read(buf, 4);
+ QCOMPARE(static_cast<const char *>(buf), "ZXCV");
+ QCOMPARE(device->pos(), qint64(4));
+ }
+ QFile::remove("peektestfile");
+}
+
+void tst_QIODevice::peekAndRead()
+{
+ QByteArray originalData;
+ for (int i=0;i<1000;i++)
+ originalData += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QBuffer buffer;
+ QFile::remove("peektestfile");
+ QFile file("peektestfile");
+
+ for (int i = 0; i < 2; ++i) {
+ QByteArray readData;
+ QIODevice *device = i ? (QIODevice *)&file : (QIODevice *)&buffer;
+ device->open(QBuffer::ReadWrite);
+ device->write(originalData);
+ device->seek(0);
+ while (!device->atEnd()) {
+ char peekIn[26];
+ device->peek(peekIn, 26);
+ readData += device->read(26);
+ }
+ QCOMPARE(readData, originalData);
+ }
+ QFile::remove("peektestfile");
+}
+
+void tst_QIODevice::readLine_data()
+{
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << QByteArray("\nAA");
+ QTest::newRow("1") << QByteArray("A\nAA");
+
+ QByteArray data(9000, 'A');
+ data[8193] = '\n';
+ QTest::newRow("8194") << data;
+ data[8193] = 'A';
+ data[8192] = '\n';
+ QTest::newRow("8193") << data;
+ data[8192] = 'A';
+ data[8191] = '\n';
+ QTest::newRow("8192") << data;
+ data[8191] = 'A';
+ data[8190] = '\n';
+ QTest::newRow("8191") << data;
+
+ data[5999] = '\n';
+ QTest::newRow("6000") << data;
+
+ data[4095] = '\n';
+ QTest::newRow("4096") << data;
+
+ data[4094] = '\n';
+ data[4095] = 'A';
+ QTest::newRow("4095") << data;
+}
+
+void tst_QIODevice::readLine()
+{
+ QFETCH(QByteArray, data);
+ QBuffer buffer(&data);
+ QVERIFY(buffer.open(QIODevice::ReadWrite));
+ QVERIFY(buffer.canReadLine());
+
+ int linelen = data.indexOf('\n') + 1;
+ QByteArray line;
+ line.reserve(linelen + 100);
+
+ int result = buffer.readLine(line.data(), linelen + 100);
+ QCOMPARE(result, linelen);
+
+ // try the exact length of the line (plus terminating \0)
+ QVERIFY(buffer.seek(0));
+ result = buffer.readLine(line.data(), linelen + 1);
+ QCOMPARE(result, linelen);
+
+ // try with a line length limit
+ QVERIFY(buffer.seek(0));
+ line = buffer.readLine(linelen + 100);
+ QCOMPARE(line.size(), linelen);
+
+ // try without a length limit
+ QVERIFY(buffer.seek(0));
+ line = buffer.readLine();
+ QCOMPARE(line.size(), linelen);
+}
+
+void tst_QIODevice::readLine2_data()
+{
+ QTest::addColumn<QByteArray>("line");
+
+ QTest::newRow("1024 - 4") << QByteArray(1024 - 4, 'x');
+ QTest::newRow("1024 - 3") << QByteArray(1024 - 3, 'x');
+ QTest::newRow("1024 - 2") << QByteArray(1024 - 2, 'x');
+ QTest::newRow("1024 - 1") << QByteArray(1024 - 1, 'x');
+ QTest::newRow("1024" ) << QByteArray(1024 , 'x');
+ QTest::newRow("1024 + 1") << QByteArray(1024 + 1, 'x');
+ QTest::newRow("1024 + 2") << QByteArray(1024 + 2, 'x');
+
+ QTest::newRow("4096 - 4") << QByteArray(4096 - 4, 'x');
+ QTest::newRow("4096 - 3") << QByteArray(4096 - 3, 'x');
+ QTest::newRow("4096 - 2") << QByteArray(4096 - 2, 'x');
+ QTest::newRow("4096 - 1") << QByteArray(4096 - 1, 'x');
+ QTest::newRow("4096" ) << QByteArray(4096 , 'x');
+ QTest::newRow("4096 + 1") << QByteArray(4096 + 1, 'x');
+ QTest::newRow("4096 + 2") << QByteArray(4096 + 2, 'x');
+
+ QTest::newRow("8192 - 4") << QByteArray(8192 - 4, 'x');
+ QTest::newRow("8192 - 3") << QByteArray(8192 - 3, 'x');
+ QTest::newRow("8192 - 2") << QByteArray(8192 - 2, 'x');
+ QTest::newRow("8192 - 1") << QByteArray(8192 - 1, 'x');
+ QTest::newRow("8192" ) << QByteArray(8192 , 'x');
+ QTest::newRow("8192 + 1") << QByteArray(8192 + 1, 'x');
+ QTest::newRow("8192 + 2") << QByteArray(8192 + 2, 'x');
+
+ QTest::newRow("16384 - 4") << QByteArray(16384 - 4, 'x');
+ QTest::newRow("16384 - 3") << QByteArray(16384 - 3, 'x');
+ QTest::newRow("16384 - 2") << QByteArray(16384 - 2, 'x');
+ QTest::newRow("16384 - 1") << QByteArray(16384 - 1, 'x');
+ QTest::newRow("16384" ) << QByteArray(16384 , 'x');
+ QTest::newRow("16384 + 1") << QByteArray(16384 + 1, 'x');
+ QTest::newRow("16384 + 2") << QByteArray(16384 + 2, 'x');
+
+ QTest::newRow("20000") << QByteArray(20000, 'x');
+
+ QTest::newRow("32768 - 4") << QByteArray(32768 - 4, 'x');
+ QTest::newRow("32768 - 3") << QByteArray(32768 - 3, 'x');
+ QTest::newRow("32768 - 2") << QByteArray(32768 - 2, 'x');
+ QTest::newRow("32768 - 1") << QByteArray(32768 - 1, 'x');
+ QTest::newRow("32768" ) << QByteArray(32768 , 'x');
+ QTest::newRow("32768 + 1") << QByteArray(32768 + 1, 'x');
+ QTest::newRow("32768 + 2") << QByteArray(32768 + 2, 'x');
+
+ QTest::newRow("40000") << QByteArray(40000, 'x');
+}
+
+void tst_QIODevice::readLine2()
+{
+ QFETCH(QByteArray, line);
+
+ int length = line.size();
+
+ QByteArray data("First line.\r\n");
+ data.append(line);
+ data.append("\r\n");
+ data.append(line);
+ data.append("\r\n");
+ data.append("\r\n0123456789");
+
+ {
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+
+ buffer.seek(0);
+ QByteArray temp;
+ temp.resize(64536);
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(13));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 2));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 2));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(2));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(10));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(-1));
+
+ buffer.seek(0);
+ QCOMPARE(buffer.readLine().size(), 13);
+ QCOMPARE(buffer.readLine().size(), length + 2);
+ QCOMPARE(buffer.readLine().size(), length + 2);
+ QCOMPARE(buffer.readLine().size(), 2);
+ QCOMPARE(buffer.readLine().size(), 10);
+ QVERIFY(buffer.readLine().isNull());
+ }
+
+ {
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly | QIODevice::Text);
+
+ buffer.seek(0);
+ QByteArray temp;
+ temp.resize(64536);
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(12));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 1));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 1));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(1));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(10));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(-1));
+
+ buffer.seek(0);
+ QCOMPARE(buffer.readLine().size(), 12);
+ QCOMPARE(buffer.readLine().size(), length + 1);
+ QCOMPARE(buffer.readLine().size(), length + 1);
+ QCOMPARE(buffer.readLine().size(), 1);
+ QCOMPARE(buffer.readLine().size(), 10);
+ QVERIFY(buffer.readLine().isNull());
+ }
+}
+
+
+class PeekBug : public QIODevice {
+ Q_OBJECT
+public:
+ char alphabet[27];
+ qint64 counter;
+ PeekBug() : QIODevice(), counter(0) {
+ memcpy(alphabet,"abcdefghijklmnopqrstuvqxyz",27);
+ };
+ qint64 readData(char *data, qint64 maxlen) {
+ qint64 pos = 0;
+ while (pos < maxlen) {
+ *(data + pos) = alphabet[counter];
+ pos++;
+ counter++;
+ if (counter == 26)
+ counter = 0;
+ }
+ return maxlen;
+ }
+ qint64 writeData(const char * /* data */, qint64 /* maxlen */) {
+ return -1;
+ }
+
+};
+
+// This is a testcase for the bug fixed with bd287865
+void tst_QIODevice::peekBug()
+{
+ PeekBug peekBug;
+ peekBug.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+
+ char onetwo[2];
+ peekBug.peek(onetwo, 2);
+ QCOMPARE(onetwo[0], 'a');
+ QCOMPARE(onetwo[1], 'b');
+
+ peekBug.read(onetwo, 1);
+ QCOMPARE(onetwo[0], 'a');
+
+ peekBug.peek(onetwo, 2);
+ QCOMPARE(onetwo[0], 'b');
+ QCOMPARE(onetwo[1], 'c');
+
+ peekBug.read(onetwo, 1);
+ QCOMPARE(onetwo[0], 'b');
+ peekBug.read(onetwo, 1);
+ QCOMPARE(onetwo[0], 'c');
+ peekBug.read(onetwo, 1);
+ QCOMPARE(onetwo[0], 'd');
+
+ peekBug.peek(onetwo, 2);
+ QCOMPARE(onetwo[0], 'e');
+ QCOMPARE(onetwo[1], 'f');
+
+}
+
+QTEST_MAIN(tst_QIODevice)
+#include "tst_qiodevice.moc"
diff --git a/tests/auto/corelib/io/qprocess/.gitignore b/tests/auto/corelib/io/qprocess/.gitignore
new file mode 100644
index 0000000000..a273810042
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/.gitignore
@@ -0,0 +1,22 @@
+tst_qprocess
+fileWriterProcess/fileWriterProcess
+test Space In Name/
+testDetached/testDetached
+testExitCodes/testExitCodes
+testGuiProcess/testGuiProcess
+testProcessCrash/testProcessCrash
+testProcessDeadWhileReading/testProcessDeadWhileReading
+testProcessEOF/testProcessEOF
+testProcessEcho/testProcessEcho
+testProcessEcho2/testProcessEcho2
+testProcessEcho3/testProcessEcho3
+testProcessEnvironment/testProcessEnvironment
+testProcessLoopback/testProcessLoopback
+testProcessNormal/testProcessNormal
+testProcessOutput/testProcessOutput
+testProcessSpacesArgs/nospace
+testProcessSpacesArgs/one space
+testProcessSpacesArgs/two space s
+testSetWorkingDirectory/testSetWorkingDirectory
+testSoftExit/testSoftExit
+data
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro b/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro
new file mode 100644
index 0000000000..c9f87ba361
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+CONFIG += console
+CONFIG -= app_bundle
+QT = core
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
new file mode 100644
index 0000000000..40e92c69be
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication ca(argc, argv);
+ QFile f;
+ f.open(stdin, QIODevice::ReadOnly);
+ QString input;
+ char buf[1024];
+ qint64 len;
+ while ((len = f.read(buf, 1024)) > 0)
+ input += QByteArray(buf, len);
+ f.close();
+ QFile f2("fileWriterProcess.txt");
+ f2.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ f2.write(input.toLatin1());
+ f2.close();
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/qprocess.pro b/tests/auto/corelib/io/qprocess/qprocess.pro
new file mode 100644
index 0000000000..77cfc8252e
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/qprocess.pro
@@ -0,0 +1,32 @@
+TEMPLATE = subdirs
+
+SUBDIRS = \
+ testProcessCrash \
+ testProcessEcho \
+ testProcessEcho2 \
+ testProcessEcho3 \
+ testProcessEnvironment \
+ testProcessLoopback \
+ testProcessNormal \
+ testProcessOutput \
+ testProcessDeadWhileReading \
+ testProcessEOF \
+ testProcessSpacesArgs/nospace.pro \
+ testExitCodes \
+ testSpaceInName \
+ testGuiProcess \
+ testDetached \
+ fileWriterProcess \
+ testSetWorkingDirectory
+
+!symbian: {
+SUBDIRS +=testProcessSpacesArgs/onespace.pro \
+ testProcessSpacesArgs/twospaces.pro \
+ testSoftExit
+}
+
+win32:!wince*:SUBDIRS+=testProcessEchoGui
+
+SUBDIRS += test
+
+
diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro
new file mode 100644
index 0000000000..a91caddd2f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/test/test.pro
@@ -0,0 +1,124 @@
+load(qttest_p4)
+
+SOURCES += ../tst_qprocess.cpp
+!wince*: {
+TARGET = ../tst_qprocess
+
+win32: {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qprocess
+} else {
+ TARGET = ../../release/tst_qprocess
+ }
+}
+} else {
+ TARGET = tst_qprocess
+}
+
+
+
+QT = core
+
+!symbian: {
+ QT += network
+}
+
+embedded: QT += gui
+
+wince*: {
+
+ addFile_fileWriterProcess.files = $$OUT_PWD/../fileWriterProcess/fileWriterProcess.exe
+ addFile_fileWriterProcess.path = fileWriterProcess
+
+ addFile_testBatFiles.files = $$PWD/../testBatFiles/*
+ addFile_testBatFiles.path = testBatFiles
+
+ addFile_testDetached.files = $$OUT_PWD/../testDetached/testDetached.exe
+ addFile_testDetached.path = testDetached
+
+ addFile_testExitCodes.files = $$OUT_PWD/../testExitCodes/testExitCodes.exe
+ addFile_testExitCodes.path = testExitCodes
+
+ addFile_testGuiProcess.files = $$OUT_PWD/../testGuiProcess/testGuiProcess.exe
+ addFile_testGuiProcess.path = testGuiProcess
+
+ addFile_testProcessCrash.files = $$OUT_PWD/../testProcessCrash/testProcessCrash.exe
+ addFile_testProcessCrash.path = testProcessCrash
+
+ addFile_testProcessDeadWhileReading.files = $$OUT_PWD/../testProcessDeadWhileReading/testProcessDeadWhileReading.exe
+ addFile_testProcessDeadWhileReading.path = testProcessDeadWhileReading
+
+ addFile_testProcessEcho.files = $$OUT_PWD/../testProcessEcho/testProcessEcho.exe
+ addFile_testProcessEcho.path = testProcessEcho
+
+ addFile_testProcessEcho2.files = $$OUT_PWD/../testProcessEcho2/testProcessEcho2.exe
+ addFile_testProcessEcho2.path = testProcessEcho2
+
+ addFile_testProcessEcho3.files = $$OUT_PWD/../testProcessEcho3/testProcessEcho3.exe
+ addFile_testProcessEcho3.path = testProcessEcho3
+
+ addFile_testProcessEOF.files = $$OUT_PWD/../testProcessEOF/testProcessEOF.exe
+ addFile_testProcessEOF.path = testProcessEOF
+
+ addFile_testProcessLoopback.files = $$OUT_PWD/../testProcessLoopback/testProcessLoopback.exe
+ addFile_testProcessLoopback.path = testProcessLoopback
+
+ addFile_testProcessNormal.files = $$OUT_PWD/../testProcessNormal/testProcessNormal.exe
+ addFile_testProcessNormal.path = testProcessNormal
+
+ addFile_testProcessOutput.files = $$OUT_PWD/../testProcessOutput/testProcessOutput.exe
+ addFile_testProcessOutput.path = testProcessOutput
+
+ addFile_testProcessNoSpacesArgs.files = $$OUT_PWD/../testProcessSpacesArgs/nospace.exe
+ addFile_testProcessNoSpacesArgs.path = testProcessSpacesArgs
+
+ addFile_testProcessOneSpacesArgs.files = $$OUT_PWD/../testProcessSpacesArgs/"one space".exe
+ addFile_testProcessOneSpacesArgs.path = testProcessSpacesArgs
+
+ addFile_testProcessTwoSpacesArgs.files = $$OUT_PWD/../testProcessSpacesArgs/"two space s".exe
+ addFile_testProcessTwoSpacesArgs.path = testProcessSpacesArgs
+
+ addFile_testSoftExit.files = $$OUT_PWD/../testSoftExit/testSoftExit.exe
+ addFile_testSoftExit.path = testSoftExit
+
+ addFile_testSpaceInName.files = $$OUT_PWD/../"test Space In Name"/testSpaceInName.exe
+ addFile_testSpaceInName.path = "test Space In Name"
+
+
+ DEPLOYMENT += addFile_fileWriterProcess \
+ addFile_testBatFiles \
+ addFile_testDetached \
+ addFile_testExitCodes \
+ addFile_testGuiProcess \
+ addFile_testProcessCrash \
+ addFile_testProcessDeadWhileReading \
+ addFile_testProcessEcho \
+ addFile_testProcessEcho2 \
+ addFile_testProcessEcho3 \
+ addFile_testProcessEchoGui \
+ addFile_testProcessEOF \
+ addFile_testProcessLoopback \
+ addFile_testProcessNormal \
+ addFile_testProcessOutput \
+ addFile_testProcessNoSpacesArgs \
+ addFile_testProcessOneSpacesArgs \
+ addFile_testProcessTwoSpacesArgs \
+ addFile_testSoftExit \
+ addFile_testSpaceInName
+}
+
+symbian: {
+ binDep.files = \
+ fileWriterProcess.exe \
+ testDetached.exe \
+ testExitCodes.exe \
+ testProcessCrash.exe \
+ testProcessEcho.exe \
+ testProcessNormal.exe \
+ testProcessOutput.exe \
+ nospace.exe \
+ testSpaceInName.exe
+ binDep.path = \\sys\\bin
+
+ DEPLOYMENT += binDep
+}
diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat
new file mode 100755
index 0000000000..900f7ae356
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat
@@ -0,0 +1,2 @@
+@echo off
+echo Hello \ No newline at end of file
diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat
new file mode 100755
index 0000000000..900f7ae356
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat
@@ -0,0 +1,2 @@
+@echo off
+echo Hello \ No newline at end of file
diff --git a/tests/auto/corelib/io/qprocess/testDetached/main.cpp b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
new file mode 100644
index 0000000000..5b4ee790b9
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QCoreApplication>
+#include <QDebug>
+#include <QStringList>
+#include <QFile>
+#include <QDir>
+
+#include <stdio.h>
+
+#if defined(Q_OS_UNIX)
+#include <sys/types.h>
+#include <unistd.h>
+#elif defined(Q_OS_WIN)
+#include <windows.h>
+#endif
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QStringList args = app.arguments();
+ if (args.count() != 2) {
+ fprintf(stderr, "Usage: testDetached filename.txt\n");
+ return 128;
+ }
+
+ QFile f(args.at(1));
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
+ fprintf(stderr, "Cannot open %s for writing", qPrintable(f.fileName()));
+ return 1;
+ }
+
+ f.write(QDir::currentPath().toUtf8());
+ f.putChar('\n');
+#if defined(Q_OS_UNIX)
+ f.write(QByteArray::number(quint64(getpid())));
+#elif defined(Q_OS_WIN)
+ f.write(QByteArray::number(quint64(GetCurrentProcessId())));
+#endif
+ f.putChar('\n');
+
+ f.close();
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro b/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro
new file mode 100644
index 0000000000..80a616b3e9
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+INSTALLS =
+DESTDIR = ./
+
+symbian: {
+TARGET.EPOCSTACKSIZE =0x14000
+}
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp b/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
new file mode 100644
index 0000000000..4d6a49e8f5
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdlib.h>
+int main(int /* argc */, char **argv)
+{
+ return atoi(argv[1]);
+}
+
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro b/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro
new file mode 100644
index 0000000000..b08371804f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro
@@ -0,0 +1,5 @@
+SOURCES += main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+
+DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp b/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
new file mode 100644
index 0000000000..90d4d4a962
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtWidgets/QApplication>
+#include <QtWidgets/QLabel>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QLabel label("This process is just waiting to die");
+ label.show();
+
+ int c;
+ Q_UNUSED(c);
+ fgetc(stdin); // block until fed
+
+ qDebug("Process is running");
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro b/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro
new file mode 100644
index 0000000000..b26a583dee
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro
@@ -0,0 +1,5 @@
+SOURCES += main.cpp
+QT += widgets
+CONFIG += console
+DESTDIR = ./
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp b/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
new file mode 100644
index 0000000000..e2ec87b3aa
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+
+struct Foo
+{
+ int i;
+};
+
+int main()
+{
+ *(char*)0 = 0;
+ Foo *f = 0;
+ return f->i;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro b/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro
new file mode 100644
index 0000000000..abd8167313
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+CONFIG += console
+CONFIG -= qt app_bundle
+
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
new file mode 100644
index 0000000000..9e285b5012
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+ for (int i=0; i<10240; i++)
+ fprintf(stdout, "%d dead while reading\n", i);
+ fflush(stdout);
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
new file mode 100644
index 0000000000..2168ba5672
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
new file mode 100644
index 0000000000..28de5c2f3a
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+#include <string.h>
+
+int main()
+{
+ char buf[32];
+ memset(buf, 0, sizeof(buf));
+
+ char *cptr = buf;
+ int c;
+ while (cptr != buf + 31 && (c = fgetc(stdin)) != EOF)
+ *cptr++ = (char) c;
+
+ printf("%s", buf);
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
new file mode 100644
index 0000000000..756bd23bb0
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+
+win32:!win32-g++*:!equals(TEMPLATE_PREFIX, "vc"):QMAKE_CXXFLAGS += /GS-
+DESTDIR = ./
+
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
new file mode 100644
index 0000000000..a7eedff56d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+#if defined(_WIN32_WCE) && defined(_X86_)
+ return 0;
+#else
+ int c;
+ while ((c = fgetc(stdin)) != -1) {
+ if (c == '\0')
+ break;
+ fputc(c, stdout);
+ fflush(stdout);
+ }
+ return 0;
+#endif
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro b/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro
new file mode 100644
index 0000000000..a14c1fe163
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
new file mode 100644
index 0000000000..1c18319bca
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+ int c;
+ while ((c = fgetc(stdin)) != -1) {
+ if (c == '\0')
+ break;
+ fputc(c, stdout);
+ fputc(c, stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro b/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro
new file mode 100644
index 0000000000..d8a303a22b
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
new file mode 100644
index 0000000000..62901a7789
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+ int c;
+ for (;;) {
+ c = fgetc(stdin);
+ if (c == '\0')
+ break;
+ if (c != -1) {
+ fputc(c, stdout);
+ fputc(c, stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro b/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro
new file mode 100644
index 0000000000..3b8f2fb0d7
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
new file mode 100644
index 0000000000..b8c2bd6abd
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <windows.h>
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+
+ HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
+ HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
+
+ for (;;) {
+
+ char c = 0;
+ DWORD read = 0;
+ if (!ReadFile(hStdin, &c, 1, &read, 0) || read == 0 || c == 'q' || c == '\0')
+ break;
+ DWORD wrote = 0;
+ WriteFile(hStdout, &c, 1, &wrote, 0);
+ WriteFile(hStderr, &c, 1, &wrote, 0);
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro b/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro
new file mode 100644
index 0000000000..b3be74cbd1
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro
@@ -0,0 +1,13 @@
+win32 {
+ SOURCES = main_win.cpp
+ !win32-borland:LIBS += -lUser32
+}
+
+CONFIG -= qt
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
new file mode 100644
index 0000000000..17ed5c61dc
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+#if defined(_WIN32_WCE)
+ // no environment in Windows CE
+ return 0;
+#else
+ if (argc == 1)
+ return 1;
+
+ char *env = getenv(argv[1]);
+ if (env) {
+ printf("%s", env);
+ return 0;
+ }
+ return 1;
+#endif
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro b/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro
new file mode 100644
index 0000000000..14ddae50f3
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro
@@ -0,0 +1,12 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+mac {
+ CONFIG -= app_bundle
+}
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessLoopback/main.cpp b/tests/auto/corelib/io/qprocess/testProcessLoopback/main.cpp
new file mode 100644
index 0000000000..6803518400
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessLoopback/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+ char buffer[1024];
+ for (;;) {
+ size_t num = fread(buffer, 1, sizeof(buffer), stdin);
+ if (num <= 0)
+ break;
+ fwrite(buffer, num, 1, stdout);
+ fflush(stdout);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro b/tests/auto/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro
new file mode 100644
index 0000000000..a14c1fe163
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp b/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
new file mode 100644
index 0000000000..008a0a2430
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+
+int main()
+{
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro b/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro
new file mode 100644
index 0000000000..3c6a595d85
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG += console
+CONFIG -= qt app_bundle
+
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp b/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
new file mode 100644
index 0000000000..b648d1bec3
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+#if defined(__SYMBIAN32__)
+ // Printing to stdout messes up the out.txt, so open a file and print there.
+ FILE* file = fopen("c:\\logs\\qprocess_output_test.txt","w+");
+ for (int i=0; i<200; i++) {
+ fprintf(file, "%d -this is a number\n", i);
+ fflush(file);
+ }
+ fclose(file);
+#else
+# if defined(_WIN32_WCE)
+ for (int i=0; i<240; i++) {
+# else //fprintf Output is very slow on Windows CE/Symbian
+ for (int i=0; i<10240; i++) {
+# endif
+ fprintf(stdout, "%d -this is a number\n", i);
+ fflush(stderr);
+ }
+#endif
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro b/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro
new file mode 100644
index 0000000000..3b8f2fb0d7
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
new file mode 100644
index 0000000000..39a0b3bac1
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main(int argc, char ** argv)
+{
+#if defined(__SYMBIAN32__) || defined(WINCE) || defined(_WIN32_WCE)
+# if defined(__SYMBIAN32__)
+ // Printing to stdout messes up the out.txt, so open a file and print there.
+ FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","w+");
+# else
+ // No pipes on this "OS"
+ FILE* file = fopen("\\temp\\qprocess_args_test.txt","w+");
+# endif
+ for (int i = 0; i < argc; ++i) {
+ if (i)
+ fprintf(file, "|");
+ fprintf(file, argv[i]);
+ }
+ fclose(file);
+#else
+ for (int i = 0; i < argc; ++i) {
+ if (i)
+ printf("|");
+ printf("%s", argv[i]);
+ }
+#endif
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro
new file mode 100644
index 0000000000..f55f02e425
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro
new file mode 100644
index 0000000000..2a56a95606
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro
@@ -0,0 +1,11 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+TARGET = "one space"
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro
new file mode 100644
index 0000000000..d7c74a64c9
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro
@@ -0,0 +1,12 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+TARGET = "two space s"
+
+# no install rule for application used by test
+INSTALLS =
+
+
+
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
new file mode 100644
index 0000000000..0035c6253a
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ QByteArray currentPath = QDir::currentPath().toLocal8Bit();
+ fprintf(stdout, "%s", currentPath.constData());
+ app.exit();
+}
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
new file mode 100644
index 0000000000..b723604171
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
@@ -0,0 +1,7 @@
+SOURCES = main.cpp
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp b/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
new file mode 100644
index 0000000000..b17ab4d9a6
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+ struct sigaction noaction;
+ memset(&noaction, 0, sizeof(noaction));
+ noaction.sa_handler = SIG_IGN;
+ ::sigaction(SIGTERM, &noaction, 0);
+
+ printf("Ready\n");
+ fflush(stdout);
+
+ for (int i = 0; i < 5; ++i)
+ sleep(1);
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp b/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
new file mode 100644
index 0000000000..29dbc46bcf
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <windows.h>
+#include <stdio.h>
+
+int main()
+{
+ printf("Ready\n");
+ fflush(stdout);
+
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ if (msg.message == WM_CLOSE)
+ PostQuitMessage(0);
+ }
+
+ return msg.wParam;
+}
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro
new file mode 100644
index 0000000000..922035907a
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro
@@ -0,0 +1,16 @@
+win32 {
+ SOURCES = main_win.cpp
+ !win32-borland:!wince*:LIBS += -lUser32
+}
+unix {
+ SOURCES = main_unix.cpp
+}
+
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp b/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
new file mode 100644
index 0000000000..3fadc68095
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <stdio.h>
+
+int main()
+{
+ int c;
+ while ((c = fgetc(stdin)) != -1) {
+ if (c == '\0')
+ break;
+ fputc(c, stdout);
+ fflush(stdout);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro b/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro
new file mode 100644
index 0000000000..913e868d03
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro
@@ -0,0 +1,13 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = "../test Space In Name"
+
+mac {
+ CONFIG -= app_bundle
+}
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
new file mode 100644
index 0000000000..9873c3e357
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -0,0 +1,2472 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+#include <QtCore/QProcess>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QThread>
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+#include <QtCore/QMetaType>
+#if !defined(Q_OS_SYMBIAN)
+// Network test unnecessary?
+#include <QtNetwork/QHostInfo>
+#endif
+#include <stdlib.h>
+
+#ifdef QT_NO_PROCESS
+QTEST_NOOP_MAIN
+#else
+
+#if defined(Q_OS_WIN)
+#include <windows.h>
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+Q_DECLARE_METATYPE(QList<QProcess::ExitStatus>);
+Q_DECLARE_METATYPE(QProcess::ExitStatus);
+Q_DECLARE_METATYPE(QProcess::ProcessState);
+
+#define QPROCESS_VERIFY(Process, Fn) \
+{ \
+const bool ret = Process.Fn; \
+if (ret == false) \
+ qWarning("QProcess error: %d: %s", Process.error(), qPrintable(Process.errorString())); \
+QVERIFY(ret); \
+}
+
+class tst_QProcess : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QProcess();
+ virtual ~tst_QProcess();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void constructing();
+ void simpleStart();
+ void execute();
+ void startDetached();
+ void crashTest();
+ void crashTest2();
+ void echoTest_data();
+ void echoTest();
+ void echoTest2();
+ void echoTest_performance();
+#if defined Q_OS_WIN
+ void echoTestGui();
+ void batFiles_data();
+ void batFiles();
+#endif
+ void exitStatus_data();
+ void exitStatus();
+ void loopBackTest();
+ void readTimeoutAndThenCrash();
+ void waitForFinished();
+ void deadWhileReading();
+ void restartProcessDeadlock();
+ void closeWriteChannel();
+ void closeReadChannel();
+ void openModes();
+ void emitReadyReadOnlyWhenNewDataArrives();
+ void hardExit();
+ void softExit();
+ void softExitInSlots_data();
+ void softExitInSlots();
+ void mergedChannels();
+ void forwardedChannels();
+ void atEnd();
+ void atEnd2();
+ void processInAThread();
+ void processesInMultipleThreads();
+ void waitForFinishedWithTimeout();
+ void waitForReadyReadInAReadyReadSlot();
+ void waitForBytesWrittenInABytesWrittenSlot();
+ void spaceArgsTest_data();
+ void spaceArgsTest();
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ void nativeArguments();
+#endif
+ void exitCodeTest();
+ void setEnvironment_data();
+ void setEnvironment();
+ void setProcessEnvironment_data();
+ void setProcessEnvironment();
+ void systemEnvironment();
+ void spaceInName();
+ void lockupsInStartDetached();
+ void waitForReadyReadForNonexistantProcess();
+ void setStandardInputFile();
+ void setStandardOutputFile_data();
+ void setStandardOutputFile();
+ void setStandardOutputProcess_data();
+ void setStandardOutputProcess();
+ void removeFileWhileProcessIsRunning();
+ void fileWriterProcess();
+ void detachedWorkingDirectoryAndPid();
+ void switchReadChannels();
+ void setWorkingDirectory();
+ void startFinishStartFinish();
+ void invalidProgramString_data();
+ void invalidProgramString();
+ void onlyOneStartedSignal();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+ void failToStart();
+ void failToStartWithWait();
+ void failToStartWithEventLoop();
+
+protected slots:
+ void readFromProcess();
+ void exitLoopSlot();
+ void restartProcess();
+ void waitForReadyReadInAReadyReadSlotSlot();
+ void waitForBytesWrittenInABytesWrittenSlotSlot();
+
+private:
+ QProcess *process;
+ qint64 bytesAvailable;
+};
+
+// Testing get/set functions
+void tst_QProcess::getSetCheck()
+{
+ QProcess obj1;
+ // ProcessChannelMode QProcess::readChannelMode()
+ // void QProcess::setReadChannelMode(ProcessChannelMode)
+ obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::SeparateChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::SeparateChannels), obj1.readChannelMode());
+ obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::MergedChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::MergedChannels), obj1.readChannelMode());
+ obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::ForwardedChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::ForwardedChannels), obj1.readChannelMode());
+
+ // ProcessChannel QProcess::readChannel()
+ // void QProcess::setReadChannel(ProcessChannel)
+ obj1.setReadChannel(QProcess::ProcessChannel(QProcess::StandardOutput));
+ QCOMPARE(QProcess::ProcessChannel(QProcess::StandardOutput), obj1.readChannel());
+ obj1.setReadChannel(QProcess::ProcessChannel(QProcess::StandardError));
+ QCOMPARE(QProcess::ProcessChannel(QProcess::StandardError), obj1.readChannel());
+}
+
+tst_QProcess::tst_QProcess()
+{
+}
+
+tst_QProcess::~tst_QProcess()
+{
+}
+
+void tst_QProcess::init()
+{
+#ifdef Q_OS_SYMBIAN
+ QString dirStr = QString::fromLatin1("c:\\logs");
+ QDir dir;
+ if (!dir.exists(dirStr))
+ dir.mkpath(dirStr);
+#endif
+}
+
+void tst_QProcess::cleanup()
+{
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::constructing()
+{
+ QProcess process;
+ QCOMPARE(process.readChannel(), QProcess::StandardOutput);
+ QCOMPARE(process.workingDirectory(), QString());
+ QCOMPARE(process.environment(), QStringList());
+ QCOMPARE(process.error(), QProcess::UnknownError);
+ QCOMPARE(process.state(), QProcess::NotRunning);
+ QCOMPARE(process.pid(), Q_PID(0));
+ QCOMPARE(process.readAllStandardOutput(), QByteArray());
+ QCOMPARE(process.readAllStandardError(), QByteArray());
+ QCOMPARE(process.canReadLine(), false);
+
+ // QIODevice
+ QCOMPARE(process.openMode(), QIODevice::NotOpen);
+ QVERIFY(!process.isOpen());
+ QVERIFY(!process.isReadable());
+ QVERIFY(!process.isWritable());
+ QVERIFY(process.isSequential());
+ QCOMPARE(process.pos(), qlonglong(0));
+ QCOMPARE(process.size(), qlonglong(0));
+ QVERIFY(process.atEnd());
+ QCOMPARE(process.bytesAvailable(), qlonglong(0));
+ QCOMPARE(process.bytesToWrite(), qlonglong(0));
+ QVERIFY(!process.errorString().isEmpty());
+
+ char c;
+ QCOMPARE(process.read(&c, 1), qlonglong(-1));
+ QCOMPARE(process.write(&c, 1), qlonglong(-1));
+
+ QProcess proc2;
+}
+
+void tst_QProcess::simpleStart()
+{
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+
+ process = new QProcess;
+ QSignalSpy spy(process, SIGNAL(stateChanged(QProcess::ProcessState)));
+ connect(process, SIGNAL(readyRead()), this, SLOT(readFromProcess()));
+
+ /* valgrind dislike SUID binaries(those that have the `s'-flag set), which
+ * makes it fail to start the process. For this reason utilities like `ping' won't
+ * start, when the auto test is run through `valgrind'. */
+ process->start("testProcessNormal/testProcessNormal");
+ if (process->state() != QProcess::Starting)
+ QCOMPARE(process->state(), QProcess::Running);
+ QVERIFY2(process->waitForStarted(5000), qPrintable(process->errorString()));
+ QCOMPARE(process->state(), QProcess::Running);
+#if defined(Q_OS_WINCE)
+ // Note: This actually seems incorrect, it will only exit the while loop when finishing fails
+ while (process->waitForFinished(5000))
+ { }
+#elif defined(Q_OS_SYMBIAN)
+ QVERIFY(process->waitForFinished(5000));
+#else
+ while (process->waitForReadyRead(5000))
+ { }
+#endif
+ QCOMPARE(int(process->state()), int(QProcess::NotRunning));
+
+ delete process;
+ process = 0;
+
+ QCOMPARE(spy.count(), 3);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(spy.at(0).at(0)), QProcess::Starting);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(spy.at(1).at(0)), QProcess::Running);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(spy.at(2).at(0)), QProcess::NotRunning);
+}
+//-----------------------------------------------------------------------------
+void tst_QProcess::execute()
+{
+ QCOMPARE(QProcess::execute("testProcessNormal/testProcessNormal",
+ QStringList() << "arg1" << "arg2"), 0);
+ QCOMPARE(QProcess::execute("nonexistingexe"), -2);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::startDetached()
+{
+ QProcess proc;
+ QVERIFY(proc.startDetached("testProcessNormal/testProcessNormal",
+ QStringList() << "arg1" << "arg2"));
+ QCOMPARE(QProcess::startDetached("nonexistingexe"), false);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::readFromProcess()
+{
+ int lines = 0;
+ while (process->canReadLine()) {
+ ++lines;
+ QByteArray line = process->readLine();
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::crashTest()
+{
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+#ifdef Q_OS_WIN
+ QSKIP("This test opens a crash dialog on Windows", SkipSingle);
+#endif
+ process = new QProcess;
+ QSignalSpy stateSpy(process, SIGNAL(stateChanged(QProcess::ProcessState)));
+ process->start("testProcessCrash/testProcessCrash");
+ QVERIFY(process->waitForStarted(5000));
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ExitStatus");
+
+ QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy spy2(process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ QVERIFY(process->waitForFinished(30000));
+
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+
+ QCOMPARE(spy2.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
+
+ QCOMPARE(process->exitStatus(), QProcess::CrashExit);
+
+ delete process;
+ process = 0;
+
+ QCOMPARE(stateSpy.count(), 3);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(0).at(0)), QProcess::Starting);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(1).at(0)), QProcess::Running);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(2).at(0)), QProcess::NotRunning);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::crashTest2()
+{
+#ifdef Q_OS_WIN
+ QSKIP("This test opens a crash dialog on Windows", SkipSingle);
+#endif
+ process = new QProcess;
+ process->start("testProcessCrash/testProcessCrash");
+ QVERIFY(process->waitForStarted(5000));
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ExitStatus");
+
+ QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy spy2(process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ QObject::connect(process, SIGNAL(finished(int)), this, SLOT(exitLoopSlot()));
+
+ QTestEventLoop::instance().enterLoop(30);
+ if (QTestEventLoop::instance().timeout())
+ QFAIL("Failed to detect crash : operation timed out");
+
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+
+ QCOMPARE(spy2.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
+
+ QCOMPARE(process->exitStatus(), QProcess::CrashExit);
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest_data()
+{
+ QTest::addColumn<QByteArray>("input");
+
+ QTest::newRow("1") << QByteArray("H");
+ QTest::newRow("2") << QByteArray("He");
+ QTest::newRow("3") << QByteArray("Hel");
+ QTest::newRow("4") << QByteArray("Hell");
+ QTest::newRow("5") << QByteArray("Hello");
+ QTest::newRow("100 bytes") << QByteArray(100, '@');
+ QTest::newRow("1000 bytes") << QByteArray(1000, '@');
+ QTest::newRow("10000 bytes") << QByteArray(10000, '@');
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QFETCH(QByteArray, input);
+
+ process = new QProcess;
+ connect(process, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ process->write(input);
+
+ QTime stopWatch;
+ stopWatch.start();
+ do {
+ QVERIFY(process->isOpen());
+ QTestEventLoop::instance().enterLoop(2);
+ } while (stopWatch.elapsed() < 60000 && process->bytesAvailable() < input.size());
+ if (stopWatch.elapsed() >= 60000)
+ QFAIL("Timed out");
+
+ QByteArray message = process->readAll();
+ QCOMPARE(message.size(), input.size());
+
+ char *c1 = message.data();
+ char *c2 = input.data();
+ while (*c1 && *c2) {
+ if (*c1 != *c2)
+ QCOMPARE(*c1, *c2);
+ ++c1;
+ ++c2;
+ }
+ QCOMPARE(*c1, *c2);
+
+ process->write("", 1);
+
+ QVERIFY(process->waitForFinished(5000));
+
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::exitLoopSlot()
+{
+ QTestEventLoop::instance().exitLoop();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest2()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ process = new QProcess;
+ connect(process, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process->start("testProcessEcho2/testProcessEcho2");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(!process->waitForReadyRead(250));
+ QCOMPARE(process->error(), QProcess::Timedout);
+
+ process->write("Hello");
+ QSignalSpy spy1(process, SIGNAL(readyReadStandardOutput()));
+ QSignalSpy spy2(process, SIGNAL(readyReadStandardError()));
+
+ QTime stopWatch;
+ stopWatch.start();
+ forever {
+ QTestEventLoop::instance().enterLoop(1);
+ if (stopWatch.elapsed() >= 30000)
+ QFAIL("Timed out");
+ process->setReadChannel(QProcess::StandardOutput);
+ qint64 baso = process->bytesAvailable();
+
+ process->setReadChannel(QProcess::StandardError);
+ qint64 base = process->bytesAvailable();
+ if (baso == 5 && base == 5)
+ break;
+ }
+
+ QVERIFY(spy1.count() > 0);
+ QVERIFY(spy2.count() > 0);
+
+ QCOMPARE(process->readAllStandardOutput(), QByteArray("Hello"));
+ QCOMPARE(process->readAllStandardError(), QByteArray("Hello"));
+
+ process->write("", 1);
+ QVERIFY(process->waitForFinished(5000));
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest_performance()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+#ifdef Q_OS_MAC
+ process.start("testProcessLoopback/testProcessLoopback.app");
+#else
+ process.start("testProcessLoopback/testProcessLoopback");
+#endif
+
+ QByteArray array;
+ array.resize(1024 * 1024);
+ for (int j = 0; j < array.size(); ++j)
+ array[j] = 'a' + (j % 20);
+
+ QVERIFY(process.waitForStarted());
+
+ QTime stopWatch;
+ stopWatch.start();
+
+ qint64 totalBytes = 0;
+ QByteArray dump;
+ QSignalSpy readyReadSpy(&process, SIGNAL(readyRead()));
+ while (stopWatch.elapsed() < 2000) {
+ process.write(array);
+ while (process.bytesToWrite() > 0) {
+ int readCount = readyReadSpy.count();
+ QVERIFY(process.waitForBytesWritten(5000));
+ if (readyReadSpy.count() == readCount)
+ QVERIFY(process.waitForReadyRead(5000));
+ }
+
+ while (process.bytesAvailable() < array.size())
+ QVERIFY2(process.waitForReadyRead(5000), qPrintable(process.errorString()));
+ dump = process.readAll();
+ totalBytes += dump.size();
+ }
+
+ qDebug() << "Elapsed time:" << stopWatch.elapsed() << "ms;"
+ << "transfer rate:" << totalBytes / (1048.576) / stopWatch.elapsed()
+ << "MB/s";
+
+ for (int j = 0; j < array.size(); ++j)
+ QCOMPARE(char(dump.at(j)), char('a' + (j % 20)));
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished());
+}
+
+#if defined Q_OS_WIN
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTestGui()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+
+ process.start("testProcessEchoGui/testProcessEchoGui");
+
+
+ process.write("Hello");
+ process.write("q");
+
+ QVERIFY(process.waitForFinished(50000));
+
+ QCOMPARE(process.readAllStandardOutput(), QByteArray("Hello"));
+ QCOMPARE(process.readAllStandardError(), QByteArray("Hello"));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::batFiles_data()
+{
+ QTest::addColumn<QString>("batFile");
+ QTest::addColumn<QByteArray>("output");
+
+ QTest::newRow("simple") << QString::fromLatin1("testBatFiles/simple.bat") << QByteArray("Hello");
+ QTest::newRow("with space") << QString::fromLatin1("testBatFiles/with space.bat") << QByteArray("Hello");
+}
+
+void tst_QProcess::batFiles()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Batch files are not supported on Windows CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Batch files are not supported on Symbian", SkipAll);
+#endif
+ QFETCH(QString, batFile);
+ QFETCH(QByteArray, output);
+
+ QProcess proc;
+
+ proc.start(batFile, QStringList());
+
+ QVERIFY(proc.waitForFinished(5000));
+
+ QVERIFY(proc.bytesAvailable() > 0);
+
+ QVERIFY(proc.readAll().startsWith(output));
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::exitStatus_data()
+{
+ QTest::addColumn<QStringList>("processList");
+ QTest::addColumn<QList<QProcess::ExitStatus> >("exitStatus");
+
+ QTest::newRow("normal") << (QStringList() << "testProcessNormal/testProcessNormal")
+ << (QList<QProcess::ExitStatus>() << QProcess::NormalExit);
+ QTest::newRow("crash") << (QStringList() << "testProcessCrash/testProcessCrash")
+ << (QList<QProcess::ExitStatus>() << QProcess::CrashExit);
+
+ QTest::newRow("normal-crash") << (QStringList()
+ << "testProcessNormal/testProcessNormal"
+ << "testProcessCrash/testProcessCrash")
+ << (QList<QProcess::ExitStatus>()
+ << QProcess::NormalExit
+ << QProcess::CrashExit);
+ QTest::newRow("crash-normal") << (QStringList()
+ << "testProcessCrash/testProcessCrash"
+ << "testProcessNormal/testProcessNormal")
+ << (QList<QProcess::ExitStatus>()
+ << QProcess::CrashExit
+ << QProcess::NormalExit);
+}
+
+void tst_QProcess::exitStatus()
+{
+ process = new QProcess;
+ QFETCH(QStringList, processList);
+ QFETCH(QList<QProcess::ExitStatus>, exitStatus);
+
+#ifdef Q_OS_WIN
+ if (exitStatus.contains(QProcess::CrashExit))
+ QSKIP("This test opens a crash dialog on Windows", SkipSingle);
+#endif
+
+ QCOMPARE(exitStatus.count(), processList.count());
+ for (int i = 0; i < processList.count(); ++i) {
+ process->start(processList.at(i));
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(process->waitForFinished(30000));
+
+ QCOMPARE(process->exitStatus(), exitStatus.at(i));
+ }
+
+ process->deleteLater();
+ process = 0;
+}
+//-----------------------------------------------------------------------------
+void tst_QProcess::loopBackTest()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ process = new QProcess;
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ for (int i = 0; i < 100; ++i) {
+ process->write("Hello");
+ do {
+ QVERIFY(process->waitForReadyRead(5000));
+ } while (process->bytesAvailable() < 5);
+ QCOMPARE(process->readAll(), QByteArray("Hello"));
+ }
+
+ process->write("", 1);
+ QVERIFY(process->waitForFinished(5000));
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::readTimeoutAndThenCrash()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ process = new QProcess;
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ if (process->state() != QProcess::Starting)
+ QCOMPARE(process->state(), QProcess::Running);
+
+ QVERIFY(process->waitForStarted(5000));
+ QCOMPARE(process->state(), QProcess::Running);
+
+ QVERIFY(!process->waitForReadyRead(5000));
+ QCOMPARE(process->error(), QProcess::Timedout);
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
+
+ process->kill();
+
+ QVERIFY(process->waitForFinished(5000));
+ QCOMPARE(process->state(), QProcess::NotRunning);
+
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+
+ delete process;
+ process = 0;
+}
+
+void tst_QProcess::waitForFinished()
+{
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessOutput/testProcessOutput.app");
+#else
+ process.start("testProcessOutput/testProcessOutput");
+#endif
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QVERIFY(process.waitForFinished(5000));
+#else
+ QVERIFY(process.waitForFinished(30000));
+#endif
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+
+#if defined(Q_OS_SYMBIAN)
+ // Symbian test outputs to a file, so check that
+ FILE* file = fopen("c:\\logs\\qprocess_output_test.txt","r");
+ int retval = 0;
+ int count = 0;
+ while((int)(retval = fgetc(file) )!= EOF)
+ if (retval == '\n')
+ count++;
+ fclose(file);
+ QCOMPARE(count, 200);
+#else
+# if defined (Q_OS_WINCE)
+ QEXPECT_FAIL("", "Reading and writing to a process is not supported on Qt/CE", Continue);
+# endif
+ QString output = process.readAll();
+ QCOMPARE(output.count("\n"), 10*1024);
+#endif
+
+ process.start("blurdybloop");
+ QVERIFY(!process.waitForFinished());
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+}
+
+
+void tst_QProcess::deadWhileReading()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessDeadWhileReading/testProcessDeadWhileReading.app");
+#else
+ process.start("testProcessDeadWhileReading/testProcessDeadWhileReading");
+#endif
+
+ QString output;
+
+ QVERIFY(process.waitForStarted(5000));
+ while (process.waitForReadyRead(5000))
+ output += process.readAll();
+
+ QCOMPARE(output.count("\n"), 10*1024);
+ process.waitForFinished();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::restartProcessDeadlock()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ // The purpose of this test is to detect whether restarting a
+ // process in the finished() connected slot causes a deadlock
+ // because of the way QProcessManager uses its locks.
+ QProcess proc;
+ process = &proc;
+ connect(process, SIGNAL(finished(int)), this, SLOT(restartProcess()));
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+
+ QCOMPARE(process->write("", 1), qlonglong(1));
+ QVERIFY(process->waitForFinished(5000));
+
+ process->disconnect(SIGNAL(finished(int)));
+
+ QCOMPARE(process->write("", 1), qlonglong(1));
+ QVERIFY(process->waitForFinished(5000));
+}
+
+void tst_QProcess::restartProcess()
+{
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::closeWriteChannel()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess more;
+ more.start("testProcessEOF/testProcessEOF");
+
+ QVERIFY(more.waitForStarted(5000));
+ QVERIFY(!more.waitForReadyRead(250));
+ QCOMPARE(more.error(), QProcess::Timedout);
+
+ QVERIFY(more.write("Data to read") != -1);
+
+ QVERIFY(!more.waitForReadyRead(250));
+ QCOMPARE(more.error(), QProcess::Timedout);
+
+ more.closeWriteChannel();
+
+ QVERIFY(more.waitForReadyRead(5000));
+ QVERIFY(more.readAll().startsWith("Data to read"));
+
+ if (more.state() == QProcess::Running)
+ more.write("q");
+ QVERIFY(more.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::closeReadChannel()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ for (int i = 0; i < 10; ++i) {
+ QProcess::ProcessChannel channel1 = QProcess::StandardOutput;
+ QProcess::ProcessChannel channel2 = QProcess::StandardError;
+
+ QProcess proc;
+#ifdef Q_OS_MAC
+ proc.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ proc.start("testProcessEcho2/testProcessEcho2");
+#endif
+ QVERIFY(proc.waitForStarted(5000));
+ proc.closeReadChannel(i&1 ? channel2 : channel1);
+ proc.setReadChannel(i&1 ? channel2 : channel1);
+ proc.write("Data");
+
+ QVERIFY(!proc.waitForReadyRead(5000));
+ QVERIFY(proc.readAll().isEmpty());
+
+ proc.setReadChannel(i&1 ? channel1 : channel2);
+
+ while (proc.bytesAvailable() < 4 && proc.waitForReadyRead(5000))
+ { }
+
+ QCOMPARE(proc.readAll(), QByteArray("Data"));
+
+ proc.write("", 1);
+ QVERIFY(proc.waitForFinished(5000));
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::openModes()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess proc;
+ QVERIFY(!proc.isOpen());
+ QVERIFY(proc.openMode() == QProcess::NotOpen);
+#ifdef Q_OS_MAC
+ proc.start("testProcessEcho3/testProcessEcho3.app");
+#else
+ proc.start("testProcessEcho3/testProcessEcho3");
+#endif
+ QVERIFY(proc.waitForStarted(5000));
+ QVERIFY(proc.isOpen());
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+ QVERIFY(proc.isReadable());
+ QVERIFY(proc.isWritable());
+
+ proc.write("Data");
+
+ proc.closeWriteChannel();
+
+ QVERIFY(proc.isWritable());
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+
+ while (proc.bytesAvailable() < 4 && proc.waitForReadyRead(5000))
+ { }
+
+ QCOMPARE(proc.readAll().constData(), QByteArray("Data").constData());
+
+ proc.closeReadChannel(QProcess::StandardOutput);
+
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+ QVERIFY(proc.isReadable());
+
+ proc.closeReadChannel(QProcess::StandardError);
+
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+ QVERIFY(proc.isReadable());
+
+ proc.close();
+ QVERIFY(!proc.isOpen());
+ QVERIFY(!proc.isReadable());
+ QVERIFY(!proc.isWritable());
+ QCOMPARE(proc.state(), QProcess::NotRunning);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess proc;
+ connect(&proc, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
+ QSignalSpy spy(&proc, SIGNAL(readyRead()));
+
+#ifdef Q_OS_MAC
+ proc.start("testProcessEcho/testProcessEcho.app");
+#else
+ proc.start("testProcessEcho/testProcessEcho");
+#endif
+
+ QCOMPARE(spy.count(), 0);
+
+ proc.write("A");
+
+ QTestEventLoop::instance().enterLoop(5);
+ if (QTestEventLoop::instance().timeout())
+ QFAIL("Operation timed out");
+
+ QCOMPARE(spy.count(), 1);
+
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(QTestEventLoop::instance().timeout());
+ QVERIFY(!proc.waitForReadyRead(250));
+
+ QObject::disconnect(&proc, SIGNAL(readyRead()), 0, 0);
+ proc.write("B");
+ QVERIFY(proc.waitForReadyRead(5000));
+
+ proc.write("", 1);
+ QVERIFY(proc.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::hardExit()
+{
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Killing started processes is not supported on Qt/Symbian due platform security", SkipAll);
+#endif
+ QProcess proc;
+
+#if defined(Q_OS_MAC)
+ proc.start("testProcessEcho/testProcessEcho.app");
+#elif defined(Q_OS_WINCE)
+ proc.start("testSoftExit/testSoftExit");
+#else
+ proc.start("testProcessEcho/testProcessEcho");
+#endif
+
+#ifndef Q_OS_WINCE
+ QVERIFY(proc.waitForStarted(5000));
+#else
+ QVERIFY(proc.waitForStarted(10000));
+#endif
+
+ proc.kill();
+
+ QVERIFY(proc.waitForFinished(5000));
+ QCOMPARE(int(proc.state()), int(QProcess::NotRunning));
+ QCOMPARE(int(proc.error()), int(QProcess::Crashed));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::softExit()
+{
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Terminating started processes is not supported on Qt/Symbian due platform security", SkipAll);
+#endif
+ QProcess proc;
+
+ proc.start("testSoftExit/testSoftExit");
+
+ QVERIFY(proc.waitForStarted(10000));
+#if !defined(Q_OS_WINCE)
+ QVERIFY(proc.waitForReadyRead(10000));
+#endif
+
+ proc.terminate();
+
+ QVERIFY(proc.waitForFinished(10000));
+ QCOMPARE(int(proc.state()), int(QProcess::NotRunning));
+ QCOMPARE(int(proc.error()), int(QProcess::UnknownError));
+}
+
+class SoftExitProcess : public QProcess
+{
+ Q_OBJECT
+public:
+ bool waitedForFinished;
+
+ SoftExitProcess(int n) : waitedForFinished(false), n(n), killing(false)
+ {
+ connect(this, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(finishedSlot(int, QProcess::ExitStatus)));
+
+ switch (n) {
+ case 0:
+ setReadChannelMode(QProcess::MergedChannels);
+ connect(this, SIGNAL(readyRead()), this, SLOT(terminateSlot()));
+ break;
+ case 1:
+ connect(this, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(terminateSlot()));
+ break;
+ case 2:
+ connect(this, SIGNAL(readyReadStandardError()),
+ this, SLOT(terminateSlot()));
+ break;
+ case 3:
+ connect(this, SIGNAL(started()),
+ this, SLOT(terminateSlot()));
+ break;
+ case 4:
+ default:
+ connect(this, SIGNAL(stateChanged(QProcess::ProcessState)),
+ this, SLOT(terminateSlot()));
+ break;
+ }
+ }
+
+public slots:
+ void terminateSlot()
+ {
+ if (killing || (n == 4 && state() != Running)) {
+ // Don't try to kill the process before it is running - that can
+ // be hazardous, as the actual child process might not be running
+ // yet. Also, don't kill it "recursively".
+ return;
+ }
+ killing = true;
+ readAll();
+ terminate();
+ if ((waitedForFinished = waitForFinished(5000)) == false) {
+ kill();
+ if (state() != NotRunning)
+ waitedForFinished = waitForFinished(5000);
+ }
+ }
+
+ void finishedSlot(int, QProcess::ExitStatus)
+ {
+ waitedForFinished = true;
+ }
+
+private:
+ int n;
+ bool killing;
+};
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::softExitInSlots_data()
+{
+ QTest::addColumn<QString>("appName");
+
+#ifdef Q_OS_MAC
+ QTest::newRow("gui app") << "testGuiProcess/testGuiProcess.app";
+#else
+ QTest::newRow("gui app") << "testGuiProcess/testGuiProcess";
+#endif
+#ifdef Q_OS_MAC
+ QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2.app";
+#else
+ QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::softExitInSlots()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QFETCH(QString, appName);
+
+ for (int i = 0; i < 5; ++i) {
+ SoftExitProcess proc(i);
+ proc.start(appName);
+ proc.write("OLEBOLE", 8); // include the \0
+ QTestEventLoop::instance().enterLoop(10);
+ QCOMPARE(proc.state(), QProcess::NotRunning);
+ QVERIFY(proc.waitedForFinished);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::mergedChannels()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+ process.setReadChannelMode(QProcess::MergedChannels);
+ QCOMPARE(process.readChannelMode(), QProcess::MergedChannels);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+
+ QVERIFY(process.waitForStarted(5000));
+
+ for (int i = 0; i < 100; ++i) {
+ QCOMPARE(process.write("abc"), qlonglong(3));
+ while (process.bytesAvailable() < 6)
+ QVERIFY(process.waitForReadyRead(5000));
+ QCOMPARE(process.readAll(), QByteArray("aabbcc"));
+ }
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::forwardedChannels()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+ process.setReadChannelMode(QProcess::ForwardedChannels);
+ QCOMPARE(process.readChannelMode(), QProcess::ForwardedChannels);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+
+ QVERIFY(process.waitForStarted(5000));
+ QCOMPARE(process.write("forwarded\n"), qlonglong(10));
+ QVERIFY(!process.waitForReadyRead(250));
+ QCOMPARE(process.bytesAvailable(), qlonglong(0));
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+}
+
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::atEnd()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+ process.write("abcdefgh\n");
+
+ while (process.bytesAvailable() < 8)
+ QVERIFY(process.waitForReadyRead(5000));
+
+ QTextStream stream(&process);
+ QVERIFY(!stream.atEnd());
+ QString tmp = stream.readLine();
+ QVERIFY(stream.atEnd());
+ QCOMPARE(tmp, QString::fromLatin1("abcdefgh"));
+
+ process.write("", 1);
+ QVERIFY(process.waitForFinished(5000));
+}
+
+class TestThread : public QThread
+{
+ Q_OBJECT
+public:
+ inline int code()
+ {
+ return exitCode;
+ }
+
+#if defined(Q_OS_SYMBIAN)
+ int serial;
+#endif
+
+protected:
+ inline void run()
+ {
+ exitCode = 90210;
+
+ QProcess process;
+ connect(&process, SIGNAL(finished(int)), this, SLOT(catchExitCode(int)),
+ Qt::DirectConnection);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#elif defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
+ // WINSCW builds in Symbian do not allow multiple processes to load Qt libraries,
+ // so use just a simple process instead of testDetached.
+ process.start("testProcessNormal");
+#elif defined(Q_OS_SYMBIAN)
+ // testDetached used because it does something, but doesn't take too long.
+ QFile infoFile(QString("c:\\logs\\detinfo%1").arg(serial));
+ QStringList args;
+ args << infoFile.fileName();
+ process.start("testDetached", args);
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QCOMPARE(process.write("abc\0", 4), qint64(4));
+#endif
+ exitCode = exec();
+ }
+
+protected slots:
+ inline void catchExitCode(int exitCode)
+ {
+ this->exitCode = exitCode;
+ exit(exitCode);
+ }
+
+private:
+ int exitCode;
+};
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::processInAThread()
+{
+ for (int i = 0; i < 10; ++i) {
+ TestThread thread;
+ thread.start();
+ QVERIFY(thread.wait(10000));
+ QCOMPARE(thread.code(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::processesInMultipleThreads()
+{
+#if defined(Q_OS_SYMBIAN)
+ int serialCounter = 0;
+#endif
+
+ for (int i = 0; i < 10; ++i) {
+ TestThread thread1;
+ TestThread thread2;
+ TestThread thread3;
+
+#if defined(Q_OS_SYMBIAN)
+ thread1.serial = serialCounter++;
+ thread2.serial = serialCounter++;
+ thread3.serial = serialCounter++;
+#endif
+ thread1.start();
+ thread2.start();
+ thread3.start();
+
+ QVERIFY(thread2.wait(10000));
+ QVERIFY(thread3.wait(10000));
+ QVERIFY(thread1.wait(10000));
+
+ QCOMPARE(thread1.code(), 0);
+ QCOMPARE(thread2.code(), 0);
+ QCOMPARE(thread3.code(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForFinishedWithTimeout()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess(this);
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#elif defined(Q_OS_SYMBIAN)
+ process->start("testProcessOutput");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+ QVERIFY(process->waitForStarted(50));
+ QVERIFY(!process->waitForFinished(1));
+#else
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(!process->waitForFinished(1));
+
+ process->write("", 1);
+#endif
+
+ QVERIFY(process->waitForFinished());
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForReadyReadInAReadyReadSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ process = new QProcess(this);
+ connect(process, SIGNAL(readyRead()), this, SLOT(waitForReadyReadInAReadyReadSlotSlot()));
+ connect(process, SIGNAL(finished(int)), this, SLOT(exitLoopSlot()));
+ bytesAvailable = 0;
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ QSignalSpy spy(process, SIGNAL(readyRead()));
+ process->write("foo");
+ QTestEventLoop::instance().enterLoop(30);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(spy.count(), 1);
+
+ process->disconnect();
+ QVERIFY(process->waitForFinished(5000));
+ QVERIFY(process->bytesAvailable() > bytesAvailable);
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ bytesAvailable = process->bytesAvailable();
+ process->write("bar", 4);
+ QVERIFY(process->waitForReadyRead(5000));
+ QTestEventLoop::instance().exitLoop();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ process = new QProcess(this);
+ connect(process, SIGNAL(bytesWritten(qint64)), this, SLOT(waitForBytesWrittenInABytesWrittenSlotSlot()));
+ bytesAvailable = 0;
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ qRegisterMetaType<qint64>("qint64");
+ QSignalSpy spy(process, SIGNAL(bytesWritten(qint64)));
+ process->write("f");
+ QTestEventLoop::instance().enterLoop(30);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(spy.count(), 1);
+ process->write("", 1);
+ process->disconnect();
+ QVERIFY(process->waitForFinished());
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForBytesWrittenInABytesWrittenSlotSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ process->write("b");
+ QVERIFY(process->waitForBytesWritten(5000));
+ QTestEventLoop::instance().exitLoop();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::spaceArgsTest_data()
+{
+ QTest::addColumn<QStringList>("args");
+ QTest::addColumn<QString>("stringArgs");
+
+ // arg1 | arg2
+ QTest::newRow("arg1 arg2") << (QStringList() << QString::fromLatin1("arg1") << QString::fromLatin1("arg2"))
+ << QString::fromLatin1("arg1 arg2");
+ // "arg1" | ar "g2
+ QTest::newRow("\"\"\"\"arg1\"\"\"\" \"ar \"\"\"g2\"") << (QStringList() << QString::fromLatin1("\"arg1\"") << QString::fromLatin1("ar \"g2"))
+ << QString::fromLatin1("\"\"\"\"arg1\"\"\"\" \"ar \"\"\"g2\"");
+ // ar g1 | a rg 2
+ QTest::newRow("\"ar g1\" \"a rg 2\"") << (QStringList() << QString::fromLatin1("ar g1") << QString::fromLatin1("a rg 2"))
+ << QString::fromLatin1("\"ar g1\" \"a rg 2\"");
+ // -lar g1 | -l"ar g2"
+ QTest::newRow("\"-lar g1\" \"-l\"\"\"ar g2\"\"\"\"") << (QStringList() << QString::fromLatin1("-lar g1") << QString::fromLatin1("-l\"ar g2\""))
+ << QString::fromLatin1("\"-lar g1\" \"-l\"\"\"ar g2\"\"\"\"");
+ // ar"g1
+ QTest::newRow("ar\"\"\"\"g1") << (QStringList() << QString::fromLatin1("ar\"g1"))
+ << QString::fromLatin1("ar\"\"\"\"g1");
+ // ar/g1
+ QTest::newRow("ar\\g1") << (QStringList() << QString::fromLatin1("ar\\g1"))
+ << QString::fromLatin1("ar\\g1");
+ // ar\g"1
+ QTest::newRow("ar\\g\"\"\"\"1") << (QStringList() << QString::fromLatin1("ar\\g\"1"))
+ << QString::fromLatin1("ar\\g\"\"\"\"1");
+ // arg\"1
+ QTest::newRow("arg\\\"\"\"1") << (QStringList() << QString::fromLatin1("arg\\\"1"))
+ << QString::fromLatin1("arg\\\"\"\"1");
+ // """"
+ QTest::newRow("\"\"\"\"\"\"\"\"\"\"\"\"") << (QStringList() << QString::fromLatin1("\"\"\"\""))
+ << QString::fromLatin1("\"\"\"\"\"\"\"\"\"\"\"\"");
+ // """" | "" ""
+ QTest::newRow("\"\"\"\"\"\"\"\"\"\"\"\" \"\"\"\"\"\"\" \"\"\"\"\"\"\"") << (QStringList() << QString::fromLatin1("\"\"\"\"") << QString::fromLatin1("\"\" \"\""))
+ << QString::fromLatin1("\"\"\"\"\"\"\"\"\"\"\"\" \"\"\"\"\"\"\" \"\"\"\"\"\"\"");
+ // "" ""
+ QTest::newRow("\"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" (bogus double quotes)") << (QStringList() << QString::fromLatin1("\"\" \"\""))
+ << QString::fromLatin1("\"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\"");
+ // "" ""
+ QTest::newRow(" \"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" (bogus double quotes)") << (QStringList() << QString::fromLatin1("\"\" \"\""))
+ << QString::fromLatin1(" \"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" ");
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::spaceArgsTest()
+{
+ QFETCH(QStringList, args);
+ QFETCH(QString, stringArgs);
+
+ QStringList programs;
+ programs << QString::fromLatin1("testProcessSpacesArgs/nospace")
+#if defined(Q_OS_SYMBIAN)
+ ; // Symbian toolchain doesn't like exes with spaces in the name
+#else
+ << QString::fromLatin1("testProcessSpacesArgs/one space")
+ << QString::fromLatin1("testProcessSpacesArgs/two space s");
+#endif
+
+ process = new QProcess(this);
+
+ for (int i = 0; i < programs.size(); ++i) {
+ QString program = programs.at(i);
+ process->start(program, args);
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(process->waitForFinished(5000));
+#else
+ QVERIFY(process->waitForStarted(10000));
+ QVERIFY(process->waitForFinished(10000));
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+ // Symbian test outputs to a file, so check that
+ FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","r");
+ QVERIFY(file);
+ char buf[256];
+ fgets(buf, 256, file);
+ fclose(file);
+ QStringList actual = QString::fromLatin1(buf).split("|");
+#elif !defined(Q_OS_WINCE)
+ QStringList actual = QString::fromLatin1(process->readAll()).split("|");
+#endif
+#if !defined(Q_OS_WINCE)
+ QVERIFY(!actual.isEmpty());
+ // not interested in the program name, it might be different.
+ actual.removeFirst();
+
+ QCOMPARE(actual, args);
+#endif
+
+ if (program.contains(" "))
+ program = "\"" + program + "\"";
+
+ if (!stringArgs.isEmpty())
+ program += QString::fromLatin1(" ") + stringArgs;
+
+ process->start(program);
+
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(process->waitForFinished(5000));
+
+#if defined(Q_OS_SYMBIAN)
+ // Symbian test outputs to a file, so check that
+ file = fopen("c:\\logs\\qprocess_args_test.txt","r");
+ QVERIFY(file);
+ fgets(buf, 256, file);
+ fclose(file);
+ actual = QString::fromLatin1(buf).split("|");
+#elif !defined(Q_OS_WINCE)
+ actual = QString::fromLatin1(process->readAll()).split("|");
+#endif
+#if !defined(Q_OS_WINCE)
+ QVERIFY(!actual.isEmpty());
+ // not interested in the program name, it might be different.
+ actual.removeFirst();
+
+ QCOMPARE(actual, args);
+#endif
+ }
+
+ delete process;
+ process = 0;
+}
+
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::nativeArguments()
+{
+ QProcess proc;
+
+ // This doesn't actually need special quoting, so it is pointless to use
+ // native arguments here, but that's not the point of this test.
+ proc.setNativeArguments("hello kitty, \"*\"!");
+
+ proc.start(QString::fromLatin1("testProcessSpacesArgs/nospace"), QStringList());
+
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QVERIFY(proc.waitForStarted(5000));
+ QVERIFY(proc.waitForFinished(5000));
+#else
+ QVERIFY(proc.waitForStarted(10000));
+ QVERIFY(proc.waitForFinished(10000));
+#endif
+
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE)
+ // Symbian test outputs to a file, so check that
+# ifdef Q_OS_SYMBIAN
+ FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","r");
+# else
+ FILE* file = fopen("\\temp\\qprocess_args_test.txt","r");
+# endif
+ QVERIFY(file);
+ char buf[256];
+ fgets(buf, 256, file);
+ fclose(file);
+ QStringList actual = QString::fromLatin1(buf).split("|");
+#else
+ QStringList actual = QString::fromLatin1(proc.readAll()).split("|");
+#endif
+ QVERIFY(!actual.isEmpty());
+ // not interested in the program name, it might be different.
+ actual.removeFirst();
+ QStringList expected;
+#if defined(Q_OS_WINCE)
+ expected << "hello" << "kitty," << "\"*\"!"; // Weird, weird ...
+#else
+ expected << "hello" << "kitty," << "*!";
+#endif
+ QCOMPARE(actual, expected);
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::exitCodeTest()
+{
+#if defined(Q_OS_SYMBIAN)
+ // Kernel will run out of process handles on some hw, as there is some
+ // delay before they are recycled, so limit the amount of processes.
+ for (int i = 0; i < 50; ++i) {
+#else
+ for (int i = 0; i < 255; ++i) {
+#endif
+ QProcess process;
+ process.start("testExitCodes/testExitCodes " + QString::number(i));
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.exitCode(), i);
+ QCOMPARE(process.error(), QProcess::UnknownError);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::failToStart()
+{
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+
+ QProcess process;
+ QSignalSpy stateSpy(&process, SIGNAL(stateChanged(QProcess::ProcessState)));
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+// Mac OS X and HP-UX have a really low default process limit (~100), so spawning
+// to many processes here will cause test failures later on.
+#if defined Q_OS_HPUX
+ const int attempts = 15;
+#elif defined Q_OS_MAC
+ const int attempts = 15;
+#else
+ const int attempts = 50;
+#endif
+
+ for (int j = 0; j < 8; ++j) {
+ for (int i = 0; i < attempts; ++i) {
+ QCOMPARE(errorSpy.count(), j * attempts + i);
+ process.start("/blurp");
+
+ switch (j) {
+ case 0:
+ case 1:
+ QVERIFY(!process.waitForStarted());
+ break;
+ case 2:
+ case 3:
+ QVERIFY(!process.waitForFinished());
+ break;
+ case 4:
+ case 5:
+ QVERIFY(!process.waitForReadyRead());
+ break;
+ case 6:
+ case 7:
+ default:
+ QVERIFY(!process.waitForBytesWritten());
+ break;
+ }
+
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(errorSpy.count(), j * attempts + i + 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+
+ int it = j * attempts + i + 1;
+
+ QCOMPARE(stateSpy.count(), it * 2);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(it * 2 - 2).at(0)), QProcess::Starting);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(it * 2 - 1).at(0)), QProcess::NotRunning);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::failToStartWithWait()
+{
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+
+ QProcess process;
+ QEventLoop loop;
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ for (int i = 0; i < 50; ++i) {
+ process.start("/blurp", QStringList() << "-v" << "-debug");
+ process.waitForStarted();
+
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(errorSpy.count(), i + 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::failToStartWithEventLoop()
+{
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+
+ QProcess process;
+ QEventLoop loop;
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ // The error signal may be emitted before start() returns
+ connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()), Qt::QueuedConnection);
+
+
+ for (int i = 0; i < 50; ++i) {
+ process.start("/blurp", QStringList() << "-v" << "-debug");
+
+ loop.exec();
+
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(errorSpy.count(), i + 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::removeFileWhileProcessIsRunning()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QFile file("removeFile.txt");
+ QVERIFY(file.open(QFile::WriteOnly));
+
+ QProcess process;
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+
+ QVERIFY(process.waitForStarted(5000));
+
+ QVERIFY(file.remove());
+
+ process.write("", 1);
+ QVERIFY(process.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setEnvironment_data()
+{
+ QTest::addColumn<QString>("name");
+ QTest::addColumn<QString>("value");
+
+ QTest::newRow("setting-empty") << "tst_QProcess" << "";
+ QTest::newRow("setting") << "tst_QProcess" << "value";
+
+#ifdef Q_OS_WIN
+ QTest::newRow("unsetting") << "PROMPT" << QString();
+ QTest::newRow("overriding") << "PROMPT" << "value";
+#else
+ QTest::newRow("unsetting") << "PATH" << QString();
+ QTest::newRow("overriding") << "PATH" << "value";
+#endif
+}
+
+void tst_QProcess::setEnvironment()
+{
+#if defined (Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("OS doesn't support environment variables", SkipAll);
+#endif
+
+ // make sure our environment variables are correct
+ QVERIFY(qgetenv("tst_QProcess").isEmpty());
+ QVERIFY(!qgetenv("PATH").isEmpty());
+#ifdef Q_OS_WIN
+ QVERIFY(!qgetenv("PROMPT").isEmpty());
+#endif
+
+ QFETCH(QString, name);
+ QFETCH(QString, value);
+ QString executable = QDir::currentPath() + "/testProcessEnvironment/testProcessEnvironment";
+
+ {
+ QProcess process;
+ QStringList environment = QProcess::systemEnvironment();
+ if (value.isNull()) {
+ int pos;
+ QRegExp rx(name + "=.*");
+#ifdef Q_OS_WIN
+ rx.setCaseSensitivity(Qt::CaseInsensitive);
+#endif
+ while ((pos = environment.indexOf(rx)) != -1)
+ environment.removeAt(pos);
+ } else {
+ environment.append(name + '=' + value);
+ }
+ process.setEnvironment(environment);
+ process.start(executable, QStringList() << name);
+
+ QVERIFY(process.waitForFinished());
+ if (value.isNull())
+ QCOMPARE(process.exitCode(), 1);
+ else if (!value.isEmpty())
+ QCOMPARE(process.exitCode(), 0);
+
+ QCOMPARE(process.readAll(), value.toLocal8Bit());
+ }
+
+ // re-do the test but set the environment twice, to make sure
+ // that the latter addition overrides
+ // this test doesn't make sense in unsetting
+ if (!value.isNull()) {
+ QProcess process;
+ QStringList environment = QProcess::systemEnvironment();
+ environment.prepend(name + "=This is not the right value");
+ environment.append(name + '=' + value);
+ process.setEnvironment(environment);
+ process.start(executable, QStringList() << name);
+
+ QVERIFY(process.waitForFinished());
+ if (!value.isEmpty())
+ QCOMPARE(process.exitCode(), 0);
+
+ QCOMPARE(process.readAll(), value.toLocal8Bit());
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setProcessEnvironment_data()
+{
+ setEnvironment_data();
+}
+
+void tst_QProcess::setProcessEnvironment()
+{
+#if defined (Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("OS doesn't support environment variables", SkipAll);
+#endif
+
+ // make sure our environment variables are correct
+ QVERIFY(qgetenv("tst_QProcess").isEmpty());
+ QVERIFY(!qgetenv("PATH").isEmpty());
+#ifdef Q_OS_WIN
+ QVERIFY(!qgetenv("PROMPT").isEmpty());
+#endif
+
+ QFETCH(QString, name);
+ QFETCH(QString, value);
+ QString executable = QDir::currentPath() + "/testProcessEnvironment/testProcessEnvironment";
+
+ {
+ QProcess process;
+ QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
+ if (value.isNull())
+ environment.remove(name);
+ else
+ environment.insert(name, value);
+ process.setProcessEnvironment(environment);
+ process.start(executable, QStringList() << name);
+
+ QVERIFY(process.waitForFinished());
+ if (value.isNull())
+ QCOMPARE(process.exitCode(), 1);
+ else if (!value.isEmpty())
+ QCOMPARE(process.exitCode(), 0);
+
+ QCOMPARE(process.readAll(), value.toLocal8Bit());
+ }
+}
+//-----------------------------------------------------------------------------
+void tst_QProcess::systemEnvironment()
+{
+#if defined (Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ // there is no concept of system variables on Windows CE as there is no console
+ QVERIFY(QProcess::systemEnvironment().isEmpty());
+ QVERIFY(QProcessEnvironment::systemEnvironment().isEmpty());
+#else
+ QVERIFY(!QProcess::systemEnvironment().isEmpty());
+ QVERIFY(!QProcessEnvironment::systemEnvironment().isEmpty());
+
+ QVERIFY(QProcessEnvironment::systemEnvironment().contains("PATH"));
+ QVERIFY(!QProcess::systemEnvironment().filter(QRegExp("^PATH=", Qt::CaseInsensitive)).isEmpty());
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::spaceInName()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+ QProcess process;
+ process.start("test Space In Name/testSpaceInName", QStringList());
+ QVERIFY(process.waitForStarted());
+ process.write("", 1);
+ QVERIFY(process.waitForFinished());
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::lockupsInStartDetached()
+{
+#if !defined(Q_OS_SYMBIAN)
+ // Check that QProcess doesn't cause a lock up at this program's
+ // exit if a thread was started and we tried to run a program that
+ // doesn't exist. Before Qt 4.2, this used to lock up on Unix due
+ // to calling ::exit instead of ::_exit if execve failed.
+
+ QHostInfo::lookupHost(QString("something.invalid"), 0, 0);
+ QProcess::execute("yjhbrty");
+ QProcess::startDetached("yjhbrty");
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::atEnd2()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+ process.write("Foo\nBar\nBaz\nBodukon\nHadukan\nTorwukan\nend\n");
+ process.putChar('\0');
+ QVERIFY(process.waitForFinished());
+ QList<QByteArray> lines;
+ while (!process.atEnd()) {
+ lines << process.readLine();
+ }
+ QCOMPARE(lines.size(), 7);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForReadyReadForNonexistantProcess()
+{
+ // This comes from task 108968
+ // Start a program that doesn't exist, process events and then try to waitForReadyRead
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+
+ QProcess process;
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy1(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+ QVERIFY(!process.waitForReadyRead()); // used to crash
+ process.start("doesntexist");
+ QVERIFY(!process.waitForReadyRead());
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy.at(0).at(0).toInt(), 0);
+ QCOMPARE(finishedSpy1.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setStandardInputFile()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ static const char data[] = "A bunch\1of\2data\3\4\5\6\7...";
+ QProcess process;
+ QFile file("data");
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.write(data, sizeof data);
+ file.close();
+
+ process.setStandardInputFile("data");
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+
+ QPROCESS_VERIFY(process, waitForFinished());
+ QByteArray all = process.readAll();
+ QCOMPARE(all.size(), int(sizeof data) - 1); // testProcessEcho drops the ending \0
+ QVERIFY(all == data);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setStandardOutputFile_data()
+{
+ QTest::addColumn<int>("channelToTest");
+ QTest::addColumn<int>("_channelMode");
+ QTest::addColumn<bool>("append");
+
+ QTest::newRow("stdout-truncate") << int(QProcess::StandardOutput)
+ << int(QProcess::SeparateChannels)
+ << false;
+ QTest::newRow("stdout-append") << int(QProcess::StandardOutput)
+ << int(QProcess::SeparateChannels)
+ << true;
+
+ QTest::newRow("stderr-truncate") << int(QProcess::StandardError)
+ << int(QProcess::SeparateChannels)
+ << false;
+ QTest::newRow("stderr-append") << int(QProcess::StandardError)
+ << int(QProcess::SeparateChannels)
+ << true;
+
+ QTest::newRow("merged-truncate") << int(QProcess::StandardOutput)
+ << int(QProcess::MergedChannels)
+ << false;
+ QTest::newRow("merged-append") << int(QProcess::StandardOutput)
+ << int(QProcess::MergedChannels)
+ << true;
+}
+
+void tst_QProcess::setStandardOutputFile()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ static const char data[] = "Original data. ";
+ static const char testdata[] = "Test data.";
+
+ QFETCH(int, channelToTest);
+ QFETCH(int, _channelMode);
+ QFETCH(bool, append);
+
+ QProcess::ProcessChannelMode channelMode = QProcess::ProcessChannelMode(_channelMode);
+ QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
+
+ // create the destination file with data
+ QFile file("data");
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.write(data, sizeof data - 1);
+ file.close();
+
+ // run the process
+ QProcess process;
+ process.setReadChannelMode(channelMode);
+ if (channelToTest == QProcess::StandardOutput)
+ process.setStandardOutputFile("data", mode);
+ else
+ process.setStandardErrorFile("data", mode);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+ process.write(testdata, sizeof testdata);
+ QPROCESS_VERIFY(process,waitForFinished());
+
+ // open the file again and verify the data
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QByteArray all = file.readAll();
+ file.close();
+
+ int expectedsize = sizeof testdata - 1;
+ if (mode == QIODevice::Append) {
+ QVERIFY(all.startsWith(data));
+ expectedsize += sizeof data - 1;
+ }
+ if (channelMode == QProcess::MergedChannels) {
+ expectedsize += sizeof testdata - 1;
+ } else {
+ QVERIFY(all.endsWith(testdata));
+ }
+
+ QCOMPARE(all.size(), expectedsize);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setStandardOutputProcess_data()
+{
+ QTest::addColumn<bool>("merged");
+ QTest::newRow("separate") << false;
+ QTest::newRow("merged") << true;
+}
+
+void tst_QProcess::setStandardOutputProcess()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QProcess source;
+ QProcess sink;
+
+ QFETCH(bool, merged);
+ source.setReadChannelMode(merged ? QProcess::MergedChannels : QProcess::SeparateChannels);
+ source.setStandardOutputProcess(&sink);
+
+#ifdef Q_OS_MAC
+ source.start("testProcessEcho2/testProcessEcho2.app");
+ sink.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ source.start("testProcessEcho2/testProcessEcho2");
+ sink.start("testProcessEcho2/testProcessEcho2");
+#endif
+
+ QByteArray data("Hello, World");
+ source.write(data);
+ source.closeWriteChannel();
+ QPROCESS_VERIFY(source, waitForFinished());
+ QPROCESS_VERIFY(sink, waitForFinished());
+ QByteArray all = sink.readAll();
+
+ if (!merged)
+ QCOMPARE(all, data);
+ else
+ QCOMPARE(all, QByteArray("HHeelllloo,, WWoorrlldd"));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::fileWriterProcess()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+
+ QString stdinStr;
+ for (int i = 0; i < 5000; ++i)
+ stdinStr += QString::fromLatin1("%1 -- testing testing 1 2 3\n").arg(i);
+
+ QTime stopWatch;
+ stopWatch.start();
+ do {
+ QFile::remove("fileWriterProcess.txt");
+ QProcess process;
+ process.start("fileWriterProcess/fileWriterProcess",
+ QIODevice::ReadWrite | QIODevice::Text);
+ process.write(stdinStr.toLatin1());
+ process.closeWriteChannel();
+ while (process.bytesToWrite()) {
+ QVERIFY(stopWatch.elapsed() < 3500);
+ QVERIFY(process.waitForBytesWritten(2000));
+ }
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(QFile("fileWriterProcess.txt").size(), qint64(stdinStr.size()));
+ } while (stopWatch.elapsed() < 3000);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::detachedWorkingDirectoryAndPid()
+{
+#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
+ // WINSCW builds in Symbian do not allow multiple processes to load Qt libraries,
+ // so this test must be skipped.
+ QSKIP("Multiple processes loading Qt are not allowed in Qt/Symbian emulator.", SkipAll);
+#endif
+ qint64 pid;
+
+#ifdef Q_OS_WINCE
+ QTest::qSleep(1000);
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+ // Symbian has no working directory support, so use logs dir as a shared directory
+ QFile infoFile(QLatin1String("c:\\logs\\detachedinfo.txt"));
+#else
+ QFile infoFile(QDir::currentPath() + QLatin1String("/detachedinfo.txt"));
+#endif
+ infoFile.remove();
+
+ QString workingDir = QDir::currentPath() + "/testDetached";
+
+#ifndef Q_OS_SYMBIAN
+ QVERIFY(QFile::exists(workingDir));
+#endif
+
+ QStringList args;
+ args << infoFile.fileName();
+ QVERIFY(QProcess::startDetached(QDir::currentPath() + QLatin1String("/testDetached/testDetached"), args, workingDir, &pid));
+
+ QFileInfo fi(infoFile);
+ fi.setCaching(false);
+ //The guard counter ensures the test does not hang if the sub process fails.
+ //Instead, the test will fail when trying to open & verify the sub process output file.
+ for (int guard = 0; guard < 100 && fi.size() == 0; guard++) {
+ QTest::qSleep(100);
+ }
+
+ QVERIFY(infoFile.open(QIODevice::ReadOnly | QIODevice::Text));
+ QString actualWorkingDir = QString::fromUtf8(infoFile.readLine());
+ actualWorkingDir.chop(1); // strip off newline
+ QByteArray processIdString = infoFile.readLine();
+ processIdString.chop(1);
+ infoFile.close();
+ infoFile.remove();
+
+ bool ok = false;
+ qint64 actualPid = processIdString.toLongLong(&ok);
+ QVERIFY(ok);
+
+#if defined(Q_OS_SYMBIAN)
+ QEXPECT_FAIL("", "Working directory is not supported on Qt/symbian", Continue);
+#endif
+ QCOMPARE(actualWorkingDir, workingDir);
+ QCOMPARE(actualPid, pid);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::switchReadChannels()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Reading and writing to a process is not supported on Qt/Symbian", SkipAll);
+#endif
+ const char data[] = "ABCD";
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+ process.write(data);
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+
+ for (int i = 0; i < 4; ++i) {
+ process.setReadChannel(QProcess::StandardOutput);
+ QCOMPARE(process.read(1), QByteArray(&data[i], 1));
+ process.setReadChannel(QProcess::StandardError);
+ QCOMPARE(process.read(1), QByteArray(&data[i], 1));
+ }
+
+ process.ungetChar('D');
+ process.setReadChannel(QProcess::StandardOutput);
+ process.ungetChar('D');
+ process.setReadChannel(QProcess::StandardError);
+ QCOMPARE(process.read(1), QByteArray("D"));
+ process.setReadChannel(QProcess::StandardOutput);
+ QCOMPARE(process.read(1), QByteArray("D"));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setWorkingDirectory()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Windows CE does not support working directory logic", SkipAll);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QSKIP("Symbian does not support working directory logic", SkipAll);
+#endif
+ process = new QProcess;
+ process->setWorkingDirectory("test");
+#ifdef Q_OS_MAC
+ process->start("testSetWorkingDirectory/testSetWorkingDirectory.app");
+#else
+ process->start("testSetWorkingDirectory/testSetWorkingDirectory");
+#endif
+#ifndef Q_OS_WIN
+ QSKIP("setWorkingDirectory will chdir before starting the process on unices", SkipAll);
+#endif
+ QVERIFY(process->waitForFinished());
+
+ QByteArray workingDir = process->readAllStandardOutput();
+ QCOMPARE(QDir("test").canonicalPath(), QDir(workingDir.constData()).canonicalPath());
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::startFinishStartFinish()
+{
+ QProcess process;
+
+ for (int i = 0; i < 3; ++i) {
+ QCOMPARE(process.state(), QProcess::NotRunning);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessOutput/testProcessOutput.app");
+#else
+ process.start("testProcessOutput/testProcessOutput");
+#endif
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QVERIFY(process.waitForReadyRead(10000));
+ QCOMPARE(QString::fromLatin1(process.readLine().trimmed()),
+ QString("0 -this is a number"));
+#endif
+ if (process.state() != QProcess::NotRunning)
+ QVERIFY(process.waitForFinished(10000));
+#if defined(Q_OS_SYMBIAN)
+ // Symbian test outputs to a file, so check that
+ FILE* file = fopen("c:\\logs\\qprocess_output_test.txt","r");
+ QVERIFY(file);
+ char buf[30];
+ fgets(buf, 30, file);
+ QCOMPARE(QString::fromLatin1(buf),
+ QString("0 -this is a number\n"));
+ fclose(file);
+#endif
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::invalidProgramString_data()
+{
+ QTest::addColumn<QString>("programString");
+ QTest::newRow("null string") << QString();
+ QTest::newRow("empty string") << QString("");
+ QTest::newRow("only blank string") << QString(" ");
+}
+
+void tst_QProcess::invalidProgramString()
+{
+ QFETCH(QString, programString);
+ QProcess process;
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ QSignalSpy spy(&process, SIGNAL(error(QProcess::ProcessError)));
+
+ process.start(programString);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(spy.count(), 1);
+
+ QVERIFY(!QProcess::startDetached(programString));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::onlyOneStartedSignal()
+{
+ QProcess process;
+
+ QSignalSpy spyStarted(&process, SIGNAL(started()));
+ QSignalSpy spyFinished(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ process.start("testProcessNormal/testProcessNormal");
+ QVERIFY(process.waitForStarted(5000));
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(spyStarted.count(), 1);
+ QCOMPARE(spyFinished.count(), 1);
+
+ spyStarted.clear();
+ spyFinished.clear();
+
+ process.start("testProcessNormal/testProcessNormal");
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(spyStarted.count(), 1);
+ QCOMPARE(spyFinished.count(), 1);
+}
+
+QTEST_MAIN(tst_QProcess)
+#include "tst_qprocess.moc"
+#endif
+
diff --git a/tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro b/tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro
new file mode 100644
index 0000000000..60dba50813
--- /dev/null
+++ b/tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+
+QT = core
+
+SOURCES += tst_qprocessenvironment.cpp
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp
new file mode 100644
index 0000000000..d88ffdedb7
--- /dev/null
+++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest>
+#include <QObject>
+#include <QProcessEnvironment>
+
+class tst_QProcessEnvironment: public QObject
+{
+ Q_OBJECT
+private slots:
+ void operator_eq();
+ void clearAndIsEmpty();
+ void insert();
+ void emptyNull();
+ void toStringList();
+ void keys();
+ void insertEnv();
+
+ void caseSensitivity();
+ void systemEnvironment();
+ void putenv();
+};
+
+void tst_QProcessEnvironment::operator_eq()
+{
+ QProcessEnvironment e1;
+ QVERIFY(e1 == e1);
+ e1.clear();
+ QVERIFY(e1 == e1);
+
+ e1 = QProcessEnvironment();
+ QProcessEnvironment e2;
+ QVERIFY(e1 == e2);
+
+ e1.clear();
+ QVERIFY(e1 != e2);
+
+ e2.clear();
+
+ QVERIFY(e1 == e2);
+}
+
+void tst_QProcessEnvironment::clearAndIsEmpty()
+{
+ QProcessEnvironment e;
+ e.insert("FOO", "bar");
+ QVERIFY(!e.isEmpty());
+ e.clear();
+ QVERIFY(e.isEmpty());
+}
+
+void tst_QProcessEnvironment::insert()
+{
+ QProcessEnvironment e;
+ e.insert("FOO", "bar");
+ QVERIFY(!e.isEmpty());
+ QVERIFY(e.contains("FOO"));
+ QCOMPARE(e.value("FOO"), QString("bar"));
+
+ e.remove("FOO");
+ QVERIFY(!e.contains("FOO"));
+ QVERIFY(e.value("FOO").isNull());
+
+ e.clear();
+ QVERIFY(!e.contains("FOO"));
+}
+
+void tst_QProcessEnvironment::emptyNull()
+{
+ QProcessEnvironment e;
+
+ e.insert("FOO", "");
+ QVERIFY(e.contains("FOO"));
+ QVERIFY(e.value("FOO").isEmpty());
+ QVERIFY(!e.value("FOO").isNull());
+
+ e.insert("FOO", QString());
+ QVERIFY(e.contains("FOO"));
+ QVERIFY(e.value("FOO").isEmpty());
+ // don't test if it's NULL, since we shall not make a guarantee
+
+ e.remove("FOO");
+ QVERIFY(!e.contains("FOO"));
+}
+
+void tst_QProcessEnvironment::toStringList()
+{
+ QProcessEnvironment e;
+ QVERIFY(e.isEmpty());
+ QVERIFY(e.toStringList().isEmpty());
+
+ e.insert("FOO", "bar");
+ QStringList result = e.toStringList();
+ QVERIFY(!result.isEmpty());
+ QCOMPARE(result.length(), 1);
+ QCOMPARE(result.at(0), QString("FOO=bar"));
+
+ e.clear();
+ e.insert("BAZ", "");
+ result = e.toStringList();
+ QCOMPARE(result.at(0), QString("BAZ="));
+
+ e.insert("FOO", "bar");
+ e.insert("A", "bc");
+ e.insert("HELLO", "World");
+ result = e.toStringList();
+ QCOMPARE(result.length(), 4);
+
+ // order is not specified, so use contains()
+ QVERIFY(result.contains("FOO=bar"));
+ QVERIFY(result.contains("BAZ="));
+ QVERIFY(result.contains("A=bc"));
+ QVERIFY(result.contains("HELLO=World"));
+}
+
+void tst_QProcessEnvironment::keys()
+{
+ QProcessEnvironment e;
+ QVERIFY(e.isEmpty());
+ QVERIFY(e.keys().isEmpty());
+
+ e.insert("FOO", "bar");
+ QStringList result = e.keys();
+ QCOMPARE(result.length(), 1);
+ QCOMPARE(result.at(0), QString("FOO"));
+
+ e.clear();
+ e.insert("BAZ", "");
+ result = e.keys();
+ QCOMPARE(result.at(0), QString("BAZ"));
+
+ e.insert("FOO", "bar");
+ e.insert("A", "bc");
+ e.insert("HELLO", "World");
+ result = e.keys();
+ QCOMPARE(result.length(), 4);
+
+ // order is not specified, so use contains()
+ QVERIFY(result.contains("FOO"));
+ QVERIFY(result.contains("BAZ"));
+ QVERIFY(result.contains("A"));
+ QVERIFY(result.contains("HELLO"));
+}
+
+void tst_QProcessEnvironment::insertEnv()
+{
+ QProcessEnvironment e;
+ e.insert("FOO", "bar");
+ e.insert("A", "bc");
+ e.insert("Hello", "World");
+
+ QProcessEnvironment e2;
+ e2.insert("FOO2", "bar2");
+ e2.insert("A2", "bc2");
+ e2.insert("Hello", "Another World");
+
+ e.insert(e2);
+ QStringList keys = e.keys();
+ QCOMPARE(keys.length(), 5);
+
+ QCOMPARE(e.value("FOO"), QString("bar"));
+ QCOMPARE(e.value("A"), QString("bc"));
+ QCOMPARE(e.value("Hello"), QString("Another World"));
+ QCOMPARE(e.value("FOO2"), QString("bar2"));
+ QCOMPARE(e.value("A2"), QString("bc2"));
+}
+
+void tst_QProcessEnvironment::caseSensitivity()
+{
+ QProcessEnvironment e;
+ e.insert("foo", "bar");
+
+#ifdef Q_OS_WIN
+ // Windows is case-insensitive, but case-preserving
+ QVERIFY(e.contains("foo"));
+ QVERIFY(e.contains("FOO"));
+ QVERIFY(e.contains("FoO"));
+
+ QCOMPARE(e.value("foo"), QString("bar"));
+ QCOMPARE(e.value("FOO"), QString("bar"));
+ QCOMPARE(e.value("FoO"), QString("bar"));
+
+ // Per Windows, this overwrites the value, but keeps the name's original capitalization
+ e.insert("Foo", "Bar");
+
+ QStringList list = e.toStringList();
+ QCOMPARE(list.length(), 1);
+ QCOMPARE(list.at(0), QString("foo=Bar"));
+#else
+ // otherwise, it's case sensitive
+ QVERIFY(e.contains("foo"));
+ QVERIFY(!e.contains("FOO"));
+
+ e.insert("FOO", "baz");
+ QVERIFY(e.contains("FOO"));
+ QCOMPARE(e.value("FOO"), QString("baz"));
+ QCOMPARE(e.value("foo"), QString("bar"));
+
+ QStringList list = e.toStringList();
+ QCOMPARE(list.length(), 2);
+ QVERIFY(list.contains("foo=bar"));
+ QVERIFY(list.contains("FOO=baz"));
+#endif
+}
+
+void tst_QProcessEnvironment::systemEnvironment()
+{
+ static const char envname[] = "THIS_ENVIRONMENT_VARIABLE_HOPEFULLY_DOESNT_EXIST";
+ QByteArray path = qgetenv("PATH");
+ QByteArray nonexistant = qgetenv(envname);
+ QProcessEnvironment system = QProcessEnvironment::systemEnvironment();
+
+ QVERIFY(nonexistant.isNull());
+
+#ifdef Q_WS_WINCE
+ // Windows CE has no environment
+ QVERIFY(path.isEmpty());
+ QVERIFY(!system.contains("PATH"));
+ QVERIFY(system.isEmpty());
+#else
+ // all other system have environments
+ if (path.isEmpty())
+ QFAIL("Could not find the PATH environment variable -- please correct the test environment");
+
+ QVERIFY(system.contains("PATH"));
+ QCOMPARE(system.value("PATH"), QString::fromLocal8Bit(path));
+
+ QVERIFY(!system.contains(envname));
+
+# ifdef Q_OS_WIN
+ // check case-insensitive too
+ QVERIFY(system.contains("path"));
+ QCOMPARE(system.value("path"), QString::fromLocal8Bit(path));
+
+ QVERIFY(!system.contains(QString(envname).toLower()));
+# endif
+#endif
+}
+
+void tst_QProcessEnvironment::putenv()
+{
+#ifdef Q_WS_WINCE
+ QSKIP("Windows CE has no environment", SkipAll);
+#else
+ static const char envname[] = "WE_RE_SETTING_THIS_ENVIRONMENT_VARIABLE";
+ static bool testRan = false;
+
+ if (testRan)
+ QFAIL("You cannot run this test more than once, since we modify the environment");
+ testRan = true;
+
+ QByteArray valBefore = qgetenv(envname);
+ if (!valBefore.isNull())
+ QFAIL("The environment variable we set in the environment is already set! -- please correct the test environment");
+ QProcessEnvironment eBefore = QProcessEnvironment::systemEnvironment();
+
+ qputenv(envname, "Hello, World");
+ QByteArray valAfter = qgetenv(envname);
+ if (valAfter != "Hello, World")
+ QSKIP("Could not test: qputenv did not do its job", SkipAll);
+
+ QProcessEnvironment eAfter = QProcessEnvironment::systemEnvironment();
+
+ QVERIFY(!eBefore.contains(envname));
+ QVERIFY(eAfter.contains(envname));
+ QCOMPARE(eAfter.value(envname), QString("Hello, World"));
+
+# ifdef Q_OS_WIN
+ // check case-insensitive too
+ QString lower = envname;
+ lower = lower.toLower();
+ QVERIFY(!eBefore.contains(lower));
+ QVERIFY(eAfter.contains(lower));
+ QCOMPARE(eAfter.value(lower), QString("Hello, World"));
+# endif
+#endif
+}
+
+QTEST_MAIN(tst_QProcessEnvironment)
+
+#include "tst_qprocessenvironment.moc"
diff --git a/tests/auto/corelib/io/qresourceengine/.gitattributes b/tests/auto/corelib/io/qresourceengine/.gitattributes
new file mode 100644
index 0000000000..add3716d81
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/.gitattributes
@@ -0,0 +1 @@
+testqrc/test.qrc -crlf
diff --git a/tests/auto/corelib/io/qresourceengine/.gitignore b/tests/auto/corelib/io/qresourceengine/.gitignore
new file mode 100644
index 0000000000..eb48d60239
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/.gitignore
@@ -0,0 +1 @@
+tst_qresourceengine
diff --git a/tests/auto/corelib/io/qresourceengine/parentdir.txt b/tests/auto/corelib/io/qresourceengine/parentdir.txt
new file mode 100644
index 0000000000..a94edee379
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/parentdir.txt
@@ -0,0 +1 @@
+abcdefgihklmnopqrstuvwxyz
diff --git a/tests/auto/corelib/io/qresourceengine/qresourceengine.pro b/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
new file mode 100644
index 0000000000..abbf39bd83
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
@@ -0,0 +1,47 @@
+######################################################################
+# Automatically generated by qmake (2.00a) ma 2. mai 16:14:33 2005
+######################################################################
+
+load(qttest_p4)
+load(resources)
+
+# Input
+SOURCES += tst_qresourceengine.cpp
+RESOURCES += testqrc/test.qrc
+
+symbian-sbsv2 {
+ runtime_resource.target = $$PWD/runtime_resource.rcc
+} else {
+ runtime_resource.target = runtime_resource.rcc
+}
+runtime_resource.depends = $$PWD/testqrc/test.qrc
+runtime_resource.commands = $$QMAKE_RCC -root /runtime_resource/ -binary $${runtime_resource.depends} -o $${runtime_resource.target}
+QMAKE_EXTRA_TARGETS = runtime_resource
+PRE_TARGETDEPS += $${runtime_resource.target}
+
+QT = core
+wince*|symbian:{
+ deploy.files += runtime_resource.rcc parentdir.txt
+ test.files = testqrc/*
+ test.path = testqrc
+ alias.files = testqrc/aliasdir/*
+ alias.path = testqrc/aliasdir
+ other.files = testqrc/otherdir/*
+ other.path = testqrc/otherdir
+ search1.files = testqrc/searchpath1/*
+ search1.path = testqrc/searchpath1
+ search2.files = testqrc/searchpath2/*
+ search2.path = testqrc/searchpath2
+ sub.files = testqrc/subdir/*
+ sub.path = testqrc/subdir
+ testsub.files = testqrc/test/*
+ testsub.path = testqrc/test
+ testsub2.files = testqrc/test/test/*
+ testsub2.path = testqrc/test/test
+ DEPLOYMENT += deploy test alias other search1 search2 sub testsub testsub2
+ !symbian:DEFINES += SRCDIR=\\\"\\\"
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+CONFIG += parallel_test
+CONFIG += insignificant_test # QTBUG-21159
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt
new file mode 100644
index 0000000000..21a3dfa0b8
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt
@@ -0,0 +1 @@
+"This is a korean text file"
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/compressme.txt b/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/compressme.txt
new file mode 100644
index 0000000000..bd596cdacd
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/compressme.txt
@@ -0,0 +1,322 @@
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt b/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt
new file mode 100644
index 0000000000..436c4d11c3
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt
@@ -0,0 +1 @@
+qwerty
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt
new file mode 100644
index 0000000000..38e389979a
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt
@@ -0,0 +1 @@
+"This is the current dir"
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt
new file mode 100644
index 0000000000..6ac16a3306
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt
@@ -0,0 +1 @@
+"This is also the current dir"
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt
new file mode 100644
index 0000000000..b0e4a124ee
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt
@@ -0,0 +1 @@
+"This is the other dir"
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/search_file.txt b/tests/auto/corelib/io/qresourceengine/testqrc/search_file.txt
new file mode 100644
index 0000000000..d8649da39d
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/search_file.txt
@@ -0,0 +1 @@
+root
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/searchpath1/search_file.txt b/tests/auto/corelib/io/qresourceengine/testqrc/searchpath1/search_file.txt
new file mode 100644
index 0000000000..3f31b59496
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/searchpath1/search_file.txt
@@ -0,0 +1 @@
+path1
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/searchpath2/search_file.txt b/tests/auto/corelib/io/qresourceengine/testqrc/searchpath2/search_file.txt
new file mode 100644
index 0000000000..8e3be1fa2e
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/searchpath2/search_file.txt
@@ -0,0 +1 @@
+path2
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt
new file mode 100644
index 0000000000..b6115207a2
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt
@@ -0,0 +1 @@
+"This is in the sub directory"
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc
new file mode 100644
index 0000000000..f5e8c849a6
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc
@@ -0,0 +1,30 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/test/abc/123/+++">
+ <file>currentdir.txt</file>
+ <file>./currentdir2.txt</file>
+ <file>../parentdir.txt</file>
+ <file>subdir/subdir.txt</file>
+ </qresource>
+ <qresource prefix="/">
+ <file>searchpath1/search_file.txt</file>
+ <file>searchpath2/search_file.txt</file>
+ <file>search_file.txt</file>
+ </qresource>
+ <qresource><file>test/testdir.txt</file>
+ <file>otherdir/otherdir.txt</file>
+ <file alias="aliasdir/aliasdir.txt">test/testdir2.txt</file>
+ <file>test/test</file>
+ </qresource>
+ <qresource lang="ko">
+ <file>aliasdir/aliasdir.txt</file>
+ </qresource>
+ <qresource lang="de_CH">
+ <file alias="aliasdir/aliasdir.txt" compress="9" threshold="30">aliasdir/compressme.txt</file>
+ </qresource>
+ <qresource lang="de">
+ <file alias="aliasdir/aliasdir.txt">test/german.txt</file>
+ </qresource>
+ <qresource prefix="withoutslashes">
+ <file>blahblah.txt</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/german.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/german.txt
new file mode 100644
index 0000000000..12b1cb7320
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/german.txt
@@ -0,0 +1 @@
+Deutsch
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt
new file mode 100644
index 0000000000..adc01d1354
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt
@@ -0,0 +1 @@
+abc
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt
new file mode 100644
index 0000000000..3f48e3cdc3
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt
@@ -0,0 +1 @@
+def
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt
new file mode 100644
index 0000000000..40ee68dccb
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt
@@ -0,0 +1 @@
+"This is in the test directory"
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt
new file mode 100644
index 0000000000..051430298a
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt
@@ -0,0 +1 @@
+"This is another file in this directory"
diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
new file mode 100644
index 0000000000..7914fc8bfc
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
@@ -0,0 +1,488 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+#include <QtCore>
+
+#ifdef Q_OS_SYMBIAN
+#define SRCDIR "."
+#endif
+
+class tst_QResourceEngine: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+ void checkUnregisterResource_data();
+ void checkUnregisterResource();
+ void checkStructure_data();
+ void checkStructure();
+ void searchPath_data();
+ void searchPath();
+ void doubleSlashInRoot();
+ void setLocale();
+
+private:
+ QString builddir;
+};
+
+Q_DECLARE_METATYPE(QLocale)
+Q_DECLARE_METATYPE(qlonglong)
+
+void tst_QResourceEngine::initTestCase()
+{
+ QVERIFY(QResource::registerResource("runtime_resource.rcc"));
+ QVERIFY(QResource::registerResource("runtime_resource.rcc", "/secondary_root/"));
+ QString srcdir(QLatin1String(SRCDIR));
+ if (!srcdir.isEmpty()) {
+ builddir = QDir::current().absolutePath();
+ if (!builddir.endsWith(QDir::separator()))
+ builddir.append(QDir::separator());
+ QDir::setCurrent(srcdir);
+ }
+}
+
+void tst_QResourceEngine::cleanupTestCase()
+{
+ if (!builddir.isEmpty()) {
+ QDir::setCurrent(builddir);
+ }
+
+ // make sure we don't leak memory
+ QVERIFY(QResource::unregisterResource("runtime_resource.rcc"));
+ QVERIFY(QResource::unregisterResource("runtime_resource.rcc", "/secondary_root/"));
+}
+
+void tst_QResourceEngine::checkStructure_data()
+{
+ QTest::addColumn<QString>("pathName");
+ QTest::addColumn<QString>("contents");
+ QTest::addColumn<QStringList>("containedFiles");
+ QTest::addColumn<QStringList>("containedDirs");
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<qlonglong>("contentsSize");
+
+ QFileInfo info;
+
+ QTest::newRow("root dir") << QString(":/")
+ << QString()
+ << (QStringList() << "search_file.txt")
+ << (QStringList() << QLatin1String("aliasdir") << QLatin1String("otherdir")
+ << QLatin1String("runtime_resource")
+ << QLatin1String("searchpath1") << QLatin1String("searchpath2")
+ << QLatin1String("secondary_root")
+ << QLatin1String("test")
+ << QLatin1String("withoutslashes"))
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow("secondary root") << QString(":/secondary_root/")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("runtime_resource"))
+ << QLocale::c()
+ << qlonglong(0);
+
+ QStringList roots;
+ roots << QString(":/") << QString(":/runtime_resource/") << QString(":/secondary_root/runtime_resource/");
+ for(int i = 0; i < roots.size(); ++i) {
+ const QString root = roots.at(i);
+
+ QTest::newRow(QString(root + "prefix dir").toLatin1().constData()) << QString(root + "test/abc/123/+++")
+ << QString()
+ << (QStringList() << QLatin1String("currentdir.txt") << QLatin1String("currentdir2.txt") << QLatin1String("parentdir.txt"))
+ << (QStringList() << QLatin1String("subdir"))
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "parent to prefix").toLatin1().constData()) << QString(root + "test/abc/123")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("+++"))
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "two parents prefix").toLatin1().constData()) << QString(root + "test/abc")
+ << QString()
+ << QStringList()
+ << QStringList(QLatin1String("123"))
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "test dir ").toLatin1().constData()) << QString(root + "test")
+ << QString()
+ << (QStringList() << QLatin1String("testdir.txt"))
+ << (QStringList() << QLatin1String("abc") << QLatin1String("test"))
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "prefix no slashes").toLatin1().constData()) << QString(root + "withoutslashes")
+ << QString()
+ << QStringList("blahblah.txt")
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "other dir").toLatin1().constData()) << QString(root + "otherdir")
+ << QString()
+ << QStringList(QLatin1String("otherdir.txt"))
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "alias dir").toLatin1().constData()) << QString(root + "aliasdir")
+ << QString()
+ << QStringList(QLatin1String("aliasdir.txt"))
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(0);
+
+ QTest::newRow(QString(root + "second test dir").toLatin1().constData()) << QString(root + "test/test")
+ << QString()
+ << (QStringList() << QLatin1String("test1.txt") << QLatin1String("test2.txt"))
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(0);
+
+ info = QFileInfo("testqrc/test/test/test1.txt");
+ QTest::newRow(QString(root + "test1 text").toLatin1().constData()) << QString(root + "test/test/test1.txt")
+ << QString("abc")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/blahblah.txt");
+ QTest::newRow(QString(root + "text no slashes").toLatin1().constData()) << QString(root + "withoutslashes/blahblah.txt")
+ << QString("qwerty")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+
+ info = QFileInfo("testqrc/test/test/test2.txt");
+ QTest::newRow(QString(root + "test1 text").toLatin1().constData()) << QString(root + "test/test/test2.txt")
+ << QString("def")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/currentdir.txt");
+ QTest::newRow(QString(root + "currentdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/currentdir.txt")
+ << QString("\"This is the current dir\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/currentdir2.txt");
+ QTest::newRow(QString(root + "currentdir text2").toLatin1().constData()) << QString(root + "test/abc/123/+++/currentdir2.txt")
+ << QString("\"This is also the current dir\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("parentdir.txt");
+ QTest::newRow(QString(root + "parentdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/parentdir.txt")
+ << QString("abcdefgihklmnopqrstuvwxyz ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/subdir/subdir.txt");
+ QTest::newRow(QString(root + "subdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/subdir/subdir.txt")
+ << QString("\"This is in the sub directory\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/test/testdir.txt");
+ QTest::newRow(QString(root + "testdir text").toLatin1().constData()) << QString(root + "test/testdir.txt")
+ << QString("\"This is in the test directory\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/otherdir/otherdir.txt");
+ QTest::newRow(QString(root + "otherdir text").toLatin1().constData()) << QString(root + "otherdir/otherdir.txt")
+ << QString("\"This is the other dir\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/test/testdir2.txt");
+ QTest::newRow(QString(root + "alias text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt")
+ << QString("\"This is another file in this directory\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale::c()
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/aliasdir/aliasdir.txt");
+ QTest::newRow(QString(root + "korean text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt")
+ << QString("\"This is a korean text file\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale("ko")
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/aliasdir/aliasdir.txt");
+ QTest::newRow(QString(root + "korean text 2").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt")
+ << QString("\"This is a korean text file\" ")
+ << QStringList()
+ << QStringList()
+ << QLocale("ko_KR")
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/test/german.txt");
+ QTest::newRow(QString(root + "german text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt")
+ << QString("Deutsch")
+ << QStringList()
+ << QStringList()
+ << QLocale("de")
+ << qlonglong(info.size());
+
+ info = QFileInfo("testqrc/test/german.txt");
+ QTest::newRow(QString(root + "german text 2").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt")
+ << QString("Deutsch")
+ << QStringList()
+ << QStringList()
+ << QLocale("de_DE")
+ << qlonglong(info.size());
+
+ QFile file("testqrc/aliasdir/compressme.txt");
+ file.open(QFile::ReadOnly);
+ info = QFileInfo("testqrc/aliasdir/compressme.txt");
+ QTest::newRow(QString(root + "compressed text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt")
+ << QString(file.readAll())
+ << QStringList()
+ << QStringList()
+ << QLocale("de_CH")
+ << qlonglong(info.size());
+ }
+}
+
+void tst_QResourceEngine::checkStructure()
+{
+ QFETCH(QString, pathName);
+ QFETCH(QString, contents);
+ QFETCH(QStringList, containedFiles);
+ QFETCH(QStringList, containedDirs);
+ QFETCH(QLocale, locale);
+ QFETCH(qlonglong, contentsSize);
+
+ bool directory = (containedDirs.size() + containedFiles.size() > 0);
+ QLocale::setDefault(locale);
+
+ QFileInfo fileInfo(pathName);
+
+ QVERIFY(fileInfo.exists());
+ QCOMPARE(fileInfo.isDir(), directory);
+ QCOMPARE(fileInfo.size(), contentsSize);
+ //QVERIFY(fileInfo.isReadable());
+ QVERIFY(!fileInfo.isWritable());
+ QVERIFY(!fileInfo.isExecutable());
+
+ if (directory) {
+ QDir dir(pathName);
+
+ // Test the Dir filter
+ QFileInfoList list = dir.entryInfoList(QDir::Dirs, QDir::Name);
+// for(int i = 0; i < list.size(); ++i)
+// qDebug() << "one" << i << list.at(i).fileName();
+// for(int i = 0; i < containedDirs.size(); ++i)
+// qDebug() << "two" << i << containedDirs.at(i);
+// qDebug() << "one" << list.size() << containedDirs.size();
+ QCOMPARE(list.size(), containedDirs.size());
+// qDebug() << "two";
+
+ int i;
+ for (i=0; i<list.size(); ++i) {
+ QVERIFY(list.at(i).isDir());
+ QCOMPARE(list.at(i).fileName(), containedDirs.at(i));
+ }
+
+ list = dir.entryInfoList(QDir::Files, QDir::Name);
+ QCOMPARE(containedFiles.size(), list.size());
+
+ for (i=0; i<list.size(); ++i) {
+ QVERIFY(!list.at(i).isDir());
+ QCOMPARE(list.at(i).fileName(), containedFiles.at(i));
+ }
+
+ list = dir.entryInfoList(QDir::NoFilter, QDir::SortFlags(QDir::Name | QDir::DirsFirst));
+ QCOMPARE(containedFiles.size() + containedDirs.size(), list.size());
+
+ for (i=0; i<list.size(); ++i) {
+ QString expectedName;
+ if (i < containedDirs.size())
+ expectedName = containedDirs.at(i);
+ else
+ expectedName = containedFiles.at(i - containedDirs.size());
+
+ QCOMPARE(list.at(i).fileName(), expectedName);
+ }
+ } else {
+ QFile file(pathName);
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ QByteArray ba = file.readAll();
+ QVERIFY(QString(ba).startsWith(contents));
+ }
+ QLocale::setDefault(QLocale::system());
+}
+
+void tst_QResourceEngine::searchPath_data()
+{
+ QTest::addColumn<QString>("searchPath");
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("no_search_path") << QString()
+ << ":search_file.txt"
+ << QByteArray("root\n");
+ QTest::newRow("path1") << "/searchpath1"
+ << ":search_file.txt"
+ << QByteArray("path1\n");
+ QTest::newRow("no_search_path2") << QString()
+ << ":/search_file.txt"
+ << QByteArray("root\n");
+ QTest::newRow("path2") << "/searchpath2"
+ << ":search_file.txt"
+ << QByteArray("path2\n");
+}
+
+void tst_QResourceEngine::searchPath()
+{
+ QFETCH(QString, searchPath);
+ QFETCH(QString, file);
+ QFETCH(QByteArray, expected);
+
+ if(!searchPath.isEmpty())
+ QDir::addResourceSearchPath(searchPath);
+ QFile qf(file);
+ QVERIFY(qf.open(QFile::ReadOnly));
+ QByteArray actual = qf.readAll();
+
+ actual.replace('\r', "");
+
+ QCOMPARE(actual, expected);
+ qf.close();
+}
+
+void tst_QResourceEngine::checkUnregisterResource_data()
+{
+ QTest::addColumn<QString>("rcc_file");
+ QTest::addColumn<QString>("root");
+ QTest::addColumn<QString>("file_check");
+ QTest::addColumn<int>("size");
+
+ QTest::newRow("currentdir.txt") << builddir + QString("runtime_resource.rcc") << QString("/check_unregister/")
+ << QString(":/check_unregister/runtime_resource/test/abc/123/+++/currentdir.txt")
+ << (int)QFileInfo("testqrc/currentdir.txt").size();
+}
+
+void tst_QResourceEngine::checkUnregisterResource()
+{
+ QFETCH(QString, rcc_file);
+ QFETCH(QString, root);
+ QFETCH(QString, file_check);
+ QFETCH(int, size);
+
+
+
+ QVERIFY(!QFile::exists(file_check));
+ QVERIFY(QResource::registerResource(rcc_file, root));
+ QVERIFY(QFile::exists(file_check));
+ QVERIFY(QResource::unregisterResource(rcc_file, root));
+ QVERIFY(!QFile::exists(file_check));
+ QVERIFY(QResource::registerResource(rcc_file, root));
+ QVERIFY(QFile::exists(file_check));
+ QFileInfo fileInfo(file_check);
+ fileInfo.setCaching(false);
+ QVERIFY(fileInfo.exists());
+ QVERIFY(!QResource::unregisterResource(rcc_file, root));
+ QVERIFY(!QFile::exists(file_check));
+ QCOMPARE((int)fileInfo.size(), size);
+}
+
+void tst_QResourceEngine::doubleSlashInRoot()
+{
+ QVERIFY(QFile::exists(":/secondary_root/runtime_resource/search_file.txt"));
+ QVERIFY(QFile::exists("://secondary_root/runtime_resource/search_file.txt"));
+}
+
+void tst_QResourceEngine::setLocale()
+{
+ QLocale::setDefault(QLocale::c());
+
+ // default constructed QResource gets the default locale
+ QResource resource;
+ resource.setFileName("aliasdir/aliasdir.txt");
+ QVERIFY(!resource.isCompressed());
+
+ // change the default locale and make sure it doesn't affect the resource
+ QLocale::setDefault(QLocale("de_CH"));
+ QVERIFY(!resource.isCompressed());
+
+ // then explicitly set the locale on qresource
+ resource.setLocale(QLocale("de_CH"));
+ QVERIFY(resource.isCompressed());
+
+ // the reset the default locale back
+ QLocale::setDefault(QLocale::system());
+}
+
+QTEST_MAIN(tst_QResourceEngine)
+
+#include "tst_qresourceengine.moc"
+
diff --git a/tests/auto/corelib/io/qsettings/.gitattributes b/tests/auto/corelib/io/qsettings/.gitattributes
new file mode 100644
index 0000000000..a4ad8d7644
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/.gitattributes
@@ -0,0 +1,5 @@
+resourcefile.ini -crlf
+resourcefile2.ini -crlf
+resourcefile3.ini -crlf
+resourcefile4.ini -crlf
+resourcefile5.ini -crlf
diff --git a/tests/auto/corelib/io/qsettings/.gitignore b/tests/auto/corelib/io/qsettings/.gitignore
new file mode 100644
index 0000000000..090588b922
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/.gitignore
@@ -0,0 +1 @@
+tst_qsettings
diff --git a/tests/auto/corelib/io/qsettings/qsettings.pro b/tests/auto/corelib/io/qsettings/qsettings.pro
new file mode 100644
index 0000000000..f15e40b267
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/qsettings.pro
@@ -0,0 +1,10 @@
+load(qttest_p4)
+
+QT += core-private
+
+SOURCES += tst_qsettings.cpp
+RESOURCES += qsettings.qrc
+
+win32-msvc*:LIBS += advapi32.lib
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qsettings/qsettings.qrc b/tests/auto/corelib/io/qsettings/qsettings.qrc
new file mode 100644
index 0000000000..587c22ebe3
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/qsettings.qrc
@@ -0,0 +1,9 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resourcefile.ini</file>
+ <file>resourcefile2.ini</file>
+ <file>resourcefile3.ini</file>
+ <file>resourcefile4.ini</file>
+ <file>resourcefile5.ini</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qsettings/resourcefile.ini b/tests/auto/corelib/io/qsettings/resourcefile.ini
new file mode 100644
index 0000000000..608d1b7885
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/resourcefile.ini
@@ -0,0 +1,46 @@
+[Field%201]
+Bottom=89
+Flags=MULTILINE|VSCROLL|READONLY
+Left=4
+Right=296
+State=No license agreement file found. Please contact support.
+Top=14
+Type=Text
+
+[Field%202]
+Bottom=8
+Left=4
+Right=294
+Text=Press Page Down to see the rest of the agreement.
+Top=0
+Type=Label
+
+[Field%203]
+Bottom=111
+Left=4
+Right=297
+Text=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install this software. Click Next to continue.
+Top=92
+Type=Label
+
+[Field%204]
+Bottom=129
+Flags=GROUP|NOTIFY
+Left=4
+Right=299
+Text=I &accept the terms in the License Agreement
+Top=120
+Type=RadioButton
+
+[Field%205]
+Bottom=140
+Flags=NOTIFY
+Left=4
+Right=300
+State=1
+Text=I &do not accept the terms in the License Agreement
+Top=129
+Type=RadioButton
+
+[Settings]
+NumFields=5
diff --git a/tests/auto/corelib/io/qsettings/resourcefile2.ini b/tests/auto/corelib/io/qsettings/resourcefile2.ini
new file mode 100644
index 0000000000..cd06b3b4de
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/resourcefile2.ini
@@ -0,0 +1,46 @@
+[Field%202]
+Flags=MULTILINE|VSCROLL|READONLY
+Left=4
+Right=296
+State=No license agreement file found. Please contact support.
+Bottom=89
+Top=14
+Type=Text
+
+[Field%201]
+Left=4
+Text=Press Page Down to see the rest of the agreement.
+Bottom=8
+Top=0
+Right=294
+Type=Label
+
+[Field%203]
+Bottom=111
+Left=4
+Right=297
+Text=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install this software. Click Next to continue.
+Top=92
+Type=Label
+
+[Field%204]
+Bottom=129
+Flags=GROUP|NOTIFY
+Left=4
+Right=299
+Text=I &accept the terms in the License Agreement
+Top=120
+Type=RadioButton
+
+[Field%205]
+Bottom=140
+Flags=NOTIFY
+Left=4
+Right=300
+State=1
+Text=I &do not accept the terms in the License Agreement
+Top=129
+Type=RadioButton
+
+[Settings]
+NumFields=5
diff --git a/tests/auto/corelib/io/qsettings/resourcefile3.ini b/tests/auto/corelib/io/qsettings/resourcefile3.ini
new file mode 100644
index 0000000000..ee54cfbbaf
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/resourcefile3.ini
@@ -0,0 +1,50 @@
+[Field%202]
+Flags=MULTILINE|VSCROLL|READONLY
+Left=4
+Right=296
+State=No license agreement file found. Please contact support.
+Bottom=89
+Top=14
+Type=Text
+
+[Field%201]
+Left=4
+Text=Press Page Down to see the rest of the agreement.
+Bottom=90
+Top=0
+Right=294
+Type=Label
+x=1
+y=1
+width=1
+height=1
+
+[Field%203]
+Bottom=111
+Left=4
+Right=297
+Text=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install this software. Click Next to continue.
+Top=92
+Type=Label
+
+[Field%204]
+Bottom=129
+Flags=GROUP|NOTIFY
+Left=4
+Right=299
+Text=I &accept the terms in the License Agreement
+Top=120
+Type=RadioButton
+
+[Field%205]
+Bottom=140
+Flags=NOTIFY
+Left=4
+Right=300
+State=1
+Text=I &do not accept the terms in the License Agreement
+Top=129
+Type=RadioButton
+
+[Settings]
+NumFields=5
diff --git a/tests/auto/corelib/io/qsettings/resourcefile4.ini b/tests/auto/corelib/io/qsettings/resourcefile4.ini
new file mode 100644
index 0000000000..09c21b1591
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/resourcefile4.ini
@@ -0,0 +1,2 @@
+[Fa%E7ade]
+QU%C9BEC=Façade/QUÉBEC
diff --git a/tests/auto/corelib/io/qsettings/resourcefile5.ini b/tests/auto/corelib/io/qsettings/resourcefile5.ini
new file mode 100644
index 0000000000..d2d2103560
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/resourcefile5.ini
@@ -0,0 +1,2 @@
+[Fa%E7ade]
+QU%C9BEC=Façade/QUÉBEC
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
new file mode 100644
index 0000000000..7436edcd8c
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -0,0 +1,3179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <qdebug.h>
+#include <QtTest/QtTest>
+
+#include <QtCore/QSettings>
+#include <private/qsettings_p.h>
+//#include <QtGui/QApplication>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QtGlobal>
+#include <QtCore/QMetaType>
+#include <QtCore/QtDebug>
+#include <QtCore/QString>
+#include "../../../../shared/util.h"
+
+#if !defined(Q_OS_SYMBIAN)
+# include <cctype>
+#endif
+#if defined(Q_OS_WIN) && defined(Q_CC_GNU)
+// need for unlink on mingw
+#include <io.h>
+#endif
+
+#if defined(Q_OS_WIN)
+#include <QtCore/qt_windows.h>
+#endif
+
+#ifndef QSETTINGS_P_H_VERSION
+#define QSETTINGS_P_H_VERSION 1
+#endif
+
+//TESTED_FILES=
+
+QT_FORWARD_DECLARE_CLASS(QSettings)
+QT_FORWARD_DECLARE_CLASS(QSettings)
+
+class tst_QSettings : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSettings();
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void getSetCheck();
+ void ctor_data();
+ void ctor();
+ void beginGroup();
+ void setValue();
+ void remove();
+ void contains();
+ void sync();
+ void setFallbacksEnabled();
+ void setFallbacksEnabled_data();
+ void fromFile_data();
+ void fromFile();
+ void setIniCodec();
+ void testArrays_data();
+ void testArrays();
+ void testEscapes();
+ void testCaseSensitivity_data();
+ void testCaseSensitivity();
+ void testErrorHandling_data();
+ void testErrorHandling();
+ void testIniParsing_data();
+ void testIniParsing();
+ void testChildKeysAndGroups_data();
+ void testChildKeysAndGroups();
+ void testUpdateRequestEvent();
+ void testThreadSafety();
+ void testNormalizedKey_data();
+ void testNormalizedKey();
+ void testEmptyData();
+ void testResourceFiles();
+ void fileName();
+ void isWritable_data();
+ void isWritable();
+ void childGroups_data();
+ void childGroups();
+ void childKeys_data();
+ void childKeys();
+ void allKeys_data();
+ void allKeys();
+ void registerFormat();
+ void setPath();
+ void setDefaultFormat();
+ void dontCreateNeedlessPaths();
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+ void dontReorderIniKeysNeedlessly();
+#endif
+#if defined(Q_OS_WIN)
+ void qtbug_13249();
+#endif
+
+ void testVariantTypes_data();
+ void testVariantTypes();
+ void rainersSyncBugOnMac_data();
+ void rainersSyncBugOnMac();
+ void recursionBug();
+
+ void testByteArray_data();
+ void testByteArray();
+
+private:
+ void oldWriteEntry_data();
+ void oldReadEntry_data();
+ void oldWriteEntryHelper(QSettings &settings);
+ void oldReadEntryHelper(QSettings &settings);
+};
+
+// Testing get/set functions
+void tst_QSettings::getSetCheck()
+{
+ QSettings obj1;
+ // bool QSettings::fallbacksEnabled()
+ // void QSettings::setFallbacksEnabled(bool)
+ obj1.setFallbacksEnabled(false);
+ QCOMPARE(false, obj1.fallbacksEnabled());
+ obj1.setFallbacksEnabled(true);
+ QCOMPARE(true, obj1.fallbacksEnabled());
+}
+
+//using namespace std;
+
+//#include <qapplication.h>
+#include <qcoreapplication.h>
+#include <qdir.h>
+#include <qregexp.h>
+#include <qthread.h>
+#include <stdlib.h>
+#ifndef Q_OS_WIN
+#include <unistd.h>
+#endif
+
+Q_DECLARE_METATYPE(QSettings::Format)
+
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+static void removePath(const QString& _path)
+{
+ QString path = _path;
+ QDir dir(path);
+ if (!dir.exists())
+ return;
+ QStringList entries = dir.entryList();
+ foreach(QString name, entries) {
+ QString absolute = path + name;
+ if (QFileInfo(absolute).isDir())
+ removePath(absolute+"\\");
+ else
+ QFile::remove(absolute);
+ }
+ dir.cdUp();
+ if (path[path.size()-1] == '\\')
+ path = path.left(path.size()-1);
+ dir.rmdir(path.mid(path.lastIndexOf('\\')+1));
+}
+#endif
+
+static QString settingsPath(const char *path = "")
+{
+ // Temporary path for files that are specified explictly in the constructor.
+ QString tempPath = QDir::tempPath();
+ if (tempPath.endsWith("/"))
+ tempPath.truncate(tempPath.size() - 1);
+ return QDir::toNativeSeparators(tempPath + "/tst_QSettings/" + QLatin1String(path));
+}
+
+static bool readCustom1File(QIODevice &device, QSettings::SettingsMap &map)
+{
+ QDataStream in(&device);
+ quint32 magic;
+ in >> magic;
+ in >> map;
+ return (magic == 0x01010101 && in.status() == QDataStream::Ok);
+}
+
+static bool writeCustom1File(QIODevice &device, const QSettings::SettingsMap &map)
+{
+ QDataStream out(&device);
+ out << quint32(0x01010101);
+ out << map;
+ return out.status() == QDataStream::Ok;
+}
+
+static bool readCustom2File(QIODevice &device, QSettings::SettingsMap &map)
+{
+ QDataStream in(&device);
+ quint64 magic;
+ in >> magic;
+ in >> map;
+ return (magic == Q_UINT64_C(0x0202020202020202) && in.status() == QDataStream::Ok);
+}
+
+static bool writeCustom2File(QIODevice &device, const QSettings::SettingsMap &map)
+{
+ QDataStream out(&device);
+ out << Q_UINT64_C(0x0202020202020202);
+ out << map;
+ return out.status() == QDataStream::Ok;
+}
+
+static bool readCustom3File(QIODevice &device, QSettings::SettingsMap &map)
+{
+ QTextStream in(&device);
+ QString tag;
+ in >> tag;
+ if (tag == "OK") {
+ map.insert("retval", "OK");
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool writeCustom3File(QIODevice &device, const QSettings::SettingsMap &map)
+{
+ QTextStream out(&device);
+ if (map.value("retval") != "OK")
+ return false;
+
+ out << "OK";
+ return true;
+}
+
+static void populateWithFormats()
+{
+ QTest::addColumn<QSettings::Format>("format");
+
+ QTest::newRow("native") << QSettings::NativeFormat;
+ QTest::newRow("ini") << QSettings::IniFormat;
+ QTest::newRow("custom1") << QSettings::CustomFormat1;
+ QTest::newRow("custom2") << QSettings::CustomFormat2;
+}
+
+tst_QSettings::tst_QSettings()
+{
+ QSettings::Format custom1 = QSettings::registerFormat("custom1", readCustom1File, writeCustom1File);
+ QSettings::Format custom2 = QSettings::registerFormat("custom2", readCustom2File, writeCustom2File
+#ifndef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
+ , Qt::CaseInsensitive
+#endif
+ );
+ QVERIFY(custom1 == QSettings::CustomFormat1);
+ QVERIFY(custom2 == QSettings::CustomFormat2);
+}
+
+void tst_QSettings::init()
+{
+ QSettings::setSystemIniPath(settingsPath("__system__"));
+ QSettings::setUserIniPath(settingsPath("__user__"));
+
+#if defined(Q_OS_WIN)
+ QSettings("HKEY_CURRENT_USER\\Software\\software.org", QSettings::NativeFormat).clear();
+ QSettings("HKEY_LOCAL_MACHINE\\Software\\software.org", QSettings::NativeFormat).clear();
+ QSettings("HKEY_CURRENT_USER\\Software\\other.software.org", QSettings::NativeFormat).clear();
+ QSettings("HKEY_LOCAL_MACHINE\\Software\\other.software.org", QSettings::NativeFormat).clear();
+ QSettings("HKEY_CURRENT_USER\\Software\\foo", QSettings::NativeFormat).clear();
+ QSettings("HKEY_CURRENT_USER\\Software\\bar", QSettings::NativeFormat).clear();
+ QSettings("HKEY_CURRENT_USER\\Software\\bat", QSettings::NativeFormat).clear();
+ QSettings("HKEY_CURRENT_USER\\Software\\baz", QSettings::NativeFormat).clear();
+ QSettings("HKEY_LOCAL_MACHINE\\Software\\foo", QSettings::NativeFormat).clear();
+ QSettings("HKEY_LOCAL_MACHINE\\Software\\bar", QSettings::NativeFormat).clear();
+ QSettings("HKEY_LOCAL_MACHINE\\Software\\bat", QSettings::NativeFormat).clear();
+ QSettings("HKEY_LOCAL_MACHINE\\Software\\baz", QSettings::NativeFormat).clear();
+ if (QDir(settingsPath()).exists()) {
+#if defined(Q_OS_WINCE)
+ removePath(settingsPath());
+#else
+ if (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based)
+ system(QString("rmdir /Q /S %1").arg(settingsPath()).toLatin1());
+ else
+ system(QString("deltree /Y %1").arg(settingsPath()).toLatin1());
+#endif
+ }
+#elif defined(Q_OS_DARWIN)
+ QSettings(QSettings::UserScope, "software.org", "KillerAPP").clear();
+ QSettings(QSettings::SystemScope, "software.org", "KillerAPP").clear();
+ QSettings(QSettings::UserScope, "other.software.org", "KillerAPP").clear();
+ QSettings(QSettings::SystemScope, "other.software.org", "KillerAPP").clear();
+ QSettings(QSettings::UserScope, "software.org").clear();
+ QSettings(QSettings::SystemScope, "software.org").clear();
+ QSettings(QSettings::UserScope, "other.software.org").clear();
+ QSettings(QSettings::SystemScope, "other.software.org").clear();
+#elif defined(Q_OS_SYMBIAN)
+ removePath(settingsPath());
+#endif
+
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+ system(QString("chmod -R u+rw %1 2> /dev/null").arg(settingsPath()).toLatin1());
+ system(QString("rm -fr %1 2> /dev/null").arg(settingsPath()).toLatin1());
+#endif
+
+ QFile::remove("foo");
+}
+
+void tst_QSettings::cleanup()
+{
+ init();
+}
+
+/*
+ Test the constructors and the assignment operator.
+*/
+
+void tst_QSettings::ctor_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::ctor()
+{
+ QFETCH(QSettings::Format, format);
+
+ {
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings2(format, QSettings::UserScope, "software.org");
+ QSettings settings3(format, QSettings::SystemScope, "software.org", "KillerAPP");
+ QSettings settings4(format, QSettings::SystemScope, "software.org");
+
+ QSettings settings5(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings6(format, QSettings::UserScope, "software.org");
+ QSettings settings7(format, QSettings::SystemScope, "software.org", "KillerAPP");
+ QSettings settings8(format, QSettings::SystemScope, "software.org");
+
+ // test QSettings::format() while we're at it
+ QVERIFY(settings1.format() == format);
+ QVERIFY(settings2.format() == format);
+ QVERIFY(settings3.format() == format);
+ QVERIFY(settings4.format() == format);
+
+ // test QSettings::scope() while we're at it
+ QVERIFY(settings1.scope() == QSettings::UserScope);
+ QVERIFY(settings2.scope() == QSettings::UserScope);
+ QVERIFY(settings3.scope() == QSettings::SystemScope);
+ QVERIFY(settings4.scope() == QSettings::SystemScope);
+
+ // test QSettings::organizationName() while we're at it
+ QVERIFY(settings1.organizationName() == "software.org");
+ QVERIFY(settings2.organizationName() == "software.org");
+ QVERIFY(settings3.organizationName() == "software.org");
+ QVERIFY(settings4.organizationName() == "software.org");
+
+ // test QSettings::applicationName() while we're at it
+ QCOMPARE(settings1.applicationName(), QString("KillerAPP"));
+ QVERIFY(settings2.applicationName().isEmpty());
+ QVERIFY(settings3.applicationName() == "KillerAPP");
+ QVERIFY(settings4.applicationName().isEmpty());
+
+ /*
+ Go forwards.
+ */
+ settings4.setValue("key 1", QString("doodah"));
+
+ QCOMPARE(settings1.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings3.setValue("key 1", QString("blah"));
+ QCOMPARE(settings1.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings2.setValue("key 1", QString("whoa"));
+ QCOMPARE(settings1.value("key 1").toString(), QString("whoa"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings1.setValue("key 1", QString("gurgle"));
+ QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ /*
+ Test the copies.
+ */
+ QCOMPARE(settings5.value("key 1").toString(), settings1.value("key 1").toString());
+ QCOMPARE(settings6.value("key 1").toString(), settings2.value("key 1").toString());
+ QCOMPARE(settings7.value("key 1").toString(), settings3.value("key 1").toString());
+ QCOMPARE(settings8.value("key 1").toString(), settings4.value("key 1").toString());
+
+ /*
+ Go backwards.
+ */
+
+ settings2.setValue("key 1", QString("bilboh"));
+ QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings3.setValue("key 1", QString("catha"));
+ QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("catha"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings4.setValue("key 1", QString("quirko"));
+ QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("catha"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("quirko"));
+
+ /*
+ Test the copies again.
+ */
+ QCOMPARE(settings5.value("key 1").toString(), settings1.value("key 1").toString());
+ QCOMPARE(settings6.value("key 1").toString(), settings2.value("key 1").toString());
+ QCOMPARE(settings7.value("key 1").toString(), settings3.value("key 1").toString());
+ QCOMPARE(settings8.value("key 1").toString(), settings4.value("key 1").toString());
+
+ /*
+ "General" is a problem key for .ini files.
+ */
+ settings1.setValue("General", 1);
+ settings1.setValue("%General", 2);
+ settings1.setValue("alpha", 3);
+ settings1.setValue("General/alpha", 4);
+ settings1.setValue("%General/alpha", 5);
+ settings1.setValue("alpha/General", 6);
+ settings1.setValue("alpha/%General", 7);
+ settings1.setValue("General/General", 8);
+ settings1.setValue("General/%General", 9);
+ settings1.setValue("%General/General", 10);
+ settings1.setValue("%General/%General", 11);
+ }
+
+ {
+ /*
+ Test that the data was stored on disk after all instances
+ of QSettings are destroyed.
+ */
+
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings2(format, QSettings::UserScope, "software.org");
+ QSettings settings3(format, QSettings::SystemScope, "software.org", "KillerAPP");
+ QSettings settings4(format, QSettings::SystemScope, "software.org");
+
+ QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("catha"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("quirko"));
+
+ /*
+ Test problem keys.
+ */
+
+ QCOMPARE(settings1.value("General").toInt(), 1);
+ QCOMPARE(settings1.value("%General").toInt(), 2);
+ QCOMPARE(settings1.value("alpha").toInt(), 3);
+ QCOMPARE(settings1.value("General/alpha").toInt(), 4);
+ QCOMPARE(settings1.value("%General/alpha").toInt(), 5);
+ QCOMPARE(settings1.value("alpha/General").toInt(), 6);
+ QCOMPARE(settings1.value("alpha/%General").toInt(), 7);
+ QCOMPARE(settings1.value("General/General").toInt(), 8);
+ QCOMPARE(settings1.value("General/%General").toInt(), 9);
+ QCOMPARE(settings1.value("%General/General").toInt(), 10);
+ QCOMPARE(settings1.value("%General/%General").toInt(), 11);
+
+ /*
+ Test that the organization and product parameters is
+ case-insensitive on Windows and Mac, case-sensitive on
+ Unix.
+ */
+ QSettings settings5(format, QSettings::UserScope, "SoftWare.ORG", "killerApp");
+ if (format == QSettings::NativeFormat) {
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(settings5.value("key 1").toString(), QString("gurgle"));
+#else
+ QVERIFY(!settings5.contains("key 1"));
+#endif
+ } else {
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(settings5.value("key 1").toString(), QString("gurgle"));
+#else
+ QVERIFY(!settings5.contains("key 1"));
+#endif
+ }
+ }
+
+ {
+ QSettings settings1(settingsPath("custom/custom.conf"), QSettings::IniFormat);
+ settings1.beginGroup("alpha/beta");
+ settings1.setValue("geometry", -7);
+ settings1.setValue("geometry/x", 1);
+ settings1.setValue("geometry/y", 2);
+ QSettings settings2(settingsPath("custom/custom.conf"), QSettings::IniFormat);
+ settings1.setValue("geometry/width", 3);
+ settings2.setValue("alpha/beta/geometry/height", 4);
+ settings2.setValue("alpha/gamma/splitter", 5);
+ settings1.endGroup();
+
+ // test QSettings::scope() while we're at it
+ QVERIFY(settings1.scope() == QSettings::UserScope);
+
+ // test QSettings::organizationName() while we're at it
+ QVERIFY(settings1.organizationName().isEmpty());
+
+ // test QSettings::applicationName() while we're at it
+ QVERIFY(settings1.organizationName().isEmpty());
+
+ QSettings settings3(settingsPath("custom/custom2.conf"), QSettings::IniFormat);
+ settings3.beginGroup("doodley/beta");
+ settings3.setValue("geometry", -7);
+ settings3.setValue("geometry/x", 1);
+ settings3.setValue("geometry/y", 2);
+ settings3.setValue("geometry/width", 3);
+ settings3.setValue("geometry/height", 4);
+ settings3.endGroup();
+ settings3.setValue("alpha/gamma/splitter", 5);
+
+ QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings1.value("alpha/beta/geometry/x").toInt(), 1);
+ QCOMPARE(settings1.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 5);
+ QCOMPARE(settings1.allKeys().count(), 6);
+
+ QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings2.value("alpha/beta/geometry/x").toInt(), 1);
+ QCOMPARE(settings2.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings2.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings2.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings2.value("alpha/gamma/splitter").toInt(), 5);
+ QCOMPARE(settings2.allKeys().count(), 6);
+ }
+
+ {
+ QSettings settings1(settingsPath("custom/custom.conf"), QSettings::IniFormat);
+ QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings1.value("alpha/beta/geometry/x").toInt(), 1);
+ QCOMPARE(settings1.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 5);
+ QCOMPARE(settings1.allKeys().count(), 6);
+ }
+
+ {
+ // QSettings's default constructor is native by default
+ if (format == QSettings::NativeFormat) {
+ QCoreApplication::instance()->setOrganizationName("");
+ QCoreApplication::instance()->setApplicationName("");
+ QSettings settings;
+ QCOMPARE(settings.status(), QSettings::AccessError);
+ QCoreApplication::instance()->setOrganizationName("software.org");
+ QCoreApplication::instance()->setApplicationName("KillerAPP");
+ QSettings settings2;
+ QCOMPARE(settings2.status(), QSettings::NoError);
+ QSettings settings3("software.org", "KillerAPP");
+ QCOMPARE(settings2.fileName(), settings3.fileName());
+ QCoreApplication::instance()->setOrganizationName("");
+ QCoreApplication::instance()->setApplicationName("");
+ }
+
+ QSettings settings(format, QSettings::UserScope, "", "");
+ QCOMPARE(settings.status(), QSettings::AccessError);
+ QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QCOMPARE(settings2.status(), QSettings::NoError);
+
+ // test QSettings::format() while we're at it
+ QVERIFY(settings.format() == format);
+ QVERIFY(settings2.format() == format);
+
+ // test QSettings::scope() while we're at it
+ QVERIFY(settings.scope() == QSettings::UserScope);
+ QVERIFY(settings2.scope() == QSettings::UserScope);
+
+ // test QSettings::organizationName() while we're at it
+ QVERIFY(settings.organizationName().isEmpty());
+ QVERIFY(settings2.organizationName() == "software.org");
+
+ // test QSettings::applicationName() while we're at it
+ QVERIFY(settings.applicationName().isEmpty());
+ QVERIFY(settings2.applicationName() == "KillerAPP");
+ }
+}
+
+void tst_QSettings::testByteArray_data()
+{
+ QTest::addColumn<QByteArray>("data");
+
+ QByteArray bytes("Hello world!");
+
+ QTest::newRow("latin1") << bytes;
+#ifndef QT_NO_COMPRESS
+ QTest::newRow("compressed") << qCompress(bytes);
+#endif
+ QTest::newRow("with \\0") << bytes + '\0' + bytes;
+}
+
+void tst_QSettings::testByteArray()
+{
+ QFETCH(QByteArray, data);
+
+ // write
+ {
+ QSettings settings("Trolltech", "tst_qsettings");
+ settings.setValue("byteArray", data);
+ }
+ // read
+ {
+ QSettings settings("Trolltech", "tst_qsettings");
+ QByteArray ret = settings.value("byteArray", data).toByteArray();
+ QCOMPARE(ret, data);
+ }
+}
+
+void tst_QSettings::testErrorHandling_data()
+{
+ QTest::addColumn<int>("filePerms"); // -1 means file should not exist
+ QTest::addColumn<int>("dirPerms");
+ QTest::addColumn<int>("statusAfterCtor");
+ QTest::addColumn<bool>("shouldBeEmpty");
+ QTest::addColumn<int>("statusAfterGet");
+ QTest::addColumn<int>("statusAfterSetAndSync");
+
+ // file dir afterCtor empty afterGet afterSetAndSync
+ QTest::newRow("0600 0700") << 0600 << 0700 << (int)QSettings::NoError << false << (int)QSettings::NoError << (int)QSettings::NoError;
+
+ QTest::newRow("0400 0700") << 0400 << 0700 << (int)QSettings::NoError
+ << false << (int)QSettings::NoError << (int)QSettings::AccessError;
+ QTest::newRow("0200 0700") << 0200 << 0700 << (int)QSettings::AccessError
+ << true << (int)QSettings::AccessError << (int)QSettings::AccessError;
+
+ QTest::newRow(" -1 0700") << -1 << 0700 << (int)QSettings::NoError << true << (int)QSettings::NoError << (int)QSettings::NoError;
+
+ QTest::newRow(" -1 0000") << -1 << 0000 << (int)QSettings::NoError << true << (int)QSettings::NoError << (int)QSettings::AccessError;
+ QTest::newRow(" -1 0100") << -1 << 0100 << (int)QSettings::NoError << true << (int)QSettings::NoError << (int)QSettings::AccessError;
+ QTest::newRow("0600 0100") << 0600 << 0100 << (int)QSettings::NoError << false << (int)QSettings::NoError << (int)QSettings::NoError;
+ QTest::newRow(" -1 0300") << -1 << 0300 << (int)QSettings::NoError << true << (int)QSettings::NoError << (int)QSettings::NoError;
+ QTest::newRow("0600 0300") << 0600 << 0300 << (int)QSettings::NoError << false << (int)QSettings::NoError << (int)QSettings::NoError;
+ QTest::newRow(" -1 0500") << -1 << 0500 << (int)QSettings::NoError << true << (int)QSettings::NoError << (int)QSettings::AccessError;
+ QTest::newRow("0600 0500") << 0600 << 0500 << (int)QSettings::NoError << false << (int)QSettings::NoError << (int)QSettings::NoError;
+}
+
+void tst_QSettings::testErrorHandling()
+{
+#ifdef QT_BUILD_INTERNAL
+#ifdef Q_OS_WIN
+ QSKIP("Windows doesn't support most file modes, including read-only directories, so this test is moot.", SkipAll);
+#elif defined(Q_OS_SYMBIAN)
+ QSKIP("Symbian/Open C doesn't support execute or write only file modes, or directory permissions, so this test is mostly moot.", SkipAll);
+#elif defined(Q_OS_UNIX)
+ if (::getuid() == 0)
+ QSKIP("Running this test as root doesn't work, since file perms do not bother him", SkipAll);
+#else
+ QFETCH(int, filePerms);
+ QFETCH(int, dirPerms);
+ QFETCH(int, statusAfterCtor);
+ QFETCH(bool, shouldBeEmpty);
+ QFETCH(int, statusAfterGet);
+ QFETCH(int, statusAfterSetAndSync);
+
+ system(QString("chmod 700 %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1());
+ system(QString("chmod -R u+rwx %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1());
+ system(QString("rm -fr %1").arg(settingsPath("someDir")).toLatin1());
+
+ // prepare a file with some settings
+ if (filePerms != -1) {
+ QSettings settings(settingsPath("someDir/someSettings.ini"), QSettings::IniFormat);
+ QCOMPARE((int) settings.status(), (int) QSettings::NoError);
+
+ settings.beginGroup("alpha/beta");
+ settings.setValue("geometry", -7);
+ settings.setValue("geometry/x", 1);
+ settings.setValue("geometry/y", 2);
+ settings.setValue("geometry/width", 3);
+ settings.setValue("geometry/height", 4);
+ settings.endGroup();
+ settings.setValue("alpha/gamma/splitter", 5);
+ } else {
+ system(QString("mkdir -p %1").arg(settingsPath("someDir")).toLatin1());
+ }
+
+ if (filePerms != -1) {
+ system(QString("chmod %1 %2")
+ .arg(QString::number(filePerms, 8))
+ .arg(settingsPath("someDir/someSettings.ini"))
+ .toLatin1());
+ }
+ system(QString("chmod %1 %2")
+ .arg(QString::number(dirPerms, 8))
+ .arg(settingsPath("someDir"))
+ .toLatin1());
+
+ // the test
+ {
+ QConfFile::clearCache();
+ QSettings settings(settingsPath("someDir/someSettings.ini"), QSettings::IniFormat);
+ QCOMPARE((int)settings.status(), statusAfterCtor);
+ if (shouldBeEmpty) {
+ QCOMPARE(settings.allKeys().count(), 0);
+ } else {
+ QVERIFY(settings.allKeys().count() > 0);
+ }
+ settings.value("alpha/beta/geometry");
+ QCOMPARE((int)settings.status(), statusAfterGet);
+ settings.setValue("alpha/beta/geometry", 100);
+ QCOMPARE((int)settings.status(), statusAfterGet);
+ QCOMPARE(settings.value("alpha/beta/geometry").toInt(), 100);
+ settings.sync();
+ QCOMPARE(settings.value("alpha/beta/geometry").toInt(), 100);
+ QCOMPARE((int)settings.status(), statusAfterSetAndSync);
+ }
+#endif // !Q_OS_WIN
+#endif
+}
+
+Q_DECLARE_METATYPE(QVariant)
+Q_DECLARE_METATYPE(QSettings::Status)
+
+void tst_QSettings::testIniParsing_data()
+{
+ QTest::addColumn<QByteArray>("inicontent");
+ QTest::addColumn<QString>("key");
+ QTest::addColumn<QVariant>("expect");
+ QTest::addColumn<QSettings::Status>("status");
+
+ // Test "forgiving" parsing of entries not terminated with newline or unterminated strings
+ QTest::newRow("good1") << QByteArray("v=1\n") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("good2") << QByteArray("v=1\\\n2") << "v" << QVariant(12) << QSettings::NoError;
+ QTest::newRow("good3") << QByteArray("v=1\\\r2") << "v" << QVariant(12) << QSettings::NoError;
+ QTest::newRow("good4") << QByteArray("v=1\\\n\r2") << "v" << QVariant(12) << QSettings::NoError;
+ QTest::newRow("good5") << QByteArray("v=1\\\r\n2") << "v" << QVariant(12) << QSettings::NoError;
+ QTest::newRow("good6") << QByteArray("v \t = \t 1\\\r\n2") << "v" << QVariant(12) << QSettings::NoError;
+ QTest::newRow("garbage1") << QByteArray("v") << "v" << QVariant() << QSettings::FormatError;
+ QTest::newRow("nonterm1") << QByteArray("v=str") << "v" << QVariant("str") << QSettings::NoError;
+ QTest::newRow("nonterm2") << QByteArray("v=\"str\"") << "v" << QVariant("str") << QSettings::NoError;
+ QTest::newRow("nonterm3") << QByteArray("v=\"str") << "v" << QVariant("str") << QSettings::NoError;
+ QTest::newRow("nonterm4") << QByteArray("v=\\") << "v" << QVariant("") << QSettings::NoError;
+ QTest::newRow("nonterm5") << QByteArray("u=s\nv=\"str") << "v" << QVariant("str") << QSettings::NoError;
+ QTest::newRow("nonterm6") << QByteArray("v=\"str\nw=ok") << "v" << QVariant("str\nw=ok") << QSettings::NoError;
+ QTest::newRow("nonterm7") << QByteArray("v=") << "v" << QVariant("") << QSettings::NoError;
+ QTest::newRow("nonterm8") << QByteArray("v=\"str\njnk") << "v" << QVariant("str\njnk") << QSettings::NoError;
+ QTest::newRow("nonterm9") << QByteArray("v=1\\") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm10") << QByteArray("v=1\\\n") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm11") << QByteArray("v=1\\\r") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm12") << QByteArray("v=1\\\n\r") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm13") << QByteArray("v=1\\\r\n") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm14") << QByteArray("v=1\\\n\nx=2") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm15") << QByteArray("v=1\\\r\rx=2") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm16") << QByteArray("v=1\\\n\n\nx=2") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm17") << QByteArray("; foo\nv=1") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm18") << QByteArray("; foo\n\nv=1") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm19") << QByteArray("\nv=1;foo") << "v" << QVariant(1) << QSettings::NoError;
+ QTest::newRow("nonterm20") << QByteArray("v=x ") << "v" << QVariant("x") << QSettings::NoError;
+ QTest::newRow("nonterm21") << QByteArray("v=x ;") << "v" << QVariant("x") << QSettings::NoError;
+}
+
+void tst_QSettings::testIniParsing()
+{
+#ifdef QT_BUILD_INTERNAL
+ qRegisterMetaType<QVariant>("QVariant");
+ qRegisterMetaType<QSettings::Status>("QSettings::Status");
+
+ QDir dir(settingsPath());
+ QVERIFY(dir.mkpath("someDir"));
+ QFile f(dir.path()+"/someDir/someSettings.ini");
+
+ QFETCH(QByteArray, inicontent);
+ QFETCH(QString, key);
+ QFETCH(QVariant, expect);
+ QFETCH(QSettings::Status, status);
+
+ QVERIFY(f.open(QFile::WriteOnly));
+ f.write(inicontent);
+ f.close();
+
+ QConfFile::clearCache();
+ QSettings settings(settingsPath("someDir/someSettings.ini"), QSettings::IniFormat);
+
+ if ( settings.status() == QSettings::NoError ) { // else no point proceeding
+ QVariant v = settings.value(key);
+ QVERIFY(v.canConvert(expect.type()));
+ // check some types so as to give prettier error messages
+ if ( v.type() == QVariant::String ) {
+ QCOMPARE(v.toString(), expect.toString());
+ } else if ( v.type() == QVariant::Int ) {
+ QCOMPARE(v.toInt(), expect.toInt());
+ } else {
+ QCOMPARE(v, expect);
+ }
+ }
+
+ QCOMPARE(settings.status(), status);
+#endif
+}
+
+/*
+ Tests beginGroup(), endGroup(), and group().
+*/
+void tst_QSettings::beginGroup()
+{
+ QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings2(QSettings::UserScope, "software.org", "KillerAPP");
+
+ /*
+ Let's start with some back and forthing.
+ */
+
+ settings1.beginGroup("alpha");
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString());
+ settings1.beginGroup("/beta");
+ QCOMPARE(settings1.group(), QString("beta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString());
+
+ settings1.beginGroup("///gamma//");
+ QCOMPARE(settings1.group(), QString("gamma"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString());
+
+ settings1.setValue("geometry", 5);
+ QCOMPARE(settings1.value("geometry").toInt(), 5);
+ QCOMPARE(settings1.value("/geometry///").toInt(), 5);
+ QCOMPARE(settings2.value("geometry").toInt(), 5);
+ QCOMPARE(settings2.value("/geometry///").toInt(), 5);
+
+ /*
+ OK, now start for real.
+ */
+
+ settings1.beginGroup("alpha");
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.setValue("geometry", 66);
+ QCOMPARE(settings1.value("geometry").toInt(), 66);
+ QCOMPARE(settings2.value("geometry").toInt(), 5);
+ QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
+
+ QSettings settings3(QSettings::UserScope, "software.org", "KillerAPP");
+ settings3.beginGroup("alpha");
+ QCOMPARE(settings3.value("geometry").toInt(), 66);
+
+ settings1.beginGroup("/beta///");
+ QCOMPARE(settings1.group(), QString("alpha/beta"));
+ settings1.setValue("geometry", 777);
+ QCOMPARE(settings1.value("geometry").toInt(), 777);
+ QCOMPARE(settings2.value("geometry").toInt(), 5);
+ QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
+ QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), 777);
+ QCOMPARE(settings3.value("geometry").toInt(), 66);
+ QCOMPARE(settings3.value("beta/geometry").toInt(), 777);
+
+ settings3.beginGroup("gamma");
+ settings3.setValue("geometry", 8888);
+ QCOMPARE(settings3.value("geometry").toInt(), 8888);
+ QCOMPARE(settings2.value("geometry").toInt(), 5);
+ QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
+ QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), 777);
+ QCOMPARE(settings2.value("alpha/gamma/geometry").toInt(), 8888);
+ QCOMPARE(settings1.value("geometry").toInt(), 777);
+
+ // endGroup() should do nothing if group() is empty
+ for (int i = 0; i < 10; ++i)
+ settings2.endGroup();
+ QCOMPARE(settings2.value("geometry").toInt(), 5);
+ QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
+ QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), 777);
+ QCOMPARE(settings2.value("alpha/gamma/geometry").toInt(), 8888);
+
+ QCOMPARE(settings1.group(), QString("alpha/beta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString());
+ QCOMPARE(settings1.value("geometry").toInt(), 5);
+ QCOMPARE(settings1.value("alpha/geometry").toInt(), 66);
+ QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), 777);
+ QCOMPARE(settings1.value("alpha/gamma/geometry").toInt(), 8888);
+
+ settings1.beginGroup("delta");
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.beginGroup("");
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.beginGroup("/");
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.beginGroup("////");
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.beginGroup("////omega///epsilon zeta eta theta/ / /");
+ QCOMPARE(settings1.group(), QString("delta/omega/epsilon zeta eta theta/ / "));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("delta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString());
+}
+
+/*
+ Tests setValue() and getXxx().
+*/
+void tst_QSettings::setValue()
+{
+ QSettings settings(QSettings::UserScope, "software.org", "KillerAPP");
+
+ settings.setValue("key 2", (int)0x7fffffff);
+ QCOMPARE(settings.value("key 2").toInt(), (int)0x7fffffff);
+ QCOMPARE(settings.value("key 2").toString(), QString::number((int)0x7fffffff));
+ settings.setValue("key 2", -1);
+ QCOMPARE(settings.value("key 2").toInt(), -1);
+ QCOMPARE(settings.value("key 2").toString(), QString("-1"));
+ settings.setValue("key 2", (int)0x80000000);
+ QCOMPARE(settings.value("key 2").toInt(), (int)0x80000000);
+ settings.setValue("key 2", (int)0);
+ QCOMPARE(settings.value("key 2", 123).toInt(), (int)0);
+ settings.setValue("key 2", (int)12345);
+ QCOMPARE(settings.value("key 2").toInt(), (int)12345);
+ QCOMPARE(settings.value("no such key", 1234).toInt(), (int)1234);
+ QCOMPARE(settings.value("no such key").toInt(), (int)0);
+
+ settings.setValue("key 2", true);
+ QCOMPARE(settings.value("key 2").toBool(), true);
+ settings.setValue("key 2", false);
+ QCOMPARE(settings.value("key 2", true).toBool(), false);
+ settings.setValue("key 2", (int)1);
+ QCOMPARE(settings.value("key 2").toBool(), true);
+ settings.setValue("key 2", (int)-1);
+ QCOMPARE(settings.value("key 2").toBool(), true);
+ settings.setValue("key 2", (int)0);
+ QCOMPARE(settings.value("key 2", true).toBool(), false);
+ settings.setValue("key 2", QString("true"));
+ QCOMPARE(settings.value("key 2").toBool(), true);
+ settings.setValue("key 2", QString("false"));
+ QCOMPARE(settings.value("key 2", true).toBool(), false);
+/*
+ settings.setValue("key 2", "true");
+ QCOMPARE(settings.value("key 2").toBool(), true);
+ settings.setValue("key 2", "false");
+ QCOMPARE(settings.value("key 2", true).toBool(), false);
+ settings.setValue("key 2", "");
+ QCOMPARE(settings.value("key 2", true).toBool(), true);
+ settings.setValue("key 2", "");
+ QCOMPARE(settings.value("key 2", false).toBool(), false);
+ settings.setValue("key 2", "0.000e-00"); // cannot convert double to a bool
+ QCOMPARE(settings.value("key 2", true).toBool(), true);
+ settings.setValue("key 2", "0.000e-00");
+ QCOMPARE(settings.value("key 2", false).toBool(), false);
+
+*/
+ settings.setValue("key 2", QStringList());
+ QCOMPARE(settings.value("key 2").toStringList(), QStringList());
+ settings.setValue("key 2", QStringList(""));
+ QCOMPARE(settings.value("key 2").toStringList(), QStringList(""));
+ settings.setValue("key 2", QStringList() << "" << "");
+ QCOMPARE(settings.value("key 2").toStringList(), QStringList() << "" << "");
+ settings.setValue("key 2", QStringList() << "" << "a" << "" << "bc" << "");
+ QCOMPARE(settings.value("key 2").toStringList(), QStringList() << "" << "a" << "" << "bc" << "");
+
+ settings.setValue("key 3", QList<QVariant>());
+ QCOMPARE(settings.value("key 3").toList(), QList<QVariant>());
+ settings.setValue("key 3", QList<QVariant>() << 1 << QString("a"));
+ QCOMPARE(settings.value("key 3").toList(), QList<QVariant>() << 1 << QString("a"));
+
+ QList<QVariant> outerList;
+ outerList << 1 << QString("b");
+ QList<QVariant> innerList = outerList;
+ outerList.append(QVariant(innerList));
+ outerList.append(QVariant(innerList));
+ outerList << 2 << QString("c");
+ innerList = outerList;
+ outerList.append(QVariant(innerList));
+ // outerList: [1, "b", [1, "b"], [1, "b"], 2, "c", [1, "b", [1, "b"], [1, "b"], 2, "c"]]
+
+ settings.setValue("key 3", outerList);
+ QCOMPARE(settings.value("key 3").toList(), outerList);
+ QCOMPARE(settings.value("key 3").toList().size(), 7);
+
+ QMap<QString, QVariant> map;
+ map.insert("1", "one");
+ map.insert("2", "two");
+ map.insert("3", outerList);
+ map.insert("5", "cinco");
+ map.insert("10", "zehn");
+ settings.setValue("key 4", map);
+ QCOMPARE(settings.value("key 4").toMap(), map);
+}
+
+void tst_QSettings::testVariantTypes_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::testVariantTypes()
+{
+#ifdef QT_BUILD_INTERNAL
+#define testVal(key, val, tp, rtype) \
+ { \
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP"); \
+ settings1.setValue(key, qVariantFromValue(val)); \
+ } \
+ QConfFile::clearCache(); \
+ { \
+ QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP"); \
+ QVariant v = settings2.value(key); \
+ QVERIFY(qvariant_cast<tp >(v) == val); \
+ QVERIFY(v.type() == QVariant::rtype); \
+ }
+
+ typedef QMap<QString, QVariant> TestVariantMap;
+
+ QFETCH(QSettings::Format, format);
+
+ TestVariantMap m2;
+ m2.insert("ene", "due");
+ m2.insert("rike", "fake");
+ m2.insert("borba", "dorba");
+ testVal("key2", m2, TestVariantMap, Map);
+
+ QStringList l2;
+
+ l2 << "ene" << "due" << "@Point(1 2)" << "@fake";
+ testVal("key3", l2, QStringList, StringList);
+
+ l2.clear();
+ l2 << "ene" << "due" << "rike" << "fake";
+ testVal("key3", l2, QStringList, StringList);
+
+ QList<QVariant> l3;
+ QDate date = QDate::currentDate();
+ QTime time = QTime::currentTime();
+ l3 << QString("ene") << 10 << qVariantFromValue(QColor(1, 2, 3)) << QVariant(QRect(1, 2, 3, 4))
+ << QVariant(QSize(4, 56)) << QVariant(QPoint(4, 2)) << true << false << date << time;
+ testVal("key3", l3, QVariantList, List);
+
+ testVal("key4", QString("hello"), QString, String);
+ testVal("key5", QColor(1, 2, 3), QColor, Color);
+ testVal("key6", QRect(1, 2, 3, 4), QRect, Rect);
+ testVal("key7", QSize(4, 56), QSize, Size);
+ testVal("key8", QPoint(4, 2), QPoint, Point);
+ testVal("key10", date, QDate, Date);
+ testVal("key11", time, QTime, Time);
+ testVal("key12", QByteArray("foo bar"), QByteArray, ByteArray);
+
+ {
+ QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QVERIFY(!settings.contains("key99"));
+ QCOMPARE(settings.value("key99"), QVariant());
+
+ settings.setValue("key99", QVariant());
+ QVERIFY(settings.contains("key99"));
+ QCOMPARE(settings.value("key99"), QVariant());
+
+ settings.setValue("key99", QVariant(1));
+ QVERIFY(settings.contains("key99"));
+ QCOMPARE(settings.value("key99"), QVariant(1));
+
+ settings.setValue("key99", QVariant());
+ QVERIFY(settings.contains("key99"));
+ QCOMPARE(settings.value("key99"), QVariant());
+
+ settings.remove("key99");
+ QVERIFY(!settings.contains("key99"));
+ QCOMPARE(settings.value("key99"), QVariant());
+ }
+
+ QList<QVariant> l4;
+ l4 << QVariant(m2) << QVariant(l2) << QVariant(l3);
+ testVal("key13", l4, QVariantList, List);
+
+ // We store key sequences as strings instead of binary variant blob, for improved
+ // readability in the resulting format.
+ if (format >= QSettings::InvalidFormat) {
+ testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QKeySequence, KeySequence);
+ } else {
+ testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QString, String);
+ }
+
+#undef testVal
+#endif
+}
+
+void tst_QSettings::remove()
+{
+ QSettings settings0(QSettings::UserScope, "software.org", "KillerAPP");
+ int initialNumKeys = settings0.allKeys().size();
+ QCOMPARE(settings0.value("key 1", "123").toString(), QString("123"));
+ settings0.remove("key 1");
+ QCOMPARE(settings0.value("key 1", "456").toString(), QString("456"));
+
+ settings0.setValue("key 1", "bubloo");
+ QCOMPARE(settings0.value("key 1").toString(), QString("bubloo"));
+ settings0.remove("key 2");
+ QCOMPARE(settings0.value("key 1").toString(), QString("bubloo"));
+ settings0.remove("key 1");
+ QCOMPARE(settings0.value("key 1", "789").toString(), QString("789"));
+
+ /*
+ Make sure that removing a key removes all the subkeys.
+ */
+ settings0.setValue("alpha/beta/geometry", -7);
+ settings0.setValue("alpha/beta/geometry/x", 1);
+ settings0.setValue("alpha/beta/geometry/y", 2);
+ settings0.setValue("alpha/beta/geometry/width", 3);
+ settings0.setValue("alpha/beta/geometry/height", 4);
+ settings0.setValue("alpha/gamma/splitter", 5);
+
+ settings0.remove("alpha/beta/geometry/x");
+ QCOMPARE(settings0.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings0.value("alpha/beta/geometry/x", 999).toInt(), 999);
+ QCOMPARE(settings0.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings0.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings0.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
+
+ settings0.remove("alpha/beta/geometry");
+ QCOMPARE(settings0.value("alpha/beta/geometry", 777).toInt(), 777);
+ QCOMPARE(settings0.value("alpha/beta/geometry/x", 111).toInt(), 111);
+ QCOMPARE(settings0.value("alpha/beta/geometry/y", 222).toInt(), 222);
+ QCOMPARE(settings0.value("alpha/beta/geometry/width", 333).toInt(), 333);
+ QCOMPARE(settings0.value("alpha/beta/geometry/height", 444).toInt(), 444);
+ QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
+
+ settings0.setValue("alpha/beta/geometry", -7);
+ settings0.setValue("alpha/beta/geometry/x", 1);
+ settings0.setValue("alpha/beta/geometry/y", 2);
+ settings0.setValue("alpha/beta/geometry/width", 3);
+ settings0.setValue("alpha/beta/geometry/height", 4);
+ settings0.setValue("alpha/gamma/splitter", 5);
+ QCOMPARE(settings0.allKeys().size(), initialNumKeys + 6);
+
+ settings0.beginGroup("alpha/beta/geometry");
+ settings0.remove("");
+ settings0.endGroup();
+ QVERIFY(!settings0.contains("alpha/beta/geometry"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/x"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/y"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/width"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/height"));
+ QVERIFY(settings0.contains("alpha/gamma/splitter"));
+ QCOMPARE(settings0.allKeys().size(), initialNumKeys + 1);
+
+ settings0.beginGroup("alpha/beta");
+ settings0.remove("");
+ settings0.endGroup();
+ QVERIFY(!settings0.contains("alpha/beta/geometry"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/x"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/y"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/width"));
+ QVERIFY(!settings0.contains("alpha/beta/geometry/height"));
+ QVERIFY(settings0.contains("alpha/gamma/splitter"));
+ QCOMPARE(settings0.allKeys().size(), initialNumKeys + 1);
+
+ settings0.remove("");
+ QVERIFY(!settings0.contains("alpha/gamma/splitter"));
+ QCOMPARE(settings0.allKeys().size(), initialNumKeys);
+
+ /*
+ Do it again, but this time let's use setGroup().
+ */
+
+ settings0.setValue("alpha/beta/geometry", -7);
+ settings0.setValue("alpha/beta/geometry/x", 1);
+ settings0.setValue("alpha/beta/geometry/y", 2);
+ settings0.setValue("alpha/beta/geometry/width", 3);
+ settings0.setValue("alpha/beta/geometry/height", 4);
+ settings0.setValue("alpha/gamma/splitter", 5);
+
+ settings0.beginGroup("foo/bar/baz/doesn't");
+ settings0.remove("exist");
+ settings0.endGroup();
+ QCOMPARE(settings0.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings0.value("alpha/beta/geometry/x").toInt(), 1);
+ QCOMPARE(settings0.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings0.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings0.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
+
+ settings0.beginGroup("alpha/beta/geometry");
+ settings0.remove("x");
+ settings0.endGroup();
+ QCOMPARE(settings0.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings0.value("alpha/beta/geometry/x", 999).toInt(), 999);
+ QCOMPARE(settings0.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings0.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings0.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
+
+ settings0.remove("alpha/beta");
+ QCOMPARE(settings0.value("alpha/beta/geometry", 777).toInt(), 777);
+ QCOMPARE(settings0.value("alpha/beta/geometry/x", 111).toInt(), 111);
+ QCOMPARE(settings0.value("alpha/beta/geometry/y", 222).toInt(), 222);
+ QCOMPARE(settings0.value("alpha/beta/geometry/width", 333).toInt(), 333);
+ QCOMPARE(settings0.value("alpha/beta/geometry/height", 444).toInt(), 444);
+ QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
+
+ settings0.clear();
+ QCOMPARE(settings0.value("alpha/gamma/splitter", 888).toInt(), 888);
+
+ /*
+ OK, now let's check what happens if settings are spread across
+ multiple files (user vs. global, product-specific vs.
+ company-wide).
+ */
+
+ QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings2(QSettings::UserScope, "software.org");
+ QSettings settings3(QSettings::SystemScope, "software.org", "KillerAPP");
+ QSettings settings4(QSettings::SystemScope, "software.org");
+
+ settings4.setValue("key 1", "doodah");
+ settings3.setValue("key 1", "blah");
+ settings2.setValue("key 1", "whoa");
+ settings1.setValue("key 1", "gurgle");
+ QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings1.remove("key 1");
+ QCOMPARE(settings1.value("key 1").toString(), QString("whoa"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings2.remove("key 1");
+ QCOMPARE(settings1.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings3.remove("key 1");
+ QCOMPARE(settings1.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("doodah"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
+
+ settings4.remove("key 1");
+ QVERIFY(!settings1.contains("key 1"));
+ QVERIFY(!settings2.contains("key 1"));
+ QVERIFY(!settings3.contains("key 1"));
+ QVERIFY(!settings4.contains("key 1"));
+
+ /*
+ Get ready for the next part of the test.
+ */
+
+ settings1.clear();
+ settings2.clear();
+ settings3.clear();
+ settings4.clear();
+
+ settings1.sync();
+ settings2.sync();
+ settings3.sync();
+ settings4.sync();
+
+ /*
+ Check that recursive removes work correctly when some of the
+ keys are loaded from the file and others have been modified in
+ memory (corresponds to originalKeys vs. addedKeys in the
+ QSettingsFile code).
+ */
+
+ settings1.setValue("alpha/beta/geometry", -7);
+ settings1.setValue("alpha/beta/geometry/x", 1);
+ settings1.setValue("alpha/beta/geometry/y", 2);
+ settings1.setValue("alpha/gamma/splitter", 5);
+ settings1.sync();
+
+ settings1.setValue("alpha/beta/geometry/width", 3);
+ settings1.setValue("alpha/beta/geometry/height", 4);
+
+ settings1.remove("alpha/beta/geometry/y");
+ QVERIFY(settings1.contains("alpha/beta/geometry"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/x"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/width"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/height"));
+ QCOMPARE(settings1.allKeys().size(), initialNumKeys + 5);
+
+ settings1.remove("alpha/beta/geometry/y");
+ QCOMPARE(settings1.allKeys().size(), initialNumKeys + 5);
+
+ settings1.remove("alpha/beta/geometry/height");
+ QVERIFY(settings1.contains("alpha/beta/geometry"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/x"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/width"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/height"));
+ QCOMPARE(settings1.allKeys().size(), initialNumKeys + 4);
+
+ settings1.remove("alpha/beta/geometry");
+ QVERIFY(!settings1.contains("alpha/beta/geometry"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/x"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/width"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/height"));
+ QVERIFY(settings1.contains("alpha/gamma/splitter"));
+ QCOMPARE(settings1.allKeys().size(), initialNumKeys + 1);
+
+ settings1.sync();
+ QVERIFY(!settings1.contains("alpha/beta/geometry"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/x"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/width"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/height"));
+ QVERIFY(settings1.contains("alpha/gamma/splitter"));
+ QCOMPARE(settings1.allKeys().size(), initialNumKeys + 1);
+}
+
+/*
+ Tests contains() and keys().
+*/
+void tst_QSettings::contains()
+{
+ QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
+ int initialNumKeys = settings1.allKeys().size(); // 0 on all platforms but Mac OS X.
+ settings1.setValue("alpha/beta/geometry", -7);
+ settings1.setValue("alpha/beta/geometry/x", 1);
+ settings1.setValue("alpha/beta/geometry/y", 2);
+ settings1.setValue("alpha/beta/geometry/width", 3);
+ settings1.setValue("alpha/beta/geometry/height", 4);
+ settings1.setValue("alpha/gamma/splitter", 5);
+ settings1.setValue("alpha/gamma/splitter/ /", 5);
+
+ QVERIFY(!settings1.contains("alpha"));
+ QVERIFY(!settings1.contains("alpha/beta"));
+ QVERIFY(!settings1.contains("///alpha///beta///"));
+ QVERIFY(settings1.contains("alpha/beta/geometry"));
+ QVERIFY(settings1.contains("///alpha///beta//geometry//"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/x"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/y"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/width"));
+ QVERIFY(settings1.contains("alpha/beta/geometry/height"));
+ QVERIFY(!settings1.contains("alpha/beta/geometry/height/foo/bar/doesn't/exist"));
+ QVERIFY(!settings1.contains("alpha/gamma"));
+ QVERIFY(settings1.contains("alpha/gamma/splitter"));
+ QVERIFY(settings1.contains("alpha/gamma/splitter/ "));
+ QVERIFY(settings1.contains("////alpha/gamma/splitter// ////"));
+
+ settings1.beginGroup("alpha");
+ QVERIFY(!settings1.contains("beta"));
+ QVERIFY(!settings1.contains("/////beta///"));
+ QVERIFY(settings1.contains("beta/geometry"));
+ QVERIFY(settings1.contains("/////beta//geometry//"));
+ QVERIFY(settings1.contains("beta/geometry/x"));
+ QVERIFY(settings1.contains("beta/geometry/y"));
+ QVERIFY(settings1.contains("beta/geometry/width"));
+ QVERIFY(settings1.contains("beta/geometry/height"));
+ QVERIFY(!settings1.contains("beta/geometry/height/foo/bar/doesn't/exist"));
+ QVERIFY(!settings1.contains("gamma"));
+ QVERIFY(settings1.contains("gamma/splitter"));
+ QVERIFY(settings1.contains("gamma/splitter/ "));
+ QVERIFY(settings1.contains("////gamma/splitter// ////"));
+
+ settings1.beginGroup("beta/geometry");
+ QVERIFY(settings1.contains("x"));
+ QVERIFY(settings1.contains("y"));
+ QVERIFY(settings1.contains("width"));
+ QVERIFY(settings1.contains("height"));
+ QVERIFY(!settings1.contains("height/foo/bar/doesn't/exist"));
+
+ QStringList keys = settings1.allKeys();
+ QStringList expectedResult = QStringList() << "x" << "y" << "width" << "height";
+ keys.sort();
+ expectedResult.sort();
+ int i;
+ QCOMPARE(keys, expectedResult);
+ for (i = 0; i < keys.size(); ++i) {
+ QVERIFY(settings1.contains(keys.at(i)));
+ }
+
+ settings1.endGroup();
+ QVERIFY(settings1.group() == "alpha");
+ keys = settings1.allKeys();
+ QCOMPARE(keys.size(), expectedResult.size() + 3);
+ for (i = 0; i < keys.size(); ++i) {
+ QVERIFY(settings1.contains(keys.at(i)));
+ }
+
+ settings1.endGroup();
+ QVERIFY(settings1.group().isEmpty());
+ keys = settings1.allKeys();
+
+ QCOMPARE(keys.size(), initialNumKeys + 7);
+ for (i = 0; i < keys.size(); ++i) {
+ QVERIFY(settings1.contains(keys.at(i)));
+ }
+}
+
+void tst_QSettings::sync()
+{
+ /*
+ What we're trying to test here is the case where two
+ instances of the same application access the same preference
+ files. We want to make sure that the results are 'merged',
+ rather than having the last application overwrite settings
+ set by the first application (like in Qt 3).
+
+ This is only applicable to the INI format. The Windows
+ registry and Mac's CFPreferences API should take care of this
+ by themselves.
+ */
+
+ QSettings settings1(QSettings::IniFormat, QSettings::UserScope, "software.org");
+ settings1.setValue("alpha/beta/geometry", -7);
+ settings1.setValue("alpha/beta/geometry/x", 1);
+ settings1.setValue("alpha/beta/geometry/y", 2);
+ settings1.setValue("alpha/beta/geometry/width", 3);
+ settings1.setValue("alpha/beta/geometry/height", 4);
+ settings1.setValue("alpha/gamma/splitter", 5);
+ settings1.sync(); // and it all goes into the file
+
+ QSettings settings2(QSettings::IniFormat, QSettings::UserScope, "other.software.org");
+ settings2.setValue("alpha/beta/geometry/x", 8);
+ settings2.sync();
+
+ settings2.setValue("moo/beta/geometry", -7);
+ settings2.setValue("moo/beta/geometry/x", 1);
+ settings2.setValue("moo/beta/geometry/y", 2);
+ settings2.setValue("moo/beta/geometry/width", 3);
+ settings2.setValue("moo/beta/geometry/height", 4);
+ settings2.setValue("moo/gamma/splitter", 5);
+ settings2.setValue("alpha/gamma/splitter", 15);
+ settings2.remove("alpha/beta/geometry/x");
+ settings2.remove("alpha/beta/geometry/y"); // should do nothing
+
+ // Now "some other app" will change other.software.org.ini
+ QString userConfDir = settingsPath("__user__") + QDir::separator();
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ unlink((userConfDir + "other.software.org.ini").toLatin1());
+ rename((userConfDir + "software.org.ini").toLatin1(),
+ (userConfDir + "other.software.org.ini").toLatin1());
+#else
+ QFile::remove(userConfDir + "other.software.org.ini");
+ QFile::rename(userConfDir + "software.org.ini" , userConfDir + "other.software.org.ini");
+#endif
+
+ settings2.sync();
+
+ // And voila, we should be merged
+
+ QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), -7);
+ QVERIFY(!settings2.contains("alpha/beta/geometry/x")); // <----- removed by settings2
+ QCOMPARE(settings2.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings2.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings2.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings2.value("alpha/gamma/splitter").toInt(), 15); // <---- set by settings2
+ QCOMPARE(settings2.value("moo/beta/geometry").toInt(), -7);
+ QCOMPARE(settings2.value("moo/beta/geometry/x").toInt(), 1);
+ QCOMPARE(settings2.value("moo/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings2.value("moo/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings2.value("moo/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings2.value("moo/gamma/splitter").toInt(), 5);
+ QCOMPARE(settings2.allKeys().count(), 11);
+
+ // Now, software.org.ini no longer exists, this is same as another app
+ // clearing all settings.
+ settings1.sync();
+ QCOMPARE(settings1.allKeys().count(), 0);
+
+/*
+ // Now "some other app" will change software.org.conf
+ unlink((userConfDir + "software.org.ini").toLatin1());
+ rename((userConfDir + "other.software.org.ini").toLatin1(),
+ (userConfDir + "software.org.ini").toLatin1());
+
+ settings1.sync();
+ QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7);
+ QCOMPARE(settings1.value("alpha/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 15);
+ QCOMPARE(settings1.value("moo/beta/geometry").toInt(), -7);
+ QCOMPARE(settings1.value("moo/beta/geometry/x").toInt(), 1);
+ QCOMPARE(settings1.value("moo/beta/geometry/y").toInt(), 2);
+ QCOMPARE(settings1.value("moo/beta/geometry/width").toInt(), 3);
+ QCOMPARE(settings1.value("moo/beta/geometry/height").toInt(), 4);
+ QCOMPARE(settings1.value("moo/gamma/splitter").toInt(), 5);
+ QCOMPARE(settings1.allKeys().count(), 11);
+*/
+}
+
+void tst_QSettings::setFallbacksEnabled_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::setFallbacksEnabled()
+{
+ QFETCH(QSettings::Format, format);
+
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings2(format, QSettings::UserScope, "software.org");
+ QSettings settings3(format, QSettings::SystemScope, "software.org", "KillerAPP");
+ QSettings settings4(format, QSettings::SystemScope, "software.org");
+
+ settings1.setValue("key 1", "alpha");
+ settings2.setValue("key 1", "beta");
+ settings3.setValue("key 1", "gamma");
+ settings4.setValue("key 1", "delta");
+
+ settings1.setValue("key 2", "alpha");
+ settings2.setValue("key 2", "beta");
+ settings3.setValue("key 2", "gamma");
+
+ settings1.setValue("key 3", "alpha");
+ settings3.setValue("key 3", "gamma");
+ settings4.setValue("key 3", "delta");
+
+ settings1.setValue("key 4", "alpha");
+ settings2.setValue("key 4", "beta");
+ settings4.setValue("key 4", "delta");
+
+ settings2.setValue("key 5", "beta");
+ settings3.setValue("key 5", "gamma");
+ settings4.setValue("key 5", "delta");
+
+ QVERIFY(settings1.fallbacksEnabled());
+ QVERIFY(settings2.fallbacksEnabled());
+ QVERIFY(settings3.fallbacksEnabled());
+ QVERIFY(settings4.fallbacksEnabled());
+
+ settings1.setFallbacksEnabled(false);
+ settings2.setFallbacksEnabled(false);
+ settings3.setFallbacksEnabled(false);
+ settings4.setFallbacksEnabled(false);
+
+ QVERIFY(!settings1.fallbacksEnabled());
+ QVERIFY(!settings2.fallbacksEnabled());
+ QVERIFY(!settings3.fallbacksEnabled());
+ QVERIFY(!settings4.fallbacksEnabled());
+
+ /*
+ Make sure that the QSettings objects can still access their
+ main associated file when fallbacks are turned off.
+ */
+
+ QCOMPARE(settings1.value("key 1").toString(), QString("alpha"));
+ QCOMPARE(settings2.value("key 1").toString(), QString("beta"));
+ QCOMPARE(settings3.value("key 1").toString(), QString("gamma"));
+ QCOMPARE(settings4.value("key 1").toString(), QString("delta"));
+
+ QCOMPARE(settings1.value("key 2").toString(), QString("alpha"));
+ QCOMPARE(settings2.value("key 2").toString(), QString("beta"));
+ QCOMPARE(settings3.value("key 2").toString(), QString("gamma"));
+ QVERIFY(!settings4.contains("key 2"));
+
+ QCOMPARE(settings1.value("key 3").toString(), QString("alpha"));
+ QCOMPARE(settings3.value("key 3").toString(), QString("gamma"));
+ QCOMPARE(settings4.value("key 3").toString(), QString("delta"));
+ QVERIFY(!settings2.contains("key 3"));
+
+ QCOMPARE(settings1.value("key 4").toString(), QString("alpha"));
+ QCOMPARE(settings2.value("key 4").toString(), QString("beta"));
+ QCOMPARE(settings4.value("key 4").toString(), QString("delta"));
+ QVERIFY(!settings3.contains("key 4"));
+
+ QCOMPARE(settings2.value("key 5").toString(), QString("beta"));
+ QCOMPARE(settings3.value("key 5").toString(), QString("gamma"));
+ QCOMPARE(settings4.value("key 5").toString(), QString("delta"));
+ QVERIFY(!settings1.contains("key 5"));
+
+ QCOMPARE(settings1.value("key 1").toString(), QString("alpha"));
+ QCOMPARE(settings1.value("key 5").toString(), QString(""));
+ QVERIFY(settings1.contains("key 1"));
+ QVERIFY(!settings1.contains("key 5"));
+}
+
+void tst_QSettings::testChildKeysAndGroups_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::testChildKeysAndGroups()
+{
+ QFETCH(QSettings::Format, format);
+
+ QSettings settings1(format, QSettings::UserScope, "software.org");
+ settings1.setFallbacksEnabled(false);
+ settings1.setValue("alpha/beta/geometry", -7);
+ settings1.setValue("alpha/beta/geometry/x", 1);
+ settings1.setValue("alpha/beta/geometry/y", 2);
+ settings1.setValue("alpha/beta/geometry/width", 3);
+ settings1.setValue("alpha/beta/geometry/height", 4);
+ settings1.setValue("alpha/gamma/splitter", 5);
+
+ QCOMPARE(settings1.childKeys(), QStringList());
+ QCOMPARE(settings1.childGroups(), QStringList() << "alpha");
+
+ settings1.beginGroup("/alpha");
+ QCOMPARE(settings1.childKeys(), QStringList());
+ QCOMPARE(settings1.childGroups(), QStringList() << "beta" << "gamma");
+
+ settings1.beginGroup("/beta");
+ QCOMPARE(settings1.childKeys(), QStringList() << "geometry");
+ QCOMPARE(settings1.childGroups(), QStringList() << "geometry");
+
+ settings1.beginGroup("/geometry");
+ QCOMPARE(settings1.childKeys(), QStringList() << "height" << "width" << "x" << "y");
+ QCOMPARE(settings1.childGroups(), QStringList());
+
+ settings1.beginGroup("/width");
+ QCOMPARE(settings1.childKeys(), QStringList());
+ QCOMPARE(settings1.childGroups(), QStringList());
+
+ settings1.endGroup();
+ settings1.endGroup();
+ settings1.endGroup();
+ settings1.endGroup();
+
+ { // task 53792
+ QSettings settings2("other.software.org");
+ settings2.setValue("viewbar/foo/test1", "1");
+ settings2.setValue("viewbar/foo/test2", "2");
+ settings2.setValue("viewbar/foo/test3", "3");
+ settings2.setValue("viewbar/foo/test4", "4");
+ settings2.setValue("viewbar/foo/test5", "5");
+ settings2.setValue("viewbar/bar/test1", "1");
+ settings2.setValue("viewbar/bar/test2", "2");
+ settings2.setValue("viewbar/bar/test3", "3");
+ settings2.setValue("viewbar/bar/test4", "4");
+ settings2.setValue("viewbar/bar/test5", "5");
+
+ settings2.beginGroup("viewbar");
+ QStringList l = settings2.childGroups();
+ settings2.endGroup();
+ l.sort();
+ QCOMPARE(l, QStringList() << "bar" << "foo");
+ }
+}
+
+void tst_QSettings::testUpdateRequestEvent()
+{
+ QFile::remove("foo");
+ QVERIFY(!QFile::exists("foo"));
+
+ QSettings settings1("foo", QSettings::IniFormat);
+ QVERIFY(!QFile::exists("foo"));
+ QVERIFY(QFileInfo("foo").size() == 0);
+ settings1.setValue("key1", 1);
+ QVERIFY(QFileInfo("foo").size() == 0);
+
+ QTRY_VERIFY(QFileInfo("foo").size() > 0);
+
+ settings1.remove("key1");
+ QVERIFY(QFileInfo("foo").size() > 0);
+
+ QTRY_VERIFY(QFileInfo("foo").size() == 0);
+
+ settings1.setValue("key2", 2);
+ QVERIFY(QFileInfo("foo").size() == 0);
+
+ QTRY_VERIFY(QFileInfo("foo").size() > 0);
+
+ settings1.clear();
+ QVERIFY(QFileInfo("foo").size() > 0);
+
+ QTRY_VERIFY(QFileInfo("foo").size() == 0);
+}
+
+const int NumIterations = 5;
+const int NumThreads = 4;
+
+class SettingsThread : public QThread
+{
+public:
+ void run();
+ void start(int n) { param = n; QThread::start(); }
+
+private:
+ int param;
+};
+
+void SettingsThread::run()
+{
+ for (int i = 0; i < NumIterations; ++i) {
+ QSettings settings("software.org", "KillerAPP");
+ settings.setValue(QString::number((param * NumIterations) + i), param);
+ settings.sync();
+ QCOMPARE((int)settings.status(), (int)QSettings::NoError);
+ }
+}
+
+void tst_QSettings::testThreadSafety()
+{
+ SettingsThread threads[NumThreads];
+ int i, j;
+
+ for (i = 0; i < NumThreads; ++i)
+ threads[i].start(i + 1);
+ for (i = 0; i < NumThreads; ++i)
+ threads[i].wait();
+
+ QSettings settings("software.org", "KillerAPP");
+ for (i = 0; i < NumThreads; ++i) {
+ int param = i + 1;
+ for (j = 0; j < NumIterations; ++j) {
+ QCOMPARE(settings.value(QString::number((param * NumIterations) + j)).toInt(), param);
+ }
+ }
+}
+
+void tst_QSettings::testNormalizedKey_data()
+{
+ QTest::addColumn<QString>("inKey");
+ QTest::addColumn<QString>("outKey");
+
+ QTest::newRow("empty1") << "" << "";
+ QTest::newRow("empty2") << "/" << "";
+ QTest::newRow("empty3") << "//" << "";
+ QTest::newRow("empty4") << "///" << "";
+
+ QTest::newRow("a1") << "a" << "a";
+ QTest::newRow("a2") << "/a" << "a";
+ QTest::newRow("a3") << "a/" << "a";
+ QTest::newRow("a4") << "//a" << "a";
+ QTest::newRow("a5") << "a//" << "a";
+ QTest::newRow("a6") << "///a" << "a";
+ QTest::newRow("a7") << "a///" << "a";
+ QTest::newRow("a8") << "///a/" << "a";
+ QTest::newRow("a9") << "/a///" << "a";
+
+ QTest::newRow("ab1") << "aaa/bbb" << "aaa/bbb";
+ QTest::newRow("ab2") << "/aaa/bbb" << "aaa/bbb";
+ QTest::newRow("ab3") << "aaa/bbb/" << "aaa/bbb";
+ QTest::newRow("ab4") << "/aaa/bbb/" << "aaa/bbb";
+ QTest::newRow("ab5") << "aaa///bbb" << "aaa/bbb";
+ QTest::newRow("ab6") << "aaa///bbb/" << "aaa/bbb";
+ QTest::newRow("ab7") << "/aaa///bbb/" << "aaa/bbb";
+ QTest::newRow("ab8") << "////aaa///bbb////" << "aaa/bbb";
+}
+
+void tst_QSettings::testNormalizedKey()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QString, inKey);
+ QFETCH(QString, outKey);
+
+ inKey.detach();
+
+ QString result = QSettingsPrivate::normalizedKey(inKey);
+ QCOMPARE(result, outKey);
+
+ /*
+ If the key is already normalized, we verify that outKey is
+ just a shallow copy of the input string. This is an important
+ optimization that shouldn't be removed accidentally.
+ */
+ if (inKey == outKey) {
+ QVERIFY(!result.isDetached());
+ } else {
+ if (!result.isEmpty()) {
+ QVERIFY(result.isDetached());
+ }
+ }
+#endif
+}
+
+void tst_QSettings::testEmptyData()
+{
+ QString filename(QDir::tempPath() + "/empty.ini");
+ QFile::remove(filename);
+ QVERIFY(!QFile::exists(filename));
+
+ QString nullString;
+ QString emptyString("");
+ QStringList emptyList;
+ QStringList list;
+ QStringList list2;
+
+ QVariantList emptyVList;
+ QVariantList vList, vList2, vList3;
+
+ list << emptyString << nullString;
+ list2 << emptyString;
+ vList << emptyString;
+ vList2 << emptyString << nullString;
+ vList3 << QString("foo");
+
+ {
+ QSettings settings(filename, QSettings::IniFormat);
+ settings.setValue("nullString", nullString);
+ settings.setValue("emptyString", emptyString);
+ settings.setValue("emptyList", emptyList);
+ settings.setValue("list", list);
+ settings.setValue("list2", list2);
+ settings.setValue("emptyVList", emptyVList);
+ settings.setValue("vList", vList);
+ settings.setValue("vList2", vList2);
+ settings.setValue("vList3", vList3);
+ QVERIFY(settings.status() == QSettings::NoError);
+ }
+ {
+ QSettings settings(filename, QSettings::IniFormat);
+ QCOMPARE(settings.value("nullString").toString(), nullString);
+ QCOMPARE(settings.value("emptyString").toString(), emptyString);
+ QCOMPARE(settings.value("emptyList").toStringList(), emptyList);
+ QCOMPARE(settings.value("list").toStringList(), list);
+ QCOMPARE(settings.value("list2").toStringList(), list2);
+ QCOMPARE(settings.value("emptyVList").toList(), emptyVList);
+ QCOMPARE(settings.value("vList").toList(), vList);
+ QCOMPARE(settings.value("vList2").toList(), vList2);
+ QCOMPARE(settings.value("vList3").toList(), vList3);
+ QVERIFY(settings.status() == QSettings::NoError);
+ }
+
+ {
+ QSettings settings("Trolltech", "tst_qsettings");
+ settings.setValue("nullString", nullString);
+ settings.setValue("emptyString", emptyString);
+ settings.setValue("emptyList", emptyList);
+ settings.setValue("list", list);
+ settings.setValue("list2", list2);
+ settings.setValue("emptyVList", emptyVList);
+ settings.setValue("vList", vList);
+ settings.setValue("vList2", vList2);
+ settings.setValue("vList3", vList3);
+ QVERIFY(settings.status() == QSettings::NoError);
+ }
+ {
+ QSettings settings("Trolltech", "tst_qsettings");
+ QCOMPARE(settings.value("nullString").toString(), nullString);
+ QCOMPARE(settings.value("emptyString").toString(), emptyString);
+ QCOMPARE(settings.value("emptyList").toStringList(), emptyList);
+ QCOMPARE(settings.value("list").toStringList(), list);
+ QCOMPARE(settings.value("list2").toStringList(), list2);
+ QCOMPARE(settings.value("emptyVList").toList(), emptyVList);
+ QCOMPARE(settings.value("vList").toList(), vList);
+ QCOMPARE(settings.value("vList2").toList(), vList2);
+ QCOMPARE(settings.value("vList3").toList(), vList3);
+ QVERIFY(settings.status() == QSettings::NoError);
+ }
+ QFile::remove(filename);
+}
+
+void tst_QSettings::testResourceFiles()
+{
+ QSettings settings(":/resourcefile.ini", QSettings::IniFormat);
+ QVERIFY(settings.status() == QSettings::NoError);
+ QVERIFY(!settings.isWritable());
+ QCOMPARE(settings.value("Field 1/Bottom").toInt(), 89);
+ settings.setValue("Field 1/Bottom", 90);
+
+ // the next two lines check the statu quo; another behavior would be possible
+ QVERIFY(settings.status() == QSettings::NoError);
+ QCOMPARE(settings.value("Field 1/Bottom").toInt(), 90);
+
+ settings.sync();
+ QVERIFY(settings.status() == QSettings::AccessError);
+ QCOMPARE(settings.value("Field 1/Bottom").toInt(), 90);
+}
+
+void tst_QSettings::fromFile_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::fromFile()
+{
+ QFETCH(QSettings::Format, format);
+
+ QFile::remove("foo");
+ QVERIFY(!QFile::exists("foo"));
+
+ QString path = "foo";
+
+#ifdef Q_OS_WIN
+ if (format == QSettings::NativeFormat)
+ path = "\\HKEY_CURRENT_USER\\Software\\foo";
+#endif
+
+ QStringList strList = QStringList() << "hope" << "destiny" << "chastity";
+
+ {
+ QSettings settings1(path, format);
+ QVERIFY(settings1.allKeys().isEmpty());
+
+ settings1.setValue("alpha", 1);
+ settings1.setValue("alpha", 2);
+ settings1.setValue("beta", strList);
+
+ QSettings settings2(path, format);
+ QCOMPARE(settings2.value("alpha").toInt(), 2);
+
+ settings1.sync();
+#ifndef Q_OS_WIN
+ QVERIFY(QFile::exists("foo"));
+#endif
+ QCOMPARE(settings1.value("alpha").toInt(), 2);
+ QCOMPARE(settings2.value("alpha").toInt(), 2);
+
+ settings2.setValue("alpha", 3);
+ settings2.setValue("gamma/foo.bar", 4);
+ QCOMPARE(settings1.value("alpha").toInt(), 3);
+ QCOMPARE(settings2.value("alpha").toInt(), 3);
+ QCOMPARE(settings1.value("beta").toStringList(), strList);
+ QCOMPARE(settings2.value("beta").toStringList(), strList);
+ QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
+ QCOMPARE(settings2.value("gamma/foo.bar").toInt(), 4);
+ }
+
+ {
+ QSettings settings1(path, format);
+ QCOMPARE(settings1.value("alpha").toInt(), 3);
+ QCOMPARE(settings1.value("beta").toStringList(), strList);
+ QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
+ QCOMPARE(settings1.allKeys().size(), 3);
+ }
+}
+
+void tst_QSettings::setIniCodec()
+{
+#ifdef QT_BUILD_INTERNAL
+ QByteArray expeContents4, expeContents5;
+ QByteArray actualContents4, actualContents5;
+
+ {
+ QFile inFile(":/resourcefile4.ini");
+ inFile.open(QIODevice::ReadOnly);
+ expeContents4 = inFile.readAll();
+ inFile.close();
+ }
+
+ {
+ QFile inFile(":/resourcefile5.ini");
+ inFile.open(QIODevice::ReadOnly);
+ expeContents5 = inFile.readAll();
+ inFile.close();
+ }
+
+ {
+ QSettings settings4(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
+ settings4.setIniCodec("UTF-8");
+ settings4.setValue(QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"), QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"));
+ settings4.sync();
+
+ QSettings settings5(QSettings::IniFormat, QSettings::UserScope, "other.software.org", "KillerAPP");
+ settings5.setIniCodec("ISO 8859-1");
+ settings5.setValue(QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"), QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"));
+ settings5.sync();
+
+ {
+ QFile inFile(settings4.fileName());
+ inFile.open(QIODevice::ReadOnly);
+ actualContents4 = inFile.readAll();
+ inFile.close();
+ }
+
+ {
+ QFile inFile(settings5.fileName());
+ inFile.open(QIODevice::ReadOnly);
+ actualContents5 = inFile.readAll();
+ inFile.close();
+ }
+ }
+
+ QConfFile::clearCache();
+
+ QCOMPARE(actualContents4, expeContents4);
+ QCOMPARE(actualContents5, expeContents5);
+
+ QSettings settings4(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
+ settings4.setIniCodec("UTF-8");
+ QSettings settings5(QSettings::IniFormat, QSettings::UserScope, "other.software.org", "KillerAPP");
+ settings5.setIniCodec("Latin-1");
+
+ QCOMPARE(settings4.allKeys().count(), 1);
+ QCOMPARE(settings5.allKeys().count(), 1);
+
+ QCOMPARE(settings4.allKeys().first(), settings5.allKeys().first());
+ QCOMPARE(settings4.value(settings4.allKeys().first()).toString(),
+ settings5.value(settings5.allKeys().first()).toString());
+#endif
+}
+
+static bool containsSubList(QStringList mom, QStringList son)
+{
+ for (int i = 0; i < son.size(); ++i) {
+ if (!mom.contains(son.at(i)))
+ return false;
+ }
+ return true;
+}
+
+void tst_QSettings::testArrays_data()
+{
+ populateWithFormats();
+}
+
+/*
+ Tests beginReadArray(), beginWriteArray(), endArray(), and
+ setArrayIndex().
+*/
+void tst_QSettings::testArrays()
+{
+ QFETCH(QSettings::Format, format);
+
+ {
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
+
+ settings1.beginWriteArray("foo/bar", 3);
+ settings1.setValue("bip", 1);
+ settings1.setArrayIndex(0);
+ settings1.setValue("ene", 2);
+ settings1.setValue("due", 3);
+ settings1.setValue("rike", 4);
+ settings1.setArrayIndex(1);
+ settings1.setValue("ene", 5);
+ settings1.setValue("due", 6);
+ settings1.setValue("rike", 7);
+ settings1.setArrayIndex(2);
+ settings1.setValue("ene", 8);
+ settings1.setValue("due", 9);
+ settings1.setValue("rike", 10);
+ settings1.endArray();
+
+ QStringList expectedList;
+ expectedList
+ << "foo/bar/bip"
+ << "foo/bar/size"
+ << "foo/bar/1/ene"
+ << "foo/bar/1/due"
+ << "foo/bar/1/rike"
+ << "foo/bar/2/ene"
+ << "foo/bar/2/due"
+ << "foo/bar/2/rike"
+ << "foo/bar/3/ene"
+ << "foo/bar/3/due"
+ << "foo/bar/3/rike";
+ expectedList.sort();
+
+ QStringList actualList = settings1.allKeys();
+ actualList.sort();
+ QVERIFY(containsSubList(actualList, expectedList));
+
+ QCOMPARE(settings1.value("/foo/bar/bip").toInt(), 1);
+ QCOMPARE(settings1.value("/foo/bar/1/ene").toInt(), 2);
+ QCOMPARE(settings1.value("/foo/bar/1/due").toInt(), 3);
+ QCOMPARE(settings1.value("/foo/bar/1/rike").toInt(), 4);
+ QCOMPARE(settings1.value("/foo/bar/2/ene").toInt(), 5);
+ QCOMPARE(settings1.value("/foo/bar/2/due").toInt(), 6);
+ QCOMPARE(settings1.value("/foo/bar/2/rike").toInt(), 7);
+ QCOMPARE(settings1.value("/foo/bar/3/ene").toInt(), 8);
+ QCOMPARE(settings1.value("/foo/bar/3/due").toInt(), 9);
+ QCOMPARE(settings1.value("/foo/bar/3/rike").toInt(), 10);
+
+ settings1.beginGroup("/foo");
+ int count = settings1.beginReadArray("bar");
+ QCOMPARE(count, 3);
+ QCOMPARE(settings1.value("bip").toInt(), 1);
+ settings1.setArrayIndex(0);
+ QCOMPARE(settings1.value("ene").toInt(), 2);
+ QCOMPARE(settings1.value("due").toInt(), 3);
+ QCOMPARE(settings1.value("rike").toInt(), 4);
+ QCOMPARE(settings1.allKeys().count(), 3);
+ settings1.setArrayIndex(1);
+ QCOMPARE(settings1.value("ene").toInt(), 5);
+ QCOMPARE(settings1.value("due").toInt(), 6);
+ QCOMPARE(settings1.value("rike").toInt(), 7);
+ QCOMPARE(settings1.allKeys().count(), 3);
+ settings1.setArrayIndex(2);
+ QCOMPARE(settings1.value("ene").toInt(), 8);
+ QCOMPARE(settings1.value("due").toInt(), 9);
+ QCOMPARE(settings1.value("rike").toInt(), 10);
+ QCOMPARE(settings1.allKeys().count(), 3);
+
+ settings1.endArray();
+ settings1.endGroup();
+ }
+ /*
+ Check that we get the arrays right when we load them again
+ */
+
+ {
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
+
+ QStringList expectedList;
+ expectedList
+ << "foo/bar/bip"
+ << "foo/bar/size"
+ << "foo/bar/1/ene"
+ << "foo/bar/1/due"
+ << "foo/bar/1/rike"
+ << "foo/bar/2/ene"
+ << "foo/bar/2/due"
+ << "foo/bar/2/rike"
+ << "foo/bar/3/ene"
+ << "foo/bar/3/due"
+ << "foo/bar/3/rike";
+ expectedList.sort();
+
+ QStringList actualList = settings1.allKeys();
+ actualList.sort();
+ QVERIFY(containsSubList(actualList, expectedList));
+
+ QCOMPARE(settings1.value("/foo/bar/bip").toInt(), 1);
+ QCOMPARE(settings1.value("/foo/bar/1/ene").toInt(), 2);
+ QCOMPARE(settings1.value("/foo/bar/1/due").toInt(), 3);
+ QCOMPARE(settings1.value("/foo/bar/1/rike").toInt(), 4);
+ QCOMPARE(settings1.value("/foo/bar/2/ene").toInt(), 5);
+ QCOMPARE(settings1.value("/foo/bar/2/due").toInt(), 6);
+ QCOMPARE(settings1.value("/foo/bar/2/rike").toInt(), 7);
+ QCOMPARE(settings1.value("/foo/bar/3/ene").toInt(), 8);
+ QCOMPARE(settings1.value("/foo/bar/3/due").toInt(), 9);
+ QCOMPARE(settings1.value("/foo/bar/3/rike").toInt(), 10);
+
+ settings1.beginGroup("/foo");
+ int count = settings1.beginReadArray("bar");
+ QCOMPARE(count, 3);
+ QCOMPARE(settings1.value("bip").toInt(), 1);
+ settings1.setArrayIndex(0);
+ QCOMPARE(settings1.value("ene").toInt(), 2);
+ QCOMPARE(settings1.value("due").toInt(), 3);
+ QCOMPARE(settings1.value("rike").toInt(), 4);
+ QCOMPARE(settings1.allKeys().count(), 3);
+ settings1.setArrayIndex(1);
+ QCOMPARE(settings1.value("ene").toInt(), 5);
+ QCOMPARE(settings1.value("due").toInt(), 6);
+ QCOMPARE(settings1.value("rike").toInt(), 7);
+ QCOMPARE(settings1.allKeys().count(), 3);
+ settings1.setArrayIndex(2);
+ QCOMPARE(settings1.value("ene").toInt(), 8);
+ QCOMPARE(settings1.value("due").toInt(), 9);
+ QCOMPARE(settings1.value("rike").toInt(), 10);
+ QCOMPARE(settings1.allKeys().count(), 3);
+
+ settings1.endArray();
+ settings1.endGroup();
+ }
+ /*
+ This code generates lots of warnings, but that's on purpose.
+ Basically, we check that endGroup() can be used instead of
+ endArray() and vice versa. This is not documented, but this
+ is the behavior that we have chosen.
+ */
+ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ settings1.clear();
+ settings1.beginGroup("/alpha");
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.setArrayIndex(0);
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.setArrayIndex(1);
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.setArrayIndex(2);
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.beginGroup("/beta");
+ QCOMPARE(settings1.group(), QString("alpha/beta"));
+ settings1.beginGroup("");
+ QCOMPARE(settings1.group(), QString("alpha/beta"));
+ settings1.beginWriteArray("DO", 4);
+ QCOMPARE(settings1.value("size").toInt(), 4);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO"));
+ settings1.setArrayIndex(0);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/1"));
+ settings1.setArrayIndex(1);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2"));
+ settings1.beginGroup("1");
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
+ settings1.setArrayIndex(3);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
+ settings1.setArrayIndex(4);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
+ settings1.beginWriteArray("RE");
+ QVERIFY(!settings1.contains("size"));
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1/RE"));
+ settings1.setArrayIndex(0);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1/RE/1"));
+ settings1.setArrayIndex(1);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1/RE/2"));
+ settings1.endArray();
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
+ settings1.endArray();
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/2"));
+ settings1.setArrayIndex(2);
+ QCOMPARE(settings1.group(), QString("alpha/beta/DO/3"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("alpha/beta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("alpha/beta"));
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString("alpha"));
+ settings1.endArray();
+ QCOMPARE(settings1.group(), QString());
+ settings1.endGroup();
+ QCOMPARE(settings1.group(), QString());
+
+ /*
+ Now, let's make sure that things work well if an array
+ is spread across multiple files.
+ */
+ int i;
+
+ settings1.clear();
+ QSettings settings2(format, QSettings::UserScope, "software.org");
+
+ QStringList threeStrings;
+ threeStrings << "Uno" << "Dos" << "Tres";
+
+ QStringList fiveStrings;
+ fiveStrings << "alpha" << "beta" << "gamma" << "delta" << "epsilon";
+
+ settings1.beginWriteArray("strings");
+ for (i = threeStrings.size() - 1; i >= 0; --i) {
+ settings1.setArrayIndex(i);
+ settings1.setValue("fileName", threeStrings.at(i));
+ }
+ settings1.endArray();
+
+ settings2.beginWriteArray("strings");
+ for (i = fiveStrings.size() - 1; i >= 0; --i) {
+ settings2.setArrayIndex(i);
+ settings2.setValue("fileName", fiveStrings.at(i));
+ }
+ settings2.endArray();
+
+ int size1 = settings1.beginReadArray("strings");
+ QCOMPARE(size1, 3);
+ QCOMPARE(settings1.value("size").toInt(), 3);
+
+ for (i = 0; i < size1; ++i) {
+ settings1.setArrayIndex(i);
+ QString str = settings1.value("fileName").toString();
+ QCOMPARE(str, threeStrings.at(i));
+ }
+ settings1.endArray();
+
+ int size2 = settings2.beginReadArray("strings");
+ QCOMPARE(size2, 5);
+ QCOMPARE(settings2.value("size").toInt(), 5);
+
+ for (i = 0; i < size2; ++i) {
+ settings2.setArrayIndex(i);
+ QString str = settings2.value("fileName").toString();
+ QCOMPARE(str, fiveStrings.at(i));
+ }
+ settings2.endArray();
+
+ size1 = settings1.beginReadArray("strings");
+ QCOMPARE(size1, 3);
+
+ // accessing entries beyond the end of settings1 goes to settings2
+ for (i = size1; i < size2; ++i) {
+ settings1.setArrayIndex(i);
+ QString str = settings1.value("fileName").toString();
+ QCOMPARE(str, fiveStrings.at(i));
+ }
+ settings1.endArray();
+}
+
+#ifdef QT_BUILD_INTERNAL
+static QByteArray iniEscapedKey(const QString &str)
+{
+ QByteArray result;
+ QSettingsPrivate::iniEscapedKey(str, result);
+ return result;
+}
+
+static QString iniUnescapedKey(const QByteArray &ba)
+{
+ QString result;
+ QSettingsPrivate::iniUnescapedKey(ba, 0, ba.size(), result);
+ return result;
+}
+
+static QByteArray iniEscapedStringList(const QStringList &strList)
+{
+ QByteArray result;
+ QSettingsPrivate::iniEscapedStringList(strList, result, 0);
+ return result;
+}
+
+static QStringList iniUnescapedStringList(const QByteArray &ba)
+{
+ QStringList result;
+ QString str;
+#if QSETTINGS_P_H_VERSION >= 2
+ bool isStringList = QSettingsPrivate::iniUnescapedStringList(ba, 0, ba.size(), str, result
+#if QSETTINGS_P_H_VERSION >= 3
+ , 0
+#endif
+ );
+ if (!isStringList)
+ result = QStringList(str);
+#else
+ QStringList *strList = QSettingsPrivate::iniUnescapedStringList(ba, 0, ba.size(), str);
+ if (strList) {
+ result = *strList;
+ delete strList;
+ } else {
+ result = QStringList(str);
+ }
+#endif
+ return result;
+}
+#endif
+
+QString escapeWeirdChars(const QString &s)
+{
+ QString result;
+ bool escapeNextDigit = false;
+
+ for (int i = 0; i < s.length(); ++i) {
+ QChar c = s.at(i);
+ if (c.unicode() < ' ' || c.unicode() > '~'
+ || (escapeNextDigit && c.unicode() >= '0' && c.unicode() <= 'f')) {
+ result += QString("\\x%1").arg(c.unicode(), 0, 16);
+ escapeNextDigit = true;
+ } else {
+ result += c;
+ escapeNextDigit = false;
+ }
+ }
+
+ return result;
+}
+
+void tst_QSettings::testEscapes()
+{
+#ifdef QT_BUILD_INTERNAL
+ QSettings settings(QSettings::UserScope, "software.org", "KillerAPP");
+
+#define testEscapedKey(plainKey, escKey) \
+ QCOMPARE(iniEscapedKey(plainKey), QByteArray(escKey)); \
+ QCOMPARE(iniUnescapedKey(escKey), QString(plainKey));
+
+#define testUnescapedKey(escKey, plainKey, reescKey) \
+ QCOMPARE(iniUnescapedKey(escKey), QString(plainKey)); \
+ QCOMPARE(iniEscapedKey(plainKey), QByteArray(reescKey)); \
+ QCOMPARE(iniUnescapedKey(reescKey), QString(plainKey));
+
+#define testEscapedStringList(plainStrList, escStrList) \
+ { \
+ QStringList plainList(plainStrList); \
+ QByteArray escList(escStrList); \
+ QCOMPARE(iniEscapedStringList(plainList), escList); \
+ QCOMPARE(iniUnescapedStringList(escList), plainList); \
+ } \
+
+
+#define testUnescapedStringList(escStrList, plainStrList, reescStrList) \
+ { \
+ QStringList plainList(plainStrList); \
+ QByteArray escList(escStrList); \
+ QByteArray reescList(reescStrList); \
+ QCOMPARE(iniUnescapedStringList(escList), plainList); \
+ QCOMPARE(iniEscapedStringList(plainList), reescList); \
+ QCOMPARE(iniUnescapedStringList(reescList), plainList); \
+ } \
+
+
+#define testVariant(val, escStr, func) \
+ { \
+ QVariant v(val); \
+ QString s = QSettingsPrivate::variantToString(v); \
+ /*qDebug() << QString("testVariant(): reference=\"%1\" result=\"%2\"").arg(escStr).arg(s); */\
+ QCOMPARE(s, escStr); \
+ QCOMPARE(QVariant(QSettingsPrivate::stringToVariant(escStr)), v); \
+ QVERIFY(val == v.func()); \
+ }
+
+#define testBadEscape(escStr, vStr) \
+ { \
+ QVariant v = QSettingsPrivate::stringToVariant(QString(escStr)); \
+ QCOMPARE(v.toString(), QString(vStr)); \
+ }
+
+ testEscapedKey("", "");
+ testEscapedKey(" ", "%20");
+ testEscapedKey(" 0123 abcd ", "%200123%20abcd%20");
+ testEscapedKey("~!@#$%^&*()_+.-/\\=", "%7E%21%40%23%24%25%5E%26%2A%28%29_%2B.-\\%5C%3D");
+ testEscapedKey(QString() + QChar(0xabcd) + QChar(0x1234) + QChar(0x0081), "%UABCD%U1234%81");
+ testEscapedKey(QString() + QChar(0xFE) + QChar(0xFF) + QChar(0x100) + QChar(0x101), "%FE%FF%U0100%U0101");
+
+ testUnescapedKey("", "", "");
+ testUnescapedKey("%20", " ", "%20");
+ testUnescapedKey("/alpha/beta", "/alpha/beta", "\\alpha\\beta");
+ testUnescapedKey("\\alpha\\beta", "/alpha/beta", "\\alpha\\beta");
+ testUnescapedKey("%5Calpha%5Cbeta", "\\alpha\\beta", "%5Calpha%5Cbeta");
+ testUnescapedKey("%", "%", "%25");
+ testUnescapedKey("%f%!%%%%1x%x1%U%Uz%U123%U1234%1234%", QString("%f%!%%%%1x%x1%U%Uz%U123") + QChar(0x1234) + "\x12" + "34%",
+ "%25f%25%21%25%25%25%251x%25x1%25U%25Uz%25U123%U1234%1234%25");
+
+ testEscapedStringList("", "");
+ testEscapedStringList(" ", "\" \"");
+ testEscapedStringList(";", "\";\"");
+ testEscapedStringList(",", "\",\"");
+ testEscapedStringList("=", "\"=\"");
+ testEscapedStringList("abc-def", "abc-def");
+ testEscapedStringList(QChar(0) + QString("0"), "\\0\\x30");
+ testEscapedStringList("~!@#$%^&*()_+.-/\\=", "\"~!@#$%^&*()_+.-/\\\\=\"");
+ testEscapedStringList("~!@#$%^&*()_+.-/\\", "~!@#$%^&*()_+.-/\\\\");
+ testEscapedStringList(QString("\x7F") + "12aFz", "\\x7f\\x31\\x32\\x61\\x46z");
+ testEscapedStringList(QString(" \t\n\\n") + QChar(0x123) + QChar(0x4567), "\" \\t\\n\\\\n\\x123\\x4567\"");
+ testEscapedStringList(QString("\a\b\f\n\r\t\v'\"?\001\002\x03\x04"), "\\a\\b\\f\\n\\r\\t\\v'\\\"?\\x1\\x2\\x3\\x4");
+ testEscapedStringList(QStringList() << "," << ";" << "a" << "ab, \tc, d ", "\",\", \";\", a, \"ab, \\tc, d \"");
+
+ /*
+ Test .ini syntax that cannot be generated by QSettings (but can be entered by users).
+ */
+ testUnescapedStringList("", "", "");
+ testUnescapedStringList("\"\"", "", "");
+ testUnescapedStringList("\"abcdef\"", "abcdef", "abcdef");
+ testUnescapedStringList("\"\\?\\'\\\"\"", "?'\"", "?'\\\"");
+ testUnescapedStringList("\\0\\00\\000\\0000000\\1\\111\\11111\\x\\x0\\xABCDEFGH\\x0123456\\",
+ QString() + QChar(0) + QChar(0) + QChar(0) + QChar(0) + QChar(1)
+ + QChar(0111) + QChar(011111) + QChar(0) + QChar(0xCDEF) + "GH"
+ + QChar(0x3456),
+ "\\0\\0\\0\\0\\x1I\\x1249\\0\\xcdefGH\\x3456");
+ testUnescapedStringList(QByteArray("\\c\\d\\e\\f\\g\\$\\*\\\0", 16), "\f", "\\f");
+ testUnescapedStringList("\"a\", \t\"bc \", \" d\" , \"ef \" ,,g, hi i,,, ,",
+ QStringList() << "a" << "bc " << " d" << "ef " << "" << "g" << "hi i"
+ << "" << "" << "" << "",
+ "a, \"bc \", \" d\", \"ef \", , g, hi i, , , , ");
+ testUnescapedStringList("a , b , c d , efg ",
+ QStringList() << "a" << "b" << "c d" << "efg",
+ "a, b, c d, efg");
+
+ // streaming qvariant into a string
+ testVariant(QString("Hello World!"), QString("Hello World!"), toString);
+ testVariant(QString("Hello, World!"), QString("Hello, World!"), toString);
+ testVariant(QString("@Hello World!"), QString("@@Hello World!"), toString);
+ testVariant(QString("@@Hello World!"), QString("@@@Hello World!"), toString);
+ testVariant(QByteArray("Hello World!"), QString("@ByteArray(Hello World!)"), toString);
+ testVariant(QByteArray("@Hello World!"), QString("@ByteArray(@Hello World!)"), toString);
+ testVariant(QVariant(100), QString("100"), toString);
+ testVariant(QStringList() << "ene" << "due" << "rike", QString::fromLatin1("@Variant(\x0\x0\x0\xb\x0\x0\x0\x3\x0\x0\x0\x6\x0\x65\x0n\x0\x65\x0\x0\x0\x6\x0\x64\x0u\x0\x65\x0\x0\x0\x8\x0r\x0i\x0k\x0\x65)", 50), toStringList);
+ testVariant(QRect(1, 2, 3, 4), QString("@Rect(1 2 3 4)"), toRect);
+ testVariant(QSize(5, 6), QString("@Size(5 6)"), toSize);
+ testVariant(QPoint(7, 8), QString("@Point(7 8)"), toPoint);
+
+ testBadEscape("", "");
+ testBadEscape("@", "@");
+ testBadEscape("@@", "@");
+ testBadEscape("@@@", "@@");
+ testBadEscape(" ", " ");
+ testBadEscape("@Rect", "@Rect");
+ testBadEscape("@Rect(", "@Rect(");
+ testBadEscape("@Rect()", "@Rect()");
+ testBadEscape("@Rect)", "@Rect)");
+ testBadEscape("@Rect(1 2 3)", "@Rect(1 2 3)");
+ testBadEscape("@@Rect(1 2 3)", "@Rect(1 2 3)");
+#endif
+}
+
+void tst_QSettings::testCaseSensitivity_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::testCaseSensitivity()
+{
+ QFETCH(QSettings::Format, format);
+
+ for (int pass = 0; pass < 2; ++pass) {
+ QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
+ settings.beginGroup("caseSensitivity");
+
+ bool cs = true;
+#ifndef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
+ switch (format) {
+ case QSettings::NativeFormat:
+#ifdef Q_OS_DARWIN
+ cs = true;
+#else
+ cs = false;
+#endif
+ break;
+ case QSettings::IniFormat:
+ cs = false;
+ break;
+ case QSettings::CustomFormat1:
+ cs = true;
+ break;
+ case QSettings::CustomFormat2:
+ cs = false;
+ break;
+ default:
+ ;
+ }
+#endif
+
+ if (pass == 0) {
+ settings.setValue("key 1", 1);
+ settings.setValue("KEY 1", 2);
+ settings.setValue("key 2", 3);
+ }
+
+ for (int i = 0; i < 2; ++i) {
+ QVERIFY(settings.contains("key 1"));
+ QVERIFY(settings.contains("KEY 1"));
+ QCOMPARE(settings.value("KEY 1").toInt(), 2);
+/* QVERIFY(settings.allKeys().contains("/KEY 1"));
+ QVERIFY(settings.allKeys().contains("/key 2")); */
+
+ if (cs) {
+ QVERIFY(!settings.contains("kEy 1"));
+ QCOMPARE(settings.value("key 1").toInt(), 1);
+ QCOMPARE(settings.allKeys().size(), 3);
+ QVERIFY(settings.allKeys().contains("key 1"));
+ } else {
+ QVERIFY(settings.contains("kEy 1"));
+ QCOMPARE(settings.value("kEy 1").toInt(), 2);
+ QCOMPARE(settings.value("key 1").toInt(), 2);
+ QCOMPARE(settings.allKeys().size(), 2);
+ }
+
+ settings.sync();
+ }
+
+ settings.remove("KeY 1");
+
+ if (cs) {
+ QVERIFY(!settings.contains("KeY 1"));
+ QVERIFY(settings.contains("key 1"));
+ QVERIFY(settings.contains("KEY 1"));
+ QCOMPARE(settings.value("key 1").toInt(), 1);
+ QCOMPARE(settings.value("KEY 1").toInt(), 2);
+ QCOMPARE(settings.allKeys().size(), 3);
+ } else {
+ QVERIFY(!settings.contains("KeY 1"));
+ QVERIFY(!settings.contains("key 1"));
+ QVERIFY(!settings.contains("KEY 1"));
+ QCOMPARE(settings.allKeys().size(), 1);
+ }
+ settings.setValue("KEY 1", 2);
+ }
+}
+
+void tst_QSettings::fileName()
+{
+#ifdef Q_OS_MAC
+ QSettings s1(QSettings::UserScope, "Apple", "Console");
+ QSettings s2(QSettings::UserScope, "Apple");
+ QSettings s3(QSettings::SystemScope, "Apple", "Console");
+ QSettings s4(QSettings::SystemScope, "Apple");
+
+ QCOMPARE(s1.fileName(), QDir::homePath() + "/Library/Preferences/com.apple.Console.plist");
+ QCOMPARE(s2.fileName(), QDir::homePath() + "/Library/Preferences/com.apple.plist");
+ QCOMPARE(s3.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
+ QCOMPARE(s4.fileName(), QString("/Library/Preferences/com.apple.plist"));
+
+ QSettings s5(QSettings::SystemScope, "Apple.com", "Console");
+ QCOMPARE(s5.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
+
+ QSettings s6(QSettings::SystemScope, "apple.com", "Console");
+ QCOMPARE(s6.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
+
+ QSettings s7(QSettings::SystemScope, "apple.Com", "Console");
+ QCOMPARE(s7.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
+
+ QSettings s8(QSettings::SystemScope, "apple.fr", "Console");
+ QCOMPARE(s8.fileName(), QString("/Library/Preferences/fr.apple.Console.plist"));
+
+ QSettings s9(QSettings::SystemScope, "apple.co.jp", "Console");
+ QCOMPARE(s9.fileName(), QString("/Library/Preferences/jp.co.apple.Console.plist"));
+
+ QSettings s10(QSettings::SystemScope, "apple.org", "Console");
+ QCOMPARE(s10.fileName(), QString("/Library/Preferences/org.apple.Console.plist"));
+
+ QSettings s11(QSettings::SystemScope, "apple.net", "Console");
+ QCOMPARE(s11.fileName(), QString("/Library/Preferences/net.apple.Console.plist"));
+
+ QSettings s12(QSettings::SystemScope, "apple.museum", "Console");
+ QCOMPARE(s12.fileName(), QString("/Library/Preferences/museum.apple.Console.plist"));
+
+ QSettings s13(QSettings::SystemScope, "apple.FR", "Console");
+ QCOMPARE(s13.fileName(), QString("/Library/Preferences/fr.apple.Console.plist"));
+
+ QSettings s14(QSettings::SystemScope, "apple.mUseum", "Console");
+ QCOMPARE(s14.fileName(), QString("/Library/Preferences/museum.apple.Console.plist"));
+
+ QSettings s15(QSettings::SystemScope, "apple.zz", "Console");
+ QCOMPARE(s15.fileName(), QString("/Library/Preferences/zz.apple.Console.plist"));
+
+ QSettings s15_prime(QSettings::SystemScope, "apple.foo", "Console");
+ QCOMPARE(s15_prime.fileName(), QString("/Library/Preferences/com.apple-foo.Console.plist"));
+
+ QSettings s16(QSettings::SystemScope, "apple.f", "Console");
+ QCOMPARE(s16.fileName(), QString("/Library/Preferences/com.apple-f.Console.plist"));
+
+ QSettings s17(QSettings::SystemScope, "apple.", "Console");
+ QCOMPARE(s17.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
+
+ QSettings s18(QSettings::SystemScope, "Foo, Inc.", "Console");
+ QCOMPARE(s18.fileName(), QString("/Library/Preferences/com.foo-inc.Console.plist"));
+
+ QSettings s19(QSettings::SystemScope, "Foo, Inc.com", "Console");
+ QCOMPARE(s19.fileName(), QString("/Library/Preferences/com.foo, inc.Console.plist"));
+
+ QSettings s20(QSettings::SystemScope, QLatin1String(" ") + QChar(0xbd) + QLatin1String("Foo//:/Barxxx Baz!()#@.com"), "Console");
+ QCOMPARE(s20.fileName(), QLatin1String("/Library/Preferences/com. ") + QChar(0xbd) + QLatin1String("foo : barxxx baz!()#@.Console.plist"));
+
+ QSettings s21(QSettings::SystemScope, QLatin1String(" ") + QChar(0xbd) + QLatin1String("Foo//:/Bar,,, Baz!()#"), "Console");
+ QCOMPARE(s21.fileName(), QString("/Library/Preferences/com.foo-bar-baz.Console.plist"));
+#else
+ QSKIP("Please write a fileName() test for the other platforms", SkipAll);
+#endif
+}
+
+void tst_QSettings::isWritable_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::isWritable()
+{
+ QFETCH(QSettings::Format, format);
+
+ {
+ QSettings s1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ s1.setValue("foo", 1);
+ s1.sync();
+ // that should create the file
+ }
+
+ {
+ QSettings s1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QVERIFY(s1.isWritable());
+ }
+
+ {
+ QSettings s1(format, QSettings::SystemScope, "software.org", "KillerAPP");
+ s1.setValue("foo", 1);
+ s1.sync();
+ // that should create the file, *if* we have the permissions
+ }
+
+ {
+ QSettings s1(format, QSettings::SystemScope, "software.org", "KillerAPP");
+ QSettings s2(format, QSettings::SystemScope, "software.org", "Something Different");
+ QSettings s3(format, QSettings::SystemScope, "foo.org", "Something Different");
+ if (s1.contains("foo")) {
+ QVERIFY(s1.isWritable());
+ QVERIFY(s2.isWritable());
+ QVERIFY(s3.isWritable());
+ } else {
+ QVERIFY(!s1.isWritable());
+ QVERIFY(!s2.isWritable());
+ QVERIFY(!s3.isWritable());
+ }
+ }
+}
+
+void tst_QSettings::childGroups_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::childGroups()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QSettings::Format, format);
+
+ {
+ QSettings settings(format, QSettings::SystemScope, "software.org");
+ settings.setValue("alpha", "1");
+ settings.setValue("alpha/a", "2");
+ settings.setValue("alpha/b", "3");
+ settings.setValue("alpha/c", "4");
+ settings.setValue("beta", "5");
+ settings.setValue("gamma", "6");
+ settings.setValue("gamma/d", "7");
+ settings.setValue("gamma/d/e", "8");
+ settings.setValue("gamma/f/g", "9");
+ settings.setValue("omicron/h/i/j/x", "10");
+ settings.setValue("omicron/h/i/k/y", "11");
+ settings.setValue("zeta/z", "12");
+ }
+
+ for (int pass = 0; pass < 3; ++pass) {
+ QConfFile::clearCache();
+ QSettings settings(format, QSettings::SystemScope, "software.org");
+ settings.setFallbacksEnabled(false);
+ if (pass == 1) {
+ settings.value("gamma/d");
+ } else if (pass == 2) {
+ settings.value("gamma");
+ }
+
+ settings.beginGroup("gamma");
+ QCOMPARE(settings.childGroups(), QStringList() << "d" << "f");
+ settings.beginGroup("d");
+ QCOMPARE(settings.childGroups(), QStringList());
+ settings.endGroup();
+ settings.endGroup();
+
+ settings.beginGroup("alpha");
+ QCOMPARE(settings.childGroups(), QStringList());
+ settings.endGroup();
+
+ settings.beginGroup("d");
+ QCOMPARE(settings.childGroups(), QStringList());
+ settings.endGroup();
+
+ settings.beginGroup("/omicron///h/i///");
+ QCOMPARE(settings.childGroups(), QStringList() << "j" << "k");
+ settings.endGroup();
+
+ settings.beginGroup("////");
+ QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta");
+ settings.endGroup();
+
+ QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta");
+ }
+#endif
+}
+
+void tst_QSettings::childKeys_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::childKeys()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QSettings::Format, format);
+
+ {
+ QSettings settings(format, QSettings::SystemScope, "software.org");
+ settings.setValue("alpha", "1");
+ settings.setValue("alpha/a", "2");
+ settings.setValue("alpha/b", "3");
+ settings.setValue("alpha/c", "4");
+ settings.setValue("beta", "5");
+ settings.setValue("gamma", "6");
+ settings.setValue("gamma/d", "7");
+ settings.setValue("gamma/d/e", "8");
+ settings.setValue("gamma/f/g", "9");
+ settings.setValue("omicron/h/i/j/x", "10");
+ settings.setValue("omicron/h/i/k/y", "11");
+ settings.setValue("zeta/z", "12");
+ }
+
+ for (int pass = 0; pass < 3; ++pass) {
+ QConfFile::clearCache();
+ QSettings settings(format, QSettings::SystemScope, "software.org");
+ settings.setFallbacksEnabled(false);
+ if (pass == 1) {
+ settings.value("gamma/d");
+ } else if (pass == 2) {
+ settings.value("gamma");
+ }
+
+ settings.beginGroup("gamma");
+ QCOMPARE(settings.childKeys(), QStringList() << "d");
+ settings.beginGroup("d");
+ QCOMPARE(settings.childKeys(), QStringList() << "e");
+ settings.endGroup();
+ settings.endGroup();
+
+ settings.beginGroup("alpha");
+ QCOMPARE(settings.childKeys(), QStringList() << "a" << "b" << "c");
+ settings.endGroup();
+
+ settings.beginGroup("d");
+ QCOMPARE(settings.childKeys(), QStringList());
+ settings.endGroup();
+
+ settings.beginGroup("/omicron///h/i///");
+ QCOMPARE(settings.childKeys(), QStringList());
+ settings.endGroup();
+
+ settings.beginGroup("////");
+ QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma");
+ settings.endGroup();
+
+ QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma");
+ }
+#endif
+}
+
+void tst_QSettings::allKeys_data()
+{
+ populateWithFormats();
+}
+
+void tst_QSettings::allKeys()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QSettings::Format, format);
+
+ QStringList allKeys;
+ allKeys << "alpha" << "alpha/a" << "alpha/b" << "alpha/c" << "beta" << "gamma" << "gamma/d"
+ << "gamma/d/e" << "gamma/f/g" << "omicron/h/i/j/x" << "omicron/h/i/k/y" << "zeta/z";
+
+ {
+ QSettings settings(format, QSettings::SystemScope, "software.org");
+ for (int i = 0; i < allKeys.size(); ++i)
+ settings.setValue(allKeys.at(i), QString::number(i + 1));
+ }
+
+ for (int pass = 0; pass < 3; ++pass) {
+ QConfFile::clearCache();
+ QSettings settings(format, QSettings::SystemScope, "software.org");
+ settings.setFallbacksEnabled(false);
+
+ if (pass == 1) {
+ settings.value("gamma/d");
+ } else if (pass == 2) {
+ settings.value("gamma");
+ }
+
+ settings.beginGroup("gamma");
+ QCOMPARE(settings.allKeys(), QStringList() << "d" << "d/e" << "f/g");
+ settings.beginGroup("d");
+ QCOMPARE(settings.allKeys(), QStringList() << "e");
+ settings.endGroup();
+ settings.endGroup();
+
+ settings.beginGroup("alpha");
+ QCOMPARE(settings.allKeys(), QStringList() << "a" << "b" << "c");
+ settings.endGroup();
+
+ settings.beginGroup("d");
+ QCOMPARE(settings.allKeys(), QStringList());
+ settings.endGroup();
+
+ settings.beginGroup("/omicron///h/i///");
+ QCOMPARE(settings.allKeys(), QStringList() << "j/x" << "k/y");
+ settings.endGroup();
+
+ settings.beginGroup("////");
+ QCOMPARE(settings.allKeys(), allKeys);
+ settings.endGroup();
+
+ QCOMPARE(settings.allKeys(), allKeys);
+ }
+#endif
+}
+
+void tst_QSettings::registerFormat()
+{
+ QSettings settings1(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settings2(QSettings::CustomFormat1, QSettings::UserScope, "software.org", "KillerAPP");
+
+ QString fileName = settings1.fileName();
+ fileName.chop(3); // "ini";
+ fileName.append("custom1");
+ QCOMPARE(settings2.fileName(), fileName);
+
+ // OK, let's see if it can read a generated file of a custom type
+ // Beware: readCustom3File() and writeCustom3File() have unintuitive behavior
+ // so we can test error handling
+
+ QSettings::Format custom3 = QSettings::registerFormat("custom3", readCustom3File, writeCustom3File);
+ QVERIFY(custom3 == QSettings::CustomFormat3);
+
+ QDir dir(settingsPath());
+ QVERIFY(dir.mkpath("someDir"));
+ QFile f(dir.path()+"/someDir/someSettings.custom3");
+
+ QVERIFY(f.open(QFile::WriteOnly));
+ f.write("OK");
+ f.close();
+
+ {
+ QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat3);
+ QCOMPARE(settings.status(), QSettings::NoError);
+ QCOMPARE(settings.value("retval").toString(), QString("OK"));
+ QVERIFY(settings.isWritable());
+ }
+
+ QVERIFY(f.open(QFile::WriteOnly));
+ f.write("NotOK");
+ f.close();
+
+ {
+ QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat3);
+ QCOMPARE(settings.status(), QSettings::FormatError);
+ QCOMPARE(settings.value("retval").toString(), QString());
+ QVERIFY(settings.isWritable());
+ }
+
+ QVERIFY(f.open(QFile::WriteOnly));
+ f.write("OK");
+ f.close();
+
+ {
+ QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat3);
+ QCOMPARE(settings.status(), QSettings::NoError);
+ settings.setValue("zzz", "bar");
+ settings.sync();
+ QCOMPARE(settings.status(), QSettings::NoError);
+
+ settings.setValue("retval", "NotOK");
+ settings.sync();
+ QCOMPARE(settings.status(), QSettings::AccessError);
+
+ QCOMPARE(settings.value("retval").toString(), QString("NotOK"));
+ QVERIFY(settings.isWritable());
+ }
+
+ {
+ QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat4);
+ QCOMPARE(settings.status(), QSettings::AccessError);
+ QVERIFY(!settings.isWritable());
+ }
+}
+
+void tst_QSettings::setPath()
+{
+#define TEST_PATH(doSet, ext, format, scope, path) \
+ { \
+ if (doSet) \
+ QSettings::setPath(QSettings::format, QSettings::scope, settingsPath(path)); \
+ QSettings settings1(QSettings::format, QSettings::scope, "software.org", "KillerAPP"); \
+ QCOMPARE(QDir(settings1.fileName()), QDir(settingsPath(path) + QDir::separator() + "software.org" \
+ + QDir::separator() + "KillerAPP." + ext)); \
+ }
+
+ /*
+ The first pass checks that setPath() works; the second
+ path checks that it has no bad side effects.
+ */
+ for (int i = 0; i < 2; ++i) {
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+ TEST_PATH(i == 0, "conf", NativeFormat, UserScope, "alpha")
+ TEST_PATH(i == 0, "conf", NativeFormat, SystemScope, "beta")
+#endif
+ TEST_PATH(i == 0, "ini", IniFormat, UserScope, "gamma")
+ TEST_PATH(i == 0, "ini", IniFormat, SystemScope, "omicron")
+ TEST_PATH(i == 0, "custom1", CustomFormat1, UserScope, "epsilon")
+ TEST_PATH(i == 0, "custom1", CustomFormat1, SystemScope, "zeta")
+ TEST_PATH(i == 0, "custom2", CustomFormat2, UserScope, "eta")
+ TEST_PATH(i == 0, "custom2", CustomFormat2, SystemScope, "iota")
+ }
+}
+
+void tst_QSettings::setDefaultFormat()
+{
+ QVERIFY(QSettings::defaultFormat() == QSettings::NativeFormat);
+
+ QSettings::setDefaultFormat(QSettings::CustomFormat1);
+ QSettings settings1("org", "app");
+ QSettings settings2(QSettings::SystemScope, "org", "app");
+ QSettings settings3;
+
+ QVERIFY(settings1.format() == QSettings::NativeFormat);
+ QVERIFY(settings2.format() == QSettings::NativeFormat);
+ QVERIFY(settings3.format() == QSettings::CustomFormat1);
+
+ QSettings::setDefaultFormat(QSettings::NativeFormat);
+ QVERIFY(QSettings::defaultFormat() == QSettings::NativeFormat);
+
+ QVERIFY(settings1.format() == QSettings::NativeFormat);
+ QVERIFY(settings2.format() == QSettings::NativeFormat);
+ QVERIFY(settings3.format() == QSettings::CustomFormat1);
+}
+
+void tst_QSettings::dontCreateNeedlessPaths()
+{
+ QString path;
+ {
+ QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Hello", "Test");
+ QVariant val = settings.value("foo", "bar");
+ path = settings.fileName();
+ }
+
+ QFileInfo fileInfo(path);
+ QVERIFY(!fileInfo.dir().exists());
+}
+
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+void tst_QSettings::dontReorderIniKeysNeedlessly()
+{
+#ifdef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
+ QSKIP("This Qt build does not preserve ordering, as a code size optimization.", SkipAll);
+#endif
+
+ /*
+ This is a very strong test. It asserts that modifying
+ resourcefile2.ini will lead to the exact contents of
+ resourcefile3.ini. Right now it's run only on Unix
+ systems, but that should be enough since the INI
+ code (unlike this test) is platform-agnostic.
+
+ Things that are tested:
+
+ * keys are written in the same order that they were
+ read in
+
+ * new keys are put at the end of their respective
+ sections
+ */
+
+ QFile inFile(":/resourcefile2.ini");
+ inFile.open(QIODevice::ReadOnly);
+ QByteArray contentsBefore = inFile.readAll();
+ inFile.close();
+
+ QByteArray expectedContentsAfter;
+
+ {
+ QFile inFile(":/resourcefile3.ini");
+ inFile.open(QIODevice::ReadOnly);
+ expectedContentsAfter = inFile.readAll();
+ inFile.close();
+ }
+
+ QString outFileName;
+ QString outFileName2;
+
+ QTemporaryFile outFile;
+ outFile.open();
+ outFile.write(contentsBefore);
+ outFileName = outFile.fileName();
+ outFile.close();
+
+ QSettings settings(outFileName, QSettings::IniFormat);
+ QVERIFY(settings.status() == QSettings::NoError);
+ QVERIFY(settings.isWritable());
+
+ settings.setValue("Field 1/Bottom", 90);
+ settings.setValue("Field 1/x", 1);
+ settings.setValue("Field 1/y", 1);
+ settings.setValue("Field 1/width", 1);
+ settings.setValue("Field 1/height", 1);
+ settings.sync();
+
+ QFile outFile2(outFileName);
+ QVERIFY(outFile2.open(QIODevice::ReadOnly));
+ QCOMPARE(outFile2.readAll(), expectedContentsAfter);
+ outFile2.close();
+}
+#endif
+
+void tst_QSettings::rainersSyncBugOnMac_data()
+{
+ ctor_data();
+}
+
+void tst_QSettings::rainersSyncBugOnMac()
+{
+ QFETCH(QSettings::Format, format);
+
+ QString fileName;
+
+ {
+ QSettings s1(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QCOMPARE(s1.value("key1", 5).toInt(), 5);
+ fileName = s1.fileName();
+ }
+
+ {
+ QSettings s2(fileName, format);
+ s2.setValue("key1", 25);
+ }
+
+ {
+ QSettings s3(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QCOMPARE(s3.value("key1", 30).toInt(), 25);
+ }
+}
+
+void tst_QSettings::recursionBug()
+{
+ QPixmap pix(10,10);
+ pix.fill("blue");
+
+ {
+ QSettings settings(settingsPath("starrunner.ini"), QSettings::IniFormat);
+ settings.setValue("General/Pixmap", pix );
+ }
+}
+
+#if defined(Q_OS_WIN)
+
+static DWORD readKeyType(HKEY handle, const QString &rSubKey)
+{
+ DWORD dataType;
+ DWORD dataSize;
+ LONG res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()), 0, &dataType, 0, &dataSize);
+
+ if (res == ERROR_SUCCESS)
+ return dataType;
+
+ return 0;
+}
+
+void tst_QSettings::qtbug_13249()
+{
+ QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
+
+ qint32 x = 1024;
+ settings1.setValue("qtbug_13249_a", (qint32)x);
+ QCOMPARE(settings1.value("qtbug_13249_a").toInt(), (qint32)1024);
+ settings1.setValue("qtbug_13249_b", (quint32)x);
+ QCOMPARE(settings1.value("qtbug_13249_b").toUInt(), (quint32)1024);
+ settings1.setValue("qtbug_13249_c", (qint64)x);
+ QCOMPARE(settings1.value("qtbug_13249_c").toLongLong(), (qint64)1024);
+ settings1.setValue("qtbug_13249_d", (quint64)x);
+ QCOMPARE(settings1.value("qtbug_13249_d").toULongLong(), (quint64)1024);
+ settings1.sync();
+
+ HKEY handle;
+ LONG res;
+ QString keyName = "Software\\software.org\\KillerAPP";
+ res = RegOpenKeyEx(HKEY_CURRENT_USER, reinterpret_cast<const wchar_t *>(keyName.utf16()), 0, KEY_READ, &handle);
+ if (res == ERROR_SUCCESS)
+ {
+ DWORD dataType;
+ dataType = readKeyType(handle, QString("qtbug_13249_a"));
+ if (dataType != 0) {
+ QCOMPARE((int)REG_DWORD, (int)dataType);
+ }
+ dataType = readKeyType(handle, QString("qtbug_13249_b"));
+ if (dataType != 0) {
+ QCOMPARE((int)REG_DWORD, (int)dataType);
+ }
+ dataType = readKeyType(handle, QString("qtbug_13249_c"));
+ if (dataType != 0) {
+ QCOMPARE((int)REG_QWORD, (int)dataType);
+ }
+ dataType = readKeyType(handle, QString("qtbug_13249_d"));
+ if (dataType != 0) {
+ QCOMPARE((int)REG_QWORD, (int)dataType);
+ }
+ RegCloseKey(handle);
+ }
+}
+#endif
+/*
+// Not tested at the moment.
+void tst_QSettings::oldSubkeyList()
+{
+ QVERIFY( TRUE );
+}
+*/
+
+QTEST_MAIN(tst_QSettings)
+#include "tst_qsettings.moc"
+
+
+// foo
diff --git a/tests/auto/corelib/io/qtemporaryfile/.gitignore b/tests/auto/corelib/io/qtemporaryfile/.gitignore
new file mode 100644
index 0000000000..67cb8bf69e
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporaryfile/.gitignore
@@ -0,0 +1 @@
+tst_qtemporaryfile
diff --git a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro b/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro
new file mode 100644
index 0000000000..64a043b19a
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro
@@ -0,0 +1,14 @@
+load(qttest_p4)
+SOURCES += tst_qtemporaryfile.cpp
+QT = core
+
+
+symbian {
+ testData.files = tst_qtemporaryfile.cpp
+ testData.path = .
+ DEPLOYMENT += testData
+}else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
new file mode 100644
index 0000000000..2edb93aee2
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -0,0 +1,729 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+#include <qcoreapplication.h>
+#include <qstring.h>
+#include <qtemporaryfile.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qset.h>
+
+#if defined(Q_OS_WIN)
+# include <windows.h>
+#endif
+#if defined(Q_OS_UNIX)
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <errno.h>
+# include <fcntl.h> // open(2)
+# include <unistd.h> // close(2)
+#endif
+
+#ifdef Q_OS_SYMBIAN
+#define SRCDIR ""
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QTemporaryFile : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QTemporaryFile();
+ virtual ~tst_QTemporaryFile();
+public slots:
+ void init();
+ void cleanup();
+
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void construction();
+ void fileTemplate();
+ void fileTemplate_data();
+ void getSetCheck();
+ void fileName();
+ void fileNameIsEmpty();
+ void autoRemove();
+ void write();
+ void openCloseOpenClose();
+ void size();
+ void resize();
+ void openOnRootDrives();
+ void stressTest();
+ void rename();
+ void renameFdLeak();
+ void reOpenThroughQFile();
+ void keepOpenMode();
+ void resetTemplateAfterError();
+ void setTemplateAfterOpen();
+ void autoRemoveAfterFailedRename();
+
+ void QTBUG_4796_data();
+ void QTBUG_4796();
+
+public:
+};
+
+void tst_QTemporaryFile::initTestCase()
+{
+ // For QTBUG_4796
+ QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX"));
+}
+
+void tst_QTemporaryFile::cleanupTestCase()
+{
+ // From QTBUG_4796
+ QVERIFY(QDir().rmdir("test-XXXXXX"));
+}
+
+void tst_QTemporaryFile::construction()
+{
+ QTemporaryFile file(0);
+ QString tmp = QDir::tempPath();
+ QCOMPARE(file.fileTemplate().left(tmp.size()), tmp);
+ QCOMPARE(file.fileTemplate().at(tmp.size()), QChar('/'));
+}
+
+// Testing get/set functions
+void tst_QTemporaryFile::getSetCheck()
+{
+ QTemporaryFile obj1;
+ // bool QTemporaryFile::autoRemove()
+ // void QTemporaryFile::setAutoRemove(bool)
+ obj1.setAutoRemove(false);
+ QCOMPARE(false, obj1.autoRemove());
+ obj1.setAutoRemove(true);
+ QCOMPARE(true, obj1.autoRemove());
+}
+
+tst_QTemporaryFile::tst_QTemporaryFile()
+{
+}
+
+tst_QTemporaryFile::~tst_QTemporaryFile()
+{
+
+}
+
+void tst_QTemporaryFile::init()
+{
+// TODO: Add initialization code here.
+// This will be executed immediately before each test is run.
+}
+
+void tst_QTemporaryFile::cleanup()
+{
+// TODO: Add cleanup code here.
+// This will be executed immediately after each test is run.
+}
+
+void tst_QTemporaryFile::fileTemplate_data()
+{
+ QTest::addColumn<QString>("constructorTemplate");
+ QTest::addColumn<QString>("prefix");
+ QTest::addColumn<QString>("suffix");
+ QTest::addColumn<QString>("fileTemplate");
+
+ QTest::newRow("constructor default") << "" << "." << "" << "";
+ QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_" << "xxx" << "";
+ QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_" << "xXx" << "";
+ QTest::newRow("constructor with no sufix") << "qt_XXXXXX" << "qt_" << "" << "";
+ QTest::newRow("constructor with >6 X's and xxx suffix") << "qt_XXXXXXXXXXxxx" << "qt_" << "xxx" << "";
+ QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_" << "" << "";
+
+ QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_" << "_XXXX" << "";
+ QTest::newRow("constructor with XXXXX suffix") << "qt_XXXXXX_XXXXX" << "qt_" << "_XXXXX" << "";
+ QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_XXXX." << "" << "";
+ QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_XXXXX." << "" << "";
+ QTest::newRow("constructor with XXXX prefix and suffix") << "qt_XXXX_XXXXXX_XXXX" << "qt_XXXX_" << "_XXXX" << "";
+ QTest::newRow("constructor with XXXXX prefix and suffix") << "qt_XXXXX_XXXXXX_XXXXX" << "qt_XXXXX_" << "_XXXXX" << "";
+
+ QTest::newRow("set template, no suffix") << "" << "foo" << "" << "foo";
+ QTest::newRow("set template, with lowercase XXXXXX") << "" << "qt_" << "xxxxxx" << "qt_XXXXXXxxxxxx";
+ QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx";
+ QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx";
+ QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX";
+}
+
+void tst_QTemporaryFile::fileTemplate()
+{
+ QFETCH(QString, constructorTemplate);
+ QFETCH(QString, prefix);
+ QFETCH(QString, suffix);
+ QFETCH(QString, fileTemplate);
+
+ QTemporaryFile file(constructorTemplate);
+ if (!fileTemplate.isEmpty())
+ file.setFileTemplate(fileTemplate);
+
+ QCOMPARE(file.open(), true);
+
+ if (prefix.length())
+ QCOMPARE(file.fileName().left(prefix.length()), prefix);
+
+ if (suffix.length())
+ QCOMPARE(file.fileName().right(suffix.length()), suffix);
+}
+
+
+/*
+ This tests whether the temporary file really gets placed in QDir::tempPath
+*/
+void tst_QTemporaryFile::fileName()
+{
+ // Get QDir::tempPath and make an absolute path.
+ QString tempPath = QDir::tempPath();
+ QString absoluteTempPath = QDir(tempPath).absolutePath();
+ QTemporaryFile file;
+ file.setAutoRemove(true);
+ file.open();
+ QString fileName = file.fileName();
+ QVERIFY(QFile::exists(fileName));
+ // Get path to the temp file, whithout the file name.
+ QString absoluteFilePath = QFileInfo(fileName).absolutePath();
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ absoluteFilePath = absoluteFilePath.toLower();
+ absoluteTempPath = absoluteTempPath.toLower();
+#endif
+ QCOMPARE(absoluteFilePath, absoluteTempPath);
+}
+
+void tst_QTemporaryFile::fileNameIsEmpty()
+{
+ QString filename;
+ {
+ QTemporaryFile file;
+ QVERIFY(file.fileName().isEmpty());
+
+ QVERIFY(file.open());
+ QVERIFY(!file.fileName().isEmpty());
+
+ filename = file.fileName();
+ QVERIFY(QFile::exists(filename));
+
+ file.close();
+ QVERIFY(!file.isOpen());
+ QVERIFY(QFile::exists(filename));
+ QVERIFY(!file.fileName().isEmpty());
+ }
+ QVERIFY(!QFile::exists(filename));
+}
+
+void tst_QTemporaryFile::autoRemove()
+{
+ // Test auto remove
+ QString fileName;
+ {
+ QTemporaryFile file("tempXXXXXX");
+ file.setAutoRemove(true);
+ QVERIFY(file.open());
+ fileName = file.fileName();
+ file.close();
+ }
+ QVERIFY(!QFile::exists(fileName));
+
+ // Test if disabling auto remove works.
+ {
+ QTemporaryFile file("tempXXXXXX");
+ file.setAutoRemove(false);
+ QVERIFY(file.open());
+ fileName = file.fileName();
+ file.close();
+ }
+ QVERIFY(QFile::exists(fileName));
+ QVERIFY(QFile::remove(fileName));
+
+
+ // Do not explicitly call setAutoRemove (tests if it really is the default as documented)
+ {
+ QTemporaryFile file("tempXXXXXX");
+ QVERIFY(file.open());
+ fileName = file.fileName();
+ file.close();
+ }
+ QVERIFY(!QFile::exists(fileName));
+
+}
+
+void tst_QTemporaryFile::write()
+{
+ QByteArray data("OLE\nOLE\nOLE");
+ QTemporaryFile file;
+ QVERIFY(file.open());
+ QCOMPARE((int)file.write(data), data.size());
+ file.reset();
+ QFile compare(file.fileName());
+ compare.open(QIODevice::ReadOnly);
+ QCOMPARE(compare.readAll() , data);
+ file.close();
+}
+
+void tst_QTemporaryFile::openCloseOpenClose()
+{
+ QString fileName;
+ {
+ // Create a temp file
+ QTemporaryFile file("tempXXXXXX");
+ file.setAutoRemove(true);
+ QVERIFY(file.open());
+ file.write("OLE");
+ fileName = file.fileName();
+ QVERIFY(QFile::exists(fileName));
+ file.close();
+
+ // Check that it still exists after being closed
+ QVERIFY(QFile::exists(fileName));
+ QVERIFY(!file.isOpen());
+ QVERIFY(file.open());
+ QCOMPARE(file.readAll(), QByteArray("OLE"));
+ // Check that it's still the same file after being opened again.
+ QCOMPARE(file.fileName(), fileName);
+ }
+ QVERIFY(!QFile::exists(fileName));
+}
+
+void tst_QTemporaryFile::size()
+{
+ QTemporaryFile file;
+ QVERIFY(file.open());
+ QVERIFY(file.exists());
+ QVERIFY(!file.isSequential());
+ QByteArray str("foobar");
+ file.write(str);
+ QVERIFY(QFile::exists(file.fileName()));
+ // On CE it takes more time for the filesystem to update
+ // the information. Usually you have to close it or seek
+ // to get latest information. flush() does not help either.
+#if !defined(Q_OS_WINCE)
+ QCOMPARE(file.size(), qint64(6));
+#endif
+ file.seek(0);
+ QCOMPARE(file.size(), qint64(6));
+}
+
+void tst_QTemporaryFile::resize()
+{
+ QTemporaryFile file;
+ file.setAutoRemove(true);
+ QVERIFY(file.open());
+ QVERIFY(file.resize(100));
+
+ QCOMPARE(QFileInfo(file.fileName()).size(), qint64(100));
+
+ file.close();
+}
+
+void tst_QTemporaryFile::openOnRootDrives()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+ // If it's possible to create a file in the root directory, it
+ // must be possible to create a temp file there too.
+ foreach (QFileInfo driveInfo, QDir::drives()) {
+ QFile testFile(driveInfo.filePath() + "XXXXXX.txt");
+ if (testFile.open(QIODevice::ReadWrite)) {
+ testFile.remove();
+ QTemporaryFile file(driveInfo.filePath() + "XXXXXX.txt");
+ file.setAutoRemove(true);
+ QVERIFY(file.open());
+ }
+ }
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ SetErrorMode(lastErrorMode);
+#endif
+}
+
+void tst_QTemporaryFile::stressTest()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ // 200 is still ok, first colision happens after ~30
+ const int iterations = 200;
+#else
+ const int iterations = 1000;
+#endif
+
+ QSet<QString> names;
+ for (int i = 0; i < iterations; ++i) {
+ QTemporaryFile file;
+ file.setAutoRemove(false);
+ QVERIFY2(file.open(), qPrintable(file.errorString()));
+ QVERIFY(!names.contains(file.fileName()));
+ names.insert(file.fileName());
+ }
+ for (QSet<QString>::const_iterator it = names.constBegin(); it != names.constEnd(); ++it) {
+ QFile::remove(*it);
+ }
+}
+
+void tst_QTemporaryFile::rename()
+{
+ // This test checks that the temporary file is deleted, even after a
+ // rename.
+
+ QDir dir;
+ QVERIFY(!dir.exists("temporary-file.txt"));
+
+ QString tempname;
+ {
+ QTemporaryFile file(dir.filePath("temporary-file.XXXXXX"));
+
+ QVERIFY(file.open());
+ tempname = file.fileName();
+ QVERIFY(dir.exists(tempname));
+
+ QVERIFY(file.rename("temporary-file.txt"));
+ QVERIFY(!dir.exists(tempname));
+ QVERIFY(dir.exists("temporary-file.txt"));
+ QCOMPARE(file.fileName(), QString("temporary-file.txt"));
+ }
+
+ QVERIFY(!dir.exists(tempname));
+ QVERIFY(!dir.exists("temporary-file.txt"));
+}
+
+void tst_QTemporaryFile::renameFdLeak()
+{
+#ifdef Q_OS_UNIX
+ // Test this on Unix only
+
+ // Open a bunch of files to force the fd count to go up
+ static const int count = 10;
+ int bunch_of_files[count];
+ for (int i = 0; i < count; ++i) {
+ bunch_of_files[i] = ::open(SRCDIR "tst_qtemporaryfile.cpp", O_RDONLY);
+ QVERIFY(bunch_of_files[i] != -1);
+ }
+
+ int fd;
+ {
+ QTemporaryFile file;
+ file.setAutoRemove(false);
+ QVERIFY(file.open());
+
+ // close the bunch of files
+ for (int i = 0; i < count; ++i)
+ ::close(bunch_of_files[i]);
+
+ // save the file descriptor for later
+ fd = file.handle();
+
+ // rename the file to something
+ QString newPath = QDir::tempPath() + "/tst_qtemporaryfile-renameFdLeak-" + QString::number(getpid());
+ file.rename(newPath);
+ QFile::remove(newPath);
+ }
+
+ // check if QTemporaryFile closed the file
+ QVERIFY(::close(fd) == -1 && errno == EBADF);
+#endif
+}
+
+void tst_QTemporaryFile::reOpenThroughQFile()
+{
+ QByteArray data("abcdefghij");
+
+ QTemporaryFile file;
+ QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
+ QCOMPARE(file.write(data), (qint64)data.size());
+
+ file.close();
+ QVERIFY(file.open());
+ QCOMPARE(file.readAll(), data);
+}
+
+void tst_QTemporaryFile::keepOpenMode()
+{
+ QByteArray data("abcdefghij");
+
+ {
+ QTemporaryFile file;
+ QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
+ QVERIFY(QIODevice::WriteOnly == file.openMode());
+
+ QCOMPARE(file.write(data), (qint64)data.size());
+ file.close();
+
+ QVERIFY(((QFile &)file).open(QIODevice::ReadOnly));
+ QVERIFY(QIODevice::ReadOnly == file.openMode());
+ QCOMPARE(file.readAll(), data);
+ }
+
+ {
+ QTemporaryFile file;
+ QVERIFY(file.open());
+ QCOMPARE(file.write(data), (qint64)data.size());
+ QVERIFY(file.rename("temporary-file.txt"));
+
+ QVERIFY(((QFile &)file).open(QIODevice::ReadOnly));
+ QVERIFY(QIODevice::ReadOnly == file.openMode());
+ QCOMPARE(file.readAll(), data);
+
+ QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
+ QVERIFY(QIODevice::WriteOnly == file.openMode());
+ }
+}
+
+void tst_QTemporaryFile::resetTemplateAfterError()
+{
+ // calling setFileTemplate on a failed open
+
+ QString tempPath = QDir::tempPath();
+
+ QString const fileTemplate("destination/qt_temp_file_test.XXXXXX");
+ QString const fileTemplate2(tempPath + "/qt_temp_file_test.XXXXXX");
+
+ QVERIFY2( QDir(tempPath).exists() || QDir().mkpath(tempPath), "Test precondition" );
+ QVERIFY2( !QFile::exists("destination"), "Test precondition" );
+ QVERIFY2( !QFile::exists(fileTemplate2) || QFile::remove(fileTemplate2), "Test precondition" );
+
+ QFile file(fileTemplate2);
+ QByteArray fileContent("This file is intentionally NOT left empty.");
+
+ QVERIFY( file.open(QIODevice::ReadWrite | QIODevice::Truncate) );
+ QCOMPARE( file.write(fileContent), (qint64)fileContent.size() );
+ QVERIFY( file.flush() );
+
+ QString fileName;
+ {
+ QTemporaryFile temp;
+
+ QVERIFY( temp.fileName().isEmpty() );
+ QVERIFY( !temp.fileTemplate().isEmpty() );
+
+ temp.setFileTemplate( fileTemplate );
+
+ QVERIFY( temp.fileName().isEmpty() );
+ QCOMPARE( temp.fileTemplate(), fileTemplate );
+
+ QVERIFY( !temp.open() );
+
+ QVERIFY( temp.fileName().isEmpty() );
+ QCOMPARE( temp.fileTemplate(), fileTemplate );
+
+ temp.setFileTemplate( fileTemplate2 );
+ QVERIFY( temp.open() );
+
+ fileName = temp.fileName();
+ QVERIFY( QFile::exists(fileName) );
+ QVERIFY( !fileName.isEmpty() );
+ QVERIFY2( fileName != fileTemplate2,
+ ("Generated name shouldn't be same as template: " + fileTemplate2).toLocal8Bit().constData() );
+ }
+
+ QVERIFY( !QFile::exists(fileName) );
+
+ file.seek(0);
+ QCOMPARE( QString(file.readAll()), QString(fileContent) );
+ QVERIFY( file.remove() );
+}
+
+void tst_QTemporaryFile::setTemplateAfterOpen()
+{
+ QTemporaryFile temp;
+
+ QVERIFY( temp.fileName().isEmpty() );
+ QVERIFY( !temp.fileTemplate().isEmpty() );
+
+ QVERIFY( temp.open() );
+
+ QString const fileName = temp.fileName();
+ QString const newTemplate("funny-path/funny-name-XXXXXX.tmp");
+
+ QVERIFY( !fileName.isEmpty() );
+ QVERIFY( QFile::exists(fileName) );
+ QVERIFY( !temp.fileTemplate().isEmpty() );
+ QVERIFY( temp.fileTemplate() != newTemplate );
+
+ temp.close(); // QTemporaryFile::setFileTemplate will assert on isOpen() up to 4.5.2
+ temp.setFileTemplate(newTemplate);
+ QCOMPARE( temp.fileTemplate(), newTemplate );
+
+ QVERIFY( temp.open() );
+ QCOMPARE( temp.fileName(), fileName );
+ QCOMPARE( temp.fileTemplate(), newTemplate );
+}
+
+void tst_QTemporaryFile::autoRemoveAfterFailedRename()
+{
+ struct CleanOnReturn
+ {
+ ~CleanOnReturn()
+ {
+ if (!tempName.isEmpty())
+ QFile::remove(tempName);
+ }
+
+ void reset()
+ {
+ tempName.clear();
+ }
+
+ QString tempName;
+ };
+
+ CleanOnReturn cleaner;
+
+ {
+ QTemporaryFile file;
+ QVERIFY( file.open() );
+ cleaner.tempName = file.fileName();
+
+ QVERIFY( QFile::exists(cleaner.tempName) );
+ QVERIFY( !QFileInfo("i-do-not-exist").isDir() );
+ QVERIFY( !file.rename("i-do-not-exist/file.txt") );
+ QVERIFY( QFile::exists(cleaner.tempName) );
+ }
+
+ QVERIFY( !QFile::exists(cleaner.tempName) );
+ cleaner.reset();
+}
+
+void tst_QTemporaryFile::QTBUG_4796_data()
+{
+ QTest::addColumn<QString>("prefix");
+ QTest::addColumn<QString>("suffix");
+ QTest::addColumn<bool>("openResult");
+
+ QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
+
+ QTest::newRow("<empty>") << QString() << QString() << true;
+ QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
+ QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true;
+ QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
+ QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true;
+ QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
+ QTest::newRow("<unicode>XXXXXX<unicode>") << unicode << unicode << true;
+}
+
+void tst_QTemporaryFile::QTBUG_4796()
+{
+ QVERIFY(QDir("test-XXXXXX").exists());
+
+ struct CleanOnReturn
+ {
+ ~CleanOnReturn()
+ {
+ Q_FOREACH(QString tempName, tempNames)
+ QFile::remove(tempName);
+ }
+
+ void reset()
+ {
+ tempNames.clear();
+ }
+
+ QStringList tempNames;
+ };
+
+ CleanOnReturn cleaner;
+
+ QFETCH(QString, prefix);
+ QFETCH(QString, suffix);
+ QFETCH(bool, openResult);
+
+ {
+ QString fileTemplate1 = prefix + QString("XX") + suffix;
+ QString fileTemplate2 = prefix + QString("XXXX") + suffix;
+ QString fileTemplate3 = prefix + QString("XXXXXX") + suffix;
+ QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix;
+
+ QTemporaryFile file1(fileTemplate1);
+ QTemporaryFile file2(fileTemplate2);
+ QTemporaryFile file3(fileTemplate3);
+ QTemporaryFile file4(fileTemplate4);
+ QTemporaryFile file5("test-XXXXXX/" + fileTemplate1);
+ QTemporaryFile file6("test-XXXXXX/" + fileTemplate3);
+
+ QCOMPARE(file1.open(), openResult);
+ QCOMPARE(file2.open(), openResult);
+ QCOMPARE(file3.open(), openResult);
+ QCOMPARE(file4.open(), openResult);
+ QCOMPARE(file5.open(), openResult);
+ QCOMPARE(file6.open(), openResult);
+
+ QCOMPARE(file1.exists(), openResult);
+ QCOMPARE(file2.exists(), openResult);
+ QCOMPARE(file3.exists(), openResult);
+ QCOMPARE(file4.exists(), openResult);
+ QCOMPARE(file5.exists(), openResult);
+ QCOMPARE(file6.exists(), openResult);
+
+ // make sure the file exists under the *correct* name
+ if (openResult) {
+ cleaner.tempNames << file1.fileName()
+ << file2.fileName()
+ << file3.fileName()
+ << file4.fileName()
+ << file5.fileName()
+ << file6.fileName();
+
+ QVERIFY(file1.fileName().startsWith(fileTemplate1 + QLatin1Char('.')));
+ QVERIFY(file2.fileName().startsWith(fileTemplate2 + QLatin1Char('.')));
+ QVERIFY(file5.fileName().startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')));
+ QVERIFY(file6.fileName().startsWith("test-XXXXXX/" + prefix));
+
+ if (!prefix.isEmpty()) {
+ QVERIFY(file3.fileName().startsWith(prefix));
+ QVERIFY(file4.fileName().startsWith(prefix));
+ }
+
+ if (!suffix.isEmpty()) {
+ QVERIFY(file3.fileName().endsWith(suffix));
+ QVERIFY(file4.fileName().endsWith(suffix));
+ QVERIFY(file6.fileName().endsWith(suffix));
+ }
+ }
+ }
+
+ Q_FOREACH(QString const &tempName, cleaner.tempNames)
+ QVERIFY( !QFile::exists(tempName) );
+
+ cleaner.reset();
+}
+
+QTEST_MAIN(tst_QTemporaryFile)
+#include "tst_qtemporaryfile.moc"
diff --git a/tests/auto/corelib/io/qtextstream/.gitattributes b/tests/auto/corelib/io/qtextstream/.gitattributes
new file mode 100644
index 0000000000..eb78a3cecf
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/.gitattributes
@@ -0,0 +1,3 @@
+rfc3261.txt -crlf
+task113817.txt -crlf
+shift-jis.txt -crlf
diff --git a/tests/auto/corelib/io/qtextstream/.gitignore b/tests/auto/corelib/io/qtextstream/.gitignore
new file mode 100644
index 0000000000..01f26ae749
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/.gitignore
@@ -0,0 +1,11 @@
+bom.txt
+out.txt
+readAllStdinProcess/readAllStdinProcess
+readAllStdinProcess/readAllStdinProcess.exe
+readLineStdinProcess/readLineStdinProcess
+readLineStdinProcess/readLineStdinProcess.exe
+stdinProcess/stdinProcess
+stdinProcess/stdinProcess.exe
+testfile
+tst_qtextstream
+utf8bom
diff --git a/tests/auto/corelib/io/qtextstream/qtextstream.pro b/tests/auto/corelib/io/qtextstream/qtextstream.pro
new file mode 100644
index 0000000000..a2dcc8108d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/qtextstream.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+SUBDIRS = test
+!symbian: SUBDIRS += stdinProcess readAllStdinProcess readLineStdinProcess
+
+
+
diff --git a/tests/auto/corelib/io/qtextstream/qtextstream.qrc b/tests/auto/corelib/io/qtextstream/qtextstream.qrc
new file mode 100644
index 0000000000..a750e35d4a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/qtextstream.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/tst_textstream/">
+ <file>resources/big_endian/</file>
+ <file>resources/little_endian/</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp
new file mode 100644
index 0000000000..ca541d053a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication a(argc, argv);
+ qDebug() << QTextStream(stdin).readAll();
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qtextstream/readAllStdinProcess/readAllStdinProcess.pro b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/readAllStdinProcess.pro
new file mode 100644
index 0000000000..9cf4d19387
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/readAllStdinProcess.pro
@@ -0,0 +1,7 @@
+SOURCES += main.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+DESTDIR = ./
+
+
diff --git a/tests/auto/corelib/io/qtextstream/readLineStdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/readLineStdinProcess/main.cpp
new file mode 100644
index 0000000000..d8d2eed000
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/readLineStdinProcess/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication a(argc, argv);
+ QTextStream qin(stdin);
+ QTextStream qerr(stderr);
+ QString line;
+ do {
+ line = qin.readLine();
+ if (!line.isNull())
+ qerr << line << flush;
+ } while (!line.isNull());
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qtextstream/readLineStdinProcess/readLineStdinProcess.pro b/tests/auto/corelib/io/qtextstream/readLineStdinProcess/readLineStdinProcess.pro
new file mode 100644
index 0000000000..9cf4d19387
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/readLineStdinProcess/readLineStdinProcess.pro
@@ -0,0 +1,7 @@
+SOURCES += main.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+DESTDIR = ./
+
+
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Latin1_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Locale_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..849ecb39ed
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..8b9647f06f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..d73722e724
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..fcb209d377
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..7939963f78
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..d155ca2863
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..104e45f940
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..3135276780
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..993d0b9e19
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_0.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_0.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_1.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_1.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_2.data
new file mode 100644
index 0000000000..fcb209d377
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_3.data
new file mode 100644
index 0000000000..7939963f78
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_4.data
new file mode 100644
index 0000000000..d155ca2863
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QByteArray_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_3.data
new file mode 100644
index 0000000000..fa7af8bf5f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_3.data
@@ -0,0 +1 @@
+z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_4.data
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Latin1_4.data
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_3.data
new file mode 100644
index 0000000000..fa7af8bf5f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_3.data
@@ -0,0 +1 @@
+z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_4.data
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Locale_4.data
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..6def16c99e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..57302ad8e7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..239c14d498
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..8fbd3327c8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..d745e1be7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..db52135603
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..0a4ca93c16
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e7c7d5a76b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..7501b59181
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..1565aaa95f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..9ac3ad9a6b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..bb28df16b9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..8c0f57437b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d494004e64
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..de421979ea
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..fa7af8bf5f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_0.data
new file mode 100644
index 0000000000..db52135603
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_1.data
new file mode 100644
index 0000000000..0a4ca93c16
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_2.data
new file mode 100644
index 0000000000..e7c7d5a76b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_3.data
new file mode 100644
index 0000000000..7501b59181
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_4.data
new file mode 100644
index 0000000000..1565aaa95f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QChar_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Latin1_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Locale_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..849ecb39ed
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..8b9647f06f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..d73722e724
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..fcb209d377
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..7939963f78
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..d155ca2863
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..104e45f940
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..3135276780
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..993d0b9e19
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_0.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_0.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_1.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_1.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_2.data
new file mode 100644
index 0000000000..fcb209d377
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_3.data
new file mode 100644
index 0000000000..7939963f78
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_4.data
new file mode 100644
index 0000000000..d155ca2863
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_QString_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_3.data
new file mode 100644
index 0000000000..9280c0d31d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_3.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_4.data
new file mode 100644
index 0000000000..c227083464
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Latin1_4.data
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_3.data
new file mode 100644
index 0000000000..9280c0d31d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_3.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_4.data
new file mode 100644
index 0000000000..c227083464
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Locale_4.data
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..6def16c99e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..57302ad8e7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..239c14d498
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..819b31d1f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..a6ff072af1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..db52135603
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..0a4ca93c16
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e7c7d5a76b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..bf9cec8ea7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..ec4665f7ff
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..9ac3ad9a6b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..bb28df16b9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..8c0f57437b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..878dc8a26e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..fd0779e0f3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..9280c0d31d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c227083464
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_0.data
new file mode 100644
index 0000000000..db52135603
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_1.data
new file mode 100644
index 0000000000..0a4ca93c16
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_2.data
new file mode 100644
index 0000000000..e7c7d5a76b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_3.data
new file mode 100644
index 0000000000..bf9cec8ea7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_4.data
new file mode 100644
index 0000000000..ec4665f7ff
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_char_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_5.data
new file mode 100644
index 0000000000..80aed3622e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_5.data
@@ -0,0 +1 @@
+ A 1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_6.data
new file mode 100644
index 0000000000..aec027753d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Latin1_6.data
@@ -0,0 +1 @@
+ A -1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_5.data
new file mode 100644
index 0000000000..80aed3622e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_5.data
@@ -0,0 +1 @@
+ A 1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_6.data
new file mode 100644
index 0000000000..aec027753d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Locale_6.data
@@ -0,0 +1 @@
+ A -1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..67ce8d83c8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..9662a9aaa1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..a74511b101
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..bdc06a6ec2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_5.data
new file mode 100644
index 0000000000..79b15d4d8a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_6.data
new file mode 100644
index 0000000000..2141e65843
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_RawUnicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..61cc689e1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..cf914bc67e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..5e08ff706a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..b6f4541bb8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.data
new file mode 100644
index 0000000000..f4a50d829a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.data
new file mode 100644
index 0000000000..2d8f67152c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..e6b94bbeb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..fb0a550264
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..48fe53930f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..811e93212d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_5.data
new file mode 100644
index 0000000000..7041fa9b4d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_6.data
new file mode 100644
index 0000000000..9fd21fade0
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeReverse_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_5.data
new file mode 100644
index 0000000000..80aed3622e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_5.data
@@ -0,0 +1 @@
+ A 1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_6.data
new file mode 100644
index 0000000000..aec027753d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_UnicodeUTF8_6.data
@@ -0,0 +1 @@
+ A -1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_1.data
new file mode 100644
index 0000000000..61cc689e1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_2.data
new file mode 100644
index 0000000000..cf914bc67e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_3.data
new file mode 100644
index 0000000000..5e08ff706a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_4.data
new file mode 100644
index 0000000000..b6f4541bb8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_5.data
new file mode 100644
index 0000000000..f4a50d829a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_6.data
new file mode 100644
index 0000000000..2d8f67152c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_double_resource_Unicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Locale_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..67ce8d83c8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..9662a9aaa1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..a74511b101
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..bdc06a6ec2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..61cc689e1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..cf914bc67e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..5e08ff706a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..b6f4541bb8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..e6b94bbeb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..fb0a550264
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..48fe53930f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..811e93212d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_1.data
new file mode 100644
index 0000000000..61cc689e1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_2.data
new file mode 100644
index 0000000000..cf914bc67e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_3.data
new file mode 100644
index 0000000000..5e08ff706a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_4.data
new file mode 100644
index 0000000000..b6f4541bb8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_float_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_8.data
new file mode 100644
index 0000000000..f4aefab396
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Latin1_8.data
@@ -0,0 +1 @@
+ A -512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_8.data
new file mode 100644
index 0000000000..f4aefab396
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Locale_8.data
@@ -0,0 +1 @@
+ A -512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..815d4fc7db
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..c933a04c07
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..69de5ef2bd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..c45139955a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_5.data
new file mode 100644
index 0000000000..396352f4d6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_6.data
new file mode 100644
index 0000000000..ea73fac731
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_7.data
new file mode 100644
index 0000000000..1f4f1a58de
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_8.data
new file mode 100644
index 0000000000..9469ca407f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_RawUnicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.data
new file mode 100644
index 0000000000..18c3344c26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.data
new file mode 100644
index 0000000000..5193701ae3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.data
new file mode 100644
index 0000000000..fab38d24ef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_5.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_6.data
new file mode 100644
index 0000000000..ebb14b2fbd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_7.data
new file mode 100644
index 0000000000..a9e1432ca9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_8.data
new file mode 100644
index 0000000000..b7e6743c28
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeReverse_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_8.data
new file mode 100644
index 0000000000..f4aefab396
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_UnicodeUTF8_8.data
@@ -0,0 +1 @@
+ A -512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_5.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_6.data
new file mode 100644
index 0000000000..18c3344c26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_7.data
new file mode 100644
index 0000000000..5193701ae3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_8.data
new file mode 100644
index 0000000000..fab38d24ef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_int_resource_Unicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_8.data
new file mode 100644
index 0000000000..cab2ee4938
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Latin1_8.data
@@ -0,0 +1 @@
+ A -65534 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_8.data
new file mode 100644
index 0000000000..cab2ee4938
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Locale_8.data
@@ -0,0 +1 @@
+ A -65534 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..815d4fc7db
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..c933a04c07
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..69de5ef2bd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..40269f4e0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_5.data
new file mode 100644
index 0000000000..396352f4d6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_6.data
new file mode 100644
index 0000000000..ea73fac731
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_7.data
new file mode 100644
index 0000000000..1f4f1a58de
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_8.data
new file mode 100644
index 0000000000..e8051f8906
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_RawUnicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..e50e2d02a9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.data
new file mode 100644
index 0000000000..18c3344c26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.data
new file mode 100644
index 0000000000..5193701ae3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.data
new file mode 100644
index 0000000000..5a9cb07f57
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..e20c76a82c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_5.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_6.data
new file mode 100644
index 0000000000..ebb14b2fbd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_7.data
new file mode 100644
index 0000000000..a9e1432ca9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_8.data
new file mode 100644
index 0000000000..f8ec5bc443
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeReverse_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_8.data
new file mode 100644
index 0000000000..cab2ee4938
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_UnicodeUTF8_8.data
@@ -0,0 +1 @@
+ A -65534 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_4.data
new file mode 100644
index 0000000000..e50e2d02a9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_5.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_6.data
new file mode 100644
index 0000000000..18c3344c26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_7.data
new file mode 100644
index 0000000000..5193701ae3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_8.data
new file mode 100644
index 0000000000..5a9cb07f57
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_long_resource_Unicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_1.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_2.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_4.data
new file mode 100644
index 0000000000..02b7f3ab7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A -254 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_1.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_1.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_2.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_4.data
new file mode 100644
index 0000000000..02b7f3ab7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Locale_4.data
@@ -0,0 +1 @@
+ A -254 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..396352f4d6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..815d4fc7db
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..69de5ef2bd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..0dc83d2713
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..b951b56531
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..80d3ca2ef1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..02b7f3ab7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A -254 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_1.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_2.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_4.data
new file mode 100644
index 0000000000..b951b56531
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_short_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..815d4fc7db
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..c933a04c07
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..69de5ef2bd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..c45139955a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_uint_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..815d4fc7db
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..c933a04c07
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..69de5ef2bd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..40269f4e0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..e50e2d02a9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..e20c76a82c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_4.data
new file mode 100644
index 0000000000..e50e2d02a9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ulong_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..feac21f921
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..815d4fc7db
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..c933a04c07
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..69de5ef2bd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..c45139955a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shift_ushort_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource0.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource0.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource0.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource1.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource1.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource1.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource10.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource10.data
new file mode 100644
index 0000000000..597f94465c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource10.data
@@ -0,0 +1 @@
+I-am-a-string \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource11.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource11.data
new file mode 100644
index 0000000000..597f94465c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource11.data
@@ -0,0 +1 @@
+I-am-a-string \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource12.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource12.data
new file mode 100644
index 0000000000..597f94465c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource12.data
@@ -0,0 +1 @@
+I-am-a-string \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource2.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource2.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource2.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource20.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource20.data
new file mode 100644
index 0000000000..b9e3a5a7c7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource20.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource21.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource21.data
new file mode 100644
index 0000000000..7014dc882f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource21.data
@@ -0,0 +1 @@
+賿 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource3.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource3.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource3.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource4.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource4.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource4.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource5.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource5.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource5.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource6.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource6.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource6.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource7.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource7.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource7.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource8.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource8.data
new file mode 100644
index 0000000000..4f3af7006e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource8.data
@@ -0,0 +1 @@
+3.1415 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource9.data b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource9.data
new file mode 100644
index 0000000000..4f3af7006e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/big_endian/operator_shiftright_resource9.data
@@ -0,0 +1 @@
+3.1415 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Latin1_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Locale_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..4d5bdc553e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..3cf181c23c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..f7f74e56a0
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_0.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..e2df5e2ee7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_1.data
@@ -0,0 +1 @@
+þÿ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..fcb209d377
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..7939963f78
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..d155ca2863
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_0.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_1.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..104e45f940
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..3135276780
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..993d0b9e19
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_0.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_0.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_1.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_1.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_2.data
new file mode 100644
index 0000000000..104e45f940
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_3.data
new file mode 100644
index 0000000000..3135276780
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_4.data
new file mode 100644
index 0000000000..993d0b9e19
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QByteArray_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_3.data
new file mode 100644
index 0000000000..fa7af8bf5f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_3.data
@@ -0,0 +1 @@
+z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_4.data
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Latin1_4.data
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_3.data
new file mode 100644
index 0000000000..fa7af8bf5f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_3.data
@@ -0,0 +1 @@
+z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_4.data
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Locale_4.data
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..e2b43e3781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..962fc922ad
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..839cc09ec8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..f71ac66a63
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..88f99805e3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..db52135603
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..0a4ca93c16
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e7c7d5a76b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..7501b59181
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..1565aaa95f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..9ac3ad9a6b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..bb28df16b9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..8c0f57437b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d494004e64
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..de421979ea
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..fa7af8bf5f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_0.data
new file mode 100644
index 0000000000..9ac3ad9a6b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_1.data
new file mode 100644
index 0000000000..bb28df16b9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_2.data
new file mode 100644
index 0000000000..8c0f57437b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_3.data
new file mode 100644
index 0000000000..d494004e64
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_4.data
new file mode 100644
index 0000000000..de421979ea
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QChar_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Latin1_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Locale_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..4d5bdc553e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..3cf181c23c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..f7f74e56a0
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..fcb209d377
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..7939963f78
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..d155ca2863
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_0.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_1.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..104e45f940
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..3135276780
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..993d0b9e19
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_0.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_1.data
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1910281566
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..a907ec3f43
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_3.data
@@ -0,0 +1,2 @@
+foo
+bar \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..61cd46aacc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_0.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_0.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_1.data
new file mode 100644
index 0000000000..46b134b197
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_1.data
@@ -0,0 +1 @@
+ÿþ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_2.data
new file mode 100644
index 0000000000..104e45f940
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_3.data
new file mode 100644
index 0000000000..3135276780
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_4.data
new file mode 100644
index 0000000000..993d0b9e19
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_QString_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_3.data
new file mode 100644
index 0000000000..9280c0d31d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_3.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_4.data
new file mode 100644
index 0000000000..c227083464
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Latin1_4.data
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_3.data
new file mode 100644
index 0000000000..9280c0d31d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_3.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_4.data
new file mode 100644
index 0000000000..c227083464
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Locale_4.data
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..e2b43e3781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..962fc922ad
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..839cc09ec8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..c33473a370
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..def7fcb589
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..db52135603
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..0a4ca93c16
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e7c7d5a76b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..bf9cec8ea7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..ec4665f7ff
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..9ac3ad9a6b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..bb28df16b9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..8c0f57437b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..878dc8a26e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..fd0779e0f3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..8c7e5a667f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..7371f47a6f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..9280c0d31d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c227083464
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_0.data
new file mode 100644
index 0000000000..9ac3ad9a6b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_1.data
new file mode 100644
index 0000000000..bb28df16b9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_2.data
new file mode 100644
index 0000000000..8c0f57437b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_3.data
new file mode 100644
index 0000000000..878dc8a26e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_4.data
new file mode 100644
index 0000000000..fd0779e0f3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_char_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_5.data
new file mode 100644
index 0000000000..80aed3622e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_5.data
@@ -0,0 +1 @@
+ A 1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_6.data
new file mode 100644
index 0000000000..aec027753d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Latin1_6.data
@@ -0,0 +1 @@
+ A -1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_5.data
new file mode 100644
index 0000000000..80aed3622e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_5.data
@@ -0,0 +1 @@
+ A 1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_6.data
new file mode 100644
index 0000000000..aec027753d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Locale_6.data
@@ -0,0 +1 @@
+ A -1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..fb911f7352
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..efbc06bf26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..4d857caa13
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..b125e2084f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_5.data
new file mode 100644
index 0000000000..f39fbde113
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_6.data
new file mode 100644
index 0000000000..5436b427ed
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_RawUnicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..61cc689e1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..cf914bc67e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..5e08ff706a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..b6f4541bb8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.data
new file mode 100644
index 0000000000..f4a50d829a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.data
new file mode 100644
index 0000000000..2d8f67152c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeNetworkOrder_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..e6b94bbeb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..fb0a550264
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..48fe53930f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..811e93212d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_5.data
new file mode 100644
index 0000000000..7041fa9b4d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_6.data
new file mode 100644
index 0000000000..9fd21fade0
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeReverse_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_5.data
new file mode 100644
index 0000000000..80aed3622e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_5.data
@@ -0,0 +1 @@
+ A 1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_6.data
new file mode 100644
index 0000000000..aec027753d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_UnicodeUTF8_6.data
@@ -0,0 +1 @@
+ A -1.23456789 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_1.data
new file mode 100644
index 0000000000..e6b94bbeb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_2.data
new file mode 100644
index 0000000000..fb0a550264
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_3.data
new file mode 100644
index 0000000000..48fe53930f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_4.data
new file mode 100644
index 0000000000..811e93212d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_5.data
new file mode 100644
index 0000000000..7041fa9b4d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_6.data
new file mode 100644
index 0000000000..9fd21fade0
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_double_resource_Unicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Locale_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..fb911f7352
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..efbc06bf26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..4d857caa13
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..b125e2084f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..61cc689e1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..cf914bc67e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..5e08ff706a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..b6f4541bb8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..e6b94bbeb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..fb0a550264
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..48fe53930f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..811e93212d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..d2fa166d7d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..1d0fa9e6a6
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A -0.0001 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..e47d45c143
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..47ce07d283
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A -3.45678 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_1.data
new file mode 100644
index 0000000000..e6b94bbeb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_2.data
new file mode 100644
index 0000000000..fb0a550264
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_3.data
new file mode 100644
index 0000000000..48fe53930f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_4.data
new file mode 100644
index 0000000000..811e93212d
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_float_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_8.data
new file mode 100644
index 0000000000..f4aefab396
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Latin1_8.data
@@ -0,0 +1 @@
+ A -512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_8.data
new file mode 100644
index 0000000000..f4aefab396
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Locale_8.data
@@ -0,0 +1 @@
+ A -512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..ee113d1cf3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..1e07040ef4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..cc7ab7dff8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..450072bc4e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_5.data
new file mode 100644
index 0000000000..73f5f259f8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_6.data
new file mode 100644
index 0000000000..9805422dfb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_7.data
new file mode 100644
index 0000000000..77f557a494
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_8.data
new file mode 100644
index 0000000000..8dd6a4b38e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_RawUnicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.data
new file mode 100644
index 0000000000..18c3344c26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.data
new file mode 100644
index 0000000000..5193701ae3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.data
new file mode 100644
index 0000000000..fab38d24ef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeNetworkOrder_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_5.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_6.data
new file mode 100644
index 0000000000..ebb14b2fbd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_7.data
new file mode 100644
index 0000000000..a9e1432ca9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_8.data
new file mode 100644
index 0000000000..b7e6743c28
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeReverse_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_8.data
new file mode 100644
index 0000000000..f4aefab396
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_UnicodeUTF8_8.data
@@ -0,0 +1 @@
+ A -512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_5.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_6.data
new file mode 100644
index 0000000000..ebb14b2fbd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_7.data
new file mode 100644
index 0000000000..a9e1432ca9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_8.data
new file mode 100644
index 0000000000..b7e6743c28
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_int_resource_Unicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_8.data
new file mode 100644
index 0000000000..cab2ee4938
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Latin1_8.data
@@ -0,0 +1 @@
+ A -65534 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_8.data
new file mode 100644
index 0000000000..cab2ee4938
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Locale_8.data
@@ -0,0 +1 @@
+ A -65534 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..ee113d1cf3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..1e07040ef4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..cc7ab7dff8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..beea1c3663
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_5.data
new file mode 100644
index 0000000000..73f5f259f8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_6.data
new file mode 100644
index 0000000000..9805422dfb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_7.data
new file mode 100644
index 0000000000..77f557a494
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_8.data
new file mode 100644
index 0000000000..be6f22a5ea
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_RawUnicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..e50e2d02a9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.data
new file mode 100644
index 0000000000..18c3344c26
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.data
new file mode 100644
index 0000000000..5193701ae3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.data
new file mode 100644
index 0000000000..5a9cb07f57
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeNetworkOrder_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..e20c76a82c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_5.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_6.data
new file mode 100644
index 0000000000..ebb14b2fbd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_7.data
new file mode 100644
index 0000000000..a9e1432ca9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_8.data
new file mode 100644
index 0000000000..f8ec5bc443
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeReverse_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_5.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_5.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_6.data
new file mode 100644
index 0000000000..f171cb6c0c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_6.data
@@ -0,0 +1 @@
+ A -10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_7.data
new file mode 100644
index 0000000000..de18d40ee8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_7.data
@@ -0,0 +1 @@
+ A -255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_8.data
new file mode 100644
index 0000000000..cab2ee4938
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_UnicodeUTF8_8.data
@@ -0,0 +1 @@
+ A -65534 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_4.data
new file mode 100644
index 0000000000..e20c76a82c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_5.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_5.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_6.data
new file mode 100644
index 0000000000..ebb14b2fbd
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_6.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_7.data
new file mode 100644
index 0000000000..a9e1432ca9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_7.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_8.data
new file mode 100644
index 0000000000..f8ec5bc443
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_long_resource_Unicode_8.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_1.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_2.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_4.data
new file mode 100644
index 0000000000..02b7f3ab7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A -254 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_1.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_1.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_2.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_4.data
new file mode 100644
index 0000000000..02b7f3ab7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Locale_4.data
@@ -0,0 +1 @@
+ A -254 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..73f5f259f8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..ee113d1cf3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..cc7ab7dff8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..584b17ea18
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..c52b277d9c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..b951b56531
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..80d3ca2ef1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..ef70e7dc3a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A -1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..02b7f3ab7b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A -254 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_1.data
new file mode 100644
index 0000000000..95742ec8f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_2.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_4.data
new file mode 100644
index 0000000000..80d3ca2ef1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_short_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..ee113d1cf3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..1e07040ef4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..cc7ab7dff8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..450072bc4e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_uint_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..ee113d1cf3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..1e07040ef4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..cc7ab7dff8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..beea1c3663
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..e50e2d02a9
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..e20c76a82c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..f667f77c45
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 65535 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_4.data
new file mode 100644
index 0000000000..e20c76a82c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ulong_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Latin1_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Locale_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_0.data
new file mode 100644
index 0000000000..775ae0f25b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_1.data
new file mode 100644
index 0000000000..ee113d1cf3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_2.data
new file mode 100644
index 0000000000..1e07040ef4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_3.data
new file mode 100644
index 0000000000..cc7ab7dff8
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_4.data
new file mode 100644
index 0000000000..450072bc4e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_RawUnicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.data
new file mode 100644
index 0000000000..2262f5ecdb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.data
new file mode 100644
index 0000000000..d7a098948e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.data
new file mode 100644
index 0000000000..e333a695b7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.data
new file mode 100644
index 0000000000..18bb47b042
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.data
new file mode 100644
index 0000000000..9a9a22daef
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeNetworkOrder_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeReverse_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data
new file mode 100644
index 0000000000..35282318cb
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_0.data
@@ -0,0 +1 @@
+ A 0 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data
new file mode 100644
index 0000000000..30c3a50213
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_1.data
@@ -0,0 +1 @@
+ A 1 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data
new file mode 100644
index 0000000000..9d64c07ef2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_2.data
@@ -0,0 +1 @@
+ A 10 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data
new file mode 100644
index 0000000000..6b37eb602b
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_3.data
@@ -0,0 +1 @@
+ A 255 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data
new file mode 100644
index 0000000000..c0e22423bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_UnicodeUTF8_4.data
@@ -0,0 +1 @@
+ A 512 B \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_0.data
new file mode 100644
index 0000000000..379e87b914
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_0.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_1.data
new file mode 100644
index 0000000000..2785156fb3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_1.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_2.data
new file mode 100644
index 0000000000..6dc818abc3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_2.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_3.data
new file mode 100644
index 0000000000..d41a1f75d3
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_3.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_4.data
new file mode 100644
index 0000000000..f5a0d874d4
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shift_ushort_resource_Unicode_4.data
Binary files differ
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource0.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource0.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource0.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource1.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource1.data
new file mode 100644
index 0000000000..0f13712411
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource1.data
@@ -0,0 +1 @@
+Z \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource10.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource10.data
new file mode 100644
index 0000000000..597f94465c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource10.data
@@ -0,0 +1 @@
+I-am-a-string \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource11.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource11.data
new file mode 100644
index 0000000000..597f94465c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource11.data
@@ -0,0 +1 @@
+I-am-a-string \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource12.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource12.data
new file mode 100644
index 0000000000..597f94465c
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource12.data
@@ -0,0 +1 @@
+I-am-a-string \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource2.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource2.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource2.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource20.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource20.data
new file mode 100644
index 0000000000..b9e3a5a7c7
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource20.data
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource21.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource21.data
new file mode 100644
index 0000000000..7014dc882f
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource21.data
@@ -0,0 +1 @@
+賿 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource3.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource3.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource3.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource4.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource4.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource4.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource5.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource5.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource5.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource6.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource6.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource6.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource7.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource7.data
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource7.data
@@ -0,0 +1 @@
+12345 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource8.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource8.data
new file mode 100644
index 0000000000..4f3af7006e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource8.data
@@ -0,0 +1 @@
+3.1415 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource9.data b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource9.data
new file mode 100644
index 0000000000..4f3af7006e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/resources/little_endian/operator_shiftright_resource9.data
@@ -0,0 +1 @@
+3.1415 \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtextstream/rfc3261.txt b/tests/auto/corelib/io/qtextstream/rfc3261.txt
new file mode 100644
index 0000000000..4cf4df93bc
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/rfc3261.txt
@@ -0,0 +1,15067 @@
+
+
+
+
+
+
+Network Working Group J. Rosenberg
+Request for Comments: 3261 dynamicsoft
+Obsoletes: 2543 H. Schulzrinne
+Category: Standards Track Columbia U.
+ G. Camarillo
+ Ericsson
+ A. Johnston
+ WorldCom
+ J. Peterson
+ Neustar
+ R. Sparks
+ dynamicsoft
+ M. Handley
+ ICIR
+ E. Schooler
+ AT&T
+ June 2002
+
+ SIP: Session Initiation Protocol
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+Abstract
+
+ This document describes Session Initiation Protocol (SIP), an
+ application-layer control (signaling) protocol for creating,
+ modifying, and terminating sessions with one or more participants.
+ These sessions include Internet telephone calls, multimedia
+ distribution, and multimedia conferences.
+
+ SIP invitations used to create sessions carry session descriptions
+ that allow participants to agree on a set of compatible media types.
+ SIP makes use of elements called proxy servers to help route requests
+ to the user's current location, authenticate and authorize users for
+ services, implement provider call-routing policies, and provide
+ features to users. SIP also provides a registration function that
+ allows users to upload their current locations for use by proxy
+ servers. SIP runs on top of several different transport protocols.
+
+
+
+Rosenberg, et. al. Standards Track [Page 1]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Table of Contents
+
+ 1 Introduction ........................................ 8
+ 2 Overview of SIP Functionality ....................... 9
+ 3 Terminology ......................................... 10
+ 4 Overview of Operation ............................... 10
+ 5 Structure of the Protocol ........................... 18
+ 6 Definitions ......................................... 20
+ 7 SIP Messages ........................................ 26
+ 7.1 Requests ............................................ 27
+ 7.2 Responses ........................................... 28
+ 7.3 Header Fields ....................................... 29
+ 7.3.1 Header Field Format ................................. 30
+ 7.3.2 Header Field Classification ......................... 32
+ 7.3.3 Compact Form ........................................ 32
+ 7.4 Bodies .............................................. 33
+ 7.4.1 Message Body Type ................................... 33
+ 7.4.2 Message Body Length ................................. 33
+ 7.5 Framing SIP Messages ................................ 34
+ 8 General User Agent Behavior ......................... 34
+ 8.1 UAC Behavior ........................................ 35
+ 8.1.1 Generating the Request .............................. 35
+ 8.1.1.1 Request-URI ......................................... 35
+ 8.1.1.2 To .................................................. 36
+ 8.1.1.3 From ................................................ 37
+ 8.1.1.4 Call-ID ............................................. 37
+ 8.1.1.5 CSeq ................................................ 38
+ 8.1.1.6 Max-Forwards ........................................ 38
+ 8.1.1.7 Via ................................................. 39
+ 8.1.1.8 Contact ............................................. 40
+ 8.1.1.9 Supported and Require ............................... 40
+ 8.1.1.10 Additional Message Components ....................... 41
+ 8.1.2 Sending the Request ................................. 41
+ 8.1.3 Processing Responses ................................ 42
+ 8.1.3.1 Transaction Layer Errors ............................ 42
+ 8.1.3.2 Unrecognized Responses .............................. 42
+ 8.1.3.3 Vias ................................................ 43
+ 8.1.3.4 Processing 3xx Responses ............................ 43
+ 8.1.3.5 Processing 4xx Responses ............................ 45
+ 8.2 UAS Behavior ........................................ 46
+ 8.2.1 Method Inspection ................................... 46
+ 8.2.2 Header Inspection ................................... 46
+ 8.2.2.1 To and Request-URI .................................. 46
+ 8.2.2.2 Merged Requests ..................................... 47
+ 8.2.2.3 Require ............................................. 47
+ 8.2.3 Content Processing .................................. 48
+ 8.2.4 Applying Extensions ................................. 49
+ 8.2.5 Processing the Request .............................. 49
+
+
+
+Rosenberg, et. al. Standards Track [Page 2]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 8.2.6 Generating the Response ............................. 49
+ 8.2.6.1 Sending a Provisional Response ...................... 49
+ 8.2.6.2 Headers and Tags .................................... 50
+ 8.2.7 Stateless UAS Behavior .............................. 50
+ 8.3 Redirect Servers .................................... 51
+ 9 Canceling a Request ................................. 53
+ 9.1 Client Behavior ..................................... 53
+ 9.2 Server Behavior ..................................... 55
+ 10 Registrations ....................................... 56
+ 10.1 Overview ............................................ 56
+ 10.2 Constructing the REGISTER Request ................... 57
+ 10.2.1 Adding Bindings ..................................... 59
+ 10.2.1.1 Setting the Expiration Interval of Contact Addresses 60
+ 10.2.1.2 Preferences among Contact Addresses ................. 61
+ 10.2.2 Removing Bindings ................................... 61
+ 10.2.3 Fetching Bindings ................................... 61
+ 10.2.4 Refreshing Bindings ................................. 61
+ 10.2.5 Setting the Internal Clock .......................... 62
+ 10.2.6 Discovering a Registrar ............................. 62
+ 10.2.7 Transmitting a Request .............................. 62
+ 10.2.8 Error Responses ..................................... 63
+ 10.3 Processing REGISTER Requests ........................ 63
+ 11 Querying for Capabilities ........................... 66
+ 11.1 Construction of OPTIONS Request ..................... 67
+ 11.2 Processing of OPTIONS Request ....................... 68
+ 12 Dialogs ............................................. 69
+ 12.1 Creation of a Dialog ................................ 70
+ 12.1.1 UAS behavior ........................................ 70
+ 12.1.2 UAC Behavior ........................................ 71
+ 12.2 Requests within a Dialog ............................ 72
+ 12.2.1 UAC Behavior ........................................ 73
+ 12.2.1.1 Generating the Request .............................. 73
+ 12.2.1.2 Processing the Responses ............................ 75
+ 12.2.2 UAS Behavior ........................................ 76
+ 12.3 Termination of a Dialog ............................. 77
+ 13 Initiating a Session ................................ 77
+ 13.1 Overview ............................................ 77
+ 13.2 UAC Processing ...................................... 78
+ 13.2.1 Creating the Initial INVITE ......................... 78
+ 13.2.2 Processing INVITE Responses ......................... 81
+ 13.2.2.1 1xx Responses ....................................... 81
+ 13.2.2.2 3xx Responses ....................................... 81
+ 13.2.2.3 4xx, 5xx and 6xx Responses .......................... 81
+ 13.2.2.4 2xx Responses ....................................... 82
+ 13.3 UAS Processing ...................................... 83
+ 13.3.1 Processing of the INVITE ............................ 83
+ 13.3.1.1 Progress ............................................ 84
+ 13.3.1.2 The INVITE is Redirected ............................ 84
+
+
+
+Rosenberg, et. al. Standards Track [Page 3]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 13.3.1.3 The INVITE is Rejected .............................. 85
+ 13.3.1.4 The INVITE is Accepted .............................. 85
+ 14 Modifying an Existing Session ....................... 86
+ 14.1 UAC Behavior ........................................ 86
+ 14.2 UAS Behavior ........................................ 88
+ 15 Terminating a Session ............................... 89
+ 15.1 Terminating a Session with a BYE Request ............ 90
+ 15.1.1 UAC Behavior ........................................ 90
+ 15.1.2 UAS Behavior ........................................ 91
+ 16 Proxy Behavior ...................................... 91
+ 16.1 Overview ............................................ 91
+ 16.2 Stateful Proxy ...................................... 92
+ 16.3 Request Validation .................................. 94
+ 16.4 Route Information Preprocessing ..................... 96
+ 16.5 Determining Request Targets ......................... 97
+ 16.6 Request Forwarding .................................. 99
+ 16.7 Response Processing ................................. 107
+ 16.8 Processing Timer C .................................. 114
+ 16.9 Handling Transport Errors ........................... 115
+ 16.10 CANCEL Processing ................................... 115
+ 16.11 Stateless Proxy ..................................... 116
+ 16.12 Summary of Proxy Route Processing ................... 118
+ 16.12.1 Examples ............................................ 118
+ 16.12.1.1 Basic SIP Trapezoid ................................. 118
+ 16.12.1.2 Traversing a Strict-Routing Proxy ................... 120
+ 16.12.1.3 Rewriting Record-Route Header Field Values .......... 121
+ 17 Transactions ........................................ 122
+ 17.1 Client Transaction .................................. 124
+ 17.1.1 INVITE Client Transaction ........................... 125
+ 17.1.1.1 Overview of INVITE Transaction ...................... 125
+ 17.1.1.2 Formal Description .................................. 125
+ 17.1.1.3 Construction of the ACK Request ..................... 129
+ 17.1.2 Non-INVITE Client Transaction ....................... 130
+ 17.1.2.1 Overview of the non-INVITE Transaction .............. 130
+ 17.1.2.2 Formal Description .................................. 131
+ 17.1.3 Matching Responses to Client Transactions ........... 132
+ 17.1.4 Handling Transport Errors ........................... 133
+ 17.2 Server Transaction .................................. 134
+ 17.2.1 INVITE Server Transaction ........................... 134
+ 17.2.2 Non-INVITE Server Transaction ....................... 137
+ 17.2.3 Matching Requests to Server Transactions ............ 138
+ 17.2.4 Handling Transport Errors ........................... 141
+ 18 Transport ........................................... 141
+ 18.1 Clients ............................................. 142
+ 18.1.1 Sending Requests .................................... 142
+ 18.1.2 Receiving Responses ................................. 144
+ 18.2 Servers ............................................. 145
+ 18.2.1 Receiving Requests .................................. 145
+
+
+
+Rosenberg, et. al. Standards Track [Page 4]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 18.2.2 Sending Responses ................................... 146
+ 18.3 Framing ............................................. 147
+ 18.4 Error Handling ...................................... 147
+ 19 Common Message Components ........................... 147
+ 19.1 SIP and SIPS Uniform Resource Indicators ............ 148
+ 19.1.1 SIP and SIPS URI Components ......................... 148
+ 19.1.2 Character Escaping Requirements ..................... 152
+ 19.1.3 Example SIP and SIPS URIs ........................... 153
+ 19.1.4 URI Comparison ...................................... 153
+ 19.1.5 Forming Requests from a URI ......................... 156
+ 19.1.6 Relating SIP URIs and tel URLs ...................... 157
+ 19.2 Option Tags ......................................... 158
+ 19.3 Tags ................................................ 159
+ 20 Header Fields ....................................... 159
+ 20.1 Accept .............................................. 161
+ 20.2 Accept-Encoding ..................................... 163
+ 20.3 Accept-Language ..................................... 164
+ 20.4 Alert-Info .......................................... 164
+ 20.5 Allow ............................................... 165
+ 20.6 Authentication-Info ................................. 165
+ 20.7 Authorization ....................................... 165
+ 20.8 Call-ID ............................................. 166
+ 20.9 Call-Info ........................................... 166
+ 20.10 Contact ............................................. 167
+ 20.11 Content-Disposition ................................. 168
+ 20.12 Content-Encoding .................................... 169
+ 20.13 Content-Language .................................... 169
+ 20.14 Content-Length ...................................... 169
+ 20.15 Content-Type ........................................ 170
+ 20.16 CSeq ................................................ 170
+ 20.17 Date ................................................ 170
+ 20.18 Error-Info .......................................... 171
+ 20.19 Expires ............................................. 171
+ 20.20 From ................................................ 172
+ 20.21 In-Reply-To ......................................... 172
+ 20.22 Max-Forwards ........................................ 173
+ 20.23 Min-Expires ......................................... 173
+ 20.24 MIME-Version ........................................ 173
+ 20.25 Organization ........................................ 174
+ 20.26 Priority ............................................ 174
+ 20.27 Proxy-Authenticate .................................. 174
+ 20.28 Proxy-Authorization ................................. 175
+ 20.29 Proxy-Require ....................................... 175
+ 20.30 Record-Route ........................................ 175
+ 20.31 Reply-To ............................................ 176
+ 20.32 Require ............................................. 176
+ 20.33 Retry-After ......................................... 176
+ 20.34 Route ............................................... 177
+
+
+
+Rosenberg, et. al. Standards Track [Page 5]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 20.35 Server .............................................. 177
+ 20.36 Subject ............................................. 177
+ 20.37 Supported ........................................... 178
+ 20.38 Timestamp ........................................... 178
+ 20.39 To .................................................. 178
+ 20.40 Unsupported ......................................... 179
+ 20.41 User-Agent .......................................... 179
+ 20.42 Via ................................................. 179
+ 20.43 Warning ............................................. 180
+ 20.44 WWW-Authenticate .................................... 182
+ 21 Response Codes ...................................... 182
+ 21.1 Provisional 1xx ..................................... 182
+ 21.1.1 100 Trying .......................................... 183
+ 21.1.2 180 Ringing ......................................... 183
+ 21.1.3 181 Call Is Being Forwarded ......................... 183
+ 21.1.4 182 Queued .......................................... 183
+ 21.1.5 183 Session Progress ................................ 183
+ 21.2 Successful 2xx ...................................... 183
+ 21.2.1 200 OK .............................................. 183
+ 21.3 Redirection 3xx ..................................... 184
+ 21.3.1 300 Multiple Choices ................................ 184
+ 21.3.2 301 Moved Permanently ............................... 184
+ 21.3.3 302 Moved Temporarily ............................... 184
+ 21.3.4 305 Use Proxy ....................................... 185
+ 21.3.5 380 Alternative Service ............................. 185
+ 21.4 Request Failure 4xx ................................. 185
+ 21.4.1 400 Bad Request ..................................... 185
+ 21.4.2 401 Unauthorized .................................... 185
+ 21.4.3 402 Payment Required ................................ 186
+ 21.4.4 403 Forbidden ....................................... 186
+ 21.4.5 404 Not Found ....................................... 186
+ 21.4.6 405 Method Not Allowed .............................. 186
+ 21.4.7 406 Not Acceptable .................................. 186
+ 21.4.8 407 Proxy Authentication Required ................... 186
+ 21.4.9 408 Request Timeout ................................. 186
+ 21.4.10 410 Gone ............................................ 187
+ 21.4.11 413 Request Entity Too Large ........................ 187
+ 21.4.12 414 Request-URI Too Long ............................ 187
+ 21.4.13 415 Unsupported Media Type .......................... 187
+ 21.4.14 416 Unsupported URI Scheme .......................... 187
+ 21.4.15 420 Bad Extension ................................... 187
+ 21.4.16 421 Extension Required .............................. 188
+ 21.4.17 423 Interval Too Brief .............................. 188
+ 21.4.18 480 Temporarily Unavailable ......................... 188
+ 21.4.19 481 Call/Transaction Does Not Exist ................. 188
+ 21.4.20 482 Loop Detected ................................... 188
+ 21.4.21 483 Too Many Hops ................................... 189
+ 21.4.22 484 Address Incomplete .............................. 189
+
+
+
+Rosenberg, et. al. Standards Track [Page 6]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 21.4.23 485 Ambiguous ....................................... 189
+ 21.4.24 486 Busy Here ....................................... 189
+ 21.4.25 487 Request Terminated .............................. 190
+ 21.4.26 488 Not Acceptable Here ............................. 190
+ 21.4.27 491 Request Pending ................................. 190
+ 21.4.28 493 Undecipherable .................................. 190
+ 21.5 Server Failure 5xx .................................. 190
+ 21.5.1 500 Server Internal Error ........................... 190
+ 21.5.2 501 Not Implemented ................................. 191
+ 21.5.3 502 Bad Gateway ..................................... 191
+ 21.5.4 503 Service Unavailable ............................. 191
+ 21.5.5 504 Server Time-out ................................. 191
+ 21.5.6 505 Version Not Supported ........................... 192
+ 21.5.7 513 Message Too Large ............................... 192
+ 21.6 Global Failures 6xx ................................. 192
+ 21.6.1 600 Busy Everywhere ................................. 192
+ 21.6.2 603 Decline ......................................... 192
+ 21.6.3 604 Does Not Exist Anywhere ......................... 192
+ 21.6.4 606 Not Acceptable .................................. 192
+ 22 Usage of HTTP Authentication ........................ 193
+ 22.1 Framework ........................................... 193
+ 22.2 User-to-User Authentication ......................... 195
+ 22.3 Proxy-to-User Authentication ........................ 197
+ 22.4 The Digest Authentication Scheme .................... 199
+ 23 S/MIME .............................................. 201
+ 23.1 S/MIME Certificates ................................. 201
+ 23.2 S/MIME Key Exchange ................................. 202
+ 23.3 Securing MIME bodies ................................ 205
+ 23.4 SIP Header Privacy and Integrity using S/MIME:
+ Tunneling SIP ....................................... 207
+ 23.4.1 Integrity and Confidentiality Properties of SIP
+ Headers ............................................. 207
+ 23.4.1.1 Integrity ........................................... 207
+ 23.4.1.2 Confidentiality ..................................... 208
+ 23.4.2 Tunneling Integrity and Authentication .............. 209
+ 23.4.3 Tunneling Encryption ................................ 211
+ 24 Examples ............................................ 213
+ 24.1 Registration ........................................ 213
+ 24.2 Session Setup ....................................... 214
+ 25 Augmented BNF for the SIP Protocol .................. 219
+ 25.1 Basic Rules ......................................... 219
+ 26 Security Considerations: Threat Model and Security
+ Usage Recommendations ............................... 232
+ 26.1 Attacks and Threat Models ........................... 233
+ 26.1.1 Registration Hijacking .............................. 233
+ 26.1.2 Impersonating a Server .............................. 234
+ 26.1.3 Tampering with Message Bodies ....................... 235
+ 26.1.4 Tearing Down Sessions ............................... 235
+
+
+
+Rosenberg, et. al. Standards Track [Page 7]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 26.1.5 Denial of Service and Amplification ................. 236
+ 26.2 Security Mechanisms ................................. 237
+ 26.2.1 Transport and Network Layer Security ................ 238
+ 26.2.2 SIPS URI Scheme ..................................... 239
+ 26.2.3 HTTP Authentication ................................. 240
+ 26.2.4 S/MIME .............................................. 240
+ 26.3 Implementing Security Mechanisms .................... 241
+ 26.3.1 Requirements for Implementers of SIP ................ 241
+ 26.3.2 Security Solutions .................................. 242
+ 26.3.2.1 Registration ........................................ 242
+ 26.3.2.2 Interdomain Requests ................................ 243
+ 26.3.2.3 Peer-to-Peer Requests ............................... 245
+ 26.3.2.4 DoS Protection ...................................... 246
+ 26.4 Limitations ......................................... 247
+ 26.4.1 HTTP Digest ......................................... 247
+ 26.4.2 S/MIME .............................................. 248
+ 26.4.3 TLS ................................................. 249
+ 26.4.4 SIPS URIs ........................................... 249
+ 26.5 Privacy ............................................. 251
+ 27 IANA Considerations ................................. 252
+ 27.1 Option Tags ......................................... 252
+ 27.2 Warn-Codes .......................................... 252
+ 27.3 Header Field Names .................................. 253
+ 27.4 Method and Response Codes ........................... 253
+ 27.5 The "message/sip" MIME type. ....................... 254
+ 27.6 New Content-Disposition Parameter Registrations ..... 255
+ 28 Changes From RFC 2543 ............................... 255
+ 28.1 Major Functional Changes ............................ 255
+ 28.2 Minor Functional Changes ............................ 260
+ 29 Normative References ................................ 261
+ 30 Informative References .............................. 262
+ A Table of Timer Values ............................... 265
+ Acknowledgments ................................................ 266
+ Authors' Addresses ............................................. 267
+ Full Copyright Statement ....................................... 269
+
+1 Introduction
+
+ There are many applications of the Internet that require the creation
+ and management of a session, where a session is considered an
+ exchange of data between an association of participants. The
+ implementation of these applications is complicated by the practices
+ of participants: users may move between endpoints, they may be
+ addressable by multiple names, and they may communicate in several
+ different media - sometimes simultaneously. Numerous protocols have
+ been authored that carry various forms of real-time multimedia
+ session data such as voice, video, or text messages. The Session
+ Initiation Protocol (SIP) works in concert with these protocols by
+
+
+
+Rosenberg, et. al. Standards Track [Page 8]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ enabling Internet endpoints (called user agents) to discover one
+ another and to agree on a characterization of a session they would
+ like to share. For locating prospective session participants, and
+ for other functions, SIP enables the creation of an infrastructure of
+ network hosts (called proxy servers) to which user agents can send
+ registrations, invitations to sessions, and other requests. SIP is
+ an agile, general-purpose tool for creating, modifying, and
+ terminating sessions that works independently of underlying transport
+ protocols and without dependency on the type of session that is being
+ established.
+
+2 Overview of SIP Functionality
+
+ SIP is an application-layer control protocol that can establish,
+ modify, and terminate multimedia sessions (conferences) such as
+ Internet telephony calls. SIP can also invite participants to
+ already existing sessions, such as multicast conferences. Media can
+ be added to (and removed from) an existing session. SIP
+ transparently supports name mapping and redirection services, which
+ supports personal mobility [27] - users can maintain a single
+ externally visible identifier regardless of their network location.
+
+ SIP supports five facets of establishing and terminating multimedia
+ communications:
+
+ User location: determination of the end system to be used for
+ communication;
+
+ User availability: determination of the willingness of the called
+ party to engage in communications;
+
+ User capabilities: determination of the media and media parameters
+ to be used;
+
+ Session setup: "ringing", establishment of session parameters at
+ both called and calling party;
+
+ Session management: including transfer and termination of
+ sessions, modifying session parameters, and invoking
+ services.
+
+ SIP is not a vertically integrated communications system. SIP is
+ rather a component that can be used with other IETF protocols to
+ build a complete multimedia architecture. Typically, these
+ architectures will include protocols such as the Real-time Transport
+ Protocol (RTP) (RFC 1889 [28]) for transporting real-time data and
+ providing QoS feedback, the Real-Time streaming protocol (RTSP) (RFC
+ 2326 [29]) for controlling delivery of streaming media, the Media
+
+
+
+Rosenberg, et. al. Standards Track [Page 9]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Gateway Control Protocol (MEGACO) (RFC 3015 [30]) for controlling
+ gateways to the Public Switched Telephone Network (PSTN), and the
+ Session Description Protocol (SDP) (RFC 2327 [1]) for describing
+ multimedia sessions. Therefore, SIP should be used in conjunction
+ with other protocols in order to provide complete services to the
+ users. However, the basic functionality and operation of SIP does
+ not depend on any of these protocols.
+
+ SIP does not provide services. Rather, SIP provides primitives that
+ can be used to implement different services. For example, SIP can
+ locate a user and deliver an opaque object to his current location.
+ If this primitive is used to deliver a session description written in
+ SDP, for instance, the endpoints can agree on the parameters of a
+ session. If the same primitive is used to deliver a photo of the
+ caller as well as the session description, a "caller ID" service can
+ be easily implemented. As this example shows, a single primitive is
+ typically used to provide several different services.
+
+ SIP does not offer conference control services such as floor control
+ or voting and does not prescribe how a conference is to be managed.
+ SIP can be used to initiate a session that uses some other conference
+ control protocol. Since SIP messages and the sessions they establish
+ can pass through entirely different networks, SIP cannot, and does
+ not, provide any kind of network resource reservation capabilities.
+
+ The nature of the services provided make security particularly
+ important. To that end, SIP provides a suite of security services,
+ which include denial-of-service prevention, authentication (both user
+ to user and proxy to user), integrity protection, and encryption and
+ privacy services.
+
+ SIP works with both IPv4 and IPv6.
+
+3 Terminology
+
+ In this document, the key words "MUST", "MUST NOT", "REQUIRED",
+ "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
+ RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as
+ described in BCP 14, RFC 2119 [2] and indicate requirement levels for
+ compliant SIP implementations.
+
+4 Overview of Operation
+
+ This section introduces the basic operations of SIP using simple
+ examples. This section is tutorial in nature and does not contain
+ any normative statements.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 10]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The first example shows the basic functions of SIP: location of an
+ end point, signal of a desire to communicate, negotiation of session
+ parameters to establish the session, and teardown of the session once
+ established.
+
+ Figure 1 shows a typical example of a SIP message exchange between
+ two users, Alice and Bob. (Each message is labeled with the letter
+ "F" and a number for reference by the text.) In this example, Alice
+ uses a SIP application on her PC (referred to as a softphone) to call
+ Bob on his SIP phone over the Internet. Also shown are two SIP proxy
+ servers that act on behalf of Alice and Bob to facilitate the session
+ establishment. This typical arrangement is often referred to as the
+ "SIP trapezoid" as shown by the geometric shape of the dotted lines
+ in Figure 1.
+
+ Alice "calls" Bob using his SIP identity, a type of Uniform Resource
+ Identifier (URI) called a SIP URI. SIP URIs are defined in Section
+ 19.1. It has a similar form to an email address, typically
+ containing a username and a host name. In this case, it is
+ sip:bob@biloxi.com, where biloxi.com is the domain of Bob's SIP
+ service provider. Alice has a SIP URI of sip:alice@atlanta.com.
+ Alice might have typed in Bob's URI or perhaps clicked on a hyperlink
+ or an entry in an address book. SIP also provides a secure URI,
+ called a SIPS URI. An example would be sips:bob@biloxi.com. A call
+ made to a SIPS URI guarantees that secure, encrypted transport
+ (namely TLS) is used to carry all SIP messages from the caller to the
+ domain of the callee. From there, the request is sent securely to
+ the callee, but with security mechanisms that depend on the policy of
+ the domain of the callee.
+
+ SIP is based on an HTTP-like request/response transaction model.
+ Each transaction consists of a request that invokes a particular
+ method, or function, on the server and at least one response. In
+ this example, the transaction begins with Alice's softphone sending
+ an INVITE request addressed to Bob's SIP URI. INVITE is an example
+ of a SIP method that specifies the action that the requestor (Alice)
+ wants the server (Bob) to take. The INVITE request contains a number
+ of header fields. Header fields are named attributes that provide
+ additional information about a message. The ones present in an
+ INVITE include a unique identifier for the call, the destination
+ address, Alice's address, and information about the type of session
+ that Alice wishes to establish with Bob. The INVITE (message F1 in
+ Figure 1) might look like this:
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 11]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ atlanta.com . . . biloxi.com
+ . proxy proxy .
+ . .
+ Alice's . . . . . . . . . . . . . . . . . . . . Bob's
+ softphone SIP Phone
+ | | | |
+ | INVITE F1 | | |
+ |--------------->| INVITE F2 | |
+ | 100 Trying F3 |--------------->| INVITE F4 |
+ |<---------------| 100 Trying F5 |--------------->|
+ | |<-------------- | 180 Ringing F6 |
+ | | 180 Ringing F7 |<---------------|
+ | 180 Ringing F8 |<---------------| 200 OK F9 |
+ |<---------------| 200 OK F10 |<---------------|
+ | 200 OK F11 |<---------------| |
+ |<---------------| | |
+ | ACK F12 |
+ |------------------------------------------------->|
+ | Media Session |
+ |<================================================>|
+ | BYE F13 |
+ |<-------------------------------------------------|
+ | 200 OK F14 |
+ |------------------------------------------------->|
+ | |
+
+ Figure 1: SIP session setup example with SIP trapezoid
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
+ Max-Forwards: 70
+ To: Bob <sip:bob@biloxi.com>
+ From: Alice <sip:alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710@pc33.atlanta.com
+ CSeq: 314159 INVITE
+ Contact: <sip:alice@pc33.atlanta.com>
+ Content-Type: application/sdp
+ Content-Length: 142
+
+ (Alice's SDP not shown)
+
+ The first line of the text-encoded message contains the method name
+ (INVITE). The lines that follow are a list of header fields. This
+ example contains a minimum required set. The header fields are
+ briefly described below:
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 12]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Via contains the address (pc33.atlanta.com) at which Alice is
+ expecting to receive responses to this request. It also contains a
+ branch parameter that identifies this transaction.
+
+ To contains a display name (Bob) and a SIP or SIPS URI
+ (sip:bob@biloxi.com) towards which the request was originally
+ directed. Display names are described in RFC 2822 [3].
+
+ From also contains a display name (Alice) and a SIP or SIPS URI
+ (sip:alice@atlanta.com) that indicate the originator of the request.
+ This header field also has a tag parameter containing a random string
+ (1928301774) that was added to the URI by the softphone. It is used
+ for identification purposes.
+
+ Call-ID contains a globally unique identifier for this call,
+ generated by the combination of a random string and the softphone's
+ host name or IP address. The combination of the To tag, From tag,
+ and Call-ID completely defines a peer-to-peer SIP relationship
+ between Alice and Bob and is referred to as a dialog.
+
+ CSeq or Command Sequence contains an integer and a method name. The
+ CSeq number is incremented for each new request within a dialog and
+ is a traditional sequence number.
+
+ Contact contains a SIP or SIPS URI that represents a direct route to
+ contact Alice, usually composed of a username at a fully qualified
+ domain name (FQDN). While an FQDN is preferred, many end systems do
+ not have registered domain names, so IP addresses are permitted.
+ While the Via header field tells other elements where to send the
+ response, the Contact header field tells other elements where to send
+ future requests.
+
+ Max-Forwards serves to limit the number of hops a request can make on
+ the way to its destination. It consists of an integer that is
+ decremented by one at each hop.
+
+ Content-Type contains a description of the message body (not shown).
+
+ Content-Length contains an octet (byte) count of the message body.
+
+ The complete set of SIP header fields is defined in Section 20.
+
+ The details of the session, such as the type of media, codec, or
+ sampling rate, are not described using SIP. Rather, the body of a
+ SIP message contains a description of the session, encoded in some
+ other protocol format. One such format is the Session Description
+ Protocol (SDP) (RFC 2327 [1]). This SDP message (not shown in the
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 13]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ example) is carried by the SIP message in a way that is analogous to
+ a document attachment being carried by an email message, or a web
+ page being carried in an HTTP message.
+
+ Since the softphone does not know the location of Bob or the SIP
+ server in the biloxi.com domain, the softphone sends the INVITE to
+ the SIP server that serves Alice's domain, atlanta.com. The address
+ of the atlanta.com SIP server could have been configured in Alice's
+ softphone, or it could have been discovered by DHCP, for example.
+
+ The atlanta.com SIP server is a type of SIP server known as a proxy
+ server. A proxy server receives SIP requests and forwards them on
+ behalf of the requestor. In this example, the proxy server receives
+ the INVITE request and sends a 100 (Trying) response back to Alice's
+ softphone. The 100 (Trying) response indicates that the INVITE has
+ been received and that the proxy is working on her behalf to route
+ the INVITE to the destination. Responses in SIP use a three-digit
+ code followed by a descriptive phrase. This response contains the
+ same To, From, Call-ID, CSeq and branch parameter in the Via as the
+ INVITE, which allows Alice's softphone to correlate this response to
+ the sent INVITE. The atlanta.com proxy server locates the proxy
+ server at biloxi.com, possibly by performing a particular type of DNS
+ (Domain Name Service) lookup to find the SIP server that serves the
+ biloxi.com domain. This is described in [4]. As a result, it
+ obtains the IP address of the biloxi.com proxy server and forwards,
+ or proxies, the INVITE request there. Before forwarding the request,
+ the atlanta.com proxy server adds an additional Via header field
+ value that contains its own address (the INVITE already contains
+ Alice's address in the first Via). The biloxi.com proxy server
+ receives the INVITE and responds with a 100 (Trying) response back to
+ the atlanta.com proxy server to indicate that it has received the
+ INVITE and is processing the request. The proxy server consults a
+ database, generically called a location service, that contains the
+ current IP address of Bob. (We shall see in the next section how
+ this database can be populated.) The biloxi.com proxy server adds
+ another Via header field value with its own address to the INVITE and
+ proxies it to Bob's SIP phone.
+
+ Bob's SIP phone receives the INVITE and alerts Bob to the incoming
+ call from Alice so that Bob can decide whether to answer the call,
+ that is, Bob's phone rings. Bob's SIP phone indicates this in a 180
+ (Ringing) response, which is routed back through the two proxies in
+ the reverse direction. Each proxy uses the Via header field to
+ determine where to send the response and removes its own address from
+ the top. As a result, although DNS and location service lookups were
+ required to route the initial INVITE, the 180 (Ringing) response can
+ be returned to the caller without lookups or without state being
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 14]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ maintained in the proxies. This also has the desirable property that
+ each proxy that sees the INVITE will also see all responses to the
+ INVITE.
+
+ When Alice's softphone receives the 180 (Ringing) response, it passes
+ this information to Alice, perhaps using an audio ringback tone or by
+ displaying a message on Alice's screen.
+
+ In this example, Bob decides to answer the call. When he picks up
+ the handset, his SIP phone sends a 200 (OK) response to indicate that
+ the call has been answered. The 200 (OK) contains a message body
+ with the SDP media description of the type of session that Bob is
+ willing to establish with Alice. As a result, there is a two-phase
+ exchange of SDP messages: Alice sent one to Bob, and Bob sent one
+ back to Alice. This two-phase exchange provides basic negotiation
+ capabilities and is based on a simple offer/answer model of SDP
+ exchange. If Bob did not wish to answer the call or was busy on
+ another call, an error response would have been sent instead of the
+ 200 (OK), which would have resulted in no media session being
+ established. The complete list of SIP response codes is in Section
+ 21. The 200 (OK) (message F9 in Figure 1) might look like this as
+ Bob sends it out:
+
+ SIP/2.0 200 OK
+ Via: SIP/2.0/UDP server10.biloxi.com
+ ;branch=z9hG4bKnashds8;received=192.0.2.3
+ Via: SIP/2.0/UDP bigbox3.site3.atlanta.com
+ ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
+ Via: SIP/2.0/UDP pc33.atlanta.com
+ ;branch=z9hG4bK776asdhds ;received=192.0.2.1
+ To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+ From: Alice <sip:alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710@pc33.atlanta.com
+ CSeq: 314159 INVITE
+ Contact: <sip:bob@192.0.2.4>
+ Content-Type: application/sdp
+ Content-Length: 131
+
+ (Bob's SDP not shown)
+
+ The first line of the response contains the response code (200) and
+ the reason phrase (OK). The remaining lines contain header fields.
+ The Via, To, From, Call-ID, and CSeq header fields are copied from
+ the INVITE request. (There are three Via header field values - one
+ added by Alice's SIP phone, one added by the atlanta.com proxy, and
+ one added by the biloxi.com proxy.) Bob's SIP phone has added a tag
+ parameter to the To header field. This tag will be incorporated by
+ both endpoints into the dialog and will be included in all future
+
+
+
+Rosenberg, et. al. Standards Track [Page 15]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ requests and responses in this call. The Contact header field
+ contains a URI at which Bob can be directly reached at his SIP phone.
+ The Content-Type and Content-Length refer to the message body (not
+ shown) that contains Bob's SDP media information.
+
+ In addition to DNS and location service lookups shown in this
+ example, proxy servers can make flexible "routing decisions" to
+ decide where to send a request. For example, if Bob's SIP phone
+ returned a 486 (Busy Here) response, the biloxi.com proxy server
+ could proxy the INVITE to Bob's voicemail server. A proxy server can
+ also send an INVITE to a number of locations at the same time. This
+ type of parallel search is known as forking.
+
+ In this case, the 200 (OK) is routed back through the two proxies and
+ is received by Alice's softphone, which then stops the ringback tone
+ and indicates that the call has been answered. Finally, Alice's
+ softphone sends an acknowledgement message, ACK, to Bob's SIP phone
+ to confirm the reception of the final response (200 (OK)). In this
+ example, the ACK is sent directly from Alice's softphone to Bob's SIP
+ phone, bypassing the two proxies. This occurs because the endpoints
+ have learned each other's address from the Contact header fields
+ through the INVITE/200 (OK) exchange, which was not known when the
+ initial INVITE was sent. The lookups performed by the two proxies
+ are no longer needed, so the proxies drop out of the call flow. This
+ completes the INVITE/200/ACK three-way handshake used to establish
+ SIP sessions. Full details on session setup are in Section 13.
+
+ Alice and Bob's media session has now begun, and they send media
+ packets using the format to which they agreed in the exchange of SDP.
+ In general, the end-to-end media packets take a different path from
+ the SIP signaling messages.
+
+ During the session, either Alice or Bob may decide to change the
+ characteristics of the media session. This is accomplished by
+ sending a re-INVITE containing a new media description. This re-
+ INVITE references the existing dialog so that the other party knows
+ that it is to modify an existing session instead of establishing a
+ new session. The other party sends a 200 (OK) to accept the change.
+ The requestor responds to the 200 (OK) with an ACK. If the other
+ party does not accept the change, he sends an error response such as
+ 488 (Not Acceptable Here), which also receives an ACK. However, the
+ failure of the re-INVITE does not cause the existing call to fail -
+ the session continues using the previously negotiated
+ characteristics. Full details on session modification are in Section
+ 14.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 16]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ At the end of the call, Bob disconnects (hangs up) first and
+ generates a BYE message. This BYE is routed directly to Alice's
+ softphone, again bypassing the proxies. Alice confirms receipt of
+ the BYE with a 200 (OK) response, which terminates the session and
+ the BYE transaction. No ACK is sent - an ACK is only sent in
+ response to a response to an INVITE request. The reasons for this
+ special handling for INVITE will be discussed later, but relate to
+ the reliability mechanisms in SIP, the length of time it can take for
+ a ringing phone to be answered, and forking. For this reason,
+ request handling in SIP is often classified as either INVITE or non-
+ INVITE, referring to all other methods besides INVITE. Full details
+ on session termination are in Section 15.
+
+ Section 24.2 describes the messages shown in Figure 1 in full.
+
+ In some cases, it may be useful for proxies in the SIP signaling path
+ to see all the messaging between the endpoints for the duration of
+ the session. For example, if the biloxi.com proxy server wished to
+ remain in the SIP messaging path beyond the initial INVITE, it would
+ add to the INVITE a required routing header field known as Record-
+ Route that contained a URI resolving to the hostname or IP address of
+ the proxy. This information would be received by both Bob's SIP
+ phone and (due to the Record-Route header field being passed back in
+ the 200 (OK)) Alice's softphone and stored for the duration of the
+ dialog. The biloxi.com proxy server would then receive and proxy the
+ ACK, BYE, and 200 (OK) to the BYE. Each proxy can independently
+ decide to receive subsequent messages, and those messages will pass
+ through all proxies that elect to receive it. This capability is
+ frequently used for proxies that are providing mid-call features.
+
+ Registration is another common operation in SIP. Registration is one
+ way that the biloxi.com server can learn the current location of Bob.
+ Upon initialization, and at periodic intervals, Bob's SIP phone sends
+ REGISTER messages to a server in the biloxi.com domain known as a SIP
+ registrar. The REGISTER messages associate Bob's SIP or SIPS URI
+ (sip:bob@biloxi.com) with the machine into which he is currently
+ logged (conveyed as a SIP or SIPS URI in the Contact header field).
+ The registrar writes this association, also called a binding, to a
+ database, called the location service, where it can be used by the
+ proxy in the biloxi.com domain. Often, a registrar server for a
+ domain is co-located with the proxy for that domain. It is an
+ important concept that the distinction between types of SIP servers
+ is logical, not physical.
+
+ Bob is not limited to registering from a single device. For example,
+ both his SIP phone at home and the one in the office could send
+ registrations. This information is stored together in the location
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 17]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ service and allows a proxy to perform various types of searches to
+ locate Bob. Similarly, more than one user can be registered on a
+ single device at the same time.
+
+ The location service is just an abstract concept. It generally
+ contains information that allows a proxy to input a URI and receive a
+ set of zero or more URIs that tell the proxy where to send the
+ request. Registrations are one way to create this information, but
+ not the only way. Arbitrary mapping functions can be configured at
+ the discretion of the administrator.
+
+ Finally, it is important to note that in SIP, registration is used
+ for routing incoming SIP requests and has no role in authorizing
+ outgoing requests. Authorization and authentication are handled in
+ SIP either on a request-by-request basis with a challenge/response
+ mechanism, or by using a lower layer scheme as discussed in Section
+ 26.
+
+ The complete set of SIP message details for this registration example
+ is in Section 24.1.
+
+ Additional operations in SIP, such as querying for the capabilities
+ of a SIP server or client using OPTIONS, or canceling a pending
+ request using CANCEL, will be introduced in later sections.
+
+5 Structure of the Protocol
+
+ SIP is structured as a layered protocol, which means that its
+ behavior is described in terms of a set of fairly independent
+ processing stages with only a loose coupling between each stage. The
+ protocol behavior is described as layers for the purpose of
+ presentation, allowing the description of functions common across
+ elements in a single section. It does not dictate an implementation
+ in any way. When we say that an element "contains" a layer, we mean
+ it is compliant to the set of rules defined by that layer.
+
+ Not every element specified by the protocol contains every layer.
+ Furthermore, the elements specified by SIP are logical elements, not
+ physical ones. A physical realization can choose to act as different
+ logical elements, perhaps even on a transaction-by-transaction basis.
+
+ The lowest layer of SIP is its syntax and encoding. Its encoding is
+ specified using an augmented Backus-Naur Form grammar (BNF). The
+ complete BNF is specified in Section 25; an overview of a SIP
+ message's structure can be found in Section 7.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 18]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The second layer is the transport layer. It defines how a client
+ sends requests and receives responses and how a server receives
+ requests and sends responses over the network. All SIP elements
+ contain a transport layer. The transport layer is described in
+ Section 18.
+
+ The third layer is the transaction layer. Transactions are a
+ fundamental component of SIP. A transaction is a request sent by a
+ client transaction (using the transport layer) to a server
+ transaction, along with all responses to that request sent from the
+ server transaction back to the client. The transaction layer handles
+ application-layer retransmissions, matching of responses to requests,
+ and application-layer timeouts. Any task that a user agent client
+ (UAC) accomplishes takes place using a series of transactions.
+ Discussion of transactions can be found in Section 17. User agents
+ contain a transaction layer, as do stateful proxies. Stateless
+ proxies do not contain a transaction layer. The transaction layer
+ has a client component (referred to as a client transaction) and a
+ server component (referred to as a server transaction), each of which
+ are represented by a finite state machine that is constructed to
+ process a particular request.
+
+ The layer above the transaction layer is called the transaction user
+ (TU). Each of the SIP entities, except the stateless proxy, is a
+ transaction user. When a TU wishes to send a request, it creates a
+ client transaction instance and passes it the request along with the
+ destination IP address, port, and transport to which to send the
+ request. A TU that creates a client transaction can also cancel it.
+ When a client cancels a transaction, it requests that the server stop
+ further processing, revert to the state that existed before the
+ transaction was initiated, and generate a specific error response to
+ that transaction. This is done with a CANCEL request, which
+ constitutes its own transaction, but references the transaction to be
+ cancelled (Section 9).
+
+ The SIP elements, that is, user agent clients and servers, stateless
+ and stateful proxies and registrars, contain a core that
+ distinguishes them from each other. Cores, except for the stateless
+ proxy, are transaction users. While the behavior of the UAC and UAS
+ cores depends on the method, there are some common rules for all
+ methods (Section 8). For a UAC, these rules govern the construction
+ of a request; for a UAS, they govern the processing of a request and
+ generating a response. Since registrations play an important role in
+ SIP, a UAS that handles a REGISTER is given the special name
+ registrar. Section 10 describes UAC and UAS core behavior for the
+ REGISTER method. Section 11 describes UAC and UAS core behavior for
+ the OPTIONS method, used for determining the capabilities of a UA.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 19]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Certain other requests are sent within a dialog. A dialog is a
+ peer-to-peer SIP relationship between two user agents that persists
+ for some time. The dialog facilitates sequencing of messages and
+ proper routing of requests between the user agents. The INVITE
+ method is the only way defined in this specification to establish a
+ dialog. When a UAC sends a request that is within the context of a
+ dialog, it follows the common UAC rules as discussed in Section 8 but
+ also the rules for mid-dialog requests. Section 12 discusses dialogs
+ and presents the procedures for their construction and maintenance,
+ in addition to construction of requests within a dialog.
+
+ The most important method in SIP is the INVITE method, which is used
+ to establish a session between participants. A session is a
+ collection of participants, and streams of media between them, for
+ the purposes of communication. Section 13 discusses how sessions are
+ initiated, resulting in one or more SIP dialogs. Section 14
+ discusses how characteristics of that session are modified through
+ the use of an INVITE request within a dialog. Finally, section 15
+ discusses how a session is terminated.
+
+ The procedures of Sections 8, 10, 11, 12, 13, 14, and 15 deal
+ entirely with the UA core (Section 9 describes cancellation, which
+ applies to both UA core and proxy core). Section 16 discusses the
+ proxy element, which facilitates routing of messages between user
+ agents.
+
+6 Definitions
+
+ The following terms have special significance for SIP.
+
+ Address-of-Record: An address-of-record (AOR) is a SIP or SIPS URI
+ that points to a domain with a location service that can map
+ the URI to another URI where the user might be available.
+ Typically, the location service is populated through
+ registrations. An AOR is frequently thought of as the "public
+ address" of the user.
+
+ Back-to-Back User Agent: A back-to-back user agent (B2BUA) is a
+ logical entity that receives a request and processes it as a
+ user agent server (UAS). In order to determine how the request
+ should be answered, it acts as a user agent client (UAC) and
+ generates requests. Unlike a proxy server, it maintains dialog
+ state and must participate in all requests sent on the dialogs
+ it has established. Since it is a concatenation of a UAC and
+ UAS, no explicit definitions are needed for its behavior.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 20]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Call: A call is an informal term that refers to some communication
+ between peers, generally set up for the purposes of a
+ multimedia conversation.
+
+ Call Leg: Another name for a dialog [31]; no longer used in this
+ specification.
+
+ Call Stateful: A proxy is call stateful if it retains state for a
+ dialog from the initiating INVITE to the terminating BYE
+ request. A call stateful proxy is always transaction stateful,
+ but the converse is not necessarily true.
+
+ Client: A client is any network element that sends SIP requests
+ and receives SIP responses. Clients may or may not interact
+ directly with a human user. User agent clients and proxies are
+ clients.
+
+ Conference: A multimedia session (see below) that contains
+ multiple participants.
+
+ Core: Core designates the functions specific to a particular type
+ of SIP entity, i.e., specific to either a stateful or stateless
+ proxy, a user agent or registrar. All cores, except those for
+ the stateless proxy, are transaction users.
+
+ Dialog: A dialog is a peer-to-peer SIP relationship between two
+ UAs that persists for some time. A dialog is established by
+ SIP messages, such as a 2xx response to an INVITE request. A
+ dialog is identified by a call identifier, local tag, and a
+ remote tag. A dialog was formerly known as a call leg in RFC
+ 2543.
+
+ Downstream: A direction of message forwarding within a transaction
+ that refers to the direction that requests flow from the user
+ agent client to user agent server.
+
+ Final Response: A response that terminates a SIP transaction, as
+ opposed to a provisional response that does not. All 2xx, 3xx,
+ 4xx, 5xx and 6xx responses are final.
+
+ Header: A header is a component of a SIP message that conveys
+ information about the message. It is structured as a sequence
+ of header fields.
+
+ Header Field: A header field is a component of the SIP message
+ header. A header field can appear as one or more header field
+ rows. Header field rows consist of a header field name and zero
+ or more header field values. Multiple header field values on a
+
+
+
+Rosenberg, et. al. Standards Track [Page 21]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ given header field row are separated by commas. Some header
+ fields can only have a single header field value, and as a
+ result, always appear as a single header field row.
+
+ Header Field Value: A header field value is a single value; a
+ header field consists of zero or more header field values.
+
+ Home Domain: The domain providing service to a SIP user.
+ Typically, this is the domain present in the URI in the
+ address-of-record of a registration.
+
+ Informational Response: Same as a provisional response.
+
+ Initiator, Calling Party, Caller: The party initiating a session
+ (and dialog) with an INVITE request. A caller retains this
+ role from the time it sends the initial INVITE that established
+ a dialog until the termination of that dialog.
+
+ Invitation: An INVITE request.
+
+ Invitee, Invited User, Called Party, Callee: The party that
+ receives an INVITE request for the purpose of establishing a
+ new session. A callee retains this role from the time it
+ receives the INVITE until the termination of the dialog
+ established by that INVITE.
+
+ Location Service: A location service is used by a SIP redirect or
+ proxy server to obtain information about a callee's possible
+ location(s). It contains a list of bindings of address-of-
+ record keys to zero or more contact addresses. The bindings
+ can be created and removed in many ways; this specification
+ defines a REGISTER method that updates the bindings.
+
+ Loop: A request that arrives at a proxy, is forwarded, and later
+ arrives back at the same proxy. When it arrives the second
+ time, its Request-URI is identical to the first time, and other
+ header fields that affect proxy operation are unchanged, so
+ that the proxy would make the same processing decision on the
+ request it made the first time. Looped requests are errors,
+ and the procedures for detecting them and handling them are
+ described by the protocol.
+
+ Loose Routing: A proxy is said to be loose routing if it follows
+ the procedures defined in this specification for processing of
+ the Route header field. These procedures separate the
+ destination of the request (present in the Request-URI) from
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 22]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ the set of proxies that need to be visited along the way
+ (present in the Route header field). A proxy compliant to
+ these mechanisms is also known as a loose router.
+
+ Message: Data sent between SIP elements as part of the protocol.
+ SIP messages are either requests or responses.
+
+ Method: The method is the primary function that a request is meant
+ to invoke on a server. The method is carried in the request
+ message itself. Example methods are INVITE and BYE.
+
+ Outbound Proxy: A proxy that receives requests from a client, even
+ though it may not be the server resolved by the Request-URI.
+ Typically, a UA is manually configured with an outbound proxy,
+ or can learn about one through auto-configuration protocols.
+
+ Parallel Search: In a parallel search, a proxy issues several
+ requests to possible user locations upon receiving an incoming
+ request. Rather than issuing one request and then waiting for
+ the final response before issuing the next request as in a
+ sequential search, a parallel search issues requests without
+ waiting for the result of previous requests.
+
+ Provisional Response: A response used by the server to indicate
+ progress, but that does not terminate a SIP transaction. 1xx
+ responses are provisional, other responses are considered
+ final.
+
+ Proxy, Proxy Server: An intermediary entity that acts as both a
+ server and a client for the purpose of making requests on
+ behalf of other clients. A proxy server primarily plays the
+ role of routing, which means its job is to ensure that a
+ request is sent to another entity "closer" to the targeted
+ user. Proxies are also useful for enforcing policy (for
+ example, making sure a user is allowed to make a call). A
+ proxy interprets, and, if necessary, rewrites specific parts of
+ a request message before forwarding it.
+
+ Recursion: A client recurses on a 3xx response when it generates a
+ new request to one or more of the URIs in the Contact header
+ field in the response.
+
+ Redirect Server: A redirect server is a user agent server that
+ generates 3xx responses to requests it receives, directing the
+ client to contact an alternate set of URIs.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 23]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Registrar: A registrar is a server that accepts REGISTER requests
+ and places the information it receives in those requests into
+ the location service for the domain it handles.
+
+ Regular Transaction: A regular transaction is any transaction with
+ a method other than INVITE, ACK, or CANCEL.
+
+ Request: A SIP message sent from a client to a server, for the
+ purpose of invoking a particular operation.
+
+ Response: A SIP message sent from a server to a client, for
+ indicating the status of a request sent from the client to the
+ server.
+
+ Ringback: Ringback is the signaling tone produced by the calling
+ party's application indicating that a called party is being
+ alerted (ringing).
+
+ Route Set: A route set is a collection of ordered SIP or SIPS URI
+ which represent a list of proxies that must be traversed when
+ sending a particular request. A route set can be learned,
+ through headers like Record-Route, or it can be configured.
+
+ Server: A server is a network element that receives requests in
+ order to service them and sends back responses to those
+ requests. Examples of servers are proxies, user agent servers,
+ redirect servers, and registrars.
+
+ Sequential Search: In a sequential search, a proxy server attempts
+ each contact address in sequence, proceeding to the next one
+ only after the previous has generated a final response. A 2xx
+ or 6xx class final response always terminates a sequential
+ search.
+
+ Session: From the SDP specification: "A multimedia session is a
+ set of multimedia senders and receivers and the data streams
+ flowing from senders to receivers. A multimedia conference is
+ an example of a multimedia session." (RFC 2327 [1]) (A session
+ as defined for SDP can comprise one or more RTP sessions.) As
+ defined, a callee can be invited several times, by different
+ calls, to the same session. If SDP is used, a session is
+ defined by the concatenation of the SDP user name, session id,
+ network type, address type, and address elements in the origin
+ field.
+
+ SIP Transaction: A SIP transaction occurs between a client and a
+ server and comprises all messages from the first request sent
+ from the client to the server up to a final (non-1xx) response
+
+
+
+Rosenberg, et. al. Standards Track [Page 24]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ sent from the server to the client. If the request is INVITE
+ and the final response is a non-2xx, the transaction also
+ includes an ACK to the response. The ACK for a 2xx response to
+ an INVITE request is a separate transaction.
+
+ Spiral: A spiral is a SIP request that is routed to a proxy,
+ forwarded onwards, and arrives once again at that proxy, but
+ this time differs in a way that will result in a different
+ processing decision than the original request. Typically, this
+ means that the request's Request-URI differs from its previous
+ arrival. A spiral is not an error condition, unlike a loop. A
+ typical cause for this is call forwarding. A user calls
+ joe@example.com. The example.com proxy forwards it to Joe's
+ PC, which in turn, forwards it to bob@example.com. This
+ request is proxied back to the example.com proxy. However,
+ this is not a loop. Since the request is targeted at a
+ different user, it is considered a spiral, and is a valid
+ condition.
+
+ Stateful Proxy: A logical entity that maintains the client and
+ server transaction state machines defined by this specification
+ during the processing of a request, also known as a transaction
+ stateful proxy. The behavior of a stateful proxy is further
+ defined in Section 16. A (transaction) stateful proxy is not
+ the same as a call stateful proxy.
+
+ Stateless Proxy: A logical entity that does not maintain the
+ client or server transaction state machines defined in this
+ specification when it processes requests. A stateless proxy
+ forwards every request it receives downstream and every
+ response it receives upstream.
+
+ Strict Routing: A proxy is said to be strict routing if it follows
+ the Route processing rules of RFC 2543 and many prior work in
+ progress versions of this RFC. That rule caused proxies to
+ destroy the contents of the Request-URI when a Route header
+ field was present. Strict routing behavior is not used in this
+ specification, in favor of a loose routing behavior. Proxies
+ that perform strict routing are also known as strict routers.
+
+ Target Refresh Request: A target refresh request sent within a
+ dialog is defined as a request that can modify the remote
+ target of the dialog.
+
+ Transaction User (TU): The layer of protocol processing that
+ resides above the transaction layer. Transaction users include
+ the UAC core, UAS core, and proxy core.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 25]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Upstream: A direction of message forwarding within a transaction
+ that refers to the direction that responses flow from the user
+ agent server back to the user agent client.
+
+ URL-encoded: A character string encoded according to RFC 2396,
+ Section 2.4 [5].
+
+ User Agent Client (UAC): A user agent client is a logical entity
+ that creates a new request, and then uses the client
+ transaction state machinery to send it. The role of UAC lasts
+ only for the duration of that transaction. In other words, if
+ a piece of software initiates a request, it acts as a UAC for
+ the duration of that transaction. If it receives a request
+ later, it assumes the role of a user agent server for the
+ processing of that transaction.
+
+ UAC Core: The set of processing functions required of a UAC that
+ reside above the transaction and transport layers.
+
+ User Agent Server (UAS): A user agent server is a logical entity
+ that generates a response to a SIP request. The response
+ accepts, rejects, or redirects the request. This role lasts
+ only for the duration of that transaction. In other words, if
+ a piece of software responds to a request, it acts as a UAS for
+ the duration of that transaction. If it generates a request
+ later, it assumes the role of a user agent client for the
+ processing of that transaction.
+
+ UAS Core: The set of processing functions required at a UAS that
+ resides above the transaction and transport layers.
+
+ User Agent (UA): A logical entity that can act as both a user
+ agent client and user agent server.
+
+ The role of UAC and UAS, as well as proxy and redirect servers, are
+ defined on a transaction-by-transaction basis. For example, the user
+ agent initiating a call acts as a UAC when sending the initial INVITE
+ request and as a UAS when receiving a BYE request from the callee.
+ Similarly, the same software can act as a proxy server for one
+ request and as a redirect server for the next request.
+
+ Proxy, location, and registrar servers defined above are logical
+ entities; implementations MAY combine them into a single application.
+
+7 SIP Messages
+
+ SIP is a text-based protocol and uses the UTF-8 charset (RFC 2279
+ [7]).
+
+
+
+Rosenberg, et. al. Standards Track [Page 26]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ A SIP message is either a request from a client to a server, or a
+ response from a server to a client.
+
+ Both Request (section 7.1) and Response (section 7.2) messages use
+ the basic format of RFC 2822 [3], even though the syntax differs in
+ character set and syntax specifics. (SIP allows header fields that
+ would not be valid RFC 2822 header fields, for example.) Both types
+ of messages consist of a start-line, one or more header fields, an
+ empty line indicating the end of the header fields, and an optional
+ message-body.
+
+ generic-message = start-line
+ *message-header
+ CRLF
+ [ message-body ]
+ start-line = Request-Line / Status-Line
+
+ The start-line, each message-header line, and the empty line MUST be
+ terminated by a carriage-return line-feed sequence (CRLF). Note that
+ the empty line MUST be present even if the message-body is not.
+
+ Except for the above difference in character sets, much of SIP's
+ message and header field syntax is identical to HTTP/1.1. Rather
+ than repeating the syntax and semantics here, we use [HX.Y] to refer
+ to Section X.Y of the current HTTP/1.1 specification (RFC 2616 [8]).
+
+ However, SIP is not an extension of HTTP.
+
+7.1 Requests
+
+ SIP requests are distinguished by having a Request-Line for a start-
+ line. A Request-Line contains a method name, a Request-URI, and the
+ protocol version separated by a single space (SP) character.
+
+ The Request-Line ends with CRLF. No CR or LF are allowed except in
+ the end-of-line CRLF sequence. No linear whitespace (LWS) is allowed
+ in any of the elements.
+
+ Request-Line = Method SP Request-URI SP SIP-Version CRLF
+
+ Method: This specification defines six methods: REGISTER for
+ registering contact information, INVITE, ACK, and CANCEL for
+ setting up sessions, BYE for terminating sessions, and
+ OPTIONS for querying servers about their capabilities. SIP
+ extensions, documented in standards track RFCs, may define
+ additional methods.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 27]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Request-URI: The Request-URI is a SIP or SIPS URI as described in
+ Section 19.1 or a general URI (RFC 2396 [5]). It indicates
+ the user or service to which this request is being addressed.
+ The Request-URI MUST NOT contain unescaped spaces or control
+ characters and MUST NOT be enclosed in "<>".
+
+ SIP elements MAY support Request-URIs with schemes other than
+ "sip" and "sips", for example the "tel" URI scheme of RFC
+ 2806 [9]. SIP elements MAY translate non-SIP URIs using any
+ mechanism at their disposal, resulting in SIP URI, SIPS URI,
+ or some other scheme.
+
+ SIP-Version: Both request and response messages include the
+ version of SIP in use, and follow [H3.1] (with HTTP replaced
+ by SIP, and HTTP/1.1 replaced by SIP/2.0) regarding version
+ ordering, compliance requirements, and upgrading of version
+ numbers. To be compliant with this specification,
+ applications sending SIP messages MUST include a SIP-Version
+ of "SIP/2.0". The SIP-Version string is case-insensitive,
+ but implementations MUST send upper-case.
+
+ Unlike HTTP/1.1, SIP treats the version number as a literal
+ string. In practice, this should make no difference.
+
+7.2 Responses
+
+ SIP responses are distinguished from requests by having a Status-Line
+ as their start-line. A Status-Line consists of the protocol version
+ followed by a numeric Status-Code and its associated textual phrase,
+ with each element separated by a single SP character.
+
+ No CR or LF is allowed except in the final CRLF sequence.
+
+ Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
+
+ The Status-Code is a 3-digit integer result code that indicates the
+ outcome of an attempt to understand and satisfy a request. The
+ Reason-Phrase is intended to give a short textual description of the
+ Status-Code. The Status-Code is intended for use by automata,
+ whereas the Reason-Phrase is intended for the human user. A client
+ is not required to examine or display the Reason-Phrase.
+
+ While this specification suggests specific wording for the reason
+ phrase, implementations MAY choose other text, for example, in the
+ language indicated in the Accept-Language header field of the
+ request.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 28]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The first digit of the Status-Code defines the class of response.
+ The last two digits do not have any categorization role. For this
+ reason, any response with a status code between 100 and 199 is
+ referred to as a "1xx response", any response with a status code
+ between 200 and 299 as a "2xx response", and so on. SIP/2.0 allows
+ six values for the first digit:
+
+ 1xx: Provisional -- request received, continuing to process the
+ request;
+
+ 2xx: Success -- the action was successfully received, understood,
+ and accepted;
+
+ 3xx: Redirection -- further action needs to be taken in order to
+ complete the request;
+
+ 4xx: Client Error -- the request contains bad syntax or cannot be
+ fulfilled at this server;
+
+ 5xx: Server Error -- the server failed to fulfill an apparently
+ valid request;
+
+ 6xx: Global Failure -- the request cannot be fulfilled at any
+ server.
+
+ Section 21 defines these classes and describes the individual codes.
+
+7.3 Header Fields
+
+ SIP header fields are similar to HTTP header fields in both syntax
+ and semantics. In particular, SIP header fields follow the [H4.2]
+ definitions of syntax for the message-header and the rules for
+ extending header fields over multiple lines. However, the latter is
+ specified in HTTP with implicit whitespace and folding. This
+ specification conforms to RFC 2234 [10] and uses only explicit
+ whitespace and folding as an integral part of the grammar.
+
+ [H4.2] also specifies that multiple header fields of the same field
+ name whose value is a comma-separated list can be combined into one
+ header field. That applies to SIP as well, but the specific rule is
+ different because of the different grammars. Specifically, any SIP
+ header whose grammar is of the form
+
+ header = "header-name" HCOLON header-value *(COMMA header-value)
+
+ allows for combining header fields of the same name into a comma-
+ separated list. The Contact header field allows a comma-separated
+ list unless the header field value is "*".
+
+
+
+Rosenberg, et. al. Standards Track [Page 29]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+7.3.1 Header Field Format
+
+ Header fields follow the same generic header format as that given in
+ Section 2.2 of RFC 2822 [3]. Each header field consists of a field
+ name followed by a colon (":") and the field value.
+
+ field-name: field-value
+
+ The formal grammar for a message-header specified in Section 25
+ allows for an arbitrary amount of whitespace on either side of the
+ colon; however, implementations should avoid spaces between the field
+ name and the colon and use a single space (SP) between the colon and
+ the field-value.
+
+ Subject: lunch
+ Subject : lunch
+ Subject :lunch
+ Subject: lunch
+
+ Thus, the above are all valid and equivalent, but the last is the
+ preferred form.
+
+ Header fields can be extended over multiple lines by preceding each
+ extra line with at least one SP or horizontal tab (HT). The line
+ break and the whitespace at the beginning of the next line are
+ treated as a single SP character. Thus, the following are
+ equivalent:
+
+ Subject: I know you're there, pick up the phone and talk to me!
+ Subject: I know you're there,
+ pick up the phone
+ and talk to me!
+
+ The relative order of header fields with different field names is not
+ significant. However, it is RECOMMENDED that header fields which are
+ needed for proxy processing (Via, Route, Record-Route, Proxy-Require,
+ Max-Forwards, and Proxy-Authorization, for example) appear towards
+ the top of the message to facilitate rapid parsing. The relative
+ order of header field rows with the same field name is important.
+ Multiple header field rows with the same field-name MAY be present in
+ a message if and only if the entire field-value for that header field
+ is defined as a comma-separated list (that is, if follows the grammar
+ defined in Section 7.3). It MUST be possible to combine the multiple
+ header field rows into one "field-name: field-value" pair, without
+ changing the semantics of the message, by appending each subsequent
+ field-value to the first, each separated by a comma. The exceptions
+ to this rule are the WWW-Authenticate, Authorization, Proxy-
+ Authenticate, and Proxy-Authorization header fields. Multiple header
+
+
+
+Rosenberg, et. al. Standards Track [Page 30]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ field rows with these names MAY be present in a message, but since
+ their grammar does not follow the general form listed in Section 7.3,
+ they MUST NOT be combined into a single header field row.
+
+ Implementations MUST be able to process multiple header field rows
+ with the same name in any combination of the single-value-per-line or
+ comma-separated value forms.
+
+ The following groups of header field rows are valid and equivalent:
+
+ Route: <sip:alice@atlanta.com>
+ Subject: Lunch
+ Route: <sip:bob@biloxi.com>
+ Route: <sip:carol@chicago.com>
+
+ Route: <sip:alice@atlanta.com>, <sip:bob@biloxi.com>
+ Route: <sip:carol@chicago.com>
+ Subject: Lunch
+
+ Subject: Lunch
+ Route: <sip:alice@atlanta.com>, <sip:bob@biloxi.com>,
+ <sip:carol@chicago.com>
+
+ Each of the following blocks is valid but not equivalent to the
+ others:
+
+ Route: <sip:alice@atlanta.com>
+ Route: <sip:bob@biloxi.com>
+ Route: <sip:carol@chicago.com>
+
+ Route: <sip:bob@biloxi.com>
+ Route: <sip:alice@atlanta.com>
+ Route: <sip:carol@chicago.com>
+
+ Route: <sip:alice@atlanta.com>,<sip:carol@chicago.com>,
+ <sip:bob@biloxi.com>
+
+ The format of a header field-value is defined per header-name. It
+ will always be either an opaque sequence of TEXT-UTF8 octets, or a
+ combination of whitespace, tokens, separators, and quoted strings.
+ Many existing header fields will adhere to the general form of a
+ value followed by a semi-colon separated sequence of parameter-name,
+ parameter-value pairs:
+
+ field-name: field-value *(;parameter-name=parameter-value)
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 31]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Even though an arbitrary number of parameter pairs may be attached to
+ a header field value, any given parameter-name MUST NOT appear more
+ than once.
+
+ When comparing header fields, field names are always case-
+ insensitive. Unless otherwise stated in the definition of a
+ particular header field, field values, parameter names, and parameter
+ values are case-insensitive. Tokens are always case-insensitive.
+ Unless specified otherwise, values expressed as quoted strings are
+ case-sensitive. For example,
+
+ Contact: <sip:alice@atlanta.com>;expires=3600
+
+ is equivalent to
+
+ CONTACT: <sip:alice@atlanta.com>;ExPiReS=3600
+
+ and
+
+ Content-Disposition: session;handling=optional
+
+ is equivalent to
+
+ content-disposition: Session;HANDLING=OPTIONAL
+
+ The following two header fields are not equivalent:
+
+ Warning: 370 devnull "Choose a bigger pipe"
+ Warning: 370 devnull "CHOOSE A BIGGER PIPE"
+
+7.3.2 Header Field Classification
+
+ Some header fields only make sense in requests or responses. These
+ are called request header fields and response header fields,
+ respectively. If a header field appears in a message not matching
+ its category (such as a request header field in a response), it MUST
+ be ignored. Section 20 defines the classification of each header
+ field.
+
+7.3.3 Compact Form
+
+ SIP provides a mechanism to represent common header field names in an
+ abbreviated form. This may be useful when messages would otherwise
+ become too large to be carried on the transport available to it
+ (exceeding the maximum transmission unit (MTU) when using UDP, for
+ example). These compact forms are defined in Section 20. A compact
+ form MAY be substituted for the longer form of a header field name at
+ any time without changing the semantics of the message. A header
+
+
+
+Rosenberg, et. al. Standards Track [Page 32]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ field name MAY appear in both long and short forms within the same
+ message. Implementations MUST accept both the long and short forms
+ of each header name.
+
+7.4 Bodies
+
+ Requests, including new requests defined in extensions to this
+ specification, MAY contain message bodies unless otherwise noted.
+ The interpretation of the body depends on the request method.
+
+ For response messages, the request method and the response status
+ code determine the type and interpretation of any message body. All
+ responses MAY include a body.
+
+7.4.1 Message Body Type
+
+ The Internet media type of the message body MUST be given by the
+ Content-Type header field. If the body has undergone any encoding
+ such as compression, then this MUST be indicated by the Content-
+ Encoding header field; otherwise, Content-Encoding MUST be omitted.
+ If applicable, the character set of the message body is indicated as
+ part of the Content-Type header-field value.
+
+ The "multipart" MIME type defined in RFC 2046 [11] MAY be used within
+ the body of the message. Implementations that send requests
+ containing multipart message bodies MUST send a session description
+ as a non-multipart message body if the remote implementation requests
+ this through an Accept header field that does not contain multipart.
+
+ SIP messages MAY contain binary bodies or body parts. When no
+ explicit charset parameter is provided by the sender, media subtypes
+ of the "text" type are defined to have a default charset value of
+ "UTF-8".
+
+7.4.2 Message Body Length
+
+ The body length in bytes is provided by the Content-Length header
+ field. Section 20.14 describes the necessary contents of this header
+ field in detail.
+
+ The "chunked" transfer encoding of HTTP/1.1 MUST NOT be used for SIP.
+ (Note: The chunked encoding modifies the body of a message in order
+ to transfer it as a series of chunks, each with its own size
+ indicator.)
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 33]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+7.5 Framing SIP Messages
+
+ Unlike HTTP, SIP implementations can use UDP or other unreliable
+ datagram protocols. Each such datagram carries one request or
+ response. See Section 18 on constraints on usage of unreliable
+ transports.
+
+ Implementations processing SIP messages over stream-oriented
+ transports MUST ignore any CRLF appearing before the start-line
+ [H4.1].
+
+ The Content-Length header field value is used to locate the end of
+ each SIP message in a stream. It will always be present when SIP
+ messages are sent over stream-oriented transports.
+
+8 General User Agent Behavior
+
+ A user agent represents an end system. It contains a user agent
+ client (UAC), which generates requests, and a user agent server
+ (UAS), which responds to them. A UAC is capable of generating a
+ request based on some external stimulus (the user clicking a button,
+ or a signal on a PSTN line) and processing a response. A UAS is
+ capable of receiving a request and generating a response based on
+ user input, external stimulus, the result of a program execution, or
+ some other mechanism.
+
+ When a UAC sends a request, the request passes through some number of
+ proxy servers, which forward the request towards the UAS. When the
+ UAS generates a response, the response is forwarded towards the UAC.
+
+ UAC and UAS procedures depend strongly on two factors. First, based
+ on whether the request or response is inside or outside of a dialog,
+ and second, based on the method of a request. Dialogs are discussed
+ thoroughly in Section 12; they represent a peer-to-peer relationship
+ between user agents and are established by specific SIP methods, such
+ as INVITE.
+
+ In this section, we discuss the method-independent rules for UAC and
+ UAS behavior when processing requests that are outside of a dialog.
+ This includes, of course, the requests which themselves establish a
+ dialog.
+
+ Security procedures for requests and responses outside of a dialog
+ are described in Section 26. Specifically, mechanisms exist for the
+ UAS and UAC to mutually authenticate. A limited set of privacy
+ features are also supported through encryption of bodies using
+ S/MIME.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 34]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+8.1 UAC Behavior
+
+ This section covers UAC behavior outside of a dialog.
+
+8.1.1 Generating the Request
+
+ A valid SIP request formulated by a UAC MUST, at a minimum, contain
+ the following header fields: To, From, CSeq, Call-ID, Max-Forwards,
+ and Via; all of these header fields are mandatory in all SIP
+ requests. These six header fields are the fundamental building
+ blocks of a SIP message, as they jointly provide for most of the
+ critical message routing services including the addressing of
+ messages, the routing of responses, limiting message propagation,
+ ordering of messages, and the unique identification of transactions.
+ These header fields are in addition to the mandatory request line,
+ which contains the method, Request-URI, and SIP version.
+
+ Examples of requests sent outside of a dialog include an INVITE to
+ establish a session (Section 13) and an OPTIONS to query for
+ capabilities (Section 11).
+
+8.1.1.1 Request-URI
+
+ The initial Request-URI of the message SHOULD be set to the value of
+ the URI in the To field. One notable exception is the REGISTER
+ method; behavior for setting the Request-URI of REGISTER is given in
+ Section 10. It may also be undesirable for privacy reasons or
+ convenience to set these fields to the same value (especially if the
+ originating UA expects that the Request-URI will be changed during
+ transit).
+
+ In some special circumstances, the presence of a pre-existing route
+ set can affect the Request-URI of the message. A pre-existing route
+ set is an ordered set of URIs that identify a chain of servers, to
+ which a UAC will send outgoing requests that are outside of a dialog.
+ Commonly, they are configured on the UA by a user or service provider
+ manually, or through some other non-SIP mechanism. When a provider
+ wishes to configure a UA with an outbound proxy, it is RECOMMENDED
+ that this be done by providing it with a pre-existing route set with
+ a single URI, that of the outbound proxy.
+
+ When a pre-existing route set is present, the procedures for
+ populating the Request-URI and Route header field detailed in Section
+ 12.2.1.1 MUST be followed (even though there is no dialog), using the
+ desired Request-URI as the remote target URI.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 35]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+8.1.1.2 To
+
+ The To header field first and foremost specifies the desired
+ "logical" recipient of the request, or the address-of-record of the
+ user or resource that is the target of this request. This may or may
+ not be the ultimate recipient of the request. The To header field
+ MAY contain a SIP or SIPS URI, but it may also make use of other URI
+ schemes (the tel URL (RFC 2806 [9]), for example) when appropriate.
+ All SIP implementations MUST support the SIP URI scheme. Any
+ implementation that supports TLS MUST support the SIPS URI scheme.
+ The To header field allows for a display name.
+
+ A UAC may learn how to populate the To header field for a particular
+ request in a number of ways. Usually the user will suggest the To
+ header field through a human interface, perhaps inputting the URI
+ manually or selecting it from some sort of address book. Frequently,
+ the user will not enter a complete URI, but rather a string of digits
+ or letters (for example, "bob"). It is at the discretion of the UA
+ to choose how to interpret this input. Using the string to form the
+ user part of a SIP URI implies that the UA wishes the name to be
+ resolved in the domain to the right-hand side (RHS) of the at-sign in
+ the SIP URI (for instance, sip:bob@example.com). Using the string to
+ form the user part of a SIPS URI implies that the UA wishes to
+ communicate securely, and that the name is to be resolved in the
+ domain to the RHS of the at-sign. The RHS will frequently be the
+ home domain of the requestor, which allows for the home domain to
+ process the outgoing request. This is useful for features like
+ "speed dial" that require interpretation of the user part in the home
+ domain. The tel URL may be used when the UA does not wish to specify
+ the domain that should interpret a telephone number that has been
+ input by the user. Rather, each domain through which the request
+ passes would be given that opportunity. As an example, a user in an
+ airport might log in and send requests through an outbound proxy in
+ the airport. If they enter "411" (this is the phone number for local
+ directory assistance in the United States), that needs to be
+ interpreted and processed by the outbound proxy in the airport, not
+ the user's home domain. In this case, tel:411 would be the right
+ choice.
+
+ A request outside of a dialog MUST NOT contain a To tag; the tag in
+ the To field of a request identifies the peer of the dialog. Since
+ no dialog is established, no tag is present.
+
+ For further information on the To header field, see Section 20.39.
+ The following is an example of a valid To header field:
+
+ To: Carol <sip:carol@chicago.com>
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 36]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+8.1.1.3 From
+
+ The From header field indicates the logical identity of the initiator
+ of the request, possibly the user's address-of-record. Like the To
+ header field, it contains a URI and optionally a display name. It is
+ used by SIP elements to determine which processing rules to apply to
+ a request (for example, automatic call rejection). As such, it is
+ very important that the From URI not contain IP addresses or the FQDN
+ of the host on which the UA is running, since these are not logical
+ names.
+
+ The From header field allows for a display name. A UAC SHOULD use
+ the display name "Anonymous", along with a syntactically correct, but
+ otherwise meaningless URI (like sip:thisis@anonymous.invalid), if the
+ identity of the client is to remain hidden.
+
+ Usually, the value that populates the From header field in requests
+ generated by a particular UA is pre-provisioned by the user or by the
+ administrators of the user's local domain. If a particular UA is
+ used by multiple users, it might have switchable profiles that
+ include a URI corresponding to the identity of the profiled user.
+ Recipients of requests can authenticate the originator of a request
+ in order to ascertain that they are who their From header field
+ claims they are (see Section 22 for more on authentication).
+
+ The From field MUST contain a new "tag" parameter, chosen by the UAC.
+ See Section 19.3 for details on choosing a tag.
+
+ For further information on the From header field, see Section 20.20.
+ Examples:
+
+ From: "Bob" <sips:bob@biloxi.com> ;tag=a48s
+ From: sip:+12125551212@phone2net.com;tag=887s
+ From: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8
+
+8.1.1.4 Call-ID
+
+ The Call-ID header field acts as a unique identifier to group
+ together a series of messages. It MUST be the same for all requests
+ and responses sent by either UA in a dialog. It SHOULD be the same
+ in each registration from a UA.
+
+ In a new request created by a UAC outside of any dialog, the Call-ID
+ header field MUST be selected by the UAC as a globally unique
+ identifier over space and time unless overridden by method-specific
+ behavior. All SIP UAs must have a means to guarantee that the Call-
+ ID header fields they produce will not be inadvertently generated by
+ any other UA. Note that when requests are retried after certain
+
+
+
+Rosenberg, et. al. Standards Track [Page 37]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ failure responses that solicit an amendment to a request (for
+ example, a challenge for authentication), these retried requests are
+ not considered new requests, and therefore do not need new Call-ID
+ header fields; see Section 8.1.3.5.
+
+ Use of cryptographically random identifiers (RFC 1750 [12]) in the
+ generation of Call-IDs is RECOMMENDED. Implementations MAY use the
+ form "localid@host". Call-IDs are case-sensitive and are simply
+ compared byte-by-byte.
+
+ Using cryptographically random identifiers provides some
+ protection against session hijacking and reduces the likelihood of
+ unintentional Call-ID collisions.
+
+ No provisioning or human interface is required for the selection of
+ the Call-ID header field value for a request.
+
+ For further information on the Call-ID header field, see Section
+ 20.8.
+
+ Example:
+
+ Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com
+
+8.1.1.5 CSeq
+
+ The CSeq header field serves as a way to identify and order
+ transactions. It consists of a sequence number and a method. The
+ method MUST match that of the request. For non-REGISTER requests
+ outside of a dialog, the sequence number value is arbitrary. The
+ sequence number value MUST be expressible as a 32-bit unsigned
+ integer and MUST be less than 2**31. As long as it follows the above
+ guidelines, a client may use any mechanism it would like to select
+ CSeq header field values.
+
+ Section 12.2.1.1 discusses construction of the CSeq for requests
+ within a dialog.
+
+ Example:
+
+ CSeq: 4711 INVITE
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 38]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+8.1.1.6 Max-Forwards
+
+ The Max-Forwards header field serves to limit the number of hops a
+ request can transit on the way to its destination. It consists of an
+ integer that is decremented by one at each hop. If the Max-Forwards
+ value reaches 0 before the request reaches its destination, it will
+ be rejected with a 483(Too Many Hops) error response.
+
+ A UAC MUST insert a Max-Forwards header field into each request it
+ originates with a value that SHOULD be 70. This number was chosen to
+ be sufficiently large to guarantee that a request would not be
+ dropped in any SIP network when there were no loops, but not so large
+ as to consume proxy resources when a loop does occur. Lower values
+ should be used with caution and only in networks where topologies are
+ known by the UA.
+
+8.1.1.7 Via
+
+ The Via header field indicates the transport used for the transaction
+ and identifies the location where the response is to be sent. A Via
+ header field value is added only after the transport that will be
+ used to reach the next hop has been selected (which may involve the
+ usage of the procedures in [4]).
+
+ When the UAC creates a request, it MUST insert a Via into that
+ request. The protocol name and protocol version in the header field
+ MUST be SIP and 2.0, respectively. The Via header field value MUST
+ contain a branch parameter. This parameter is used to identify the
+ transaction created by that request. This parameter is used by both
+ the client and the server.
+
+ The branch parameter value MUST be unique across space and time for
+ all requests sent by the UA. The exceptions to this rule are CANCEL
+ and ACK for non-2xx responses. As discussed below, a CANCEL request
+ will have the same value of the branch parameter as the request it
+ cancels. As discussed in Section 17.1.1.3, an ACK for a non-2xx
+ response will also have the same branch ID as the INVITE whose
+ response it acknowledges.
+
+ The uniqueness property of the branch ID parameter, to facilitate
+ its use as a transaction ID, was not part of RFC 2543.
+
+ The branch ID inserted by an element compliant with this
+ specification MUST always begin with the characters "z9hG4bK". These
+ 7 characters are used as a magic cookie (7 is deemed sufficient to
+ ensure that an older RFC 2543 implementation would not pick such a
+ value), so that servers receiving the request can determine that the
+ branch ID was constructed in the fashion described by this
+
+
+
+Rosenberg, et. al. Standards Track [Page 39]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ specification (that is, globally unique). Beyond this requirement,
+ the precise format of the branch token is implementation-defined.
+
+ The Via header maddr, ttl, and sent-by components will be set when
+ the request is processed by the transport layer (Section 18).
+
+ Via processing for proxies is described in Section 16.6 Item 8 and
+ Section 16.7 Item 3.
+
+8.1.1.8 Contact
+
+ The Contact header field provides a SIP or SIPS URI that can be used
+ to contact that specific instance of the UA for subsequent requests.
+ The Contact header field MUST be present and contain exactly one SIP
+ or SIPS URI in any request that can result in the establishment of a
+ dialog. For the methods defined in this specification, that includes
+ only the INVITE request. For these requests, the scope of the
+ Contact is global. That is, the Contact header field value contains
+ the URI at which the UA would like to receive requests, and this URI
+ MUST be valid even if used in subsequent requests outside of any
+ dialogs.
+
+ If the Request-URI or top Route header field value contains a SIPS
+ URI, the Contact header field MUST contain a SIPS URI as well.
+
+ For further information on the Contact header field, see Section
+ 20.10.
+
+8.1.1.9 Supported and Require
+
+ If the UAC supports extensions to SIP that can be applied by the
+ server to the response, the UAC SHOULD include a Supported header
+ field in the request listing the option tags (Section 19.2) for those
+ extensions.
+
+ The option tags listed MUST only refer to extensions defined in
+ standards-track RFCs. This is to prevent servers from insisting that
+ clients implement non-standard, vendor-defined features in order to
+ receive service. Extensions defined by experimental and
+ informational RFCs are explicitly excluded from usage with the
+ Supported header field in a request, since they too are often used to
+ document vendor-defined extensions.
+
+ If the UAC wishes to insist that a UAS understand an extension that
+ the UAC will apply to the request in order to process the request, it
+ MUST insert a Require header field into the request listing the
+ option tag for that extension. If the UAC wishes to apply an
+ extension to the request and insist that any proxies that are
+
+
+
+Rosenberg, et. al. Standards Track [Page 40]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ traversed understand that extension, it MUST insert a Proxy-Require
+ header field into the request listing the option tag for that
+ extension.
+
+ As with the Supported header field, the option tags in the Require
+ and Proxy-Require header fields MUST only refer to extensions defined
+ in standards-track RFCs.
+
+8.1.1.10 Additional Message Components
+
+ After a new request has been created, and the header fields described
+ above have been properly constructed, any additional optional header
+ fields are added, as are any header fields specific to the method.
+
+ SIP requests MAY contain a MIME-encoded message-body. Regardless of
+ the type of body that a request contains, certain header fields must
+ be formulated to characterize the contents of the body. For further
+ information on these header fields, see Sections 20.11 through 20.15.
+
+8.1.2 Sending the Request
+
+ The destination for the request is then computed. Unless there is
+ local policy specifying otherwise, the destination MUST be determined
+ by applying the DNS procedures described in [4] as follows. If the
+ first element in the route set indicated a strict router (resulting
+ in forming the request as described in Section 12.2.1.1), the
+ procedures MUST be applied to the Request-URI of the request.
+ Otherwise, the procedures are applied to the first Route header field
+ value in the request (if one exists), or to the request's Request-URI
+ if there is no Route header field present. These procedures yield an
+ ordered set of address, port, and transports to attempt. Independent
+ of which URI is used as input to the procedures of [4], if the
+ Request-URI specifies a SIPS resource, the UAC MUST follow the
+ procedures of [4] as if the input URI were a SIPS URI.
+
+ Local policy MAY specify an alternate set of destinations to attempt.
+ If the Request-URI contains a SIPS URI, any alternate destinations
+ MUST be contacted with TLS. Beyond that, there are no restrictions
+ on the alternate destinations if the request contains no Route header
+ field. This provides a simple alternative to a pre-existing route
+ set as a way to specify an outbound proxy. However, that approach
+ for configuring an outbound proxy is NOT RECOMMENDED; a pre-existing
+ route set with a single URI SHOULD be used instead. If the request
+ contains a Route header field, the request SHOULD be sent to the
+ locations derived from its topmost value, but MAY be sent to any
+ server that the UA is certain will honor the Route and Request-URI
+ policies specified in this document (as opposed to those in RFC
+ 2543). In particular, a UAC configured with an outbound proxy SHOULD
+
+
+
+Rosenberg, et. al. Standards Track [Page 41]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ attempt to send the request to the location indicated in the first
+ Route header field value instead of adopting the policy of sending
+ all messages to the outbound proxy.
+
+ This ensures that outbound proxies that do not add Record-Route
+ header field values will drop out of the path of subsequent
+ requests. It allows endpoints that cannot resolve the first Route
+ URI to delegate that task to an outbound proxy.
+
+ The UAC SHOULD follow the procedures defined in [4] for stateful
+ elements, trying each address until a server is contacted. Each try
+ constitutes a new transaction, and therefore each carries a different
+ topmost Via header field value with a new branch parameter.
+ Furthermore, the transport value in the Via header field is set to
+ whatever transport was determined for the target server.
+
+8.1.3 Processing Responses
+
+ Responses are first processed by the transport layer and then passed
+ up to the transaction layer. The transaction layer performs its
+ processing and then passes the response up to the TU. The majority
+ of response processing in the TU is method specific. However, there
+ are some general behaviors independent of the method.
+
+8.1.3.1 Transaction Layer Errors
+
+ In some cases, the response returned by the transaction layer will
+ not be a SIP message, but rather a transaction layer error. When a
+ timeout error is received from the transaction layer, it MUST be
+ treated as if a 408 (Request Timeout) status code has been received.
+ If a fatal transport error is reported by the transport layer
+ (generally, due to fatal ICMP errors in UDP or connection failures in
+ TCP), the condition MUST be treated as a 503 (Service Unavailable)
+ status code.
+
+8.1.3.2 Unrecognized Responses
+
+ A UAC MUST treat any final response it does not recognize as being
+ equivalent to the x00 response code of that class, and MUST be able
+ to process the x00 response code for all classes. For example, if a
+ UAC receives an unrecognized response code of 431, it can safely
+ assume that there was something wrong with its request and treat the
+ response as if it had received a 400 (Bad Request) response code. A
+ UAC MUST treat any provisional response different than 100 that it
+ does not recognize as 183 (Session Progress). A UAC MUST be able to
+ process 100 and 183 responses.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 42]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+8.1.3.3 Vias
+
+ If more than one Via header field value is present in a response, the
+ UAC SHOULD discard the message.
+
+ The presence of additional Via header field values that precede
+ the originator of the request suggests that the message was
+ misrouted or possibly corrupted.
+
+8.1.3.4 Processing 3xx Responses
+
+ Upon receipt of a redirection response (for example, a 301 response
+ status code), clients SHOULD use the URI(s) in the Contact header
+ field to formulate one or more new requests based on the redirected
+ request. This process is similar to that of a proxy recursing on a
+ 3xx class response as detailed in Sections 16.5 and 16.6. A client
+ starts with an initial target set containing exactly one URI, the
+ Request-URI of the original request. If a client wishes to formulate
+ new requests based on a 3xx class response to that request, it places
+ the URIs to try into the target set. Subject to the restrictions in
+ this specification, a client can choose which Contact URIs it places
+ into the target set. As with proxy recursion, a client processing
+ 3xx class responses MUST NOT add any given URI to the target set more
+ than once. If the original request had a SIPS URI in the Request-
+ URI, the client MAY choose to recurse to a non-SIPS URI, but SHOULD
+ inform the user of the redirection to an insecure URI.
+
+ Any new request may receive 3xx responses themselves containing
+ the original URI as a contact. Two locations can be configured to
+ redirect to each other. Placing any given URI in the target set
+ only once prevents infinite redirection loops.
+
+ As the target set grows, the client MAY generate new requests to the
+ URIs in any order. A common mechanism is to order the set by the "q"
+ parameter value from the Contact header field value. Requests to the
+ URIs MAY be generated serially or in parallel. One approach is to
+ process groups of decreasing q-values serially and process the URIs
+ in each q-value group in parallel. Another is to perform only serial
+ processing in decreasing q-value order, arbitrarily choosing between
+ contacts of equal q-value.
+
+ If contacting an address in the list results in a failure, as defined
+ in the next paragraph, the element moves to the next address in the
+ list, until the list is exhausted. If the list is exhausted, then
+ the request has failed.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 43]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Failures SHOULD be detected through failure response codes (codes
+ greater than 399); for network errors the client transaction will
+ report any transport layer failures to the transaction user. Note
+ that some response codes (detailed in 8.1.3.5) indicate that the
+ request can be retried; requests that are reattempted should not be
+ considered failures.
+
+ When a failure for a particular contact address is received, the
+ client SHOULD try the next contact address. This will involve
+ creating a new client transaction to deliver a new request.
+
+ In order to create a request based on a contact address in a 3xx
+ response, a UAC MUST copy the entire URI from the target set into the
+ Request-URI, except for the "method-param" and "header" URI
+ parameters (see Section 19.1.1 for a definition of these parameters).
+ It uses the "header" parameters to create header field values for the
+ new request, overwriting header field values associated with the
+ redirected request in accordance with the guidelines in Section
+ 19.1.5.
+
+ Note that in some instances, header fields that have been
+ communicated in the contact address may instead append to existing
+ request header fields in the original redirected request. As a
+ general rule, if the header field can accept a comma-separated list
+ of values, then the new header field value MAY be appended to any
+ existing values in the original redirected request. If the header
+ field does not accept multiple values, the value in the original
+ redirected request MAY be overwritten by the header field value
+ communicated in the contact address. For example, if a contact
+ address is returned with the following value:
+
+ sip:user@host?Subject=foo&Call-Info=<http://www.foo.com>
+
+ Then any Subject header field in the original redirected request is
+ overwritten, but the HTTP URL is merely appended to any existing
+ Call-Info header field values.
+
+ It is RECOMMENDED that the UAC reuse the same To, From, and Call-ID
+ used in the original redirected request, but the UAC MAY also choose
+ to update the Call-ID header field value for new requests, for
+ example.
+
+ Finally, once the new request has been constructed, it is sent using
+ a new client transaction, and therefore MUST have a new branch ID in
+ the top Via field as discussed in Section 8.1.1.7.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 44]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ In all other respects, requests sent upon receipt of a redirect
+ response SHOULD re-use the header fields and bodies of the original
+ request.
+
+ In some instances, Contact header field values may be cached at UAC
+ temporarily or permanently depending on the status code received and
+ the presence of an expiration interval; see Sections 21.3.2 and
+ 21.3.3.
+
+8.1.3.5 Processing 4xx Responses
+
+ Certain 4xx response codes require specific UA processing,
+ independent of the method.
+
+ If a 401 (Unauthorized) or 407 (Proxy Authentication Required)
+ response is received, the UAC SHOULD follow the authorization
+ procedures of Section 22.2 and Section 22.3 to retry the request with
+ credentials.
+
+ If a 413 (Request Entity Too Large) response is received (Section
+ 21.4.11), the request contained a body that was longer than the UAS
+ was willing to accept. If possible, the UAC SHOULD retry the
+ request, either omitting the body or using one of a smaller length.
+
+ If a 415 (Unsupported Media Type) response is received (Section
+ 21.4.13), the request contained media types not supported by the UAS.
+ The UAC SHOULD retry sending the request, this time only using
+ content with types listed in the Accept header field in the response,
+ with encodings listed in the Accept-Encoding header field in the
+ response, and with languages listed in the Accept-Language in the
+ response.
+
+ If a 416 (Unsupported URI Scheme) response is received (Section
+ 21.4.14), the Request-URI used a URI scheme not supported by the
+ server. The client SHOULD retry the request, this time, using a SIP
+ URI.
+
+ If a 420 (Bad Extension) response is received (Section 21.4.15), the
+ request contained a Require or Proxy-Require header field listing an
+ option-tag for a feature not supported by a proxy or UAS. The UAC
+ SHOULD retry the request, this time omitting any extensions listed in
+ the Unsupported header field in the response.
+
+ In all of the above cases, the request is retried by creating a new
+ request with the appropriate modifications. This new request
+ constitutes a new transaction and SHOULD have the same value of the
+ Call-ID, To, and From of the previous request, but the CSeq should
+ contain a new sequence number that is one higher than the previous.
+
+
+
+Rosenberg, et. al. Standards Track [Page 45]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ With other 4xx responses, including those yet to be defined, a retry
+ may or may not be possible depending on the method and the use case.
+
+8.2 UAS Behavior
+
+ When a request outside of a dialog is processed by a UAS, there is a
+ set of processing rules that are followed, independent of the method.
+ Section 12 gives guidance on how a UAS can tell whether a request is
+ inside or outside of a dialog.
+
+ Note that request processing is atomic. If a request is accepted,
+ all state changes associated with it MUST be performed. If it is
+ rejected, all state changes MUST NOT be performed.
+
+ UASs SHOULD process the requests in the order of the steps that
+ follow in this section (that is, starting with authentication, then
+ inspecting the method, the header fields, and so on throughout the
+ remainder of this section).
+
+8.2.1 Method Inspection
+
+ Once a request is authenticated (or authentication is skipped), the
+ UAS MUST inspect the method of the request. If the UAS recognizes
+ but does not support the method of a request, it MUST generate a 405
+ (Method Not Allowed) response. Procedures for generating responses
+ are described in Section 8.2.6. The UAS MUST also add an Allow
+ header field to the 405 (Method Not Allowed) response. The Allow
+ header field MUST list the set of methods supported by the UAS
+ generating the message. The Allow header field is presented in
+ Section 20.5.
+
+ If the method is one supported by the server, processing continues.
+
+8.2.2 Header Inspection
+
+ If a UAS does not understand a header field in a request (that is,
+ the header field is not defined in this specification or in any
+ supported extension), the server MUST ignore that header field and
+ continue processing the message. A UAS SHOULD ignore any malformed
+ header fields that are not necessary for processing requests.
+
+8.2.2.1 To and Request-URI
+
+ The To header field identifies the original recipient of the request
+ designated by the user identified in the From field. The original
+ recipient may or may not be the UAS processing the request, due to
+ call forwarding or other proxy operations. A UAS MAY apply any
+ policy it wishes to determine whether to accept requests when the To
+
+
+
+Rosenberg, et. al. Standards Track [Page 46]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ header field is not the identity of the UAS. However, it is
+ RECOMMENDED that a UAS accept requests even if they do not recognize
+ the URI scheme (for example, a tel: URI) in the To header field, or
+ if the To header field does not address a known or current user of
+ this UAS. If, on the other hand, the UAS decides to reject the
+ request, it SHOULD generate a response with a 403 (Forbidden) status
+ code and pass it to the server transaction for transmission.
+
+ However, the Request-URI identifies the UAS that is to process the
+ request. If the Request-URI uses a scheme not supported by the UAS,
+ it SHOULD reject the request with a 416 (Unsupported URI Scheme)
+ response. If the Request-URI does not identify an address that the
+ UAS is willing to accept requests for, it SHOULD reject the request
+ with a 404 (Not Found) response. Typically, a UA that uses the
+ REGISTER method to bind its address-of-record to a specific contact
+ address will see requests whose Request-URI equals that contact
+ address. Other potential sources of received Request-URIs include
+ the Contact header fields of requests and responses sent by the UA
+ that establish or refresh dialogs.
+
+8.2.2.2 Merged Requests
+
+ If the request has no tag in the To header field, the UAS core MUST
+ check the request against ongoing transactions. If the From tag,
+ Call-ID, and CSeq exactly match those associated with an ongoing
+ transaction, but the request does not match that transaction (based
+ on the matching rules in Section 17.2.3), the UAS core SHOULD
+ generate a 482 (Loop Detected) response and pass it to the server
+ transaction.
+
+ The same request has arrived at the UAS more than once, following
+ different paths, most likely due to forking. The UAS processes
+ the first such request received and responds with a 482 (Loop
+ Detected) to the rest of them.
+
+8.2.2.3 Require
+
+ Assuming the UAS decides that it is the proper element to process the
+ request, it examines the Require header field, if present.
+
+ The Require header field is used by a UAC to tell a UAS about SIP
+ extensions that the UAC expects the UAS to support in order to
+ process the request properly. Its format is described in Section
+ 20.32. If a UAS does not understand an option-tag listed in a
+ Require header field, it MUST respond by generating a response with
+ status code 420 (Bad Extension). The UAS MUST add an Unsupported
+ header field, and list in it those options it does not understand
+ amongst those in the Require header field of the request.
+
+
+
+Rosenberg, et. al. Standards Track [Page 47]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Note that Require and Proxy-Require MUST NOT be used in a SIP CANCEL
+ request, or in an ACK request sent for a non-2xx response. These
+ header fields MUST be ignored if they are present in these requests.
+
+ An ACK request for a 2xx response MUST contain only those Require and
+ Proxy-Require values that were present in the initial request.
+
+ Example:
+
+ UAC->UAS: INVITE sip:watson@bell-telephone.com SIP/2.0
+ Require: 100rel
+
+ UAS->UAC: SIP/2.0 420 Bad Extension
+ Unsupported: 100rel
+
+ This behavior ensures that the client-server interaction will
+ proceed without delay when all options are understood by both
+ sides, and only slow down if options are not understood (as in the
+ example above). For a well-matched client-server pair, the
+ interaction proceeds quickly, saving a round-trip often required
+ by negotiation mechanisms. In addition, it also removes ambiguity
+ when the client requires features that the server does not
+ understand. Some features, such as call handling fields, are only
+ of interest to end systems.
+
+8.2.3 Content Processing
+
+ Assuming the UAS understands any extensions required by the client,
+ the UAS examines the body of the message, and the header fields that
+ describe it. If there are any bodies whose type (indicated by the
+ Content-Type), language (indicated by the Content-Language) or
+ encoding (indicated by the Content-Encoding) are not understood, and
+ that body part is not optional (as indicated by the Content-
+ Disposition header field), the UAS MUST reject the request with a 415
+ (Unsupported Media Type) response. The response MUST contain an
+ Accept header field listing the types of all bodies it understands,
+ in the event the request contained bodies of types not supported by
+ the UAS. If the request contained content encodings not understood
+ by the UAS, the response MUST contain an Accept-Encoding header field
+ listing the encodings understood by the UAS. If the request
+ contained content with languages not understood by the UAS, the
+ response MUST contain an Accept-Language header field indicating the
+ languages understood by the UAS. Beyond these checks, body handling
+ depends on the method and type. For further information on the
+ processing of content-specific header fields, see Section 7.4 as well
+ as Section 20.11 through 20.15.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 48]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+8.2.4 Applying Extensions
+
+ A UAS that wishes to apply some extension when generating the
+ response MUST NOT do so unless support for that extension is
+ indicated in the Supported header field in the request. If the
+ desired extension is not supported, the server SHOULD rely only on
+ baseline SIP and any other extensions supported by the client. In
+ rare circumstances, where the server cannot process the request
+ without the extension, the server MAY send a 421 (Extension Required)
+ response. This response indicates that the proper response cannot be
+ generated without support of a specific extension. The needed
+ extension(s) MUST be included in a Require header field in the
+ response. This behavior is NOT RECOMMENDED, as it will generally
+ break interoperability.
+
+ Any extensions applied to a non-421 response MUST be listed in a
+ Require header field included in the response. Of course, the server
+ MUST NOT apply extensions not listed in the Supported header field in
+ the request. As a result of this, the Require header field in a
+ response will only ever contain option tags defined in standards-
+ track RFCs.
+
+8.2.5 Processing the Request
+
+ Assuming all of the checks in the previous subsections are passed,
+ the UAS processing becomes method-specific. Section 10 covers the
+ REGISTER request, Section 11 covers the OPTIONS request, Section 13
+ covers the INVITE request, and Section 15 covers the BYE request.
+
+8.2.6 Generating the Response
+
+ When a UAS wishes to construct a response to a request, it follows
+ the general procedures detailed in the following subsections.
+ Additional behaviors specific to the response code in question, which
+ are not detailed in this section, may also be required.
+
+ Once all procedures associated with the creation of a response have
+ been completed, the UAS hands the response back to the server
+ transaction from which it received the request.
+
+8.2.6.1 Sending a Provisional Response
+
+ One largely non-method-specific guideline for the generation of
+ responses is that UASs SHOULD NOT issue a provisional response for a
+ non-INVITE request. Rather, UASs SHOULD generate a final response to
+ a non-INVITE request as soon as possible.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 49]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ When a 100 (Trying) response is generated, any Timestamp header field
+ present in the request MUST be copied into this 100 (Trying)
+ response. If there is a delay in generating the response, the UAS
+ SHOULD add a delay value into the Timestamp value in the response.
+ This value MUST contain the difference between the time of sending of
+ the response and receipt of the request, measured in seconds.
+
+8.2.6.2 Headers and Tags
+
+ The From field of the response MUST equal the From header field of
+ the request. The Call-ID header field of the response MUST equal the
+ Call-ID header field of the request. The CSeq header field of the
+ response MUST equal the CSeq field of the request. The Via header
+ field values in the response MUST equal the Via header field values
+ in the request and MUST maintain the same ordering.
+
+ If a request contained a To tag in the request, the To header field
+ in the response MUST equal that of the request. However, if the To
+ header field in the request did not contain a tag, the URI in the To
+ header field in the response MUST equal the URI in the To header
+ field; additionally, the UAS MUST add a tag to the To header field in
+ the response (with the exception of the 100 (Trying) response, in
+ which a tag MAY be present). This serves to identify the UAS that is
+ responding, possibly resulting in a component of a dialog ID. The
+ same tag MUST be used for all responses to that request, both final
+ and provisional (again excepting the 100 (Trying)). Procedures for
+ the generation of tags are defined in Section 19.3.
+
+8.2.7 Stateless UAS Behavior
+
+ A stateless UAS is a UAS that does not maintain transaction state.
+ It replies to requests normally, but discards any state that would
+ ordinarily be retained by a UAS after a response has been sent. If a
+ stateless UAS receives a retransmission of a request, it regenerates
+ the response and resends it, just as if it were replying to the first
+ instance of the request. A UAS cannot be stateless unless the request
+ processing for that method would always result in the same response
+ if the requests are identical. This rules out stateless registrars,
+ for example. Stateless UASs do not use a transaction layer; they
+ receive requests directly from the transport layer and send responses
+ directly to the transport layer.
+
+ The stateless UAS role is needed primarily to handle unauthenticated
+ requests for which a challenge response is issued. If
+ unauthenticated requests were handled statefully, then malicious
+ floods of unauthenticated requests could create massive amounts of
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 50]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ transaction state that might slow or completely halt call processing
+ in a UAS, effectively creating a denial of service condition; for
+ more information see Section 26.1.5.
+
+ The most important behaviors of a stateless UAS are the following:
+
+ o A stateless UAS MUST NOT send provisional (1xx) responses.
+
+ o A stateless UAS MUST NOT retransmit responses.
+
+ o A stateless UAS MUST ignore ACK requests.
+
+ o A stateless UAS MUST ignore CANCEL requests.
+
+ o To header tags MUST be generated for responses in a stateless
+ manner - in a manner that will generate the same tag for the
+ same request consistently. For information on tag construction
+ see Section 19.3.
+
+ In all other respects, a stateless UAS behaves in the same manner as
+ a stateful UAS. A UAS can operate in either a stateful or stateless
+ mode for each new request.
+
+8.3 Redirect Servers
+
+ In some architectures it may be desirable to reduce the processing
+ load on proxy servers that are responsible for routing requests, and
+ improve signaling path robustness, by relying on redirection.
+
+ Redirection allows servers to push routing information for a request
+ back in a response to the client, thereby taking themselves out of
+ the loop of further messaging for this transaction while still aiding
+ in locating the target of the request. When the originator of the
+ request receives the redirection, it will send a new request based on
+ the URI(s) it has received. By propagating URIs from the core of the
+ network to its edges, redirection allows for considerable network
+ scalability.
+
+ A redirect server is logically constituted of a server transaction
+ layer and a transaction user that has access to a location service of
+ some kind (see Section 10 for more on registrars and location
+ services). This location service is effectively a database
+ containing mappings between a single URI and a set of one or more
+ alternative locations at which the target of that URI can be found.
+
+ A redirect server does not issue any SIP requests of its own. After
+ receiving a request other than CANCEL, the server either refuses the
+ request or gathers the list of alternative locations from the
+
+
+
+Rosenberg, et. al. Standards Track [Page 51]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ location service and returns a final response of class 3xx. For
+ well-formed CANCEL requests, it SHOULD return a 2xx response. This
+ response ends the SIP transaction. The redirect server maintains
+ transaction state for an entire SIP transaction. It is the
+ responsibility of clients to detect forwarding loops between redirect
+ servers.
+
+ When a redirect server returns a 3xx response to a request, it
+ populates the list of (one or more) alternative locations into the
+ Contact header field. An "expires" parameter to the Contact header
+ field values may also be supplied to indicate the lifetime of the
+ Contact data.
+
+ The Contact header field contains URIs giving the new locations or
+ user names to try, or may simply specify additional transport
+ parameters. A 301 (Moved Permanently) or 302 (Moved Temporarily)
+ response may also give the same location and username that was
+ targeted by the initial request but specify additional transport
+ parameters such as a different server or multicast address to try, or
+ a change of SIP transport from UDP to TCP or vice versa.
+
+ However, redirect servers MUST NOT redirect a request to a URI equal
+ to the one in the Request-URI; instead, provided that the URI does
+ not point to itself, the server MAY proxy the request to the
+ destination URI, or MAY reject it with a 404.
+
+ If a client is using an outbound proxy, and that proxy actually
+ redirects requests, a potential arises for infinite redirection
+ loops.
+
+ Note that a Contact header field value MAY also refer to a different
+ resource than the one originally called. For example, a SIP call
+ connected to PSTN gateway may need to deliver a special informational
+ announcement such as "The number you have dialed has been changed."
+
+ A Contact response header field can contain any suitable URI
+ indicating where the called party can be reached, not limited to SIP
+ URIs. For example, it could contain URIs for phones, fax, or irc (if
+ they were defined) or a mailto: (RFC 2368 [32]) URL. Section 26.4.4
+ discusses implications and limitations of redirecting a SIPS URI to a
+ non-SIPS URI.
+
+ The "expires" parameter of a Contact header field value indicates how
+ long the URI is valid. The value of the parameter is a number
+ indicating seconds. If this parameter is not provided, the value of
+ the Expires header field determines how long the URI is valid.
+ Malformed values SHOULD be treated as equivalent to 3600.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 52]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ This provides a modest level of backwards compatibility with RFC
+ 2543, which allowed absolute times in this header field. If an
+ absolute time is received, it will be treated as malformed, and
+ then default to 3600.
+
+ Redirect servers MUST ignore features that are not understood
+ (including unrecognized header fields, any unknown option tags in
+ Require, or even method names) and proceed with the redirection of
+ the request in question.
+
+9 Canceling a Request
+
+ The previous section has discussed general UA behavior for generating
+ requests and processing responses for requests of all methods. In
+ this section, we discuss a general purpose method, called CANCEL.
+
+ The CANCEL request, as the name implies, is used to cancel a previous
+ request sent by a client. Specifically, it asks the UAS to cease
+ processing the request and to generate an error response to that
+ request. CANCEL has no effect on a request to which a UAS has
+ already given a final response. Because of this, it is most useful
+ to CANCEL requests to which it can take a server long time to
+ respond. For this reason, CANCEL is best for INVITE requests, which
+ can take a long time to generate a response. In that usage, a UAS
+ that receives a CANCEL request for an INVITE, but has not yet sent a
+ final response, would "stop ringing", and then respond to the INVITE
+ with a specific error response (a 487).
+
+ CANCEL requests can be constructed and sent by both proxies and user
+ agent clients. Section 15 discusses under what conditions a UAC
+ would CANCEL an INVITE request, and Section 16.10 discusses proxy
+ usage of CANCEL.
+
+ A stateful proxy responds to a CANCEL, rather than simply forwarding
+ a response it would receive from a downstream element. For that
+ reason, CANCEL is referred to as a "hop-by-hop" request, since it is
+ responded to at each stateful proxy hop.
+
+9.1 Client Behavior
+
+ A CANCEL request SHOULD NOT be sent to cancel a request other than
+ INVITE.
+
+ Since requests other than INVITE are responded to immediately,
+ sending a CANCEL for a non-INVITE request would always create a
+ race condition.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 53]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The following procedures are used to construct a CANCEL request. The
+ Request-URI, Call-ID, To, the numeric part of CSeq, and From header
+ fields in the CANCEL request MUST be identical to those in the
+ request being cancelled, including tags. A CANCEL constructed by a
+ client MUST have only a single Via header field value matching the
+ top Via value in the request being cancelled. Using the same values
+ for these header fields allows the CANCEL to be matched with the
+ request it cancels (Section 9.2 indicates how such matching occurs).
+ However, the method part of the CSeq header field MUST have a value
+ of CANCEL. This allows it to be identified and processed as a
+ transaction in its own right (See Section 17).
+
+ If the request being cancelled contains a Route header field, the
+ CANCEL request MUST include that Route header field's values.
+
+ This is needed so that stateless proxies are able to route CANCEL
+ requests properly.
+
+ The CANCEL request MUST NOT contain any Require or Proxy-Require
+ header fields.
+
+ Once the CANCEL is constructed, the client SHOULD check whether it
+ has received any response (provisional or final) for the request
+ being cancelled (herein referred to as the "original request").
+
+ If no provisional response has been received, the CANCEL request MUST
+ NOT be sent; rather, the client MUST wait for the arrival of a
+ provisional response before sending the request. If the original
+ request has generated a final response, the CANCEL SHOULD NOT be
+ sent, as it is an effective no-op, since CANCEL has no effect on
+ requests that have already generated a final response. When the
+ client decides to send the CANCEL, it creates a client transaction
+ for the CANCEL and passes it the CANCEL request along with the
+ destination address, port, and transport. The destination address,
+ port, and transport for the CANCEL MUST be identical to those used to
+ send the original request.
+
+ If it was allowed to send the CANCEL before receiving a response
+ for the previous request, the server could receive the CANCEL
+ before the original request.
+
+ Note that both the transaction corresponding to the original request
+ and the CANCEL transaction will complete independently. However, a
+ UAC canceling a request cannot rely on receiving a 487 (Request
+ Terminated) response for the original request, as an RFC 2543-
+ compliant UAS will not generate such a response. If there is no
+ final response for the original request in 64*T1 seconds (T1 is
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 54]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ defined in Section 17.1.1.1), the client SHOULD then consider the
+ original transaction cancelled and SHOULD destroy the client
+ transaction handling the original request.
+
+9.2 Server Behavior
+
+ The CANCEL method requests that the TU at the server side cancel a
+ pending transaction. The TU determines the transaction to be
+ cancelled by taking the CANCEL request, and then assuming that the
+ request method is anything but CANCEL or ACK and applying the
+ transaction matching procedures of Section 17.2.3. The matching
+ transaction is the one to be cancelled.
+
+ The processing of a CANCEL request at a server depends on the type of
+ server. A stateless proxy will forward it, a stateful proxy might
+ respond to it and generate some CANCEL requests of its own, and a UAS
+ will respond to it. See Section 16.10 for proxy treatment of CANCEL.
+
+ A UAS first processes the CANCEL request according to the general UAS
+ processing described in Section 8.2. However, since CANCEL requests
+ are hop-by-hop and cannot be resubmitted, they cannot be challenged
+ by the server in order to get proper credentials in an Authorization
+ header field. Note also that CANCEL requests do not contain a
+ Require header field.
+
+ If the UAS did not find a matching transaction for the CANCEL
+ according to the procedure above, it SHOULD respond to the CANCEL
+ with a 481 (Call Leg/Transaction Does Not Exist). If the transaction
+ for the original request still exists, the behavior of the UAS on
+ receiving a CANCEL request depends on whether it has already sent a
+ final response for the original request. If it has, the CANCEL
+ request has no effect on the processing of the original request, no
+ effect on any session state, and no effect on the responses generated
+ for the original request. If the UAS has not issued a final response
+ for the original request, its behavior depends on the method of the
+ original request. If the original request was an INVITE, the UAS
+ SHOULD immediately respond to the INVITE with a 487 (Request
+ Terminated). A CANCEL request has no impact on the processing of
+ transactions with any other method defined in this specification.
+
+ Regardless of the method of the original request, as long as the
+ CANCEL matched an existing transaction, the UAS answers the CANCEL
+ request itself with a 200 (OK) response. This response is
+ constructed following the procedures described in Section 8.2.6
+ noting that the To tag of the response to the CANCEL and the To tag
+ in the response to the original request SHOULD be the same. The
+ response to CANCEL is passed to the server transaction for
+ transmission.
+
+
+
+Rosenberg, et. al. Standards Track [Page 55]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+10 Registrations
+
+10.1 Overview
+
+ SIP offers a discovery capability. If a user wants to initiate a
+ session with another user, SIP must discover the current host(s) at
+ which the destination user is reachable. This discovery process is
+ frequently accomplished by SIP network elements such as proxy servers
+ and redirect servers which are responsible for receiving a request,
+ determining where to send it based on knowledge of the location of
+ the user, and then sending it there. To do this, SIP network
+ elements consult an abstract service known as a location service,
+ which provides address bindings for a particular domain. These
+ address bindings map an incoming SIP or SIPS URI, sip:bob@biloxi.com,
+ for example, to one or more URIs that are somehow "closer" to the
+ desired user, sip:bob@engineering.biloxi.com, for example.
+ Ultimately, a proxy will consult a location service that maps a
+ received URI to the user agent(s) at which the desired recipient is
+ currently residing.
+
+ Registration creates bindings in a location service for a particular
+ domain that associates an address-of-record URI with one or more
+ contact addresses. Thus, when a proxy for that domain receives a
+ request whose Request-URI matches the address-of-record, the proxy
+ will forward the request to the contact addresses registered to that
+ address-of-record. Generally, it only makes sense to register an
+ address-of-record at a domain's location service when requests for
+ that address-of-record would be routed to that domain. In most
+ cases, this means that the domain of the registration will need to
+ match the domain in the URI of the address-of-record.
+
+ There are many ways by which the contents of the location service can
+ be established. One way is administratively. In the above example,
+ Bob is known to be a member of the engineering department through
+ access to a corporate database. However, SIP provides a mechanism
+ for a UA to create a binding explicitly. This mechanism is known as
+ registration.
+
+ Registration entails sending a REGISTER request to a special type of
+ UAS known as a registrar. A registrar acts as the front end to the
+ location service for a domain, reading and writing mappings based on
+ the contents of REGISTER requests. This location service is then
+ typically consulted by a proxy server that is responsible for routing
+ requests for that domain.
+
+ An illustration of the overall registration process is given in
+ Figure 2. Note that the registrar and proxy server are logical roles
+ that can be played by a single device in a network; for purposes of
+
+
+
+Rosenberg, et. al. Standards Track [Page 56]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ clarity the two are separated in this illustration. Also note that
+ UAs may send requests through a proxy server in order to reach a
+ registrar if the two are separate elements.
+
+ SIP does not mandate a particular mechanism for implementing the
+ location service. The only requirement is that a registrar for some
+ domain MUST be able to read and write data to the location service,
+ and a proxy or a redirect server for that domain MUST be capable of
+ reading that same data. A registrar MAY be co-located with a
+ particular SIP proxy server for the same domain.
+
+10.2 Constructing the REGISTER Request
+
+ REGISTER requests add, remove, and query bindings. A REGISTER
+ request can add a new binding between an address-of-record and one or
+ more contact addresses. Registration on behalf of a particular
+ address-of-record can be performed by a suitably authorized third
+ party. A client can also remove previous bindings or query to
+ determine which bindings are currently in place for an address-of-
+ record.
+
+ Except as noted, the construction of the REGISTER request and the
+ behavior of clients sending a REGISTER request is identical to the
+ general UAC behavior described in Section 8.1 and Section 17.1.
+
+ A REGISTER request does not establish a dialog. A UAC MAY include a
+ Route header field in a REGISTER request based on a pre-existing
+ route set as described in Section 8.1. The Record-Route header field
+ has no meaning in REGISTER requests or responses, and MUST be ignored
+ if present. In particular, the UAC MUST NOT create a new route set
+ based on the presence or absence of a Record-Route header field in
+ any response to a REGISTER request.
+
+ The following header fields, except Contact, MUST be included in a
+ REGISTER request. A Contact header field MAY be included:
+
+ Request-URI: The Request-URI names the domain of the location
+ service for which the registration is meant (for example,
+ "sip:chicago.com"). The "userinfo" and "@" components of the
+ SIP URI MUST NOT be present.
+
+ To: The To header field contains the address of record whose
+ registration is to be created, queried, or modified. The To
+ header field and the Request-URI field typically differ, as
+ the former contains a user name. This address-of-record MUST
+ be a SIP URI or SIPS URI.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 57]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ From: The From header field contains the address-of-record of the
+ person responsible for the registration. The value is the
+ same as the To header field unless the request is a third-
+ party registration.
+
+ Call-ID: All registrations from a UAC SHOULD use the same Call-ID
+ header field value for registrations sent to a particular
+ registrar.
+
+ If the same client were to use different Call-ID values, a
+ registrar could not detect whether a delayed REGISTER request
+ might have arrived out of order.
+
+ CSeq: The CSeq value guarantees proper ordering of REGISTER
+ requests. A UA MUST increment the CSeq value by one for each
+ REGISTER request with the same Call-ID.
+
+ Contact: REGISTER requests MAY contain a Contact header field with
+ zero or more values containing address bindings.
+
+ UAs MUST NOT send a new registration (that is, containing new Contact
+ header field values, as opposed to a retransmission) until they have
+ received a final response from the registrar for the previous one or
+ the previous REGISTER request has timed out.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 58]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ bob
+ +----+
+ | UA |
+ | |
+ +----+
+ |
+ |3)INVITE
+ | carol@chicago.com
+ chicago.com +--------+ V
+ +---------+ 2)Store|Location|4)Query +-----+
+ |Registrar|=======>| Service|<=======|Proxy|sip.chicago.com
+ +---------+ +--------+=======>+-----+
+ A 5)Resp |
+ | |
+ | |
+ 1)REGISTER| |
+ | |
+ +----+ |
+ | UA |<-------------------------------+
+ cube2214a| | 6)INVITE
+ +----+ carol@cube2214a.chicago.com
+ carol
+
+ Figure 2: REGISTER example
+
+ The following Contact header parameters have a special meaning in
+ REGISTER requests:
+
+ action: The "action" parameter from RFC 2543 has been deprecated.
+ UACs SHOULD NOT use the "action" parameter.
+
+ expires: The "expires" parameter indicates how long the UA would
+ like the binding to be valid. The value is a number
+ indicating seconds. If this parameter is not provided, the
+ value of the Expires header field is used instead.
+ Implementations MAY treat values larger than 2**32-1
+ (4294967295 seconds or 136 years) as equivalent to 2**32-1.
+ Malformed values SHOULD be treated as equivalent to 3600.
+
+10.2.1 Adding Bindings
+
+ The REGISTER request sent to a registrar includes the contact
+ address(es) to which SIP requests for the address-of-record should be
+ forwarded. The address-of-record is included in the To header field
+ of the REGISTER request.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 59]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The Contact header field values of the request typically consist of
+ SIP or SIPS URIs that identify particular SIP endpoints (for example,
+ "sip:carol@cube2214a.chicago.com"), but they MAY use any URI scheme.
+ A SIP UA can choose to register telephone numbers (with the tel URL,
+ RFC 2806 [9]) or email addresses (with a mailto URL, RFC 2368 [32])
+ as Contacts for an address-of-record, for example.
+
+ For example, Carol, with address-of-record "sip:carol@chicago.com",
+ would register with the SIP registrar of the domain chicago.com. Her
+ registrations would then be used by a proxy server in the chicago.com
+ domain to route requests for Carol's address-of-record to her SIP
+ endpoint.
+
+ Once a client has established bindings at a registrar, it MAY send
+ subsequent registrations containing new bindings or modifications to
+ existing bindings as necessary. The 2xx response to the REGISTER
+ request will contain, in a Contact header field, a complete list of
+ bindings that have been registered for this address-of-record at this
+ registrar.
+
+ If the address-of-record in the To header field of a REGISTER request
+ is a SIPS URI, then any Contact header field values in the request
+ SHOULD also be SIPS URIs. Clients should only register non-SIPS URIs
+ under a SIPS address-of-record when the security of the resource
+ represented by the contact address is guaranteed by other means.
+ This may be applicable to URIs that invoke protocols other than SIP,
+ or SIP devices secured by protocols other than TLS.
+
+ Registrations do not need to update all bindings. Typically, a UA
+ only updates its own contact addresses.
+
+10.2.1.1 Setting the Expiration Interval of Contact Addresses
+
+ When a client sends a REGISTER request, it MAY suggest an expiration
+ interval that indicates how long the client would like the
+ registration to be valid. (As described in Section 10.3, the
+ registrar selects the actual time interval based on its local
+ policy.)
+
+ There are two ways in which a client can suggest an expiration
+ interval for a binding: through an Expires header field or an
+ "expires" Contact header parameter. The latter allows expiration
+ intervals to be suggested on a per-binding basis when more than one
+ binding is given in a single REGISTER request, whereas the former
+ suggests an expiration interval for all Contact header field values
+ that do not contain the "expires" parameter.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 60]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If neither mechanism for expressing a suggested expiration time is
+ present in a REGISTER, the client is indicating its desire for the
+ server to choose.
+
+10.2.1.2 Preferences among Contact Addresses
+
+ If more than one Contact is sent in a REGISTER request, the
+ registering UA intends to associate all of the URIs in these Contact
+ header field values with the address-of-record present in the To
+ field. This list can be prioritized with the "q" parameter in the
+ Contact header field. The "q" parameter indicates a relative
+ preference for the particular Contact header field value compared to
+ other bindings for this address-of-record. Section 16.6 describes
+ how a proxy server uses this preference indication.
+
+10.2.2 Removing Bindings
+
+ Registrations are soft state and expire unless refreshed, but can
+ also be explicitly removed. A client can attempt to influence the
+ expiration interval selected by the registrar as described in Section
+ 10.2.1. A UA requests the immediate removal of a binding by
+ specifying an expiration interval of "0" for that contact address in
+ a REGISTER request. UAs SHOULD support this mechanism so that
+ bindings can be removed before their expiration interval has passed.
+
+ The REGISTER-specific Contact header field value of "*" applies to
+ all registrations, but it MUST NOT be used unless the Expires header
+ field is present with a value of "0".
+
+ Use of the "*" Contact header field value allows a registering UA
+ to remove all bindings associated with an address-of-record
+ without knowing their precise values.
+
+10.2.3 Fetching Bindings
+
+ A success response to any REGISTER request contains the complete list
+ of existing bindings, regardless of whether the request contained a
+ Contact header field. If no Contact header field is present in a
+ REGISTER request, the list of bindings is left unchanged.
+
+10.2.4 Refreshing Bindings
+
+ Each UA is responsible for refreshing the bindings that it has
+ previously established. A UA SHOULD NOT refresh bindings set up by
+ other UAs.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 61]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The 200 (OK) response from the registrar contains a list of Contact
+ fields enumerating all current bindings. The UA compares each
+ contact address to see if it created the contact address, using
+ comparison rules in Section 19.1.4. If so, it updates the expiration
+ time interval according to the expires parameter or, if absent, the
+ Expires field value. The UA then issues a REGISTER request for each
+ of its bindings before the expiration interval has elapsed. It MAY
+ combine several updates into one REGISTER request.
+
+ A UA SHOULD use the same Call-ID for all registrations during a
+ single boot cycle. Registration refreshes SHOULD be sent to the same
+ network address as the original registration, unless redirected.
+
+10.2.5 Setting the Internal Clock
+
+ If the response for a REGISTER request contains a Date header field,
+ the client MAY use this header field to learn the current time in
+ order to set any internal clocks.
+
+10.2.6 Discovering a Registrar
+
+ UAs can use three ways to determine the address to which to send
+ registrations: by configuration, using the address-of-record, and
+ multicast. A UA can be configured, in ways beyond the scope of this
+ specification, with a registrar address. If there is no configured
+ registrar address, the UA SHOULD use the host part of the address-
+ of-record as the Request-URI and address the request there, using the
+ normal SIP server location mechanisms [4]. For example, the UA for
+ the user "sip:carol@chicago.com" addresses the REGISTER request to
+ "sip:chicago.com".
+
+ Finally, a UA can be configured to use multicast. Multicast
+ registrations are addressed to the well-known "all SIP servers"
+ multicast address "sip.mcast.net" (224.0.1.75 for IPv4). No well-
+ known IPv6 multicast address has been allocated; such an allocation
+ will be documented separately when needed. SIP UAs MAY listen to
+ that address and use it to become aware of the location of other
+ local users (see [33]); however, they do not respond to the request.
+
+ Multicast registration may be inappropriate in some environments,
+ for example, if multiple businesses share the same local area
+ network.
+
+10.2.7 Transmitting a Request
+
+ Once the REGISTER method has been constructed, and the destination of
+ the message identified, UACs follow the procedures described in
+ Section 8.1.2 to hand off the REGISTER to the transaction layer.
+
+
+
+Rosenberg, et. al. Standards Track [Page 62]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If the transaction layer returns a timeout error because the REGISTER
+ yielded no response, the UAC SHOULD NOT immediately re-attempt a
+ registration to the same registrar.
+
+ An immediate re-attempt is likely to also timeout. Waiting some
+ reasonable time interval for the conditions causing the timeout to
+ be corrected reduces unnecessary load on the network. No specific
+ interval is mandated.
+
+10.2.8 Error Responses
+
+ If a UA receives a 423 (Interval Too Brief) response, it MAY retry
+ the registration after making the expiration interval of all contact
+ addresses in the REGISTER request equal to or greater than the
+ expiration interval within the Min-Expires header field of the 423
+ (Interval Too Brief) response.
+
+10.3 Processing REGISTER Requests
+
+ A registrar is a UAS that responds to REGISTER requests and maintains
+ a list of bindings that are accessible to proxy servers and redirect
+ servers within its administrative domain. A registrar handles
+ requests according to Section 8.2 and Section 17.2, but it accepts
+ only REGISTER requests. A registrar MUST not generate 6xx responses.
+
+ A registrar MAY redirect REGISTER requests as appropriate. One
+ common usage would be for a registrar listening on a multicast
+ interface to redirect multicast REGISTER requests to its own unicast
+ interface with a 302 (Moved Temporarily) response.
+
+ Registrars MUST ignore the Record-Route header field if it is
+ included in a REGISTER request. Registrars MUST NOT include a
+ Record-Route header field in any response to a REGISTER request.
+
+ A registrar might receive a request that traversed a proxy which
+ treats REGISTER as an unknown request and which added a Record-
+ Route header field value.
+
+ A registrar has to know (for example, through configuration) the set
+ of domain(s) for which it maintains bindings. REGISTER requests MUST
+ be processed by a registrar in the order that they are received.
+ REGISTER requests MUST also be processed atomically, meaning that a
+ particular REGISTER request is either processed completely or not at
+ all. Each REGISTER message MUST be processed independently of any
+ other registration or binding changes.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 63]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ When receiving a REGISTER request, a registrar follows these steps:
+
+ 1. The registrar inspects the Request-URI to determine whether it
+ has access to bindings for the domain identified in the
+ Request-URI. If not, and if the server also acts as a proxy
+ server, the server SHOULD forward the request to the addressed
+ domain, following the general behavior for proxying messages
+ described in Section 16.
+
+ 2. To guarantee that the registrar supports any necessary
+ extensions, the registrar MUST process the Require header field
+ values as described for UASs in Section 8.2.2.
+
+ 3. A registrar SHOULD authenticate the UAC. Mechanisms for the
+ authentication of SIP user agents are described in Section 22.
+ Registration behavior in no way overrides the generic
+ authentication framework for SIP. If no authentication
+ mechanism is available, the registrar MAY take the From address
+ as the asserted identity of the originator of the request.
+
+ 4. The registrar SHOULD determine if the authenticated user is
+ authorized to modify registrations for this address-of-record.
+ For example, a registrar might consult an authorization
+ database that maps user names to a list of addresses-of-record
+ for which that user has authorization to modify bindings. If
+ the authenticated user is not authorized to modify bindings,
+ the registrar MUST return a 403 (Forbidden) and skip the
+ remaining steps.
+
+ In architectures that support third-party registration, one
+ entity may be responsible for updating the registrations
+ associated with multiple addresses-of-record.
+
+ 5. The registrar extracts the address-of-record from the To header
+ field of the request. If the address-of-record is not valid
+ for the domain in the Request-URI, the registrar MUST send a
+ 404 (Not Found) response and skip the remaining steps. The URI
+ MUST then be converted to a canonical form. To do that, all
+ URI parameters MUST be removed (including the user-param), and
+ any escaped characters MUST be converted to their unescaped
+ form. The result serves as an index into the list of bindings.
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 64]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 6. The registrar checks whether the request contains the Contact
+ header field. If not, it skips to the last step. If the
+ Contact header field is present, the registrar checks if there
+ is one Contact field value that contains the special value "*"
+ and an Expires field. If the request has additional Contact
+ fields or an expiration time other than zero, the request is
+ invalid, and the server MUST return a 400 (Invalid Request) and
+ skip the remaining steps. If not, the registrar checks whether
+ the Call-ID agrees with the value stored for each binding. If
+ not, it MUST remove the binding. If it does agree, it MUST
+ remove the binding only if the CSeq in the request is higher
+ than the value stored for that binding. Otherwise, the update
+ MUST be aborted and the request fails.
+
+ 7. The registrar now processes each contact address in the Contact
+ header field in turn. For each address, it determines the
+ expiration interval as follows:
+
+ - If the field value has an "expires" parameter, that value
+ MUST be taken as the requested expiration.
+
+ - If there is no such parameter, but the request has an
+ Expires header field, that value MUST be taken as the
+ requested expiration.
+
+ - If there is neither, a locally-configured default value MUST
+ be taken as the requested expiration.
+
+ The registrar MAY choose an expiration less than the requested
+ expiration interval. If and only if the requested expiration
+ interval is greater than zero AND smaller than one hour AND
+ less than a registrar-configured minimum, the registrar MAY
+ reject the registration with a response of 423 (Interval Too
+ Brief). This response MUST contain a Min-Expires header field
+ that states the minimum expiration interval the registrar is
+ willing to honor. It then skips the remaining steps.
+
+ Allowing the registrar to set the registration interval
+ protects it against excessively frequent registration refreshes
+ while limiting the state that it needs to maintain and
+ decreasing the likelihood of registrations going stale. The
+ expiration interval of a registration is frequently used in the
+ creation of services. An example is a follow-me service, where
+ the user may only be available at a terminal for a brief
+ period. Therefore, registrars should accept brief
+ registrations; a request should only be rejected if the
+ interval is so short that the refreshes would degrade registrar
+ performance.
+
+
+
+Rosenberg, et. al. Standards Track [Page 65]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ For each address, the registrar then searches the list of
+ current bindings using the URI comparison rules. If the
+ binding does not exist, it is tentatively added. If the
+ binding does exist, the registrar checks the Call-ID value. If
+ the Call-ID value in the existing binding differs from the
+ Call-ID value in the request, the binding MUST be removed if
+ the expiration time is zero and updated otherwise. If they are
+ the same, the registrar compares the CSeq value. If the value
+ is higher than that of the existing binding, it MUST update or
+ remove the binding as above. If not, the update MUST be
+ aborted and the request fails.
+
+ This algorithm ensures that out-of-order requests from the same
+ UA are ignored.
+
+ Each binding record records the Call-ID and CSeq values from
+ the request.
+
+ The binding updates MUST be committed (that is, made visible to
+ the proxy or redirect server) if and only if all binding
+ updates and additions succeed. If any one of them fails (for
+ example, because the back-end database commit failed), the
+ request MUST fail with a 500 (Server Error) response and all
+ tentative binding updates MUST be removed.
+
+ 8. The registrar returns a 200 (OK) response. The response MUST
+ contain Contact header field values enumerating all current
+ bindings. Each Contact value MUST feature an "expires"
+ parameter indicating its expiration interval chosen by the
+ registrar. The response SHOULD include a Date header field.
+
+11 Querying for Capabilities
+
+ The SIP method OPTIONS allows a UA to query another UA or a proxy
+ server as to its capabilities. This allows a client to discover
+ information about the supported methods, content types, extensions,
+ codecs, etc. without "ringing" the other party. For example, before
+ a client inserts a Require header field into an INVITE listing an
+ option that it is not certain the destination UAS supports, the
+ client can query the destination UAS with an OPTIONS to see if this
+ option is returned in a Supported header field. All UAs MUST support
+ the OPTIONS method.
+
+ The target of the OPTIONS request is identified by the Request-URI,
+ which could identify another UA or a SIP server. If the OPTIONS is
+ addressed to a proxy server, the Request-URI is set without a user
+ part, similar to the way a Request-URI is set for a REGISTER request.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 66]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Alternatively, a server receiving an OPTIONS request with a Max-
+ Forwards header field value of 0 MAY respond to the request
+ regardless of the Request-URI.
+
+ This behavior is common with HTTP/1.1. This behavior can be used
+ as a "traceroute" functionality to check the capabilities of
+ individual hop servers by sending a series of OPTIONS requests
+ with incremented Max-Forwards values.
+
+ As is the case for general UA behavior, the transaction layer can
+ return a timeout error if the OPTIONS yields no response. This may
+ indicate that the target is unreachable and hence unavailable.
+
+ An OPTIONS request MAY be sent as part of an established dialog to
+ query the peer on capabilities that may be utilized later in the
+ dialog.
+
+11.1 Construction of OPTIONS Request
+
+ An OPTIONS request is constructed using the standard rules for a SIP
+ request as discussed in Section 8.1.1.
+
+ A Contact header field MAY be present in an OPTIONS.
+
+ An Accept header field SHOULD be included to indicate the type of
+ message body the UAC wishes to receive in the response. Typically,
+ this is set to a format that is used to describe the media
+ capabilities of a UA, such as SDP (application/sdp).
+
+ The response to an OPTIONS request is assumed to be scoped to the
+ Request-URI in the original request. However, only when an OPTIONS
+ is sent as part of an established dialog is it guaranteed that future
+ requests will be received by the server that generated the OPTIONS
+ response.
+
+ Example OPTIONS request:
+
+ OPTIONS sip:carol@chicago.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877
+ Max-Forwards: 70
+ To: <sip:carol@chicago.com>
+ From: Alice <sip:alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710
+ CSeq: 63104 OPTIONS
+ Contact: <sip:alice@pc33.atlanta.com>
+ Accept: application/sdp
+ Content-Length: 0
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 67]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+11.2 Processing of OPTIONS Request
+
+ The response to an OPTIONS is constructed using the standard rules
+ for a SIP response as discussed in Section 8.2.6. The response code
+ chosen MUST be the same that would have been chosen had the request
+ been an INVITE. That is, a 200 (OK) would be returned if the UAS is
+ ready to accept a call, a 486 (Busy Here) would be returned if the
+ UAS is busy, etc. This allows an OPTIONS request to be used to
+ determine the basic state of a UAS, which can be an indication of
+ whether the UAS will accept an INVITE request.
+
+ An OPTIONS request received within a dialog generates a 200 (OK)
+ response that is identical to one constructed outside a dialog and
+ does not have any impact on the dialog.
+
+ This use of OPTIONS has limitations due to the differences in proxy
+ handling of OPTIONS and INVITE requests. While a forked INVITE can
+ result in multiple 200 (OK) responses being returned, a forked
+ OPTIONS will only result in a single 200 (OK) response, since it is
+ treated by proxies using the non-INVITE handling. See Section 16.7
+ for the normative details.
+
+ If the response to an OPTIONS is generated by a proxy server, the
+ proxy returns a 200 (OK), listing the capabilities of the server.
+ The response does not contain a message body.
+
+ Allow, Accept, Accept-Encoding, Accept-Language, and Supported header
+ fields SHOULD be present in a 200 (OK) response to an OPTIONS
+ request. If the response is generated by a proxy, the Allow header
+ field SHOULD be omitted as it is ambiguous since a proxy is method
+ agnostic. Contact header fields MAY be present in a 200 (OK)
+ response and have the same semantics as in a 3xx response. That is,
+ they may list a set of alternative names and methods of reaching the
+ user. A Warning header field MAY be present.
+
+ A message body MAY be sent, the type of which is determined by the
+ Accept header field in the OPTIONS request (application/sdp is the
+ default if the Accept header field is not present). If the types
+ include one that can describe media capabilities, the UAS SHOULD
+ include a body in the response for that purpose. Details on the
+ construction of such a body in the case of application/sdp are
+ described in [13].
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 68]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example OPTIONS response generated by a UAS (corresponding to the
+ request in Section 11.1):
+
+ SIP/2.0 200 OK
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877
+ ;received=192.0.2.4
+ To: <sip:carol@chicago.com>;tag=93810874
+ From: Alice <sip:alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710
+ CSeq: 63104 OPTIONS
+ Contact: <sip:carol@chicago.com>
+ Contact: <mailto:carol@chicago.com>
+ Allow: INVITE, ACK, CANCEL, OPTIONS, BYE
+ Accept: application/sdp
+ Accept-Encoding: gzip
+ Accept-Language: en
+ Supported: foo
+ Content-Type: application/sdp
+ Content-Length: 274
+
+ (SDP not shown)
+
+12 Dialogs
+
+ A key concept for a user agent is that of a dialog. A dialog
+ represents a peer-to-peer SIP relationship between two user agents
+ that persists for some time. The dialog facilitates sequencing of
+ messages between the user agents and proper routing of requests
+ between both of them. The dialog represents a context in which to
+ interpret SIP messages. Section 8 discussed method independent UA
+ processing for requests and responses outside of a dialog. This
+ section discusses how those requests and responses are used to
+ construct a dialog, and then how subsequent requests and responses
+ are sent within a dialog.
+
+ A dialog is identified at each UA with a dialog ID, which consists of
+ a Call-ID value, a local tag and a remote tag. The dialog ID at each
+ UA involved in the dialog is not the same. Specifically, the local
+ tag at one UA is identical to the remote tag at the peer UA. The
+ tags are opaque tokens that facilitate the generation of unique
+ dialog IDs.
+
+ A dialog ID is also associated with all responses and with any
+ request that contains a tag in the To field. The rules for computing
+ the dialog ID of a message depend on whether the SIP element is a UAC
+ or UAS. For a UAC, the Call-ID value of the dialog ID is set to the
+ Call-ID of the message, the remote tag is set to the tag in the To
+ field of the message, and the local tag is set to the tag in the From
+
+
+
+Rosenberg, et. al. Standards Track [Page 69]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ field of the message (these rules apply to both requests and
+ responses). As one would expect for a UAS, the Call-ID value of the
+ dialog ID is set to the Call-ID of the message, the remote tag is set
+ to the tag in the From field of the message, and the local tag is set
+ to the tag in the To field of the message.
+
+ A dialog contains certain pieces of state needed for further message
+ transmissions within the dialog. This state consists of the dialog
+ ID, a local sequence number (used to order requests from the UA to
+ its peer), a remote sequence number (used to order requests from its
+ peer to the UA), a local URI, a remote URI, remote target, a boolean
+ flag called "secure", and a route set, which is an ordered list of
+ URIs. The route set is the list of servers that need to be traversed
+ to send a request to the peer. A dialog can also be in the "early"
+ state, which occurs when it is created with a provisional response,
+ and then transition to the "confirmed" state when a 2xx final
+ response arrives. For other responses, or if no response arrives at
+ all on that dialog, the early dialog terminates.
+
+12.1 Creation of a Dialog
+
+ Dialogs are created through the generation of non-failure responses
+ to requests with specific methods. Within this specification, only
+ 2xx and 101-199 responses with a To tag, where the request was
+ INVITE, will establish a dialog. A dialog established by a non-final
+ response to a request is in the "early" state and it is called an
+ early dialog. Extensions MAY define other means for creating
+ dialogs. Section 13 gives more details that are specific to the
+ INVITE method. Here, we describe the process for creation of dialog
+ state that is not dependent on the method.
+
+ UAs MUST assign values to the dialog ID components as described
+ below.
+
+12.1.1 UAS behavior
+
+ When a UAS responds to a request with a response that establishes a
+ dialog (such as a 2xx to INVITE), the UAS MUST copy all Record-Route
+ header field values from the request into the response (including the
+ URIs, URI parameters, and any Record-Route header field parameters,
+ whether they are known or unknown to the UAS) and MUST maintain the
+ order of those values. The UAS MUST add a Contact header field to
+ the response. The Contact header field contains an address where the
+ UAS would like to be contacted for subsequent requests in the dialog
+ (which includes the ACK for a 2xx response in the case of an INVITE).
+ Generally, the host portion of this URI is the IP address or FQDN of
+ the host. The URI provided in the Contact header field MUST be a SIP
+ or SIPS URI. If the request that initiated the dialog contained a
+
+
+
+Rosenberg, et. al. Standards Track [Page 70]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ SIPS URI in the Request-URI or in the top Record-Route header field
+ value, if there was any, or the Contact header field if there was no
+ Record-Route header field, the Contact header field in the response
+ MUST be a SIPS URI. The URI SHOULD have global scope (that is, the
+ same URI can be used in messages outside this dialog). The same way,
+ the scope of the URI in the Contact header field of the INVITE is not
+ limited to this dialog either. It can therefore be used in messages
+ to the UAC even outside this dialog.
+
+ The UAS then constructs the state of the dialog. This state MUST be
+ maintained for the duration of the dialog.
+
+ If the request arrived over TLS, and the Request-URI contained a SIPS
+ URI, the "secure" flag is set to TRUE.
+
+ The route set MUST be set to the list of URIs in the Record-Route
+ header field from the request, taken in order and preserving all URI
+ parameters. If no Record-Route header field is present in the
+ request, the route set MUST be set to the empty set. This route set,
+ even if empty, overrides any pre-existing route set for future
+ requests in this dialog. The remote target MUST be set to the URI
+ from the Contact header field of the request.
+
+ The remote sequence number MUST be set to the value of the sequence
+ number in the CSeq header field of the request. The local sequence
+ number MUST be empty. The call identifier component of the dialog ID
+ MUST be set to the value of the Call-ID in the request. The local
+ tag component of the dialog ID MUST be set to the tag in the To field
+ in the response to the request (which always includes a tag), and the
+ remote tag component of the dialog ID MUST be set to the tag from the
+ From field in the request. A UAS MUST be prepared to receive a
+ request without a tag in the From field, in which case the tag is
+ considered to have a value of null.
+
+ This is to maintain backwards compatibility with RFC 2543, which
+ did not mandate From tags.
+
+ The remote URI MUST be set to the URI in the From field, and the
+ local URI MUST be set to the URI in the To field.
+
+12.1.2 UAC Behavior
+
+ When a UAC sends a request that can establish a dialog (such as an
+ INVITE) it MUST provide a SIP or SIPS URI with global scope (i.e.,
+ the same SIP URI can be used in messages outside this dialog) in the
+ Contact header field of the request. If the request has a Request-
+ URI or a topmost Route header field value with a SIPS URI, the
+ Contact header field MUST contain a SIPS URI.
+
+
+
+Rosenberg, et. al. Standards Track [Page 71]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ When a UAC receives a response that establishes a dialog, it
+ constructs the state of the dialog. This state MUST be maintained
+ for the duration of the dialog.
+
+ If the request was sent over TLS, and the Request-URI contained a
+ SIPS URI, the "secure" flag is set to TRUE.
+
+ The route set MUST be set to the list of URIs in the Record-Route
+ header field from the response, taken in reverse order and preserving
+ all URI parameters. If no Record-Route header field is present in
+ the response, the route set MUST be set to the empty set. This route
+ set, even if empty, overrides any pre-existing route set for future
+ requests in this dialog. The remote target MUST be set to the URI
+ from the Contact header field of the response.
+
+ The local sequence number MUST be set to the value of the sequence
+ number in the CSeq header field of the request. The remote sequence
+ number MUST be empty (it is established when the remote UA sends a
+ request within the dialog). The call identifier component of the
+ dialog ID MUST be set to the value of the Call-ID in the request.
+ The local tag component of the dialog ID MUST be set to the tag in
+ the From field in the request, and the remote tag component of the
+ dialog ID MUST be set to the tag in the To field of the response. A
+ UAC MUST be prepared to receive a response without a tag in the To
+ field, in which case the tag is considered to have a value of null.
+
+ This is to maintain backwards compatibility with RFC 2543, which
+ did not mandate To tags.
+
+ The remote URI MUST be set to the URI in the To field, and the local
+ URI MUST be set to the URI in the From field.
+
+12.2 Requests within a Dialog
+
+ Once a dialog has been established between two UAs, either of them
+ MAY initiate new transactions as needed within the dialog. The UA
+ sending the request will take the UAC role for the transaction. The
+ UA receiving the request will take the UAS role. Note that these may
+ be different roles than the UAs held during the transaction that
+ established the dialog.
+
+ Requests within a dialog MAY contain Record-Route and Contact header
+ fields. However, these requests do not cause the dialog's route set
+ to be modified, although they may modify the remote target URI.
+ Specifically, requests that are not target refresh requests do not
+ modify the dialog's remote target URI, and requests that are target
+ refresh requests do. For dialogs that have been established with an
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 72]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ INVITE, the only target refresh request defined is re-INVITE (see
+ Section 14). Other extensions may define different target refresh
+ requests for dialogs established in other ways.
+
+ Note that an ACK is NOT a target refresh request.
+
+ Target refresh requests only update the dialog's remote target URI,
+ and not the route set formed from the Record-Route. Updating the
+ latter would introduce severe backwards compatibility problems with
+ RFC 2543-compliant systems.
+
+12.2.1 UAC Behavior
+
+12.2.1.1 Generating the Request
+
+ A request within a dialog is constructed by using many of the
+ components of the state stored as part of the dialog.
+
+ The URI in the To field of the request MUST be set to the remote URI
+ from the dialog state. The tag in the To header field of the request
+ MUST be set to the remote tag of the dialog ID. The From URI of the
+ request MUST be set to the local URI from the dialog state. The tag
+ in the From header field of the request MUST be set to the local tag
+ of the dialog ID. If the value of the remote or local tags is null,
+ the tag parameter MUST be omitted from the To or From header fields,
+ respectively.
+
+ Usage of the URI from the To and From fields in the original
+ request within subsequent requests is done for backwards
+ compatibility with RFC 2543, which used the URI for dialog
+ identification. In this specification, only the tags are used for
+ dialog identification. It is expected that mandatory reflection
+ of the original To and From URI in mid-dialog requests will be
+ deprecated in a subsequent revision of this specification.
+
+ The Call-ID of the request MUST be set to the Call-ID of the dialog.
+ Requests within a dialog MUST contain strictly monotonically
+ increasing and contiguous CSeq sequence numbers (increasing-by-one)
+ in each direction (excepting ACK and CANCEL of course, whose numbers
+ equal the requests being acknowledged or cancelled). Therefore, if
+ the local sequence number is not empty, the value of the local
+ sequence number MUST be incremented by one, and this value MUST be
+ placed into the CSeq header field. If the local sequence number is
+ empty, an initial value MUST be chosen using the guidelines of
+ Section 8.1.1.5. The method field in the CSeq header field value
+ MUST match the method of the request.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 73]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ With a length of 32 bits, a client could generate, within a single
+ call, one request a second for about 136 years before needing to
+ wrap around. The initial value of the sequence number is chosen
+ so that subsequent requests within the same call will not wrap
+ around. A non-zero initial value allows clients to use a time-
+ based initial sequence number. A client could, for example,
+ choose the 31 most significant bits of a 32-bit second clock as an
+ initial sequence number.
+
+ The UAC uses the remote target and route set to build the Request-URI
+ and Route header field of the request.
+
+ If the route set is empty, the UAC MUST place the remote target URI
+ into the Request-URI. The UAC MUST NOT add a Route header field to
+ the request.
+
+ If the route set is not empty, and the first URI in the route set
+ contains the lr parameter (see Section 19.1.1), the UAC MUST place
+ the remote target URI into the Request-URI and MUST include a Route
+ header field containing the route set values in order, including all
+ parameters.
+
+ If the route set is not empty, and its first URI does not contain the
+ lr parameter, the UAC MUST place the first URI from the route set
+ into the Request-URI, stripping any parameters that are not allowed
+ in a Request-URI. The UAC MUST add a Route header field containing
+ the remainder of the route set values in order, including all
+ parameters. The UAC MUST then place the remote target URI into the
+ Route header field as the last value.
+
+ For example, if the remote target is sip:user@remoteua and the route
+ set contains:
+
+ <sip:proxy1>,<sip:proxy2>,<sip:proxy3;lr>,<sip:proxy4>
+
+ The request will be formed with the following Request-URI and Route
+ header field:
+
+ METHOD sip:proxy1
+ Route: <sip:proxy2>,<sip:proxy3;lr>,<sip:proxy4>,<sip:user@remoteua>
+
+ If the first URI of the route set does not contain the lr
+ parameter, the proxy indicated does not understand the routing
+ mechanisms described in this document and will act as specified in
+ RFC 2543, replacing the Request-URI with the first Route header
+ field value it receives while forwarding the message. Placing the
+ Request-URI at the end of the Route header field preserves the
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 74]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ information in that Request-URI across the strict router (it will
+ be returned to the Request-URI when the request reaches a loose-
+ router).
+
+ A UAC SHOULD include a Contact header field in any target refresh
+ requests within a dialog, and unless there is a need to change it,
+ the URI SHOULD be the same as used in previous requests within the
+ dialog. If the "secure" flag is true, that URI MUST be a SIPS URI.
+ As discussed in Section 12.2.2, a Contact header field in a target
+ refresh request updates the remote target URI. This allows a UA to
+ provide a new contact address, should its address change during the
+ duration of the dialog.
+
+ However, requests that are not target refresh requests do not affect
+ the remote target URI for the dialog.
+
+ The rest of the request is formed as described in Section 8.1.1.
+
+ Once the request has been constructed, the address of the server is
+ computed and the request is sent, using the same procedures for
+ requests outside of a dialog (Section 8.1.2).
+
+ The procedures in Section 8.1.2 will normally result in the
+ request being sent to the address indicated by the topmost Route
+ header field value or the Request-URI if no Route header field is
+ present. Subject to certain restrictions, they allow the request
+ to be sent to an alternate address (such as a default outbound
+ proxy not represented in the route set).
+
+12.2.1.2 Processing the Responses
+
+ The UAC will receive responses to the request from the transaction
+ layer. If the client transaction returns a timeout, this is treated
+ as a 408 (Request Timeout) response.
+
+ The behavior of a UAC that receives a 3xx response for a request sent
+ within a dialog is the same as if the request had been sent outside a
+ dialog. This behavior is described in Section 8.1.3.4.
+
+ Note, however, that when the UAC tries alternative locations, it
+ still uses the route set for the dialog to build the Route header
+ of the request.
+
+ When a UAC receives a 2xx response to a target refresh request, it
+ MUST replace the dialog's remote target URI with the URI from the
+ Contact header field in that response, if present.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 75]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If the response for a request within a dialog is a 481
+ (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the UAC
+ SHOULD terminate the dialog. A UAC SHOULD also terminate a dialog if
+ no response at all is received for the request (the client
+ transaction would inform the TU about the timeout.)
+
+ For INVITE initiated dialogs, terminating the dialog consists of
+ sending a BYE.
+
+12.2.2 UAS Behavior
+
+ Requests sent within a dialog, as any other requests, are atomic. If
+ a particular request is accepted by the UAS, all the state changes
+ associated with it are performed. If the request is rejected, none
+ of the state changes are performed.
+
+ Note that some requests, such as INVITEs, affect several pieces of
+ state.
+
+ The UAS will receive the request from the transaction layer. If the
+ request has a tag in the To header field, the UAS core computes the
+ dialog identifier corresponding to the request and compares it with
+ existing dialogs. If there is a match, this is a mid-dialog request.
+ In that case, the UAS first applies the same processing rules for
+ requests outside of a dialog, discussed in Section 8.2.
+
+ If the request has a tag in the To header field, but the dialog
+ identifier does not match any existing dialogs, the UAS may have
+ crashed and restarted, or it may have received a request for a
+ different (possibly failed) UAS (the UASs can construct the To tags
+ so that a UAS can identify that the tag was for a UAS for which it is
+ providing recovery). Another possibility is that the incoming
+ request has been simply misrouted. Based on the To tag, the UAS MAY
+ either accept or reject the request. Accepting the request for
+ acceptable To tags provides robustness, so that dialogs can persist
+ even through crashes. UAs wishing to support this capability must
+ take into consideration some issues such as choosing monotonically
+ increasing CSeq sequence numbers even across reboots, reconstructing
+ the route set, and accepting out-of-range RTP timestamps and sequence
+ numbers.
+
+ If the UAS wishes to reject the request because it does not wish to
+ recreate the dialog, it MUST respond to the request with a 481
+ (Call/Transaction Does Not Exist) status code and pass that to the
+ server transaction.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 76]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Requests that do not change in any way the state of a dialog may be
+ received within a dialog (for example, an OPTIONS request). They are
+ processed as if they had been received outside the dialog.
+
+ If the remote sequence number is empty, it MUST be set to the value
+ of the sequence number in the CSeq header field value in the request.
+ If the remote sequence number was not empty, but the sequence number
+ of the request is lower than the remote sequence number, the request
+ is out of order and MUST be rejected with a 500 (Server Internal
+ Error) response. If the remote sequence number was not empty, and
+ the sequence number of the request is greater than the remote
+ sequence number, the request is in order. It is possible for the
+ CSeq sequence number to be higher than the remote sequence number by
+ more than one. This is not an error condition, and a UAS SHOULD be
+ prepared to receive and process requests with CSeq values more than
+ one higher than the previous received request. The UAS MUST then set
+ the remote sequence number to the value of the sequence number in the
+ CSeq header field value in the request.
+
+ If a proxy challenges a request generated by the UAC, the UAC has
+ to resubmit the request with credentials. The resubmitted request
+ will have a new CSeq number. The UAS will never see the first
+ request, and thus, it will notice a gap in the CSeq number space.
+ Such a gap does not represent any error condition.
+
+ When a UAS receives a target refresh request, it MUST replace the
+ dialog's remote target URI with the URI from the Contact header field
+ in that request, if present.
+
+12.3 Termination of a Dialog
+
+ Independent of the method, if a request outside of a dialog generates
+ a non-2xx final response, any early dialogs created through
+ provisional responses to that request are terminated. The mechanism
+ for terminating confirmed dialogs is method specific. In this
+ specification, the BYE method terminates a session and the dialog
+ associated with it. See Section 15 for details.
+
+13 Initiating a Session
+
+13.1 Overview
+
+ When a user agent client desires to initiate a session (for example,
+ audio, video, or a game), it formulates an INVITE request. The
+ INVITE request asks a server to establish a session. This request
+ may be forwarded by proxies, eventually arriving at one or more UAS
+ that can potentially accept the invitation. These UASs will
+ frequently need to query the user about whether to accept the
+
+
+
+Rosenberg, et. al. Standards Track [Page 77]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ invitation. After some time, those UASs can accept the invitation
+ (meaning the session is to be established) by sending a 2xx response.
+ If the invitation is not accepted, a 3xx, 4xx, 5xx or 6xx response is
+ sent, depending on the reason for the rejection. Before sending a
+ final response, the UAS can also send provisional responses (1xx) to
+ advise the UAC of progress in contacting the called user.
+
+ After possibly receiving one or more provisional responses, the UAC
+ will get one or more 2xx responses or one non-2xx final response.
+ Because of the protracted amount of time it can take to receive final
+ responses to INVITE, the reliability mechanisms for INVITE
+ transactions differ from those of other requests (like OPTIONS).
+ Once it receives a final response, the UAC needs to send an ACK for
+ every final response it receives. The procedure for sending this ACK
+ depends on the type of response. For final responses between 300 and
+ 699, the ACK processing is done in the transaction layer and follows
+ one set of rules (See Section 17). For 2xx responses, the ACK is
+ generated by the UAC core.
+
+ A 2xx response to an INVITE establishes a session, and it also
+ creates a dialog between the UA that issued the INVITE and the UA
+ that generated the 2xx response. Therefore, when multiple 2xx
+ responses are received from different remote UAs (because the INVITE
+ forked), each 2xx establishes a different dialog. All these dialogs
+ are part of the same call.
+
+ This section provides details on the establishment of a session using
+ INVITE. A UA that supports INVITE MUST also support ACK, CANCEL and
+ BYE.
+
+13.2 UAC Processing
+
+13.2.1 Creating the Initial INVITE
+
+ Since the initial INVITE represents a request outside of a dialog,
+ its construction follows the procedures of Section 8.1.1. Additional
+ processing is required for the specific case of INVITE.
+
+ An Allow header field (Section 20.5) SHOULD be present in the INVITE.
+ It indicates what methods can be invoked within a dialog, on the UA
+ sending the INVITE, for the duration of the dialog. For example, a
+ UA capable of receiving INFO requests within a dialog [34] SHOULD
+ include an Allow header field listing the INFO method.
+
+ A Supported header field (Section 20.37) SHOULD be present in the
+ INVITE. It enumerates all the extensions understood by the UAC.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 78]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ An Accept (Section 20.1) header field MAY be present in the INVITE.
+ It indicates which Content-Types are acceptable to the UA, in both
+ the response received by it, and in any subsequent requests sent to
+ it within dialogs established by the INVITE. The Accept header field
+ is especially useful for indicating support of various session
+ description formats.
+
+ The UAC MAY add an Expires header field (Section 20.19) to limit the
+ validity of the invitation. If the time indicated in the Expires
+ header field is reached and no final answer for the INVITE has been
+ received, the UAC core SHOULD generate a CANCEL request for the
+ INVITE, as per Section 9.
+
+ A UAC MAY also find it useful to add, among others, Subject (Section
+ 20.36), Organization (Section 20.25) and User-Agent (Section 20.41)
+ header fields. They all contain information related to the INVITE.
+
+ The UAC MAY choose to add a message body to the INVITE. Section
+ 8.1.1.10 deals with how to construct the header fields -- Content-
+ Type among others -- needed to describe the message body.
+
+ There are special rules for message bodies that contain a session
+ description - their corresponding Content-Disposition is "session".
+ SIP uses an offer/answer model where one UA sends a session
+ description, called the offer, which contains a proposed description
+ of the session. The offer indicates the desired communications means
+ (audio, video, games), parameters of those means (such as codec
+ types) and addresses for receiving media from the answerer. The
+ other UA responds with another session description, called the
+ answer, which indicates which communications means are accepted, the
+ parameters that apply to those means, and addresses for receiving
+ media from the offerer. An offer/answer exchange is within the
+ context of a dialog, so that if a SIP INVITE results in multiple
+ dialogs, each is a separate offer/answer exchange. The offer/answer
+ model defines restrictions on when offers and answers can be made
+ (for example, you cannot make a new offer while one is in progress).
+ This results in restrictions on where the offers and answers can
+ appear in SIP messages. In this specification, offers and answers
+ can only appear in INVITE requests and responses, and ACK. The usage
+ of offers and answers is further restricted. For the initial INVITE
+ transaction, the rules are:
+
+ o The initial offer MUST be in either an INVITE or, if not there,
+ in the first reliable non-failure message from the UAS back to
+ the UAC. In this specification, that is the final 2xx
+ response.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 79]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o If the initial offer is in an INVITE, the answer MUST be in a
+ reliable non-failure message from UAS back to UAC which is
+ correlated to that INVITE. For this specification, that is
+ only the final 2xx response to that INVITE. That same exact
+ answer MAY also be placed in any provisional responses sent
+ prior to the answer. The UAC MUST treat the first session
+ description it receives as the answer, and MUST ignore any
+ session descriptions in subsequent responses to the initial
+ INVITE.
+
+ o If the initial offer is in the first reliable non-failure
+ message from the UAS back to UAC, the answer MUST be in the
+ acknowledgement for that message (in this specification, ACK
+ for a 2xx response).
+
+ o After having sent or received an answer to the first offer, the
+ UAC MAY generate subsequent offers in requests based on rules
+ specified for that method, but only if it has received answers
+ to any previous offers, and has not sent any offers to which it
+ hasn't gotten an answer.
+
+ o Once the UAS has sent or received an answer to the initial
+ offer, it MUST NOT generate subsequent offers in any responses
+ to the initial INVITE. This means that a UAS based on this
+ specification alone can never generate subsequent offers until
+ completion of the initial transaction.
+
+ Concretely, the above rules specify two exchanges for UAs compliant
+ to this specification alone - the offer is in the INVITE, and the
+ answer in the 2xx (and possibly in a 1xx as well, with the same
+ value), or the offer is in the 2xx, and the answer is in the ACK.
+ All user agents that support INVITE MUST support these two exchanges.
+
+ The Session Description Protocol (SDP) (RFC 2327 [1]) MUST be
+ supported by all user agents as a means to describe sessions, and its
+ usage for constructing offers and answers MUST follow the procedures
+ defined in [13].
+
+ The restrictions of the offer-answer model just described only apply
+ to bodies whose Content-Disposition header field value is "session".
+ Therefore, it is possible that both the INVITE and the ACK contain a
+ body message (for example, the INVITE carries a photo (Content-
+ Disposition: render) and the ACK a session description (Content-
+ Disposition: session)).
+
+ If the Content-Disposition header field is missing, bodies of
+ Content-Type application/sdp imply the disposition "session", while
+ other content types imply "render".
+
+
+
+Rosenberg, et. al. Standards Track [Page 80]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Once the INVITE has been created, the UAC follows the procedures
+ defined for sending requests outside of a dialog (Section 8). This
+ results in the construction of a client transaction that will
+ ultimately send the request and deliver responses to the UAC.
+
+13.2.2 Processing INVITE Responses
+
+ Once the INVITE has been passed to the INVITE client transaction, the
+ UAC waits for responses for the INVITE. If the INVITE client
+ transaction returns a timeout rather than a response the TU acts as
+ if a 408 (Request Timeout) response had been received, as described
+ in Section 8.1.3.
+
+13.2.2.1 1xx Responses
+
+ Zero, one or multiple provisional responses may arrive before one or
+ more final responses are received. Provisional responses for an
+ INVITE request can create "early dialogs". If a provisional response
+ has a tag in the To field, and if the dialog ID of the response does
+ not match an existing dialog, one is constructed using the procedures
+ defined in Section 12.1.2.
+
+ The early dialog will only be needed if the UAC needs to send a
+ request to its peer within the dialog before the initial INVITE
+ transaction completes. Header fields present in a provisional
+ response are applicable as long as the dialog is in the early state
+ (for example, an Allow header field in a provisional response
+ contains the methods that can be used in the dialog while this is in
+ the early state).
+
+13.2.2.2 3xx Responses
+
+ A 3xx response may contain one or more Contact header field values
+ providing new addresses where the callee might be reachable.
+ Depending on the status code of the 3xx response (see Section 21.3),
+ the UAC MAY choose to try those new addresses.
+
+13.2.2.3 4xx, 5xx and 6xx Responses
+
+ A single non-2xx final response may be received for the INVITE. 4xx,
+ 5xx and 6xx responses may contain a Contact header field value
+ indicating the location where additional information about the error
+ can be found. Subsequent final responses (which would only arrive
+ under error conditions) MUST be ignored.
+
+ All early dialogs are considered terminated upon reception of the
+ non-2xx final response.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 81]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ After having received the non-2xx final response the UAC core
+ considers the INVITE transaction completed. The INVITE client
+ transaction handles the generation of ACKs for the response (see
+ Section 17).
+
+13.2.2.4 2xx Responses
+
+ Multiple 2xx responses may arrive at the UAC for a single INVITE
+ request due to a forking proxy. Each response is distinguished by
+ the tag parameter in the To header field, and each represents a
+ distinct dialog, with a distinct dialog identifier.
+
+ If the dialog identifier in the 2xx response matches the dialog
+ identifier of an existing dialog, the dialog MUST be transitioned to
+ the "confirmed" state, and the route set for the dialog MUST be
+ recomputed based on the 2xx response using the procedures of Section
+ 12.2.1.2. Otherwise, a new dialog in the "confirmed" state MUST be
+ constructed using the procedures of Section 12.1.2.
+
+ Note that the only piece of state that is recomputed is the route
+ set. Other pieces of state such as the highest sequence numbers
+ (remote and local) sent within the dialog are not recomputed. The
+ route set only is recomputed for backwards compatibility. RFC
+ 2543 did not mandate mirroring of the Record-Route header field in
+ a 1xx, only 2xx. However, we cannot update the entire state of
+ the dialog, since mid-dialog requests may have been sent within
+ the early dialog, modifying the sequence numbers, for example.
+
+ The UAC core MUST generate an ACK request for each 2xx received from
+ the transaction layer. The header fields of the ACK are constructed
+ in the same way as for any request sent within a dialog (see Section
+ 12) with the exception of the CSeq and the header fields related to
+ authentication. The sequence number of the CSeq header field MUST be
+ the same as the INVITE being acknowledged, but the CSeq method MUST
+ be ACK. The ACK MUST contain the same credentials as the INVITE. If
+ the 2xx contains an offer (based on the rules above), the ACK MUST
+ carry an answer in its body. If the offer in the 2xx response is not
+ acceptable, the UAC core MUST generate a valid answer in the ACK and
+ then send a BYE immediately.
+
+ Once the ACK has been constructed, the procedures of [4] are used to
+ determine the destination address, port and transport. However, the
+ request is passed to the transport layer directly for transmission,
+ rather than a client transaction. This is because the UAC core
+ handles retransmissions of the ACK, not the transaction layer. The
+ ACK MUST be passed to the client transport every time a
+ retransmission of the 2xx final response that triggered the ACK
+ arrives.
+
+
+
+Rosenberg, et. al. Standards Track [Page 82]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The UAC core considers the INVITE transaction completed 64*T1 seconds
+ after the reception of the first 2xx response. At this point all the
+ early dialogs that have not transitioned to established dialogs are
+ terminated. Once the INVITE transaction is considered completed by
+ the UAC core, no more new 2xx responses are expected to arrive.
+
+ If, after acknowledging any 2xx response to an INVITE, the UAC does
+ not want to continue with that dialog, then the UAC MUST terminate
+ the dialog by sending a BYE request as described in Section 15.
+
+13.3 UAS Processing
+
+13.3.1 Processing of the INVITE
+
+ The UAS core will receive INVITE requests from the transaction layer.
+ It first performs the request processing procedures of Section 8.2,
+ which are applied for both requests inside and outside of a dialog.
+
+ Assuming these processing states are completed without generating a
+ response, the UAS core performs the additional processing steps:
+
+ 1. If the request is an INVITE that contains an Expires header
+ field, the UAS core sets a timer for the number of seconds
+ indicated in the header field value. When the timer fires, the
+ invitation is considered to be expired. If the invitation
+ expires before the UAS has generated a final response, a 487
+ (Request Terminated) response SHOULD be generated.
+
+ 2. If the request is a mid-dialog request, the method-independent
+ processing described in Section 12.2.2 is first applied. It
+ might also modify the session; Section 14 provides details.
+
+ 3. If the request has a tag in the To header field but the dialog
+ identifier does not match any of the existing dialogs, the UAS
+ may have crashed and restarted, or may have received a request
+ for a different (possibly failed) UAS. Section 12.2.2 provides
+ guidelines to achieve a robust behavior under such a situation.
+
+ Processing from here forward assumes that the INVITE is outside of a
+ dialog, and is thus for the purposes of establishing a new session.
+
+ The INVITE may contain a session description, in which case the UAS
+ is being presented with an offer for that session. It is possible
+ that the user is already a participant in that session, even though
+ the INVITE is outside of a dialog. This can happen when a user is
+ invited to the same multicast conference by multiple other
+ participants. If desired, the UAS MAY use identifiers within the
+ session description to detect this duplication. For example, SDP
+
+
+
+Rosenberg, et. al. Standards Track [Page 83]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ contains a session id and version number in the origin (o) field. If
+ the user is already a member of the session, and the session
+ parameters contained in the session description have not changed, the
+ UAS MAY silently accept the INVITE (that is, send a 2xx response
+ without prompting the user).
+
+ If the INVITE does not contain a session description, the UAS is
+ being asked to participate in a session, and the UAC has asked that
+ the UAS provide the offer of the session. It MUST provide the offer
+ in its first non-failure reliable message back to the UAC. In this
+ specification, that is a 2xx response to the INVITE.
+
+ The UAS can indicate progress, accept, redirect, or reject the
+ invitation. In all of these cases, it formulates a response using
+ the procedures described in Section 8.2.6.
+
+13.3.1.1 Progress
+
+ If the UAS is not able to answer the invitation immediately, it can
+ choose to indicate some kind of progress to the UAC (for example, an
+ indication that a phone is ringing). This is accomplished with a
+ provisional response between 101 and 199. These provisional
+ responses establish early dialogs and therefore follow the procedures
+ of Section 12.1.1 in addition to those of Section 8.2.6. A UAS MAY
+ send as many provisional responses as it likes. Each of these MUST
+ indicate the same dialog ID. However, these will not be delivered
+ reliably.
+
+ If the UAS desires an extended period of time to answer the INVITE,
+ it will need to ask for an "extension" in order to prevent proxies
+ from canceling the transaction. A proxy has the option of canceling
+ a transaction when there is a gap of 3 minutes between responses in a
+ transaction. To prevent cancellation, the UAS MUST send a non-100
+ provisional response at every minute, to handle the possibility of
+ lost provisional responses.
+
+ An INVITE transaction can go on for extended durations when the
+ user is placed on hold, or when interworking with PSTN systems
+ which allow communications to take place without answering the
+ call. The latter is common in Interactive Voice Response (IVR)
+ systems.
+
+13.3.1.2 The INVITE is Redirected
+
+ If the UAS decides to redirect the call, a 3xx response is sent. A
+ 300 (Multiple Choices), 301 (Moved Permanently) or 302 (Moved
+ Temporarily) response SHOULD contain a Contact header field
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 84]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ containing one or more URIs of new addresses to be tried. The
+ response is passed to the INVITE server transaction, which will deal
+ with its retransmissions.
+
+13.3.1.3 The INVITE is Rejected
+
+ A common scenario occurs when the callee is currently not willing or
+ able to take additional calls at this end system. A 486 (Busy Here)
+ SHOULD be returned in such a scenario. If the UAS knows that no
+ other end system will be able to accept this call, a 600 (Busy
+ Everywhere) response SHOULD be sent instead. However, it is unlikely
+ that a UAS will be able to know this in general, and thus this
+ response will not usually be used. The response is passed to the
+ INVITE server transaction, which will deal with its retransmissions.
+
+ A UAS rejecting an offer contained in an INVITE SHOULD return a 488
+ (Not Acceptable Here) response. Such a response SHOULD include a
+ Warning header field value explaining why the offer was rejected.
+
+13.3.1.4 The INVITE is Accepted
+
+ The UAS core generates a 2xx response. This response establishes a
+ dialog, and therefore follows the procedures of Section 12.1.1 in
+ addition to those of Section 8.2.6.
+
+ A 2xx response to an INVITE SHOULD contain the Allow header field and
+ the Supported header field, and MAY contain the Accept header field.
+ Including these header fields allows the UAC to determine the
+ features and extensions supported by the UAS for the duration of the
+ call, without probing.
+
+ If the INVITE request contained an offer, and the UAS had not yet
+ sent an answer, the 2xx MUST contain an answer. If the INVITE did
+ not contain an offer, the 2xx MUST contain an offer if the UAS had
+ not yet sent an offer.
+
+ Once the response has been constructed, it is passed to the INVITE
+ server transaction. Note, however, that the INVITE server
+ transaction will be destroyed as soon as it receives this final
+ response and passes it to the transport. Therefore, it is necessary
+ to periodically pass the response directly to the transport until the
+ ACK arrives. The 2xx response is passed to the transport with an
+ interval that starts at T1 seconds and doubles for each
+ retransmission until it reaches T2 seconds (T1 and T2 are defined in
+ Section 17). Response retransmissions cease when an ACK request for
+ the response is received. This is independent of whatever transport
+ protocols are used to send the response.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 85]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Since 2xx is retransmitted end-to-end, there may be hops between
+ UAS and UAC that are UDP. To ensure reliable delivery across
+ these hops, the response is retransmitted periodically even if the
+ transport at the UAS is reliable.
+
+ If the server retransmits the 2xx response for 64*T1 seconds without
+ receiving an ACK, the dialog is confirmed, but the session SHOULD be
+ terminated. This is accomplished with a BYE, as described in Section
+ 15.
+
+14 Modifying an Existing Session
+
+ A successful INVITE request (see Section 13) establishes both a
+ dialog between two user agents and a session using the offer-answer
+ model. Section 12 explains how to modify an existing dialog using a
+ target refresh request (for example, changing the remote target URI
+ of the dialog). This section describes how to modify the actual
+ session. This modification can involve changing addresses or ports,
+ adding a media stream, deleting a media stream, and so on. This is
+ accomplished by sending a new INVITE request within the same dialog
+ that established the session. An INVITE request sent within an
+ existing dialog is known as a re-INVITE.
+
+ Note that a single re-INVITE can modify the dialog and the
+ parameters of the session at the same time.
+
+ Either the caller or callee can modify an existing session.
+
+ The behavior of a UA on detection of media failure is a matter of
+ local policy. However, automated generation of re-INVITE or BYE is
+ NOT RECOMMENDED to avoid flooding the network with traffic when there
+ is congestion. In any case, if these messages are sent
+ automatically, they SHOULD be sent after some randomized interval.
+
+ Note that the paragraph above refers to automatically generated
+ BYEs and re-INVITEs. If the user hangs up upon media failure, the
+ UA would send a BYE request as usual.
+
+14.1 UAC Behavior
+
+ The same offer-answer model that applies to session descriptions in
+ INVITEs (Section 13.2.1) applies to re-INVITEs. As a result, a UAC
+ that wants to add a media stream, for example, will create a new
+ offer that contains this media stream, and send that in an INVITE
+ request to its peer. It is important to note that the full
+ description of the session, not just the change, is sent. This
+ supports stateless session processing in various elements, and
+ supports failover and recovery capabilities. Of course, a UAC MAY
+
+
+
+Rosenberg, et. al. Standards Track [Page 86]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ send a re-INVITE with no session description, in which case the first
+ reliable non-failure response to the re-INVITE will contain the offer
+ (in this specification, that is a 2xx response).
+
+ If the session description format has the capability for version
+ numbers, the offerer SHOULD indicate that the version of the session
+ description has changed.
+
+ The To, From, Call-ID, CSeq, and Request-URI of a re-INVITE are set
+ following the same rules as for regular requests within an existing
+ dialog, described in Section 12.
+
+ A UAC MAY choose not to add an Alert-Info header field or a body with
+ Content-Disposition "alert" to re-INVITEs because UASs do not
+ typically alert the user upon reception of a re-INVITE.
+
+ Unlike an INVITE, which can fork, a re-INVITE will never fork, and
+ therefore, only ever generate a single final response. The reason a
+ re-INVITE will never fork is that the Request-URI identifies the
+ target as the UA instance it established the dialog with, rather than
+ identifying an address-of-record for the user.
+
+ Note that a UAC MUST NOT initiate a new INVITE transaction within a
+ dialog while another INVITE transaction is in progress in either
+ direction.
+
+ 1. If there is an ongoing INVITE client transaction, the TU MUST
+ wait until the transaction reaches the completed or terminated
+ state before initiating the new INVITE.
+
+ 2. If there is an ongoing INVITE server transaction, the TU MUST
+ wait until the transaction reaches the confirmed or terminated
+ state before initiating the new INVITE.
+
+ However, a UA MAY initiate a regular transaction while an INVITE
+ transaction is in progress. A UA MAY also initiate an INVITE
+ transaction while a regular transaction is in progress.
+
+ If a UA receives a non-2xx final response to a re-INVITE, the session
+ parameters MUST remain unchanged, as if no re-INVITE had been issued.
+ Note that, as stated in Section 12.2.1.2, if the non-2xx final
+ response is a 481 (Call/Transaction Does Not Exist), or a 408
+ (Request Timeout), or no response at all is received for the re-
+ INVITE (that is, a timeout is returned by the INVITE client
+ transaction), the UAC will terminate the dialog.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 87]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If a UAC receives a 491 response to a re-INVITE, it SHOULD start a
+ timer with a value T chosen as follows:
+
+ 1. If the UAC is the owner of the Call-ID of the dialog ID
+ (meaning it generated the value), T has a randomly chosen value
+ between 2.1 and 4 seconds in units of 10 ms.
+
+ 2. If the UAC is not the owner of the Call-ID of the dialog ID, T
+ has a randomly chosen value of between 0 and 2 seconds in units
+ of 10 ms.
+
+ When the timer fires, the UAC SHOULD attempt the re-INVITE once more,
+ if it still desires for that session modification to take place. For
+ example, if the call was already hung up with a BYE, the re-INVITE
+ would not take place.
+
+ The rules for transmitting a re-INVITE and for generating an ACK for
+ a 2xx response to re-INVITE are the same as for the initial INVITE
+ (Section 13.2.1).
+
+14.2 UAS Behavior
+
+ Section 13.3.1 describes the procedure for distinguishing incoming
+ re-INVITEs from incoming initial INVITEs and handling a re-INVITE for
+ an existing dialog.
+
+ A UAS that receives a second INVITE before it sends the final
+ response to a first INVITE with a lower CSeq sequence number on the
+ same dialog MUST return a 500 (Server Internal Error) response to the
+ second INVITE and MUST include a Retry-After header field with a
+ randomly chosen value of between 0 and 10 seconds.
+
+ A UAS that receives an INVITE on a dialog while an INVITE it had sent
+ on that dialog is in progress MUST return a 491 (Request Pending)
+ response to the received INVITE.
+
+ If a UA receives a re-INVITE for an existing dialog, it MUST check
+ any version identifiers in the session description or, if there are
+ no version identifiers, the content of the session description to see
+ if it has changed. If the session description has changed, the UAS
+ MUST adjust the session parameters accordingly, possibly after asking
+ the user for confirmation.
+
+ Versioning of the session description can be used to accommodate
+ the capabilities of new arrivals to a conference, add or delete
+ media, or change from a unicast to a multicast conference.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 88]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If the new session description is not acceptable, the UAS can reject
+ it by returning a 488 (Not Acceptable Here) response for the re-
+ INVITE. This response SHOULD include a Warning header field.
+
+ If a UAS generates a 2xx response and never receives an ACK, it
+ SHOULD generate a BYE to terminate the dialog.
+
+ A UAS MAY choose not to generate 180 (Ringing) responses for a re-
+ INVITE because UACs do not typically render this information to the
+ user. For the same reason, UASs MAY choose not to use an Alert-Info
+ header field or a body with Content-Disposition "alert" in responses
+ to a re-INVITE.
+
+ A UAS providing an offer in a 2xx (because the INVITE did not contain
+ an offer) SHOULD construct the offer as if the UAS were making a
+ brand new call, subject to the constraints of sending an offer that
+ updates an existing session, as described in [13] in the case of SDP.
+ Specifically, this means that it SHOULD include as many media formats
+ and media types that the UA is willing to support. The UAS MUST
+ ensure that the session description overlaps with its previous
+ session description in media formats, transports, or other parameters
+ that require support from the peer. This is to avoid the need for
+ the peer to reject the session description. If, however, it is
+ unacceptable to the UAC, the UAC SHOULD generate an answer with a
+ valid session description, and then send a BYE to terminate the
+ session.
+
+15 Terminating a Session
+
+ This section describes the procedures for terminating a session
+ established by SIP. The state of the session and the state of the
+ dialog are very closely related. When a session is initiated with an
+ INVITE, each 1xx or 2xx response from a distinct UAS creates a
+ dialog, and if that response completes the offer/answer exchange, it
+ also creates a session. As a result, each session is "associated"
+ with a single dialog - the one which resulted in its creation. If an
+ initial INVITE generates a non-2xx final response, that terminates
+ all sessions (if any) and all dialogs (if any) that were created
+ through responses to the request. By virtue of completing the
+ transaction, a non-2xx final response also prevents further sessions
+ from being created as a result of the INVITE. The BYE request is
+ used to terminate a specific session or attempted session. In this
+ case, the specific session is the one with the peer UA on the other
+ side of the dialog. When a BYE is received on a dialog, any session
+ associated with that dialog SHOULD terminate. A UA MUST NOT send a
+ BYE outside of a dialog. The caller's UA MAY send a BYE for either
+ confirmed or early dialogs, and the callee's UA MAY send a BYE on
+ confirmed dialogs, but MUST NOT send a BYE on early dialogs.
+
+
+
+Rosenberg, et. al. Standards Track [Page 89]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ However, the callee's UA MUST NOT send a BYE on a confirmed dialog
+ until it has received an ACK for its 2xx response or until the server
+ transaction times out. If no SIP extensions have defined other
+ application layer states associated with the dialog, the BYE also
+ terminates the dialog.
+
+ The impact of a non-2xx final response to INVITE on dialogs and
+ sessions makes the use of CANCEL attractive. The CANCEL attempts to
+ force a non-2xx response to the INVITE (in particular, a 487).
+ Therefore, if a UAC wishes to give up on its call attempt entirely,
+ it can send a CANCEL. If the INVITE results in 2xx final response(s)
+ to the INVITE, this means that a UAS accepted the invitation while
+ the CANCEL was in progress. The UAC MAY continue with the sessions
+ established by any 2xx responses, or MAY terminate them with BYE.
+
+ The notion of "hanging up" is not well defined within SIP. It is
+ specific to a particular, albeit common, user interface.
+ Typically, when the user hangs up, it indicates a desire to
+ terminate the attempt to establish a session, and to terminate any
+ sessions already created. For the caller's UA, this would imply a
+ CANCEL request if the initial INVITE has not generated a final
+ response, and a BYE to all confirmed dialogs after a final
+ response. For the callee's UA, it would typically imply a BYE;
+ presumably, when the user picked up the phone, a 2xx was
+ generated, and so hanging up would result in a BYE after the ACK
+ is received. This does not mean a user cannot hang up before
+ receipt of the ACK, it just means that the software in his phone
+ needs to maintain state for a short while in order to clean up
+ properly. If the particular UI allows for the user to reject a
+ call before its answered, a 403 (Forbidden) is a good way to
+ express that. As per the rules above, a BYE can't be sent.
+
+15.1 Terminating a Session with a BYE Request
+
+15.1.1 UAC Behavior
+
+ A BYE request is constructed as would any other request within a
+ dialog, as described in Section 12.
+
+ Once the BYE is constructed, the UAC core creates a new non-INVITE
+ client transaction, and passes it the BYE request. The UAC MUST
+ consider the session terminated (and therefore stop sending or
+ listening for media) as soon as the BYE request is passed to the
+ client transaction. If the response for the BYE is a 481
+ (Call/Transaction Does Not Exist) or a 408 (Request Timeout) or no
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 90]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ response at all is received for the BYE (that is, a timeout is
+ returned by the client transaction), the UAC MUST consider the
+ session and the dialog terminated.
+
+15.1.2 UAS Behavior
+
+ A UAS first processes the BYE request according to the general UAS
+ processing described in Section 8.2. A UAS core receiving a BYE
+ request checks if it matches an existing dialog. If the BYE does not
+ match an existing dialog, the UAS core SHOULD generate a 481
+ (Call/Transaction Does Not Exist) response and pass that to the
+ server transaction.
+
+ This rule means that a BYE sent without tags by a UAC will be
+ rejected. This is a change from RFC 2543, which allowed BYE
+ without tags.
+
+ A UAS core receiving a BYE request for an existing dialog MUST follow
+ the procedures of Section 12.2.2 to process the request. Once done,
+ the UAS SHOULD terminate the session (and therefore stop sending and
+ listening for media). The only case where it can elect not to are
+ multicast sessions, where participation is possible even if the other
+ participant in the dialog has terminated its involvement in the
+ session. Whether or not it ends its participation on the session,
+ the UAS core MUST generate a 2xx response to the BYE, and MUST pass
+ that to the server transaction for transmission.
+
+ The UAS MUST still respond to any pending requests received for that
+ dialog. It is RECOMMENDED that a 487 (Request Terminated) response
+ be generated to those pending requests.
+
+16 Proxy Behavior
+
+16.1 Overview
+
+ SIP proxies are elements that route SIP requests to user agent
+ servers and SIP responses to user agent clients. A request may
+ traverse several proxies on its way to a UAS. Each will make routing
+ decisions, modifying the request before forwarding it to the next
+ element. Responses will route through the same set of proxies
+ traversed by the request in the reverse order.
+
+ Being a proxy is a logical role for a SIP element. When a request
+ arrives, an element that can play the role of a proxy first decides
+ if it needs to respond to the request on its own. For instance, the
+ request may be malformed or the element may need credentials from the
+ client before acting as a proxy. The element MAY respond with any
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 91]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ appropriate error code. When responding directly to a request, the
+ element is playing the role of a UAS and MUST behave as described in
+ Section 8.2.
+
+ A proxy can operate in either a stateful or stateless mode for each
+ new request. When stateless, a proxy acts as a simple forwarding
+ element. It forwards each request downstream to a single element
+ determined by making a targeting and routing decision based on the
+ request. It simply forwards every response it receives upstream. A
+ stateless proxy discards information about a message once the message
+ has been forwarded. A stateful proxy remembers information
+ (specifically, transaction state) about each incoming request and any
+ requests it sends as a result of processing the incoming request. It
+ uses this information to affect the processing of future messages
+ associated with that request. A stateful proxy MAY choose to "fork"
+ a request, routing it to multiple destinations. Any request that is
+ forwarded to more than one location MUST be handled statefully.
+
+ In some circumstances, a proxy MAY forward requests using stateful
+ transports (such as TCP) without being transaction-stateful. For
+ instance, a proxy MAY forward a request from one TCP connection to
+ another transaction statelessly as long as it places enough
+ information in the message to be able to forward the response down
+ the same connection the request arrived on. Requests forwarded
+ between different types of transports where the proxy's TU must take
+ an active role in ensuring reliable delivery on one of the transports
+ MUST be forwarded transaction statefully.
+
+ A stateful proxy MAY transition to stateless operation at any time
+ during the processing of a request, so long as it did not do anything
+ that would otherwise prevent it from being stateless initially
+ (forking, for example, or generation of a 100 response). When
+ performing such a transition, all state is simply discarded. The
+ proxy SHOULD NOT initiate a CANCEL request.
+
+ Much of the processing involved when acting statelessly or statefully
+ for a request is identical. The next several subsections are written
+ from the point of view of a stateful proxy. The last section calls
+ out those places where a stateless proxy behaves differently.
+
+16.2 Stateful Proxy
+
+ When stateful, a proxy is purely a SIP transaction processing engine.
+ Its behavior is modeled here in terms of the server and client
+ transactions defined in Section 17. A stateful proxy has a server
+ transaction associated with one or more client transactions by a
+ higher layer proxy processing component (see figure 3), known as a
+ proxy core. An incoming request is processed by a server
+
+
+
+Rosenberg, et. al. Standards Track [Page 92]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ transaction. Requests from the server transaction are passed to a
+ proxy core. The proxy core determines where to route the request,
+ choosing one or more next-hop locations. An outgoing request for
+ each next-hop location is processed by its own associated client
+ transaction. The proxy core collects the responses from the client
+ transactions and uses them to send responses to the server
+ transaction.
+
+ A stateful proxy creates a new server transaction for each new
+ request received. Any retransmissions of the request will then be
+ handled by that server transaction per Section 17. The proxy core
+ MUST behave as a UAS with respect to sending an immediate provisional
+ on that server transaction (such as 100 Trying) as described in
+ Section 8.2.6. Thus, a stateful proxy SHOULD NOT generate 100
+ (Trying) responses to non-INVITE requests.
+
+ This is a model of proxy behavior, not of software. An
+ implementation is free to take any approach that replicates the
+ external behavior this model defines.
+
+ For all new requests, including any with unknown methods, an element
+ intending to proxy the request MUST:
+
+ 1. Validate the request (Section 16.3)
+
+ 2. Preprocess routing information (Section 16.4)
+
+ 3. Determine target(s) for the request (Section 16.5)
+
+ +--------------------+
+ | | +---+
+ | | | C |
+ | | | T |
+ | | +---+
+ +---+ | Proxy | +---+ CT = Client Transaction
+ | S | | "Higher" Layer | | C |
+ | T | | | | T | ST = Server Transaction
+ +---+ | | +---+
+ | | +---+
+ | | | C |
+ | | | T |
+ | | +---+
+ +--------------------+
+
+ Figure 3: Stateful Proxy Model
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 93]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 4. Forward the request to each target (Section 16.6)
+
+ 5. Process all responses (Section 16.7)
+
+16.3 Request Validation
+
+ Before an element can proxy a request, it MUST verify the message's
+ validity. A valid message must pass the following checks:
+
+ 1. Reasonable Syntax
+
+ 2. URI scheme
+
+ 3. Max-Forwards
+
+ 4. (Optional) Loop Detection
+
+ 5. Proxy-Require
+
+ 6. Proxy-Authorization
+
+ If any of these checks fail, the element MUST behave as a user agent
+ server (see Section 8.2) and respond with an error code.
+
+ Notice that a proxy is not required to detect merged requests and
+ MUST NOT treat merged requests as an error condition. The endpoints
+ receiving the requests will resolve the merge as described in Section
+ 8.2.2.2.
+
+ 1. Reasonable syntax check
+
+ The request MUST be well-formed enough to be handled with a server
+ transaction. Any components involved in the remainder of these
+ Request Validation steps or the Request Forwarding section MUST be
+ well-formed. Any other components, well-formed or not, SHOULD be
+ ignored and remain unchanged when the message is forwarded. For
+ instance, an element would not reject a request because of a
+ malformed Date header field. Likewise, a proxy would not remove a
+ malformed Date header field before forwarding a request.
+
+ This protocol is designed to be extended. Future extensions may
+ define new methods and header fields at any time. An element MUST
+ NOT refuse to proxy a request because it contains a method or
+ header field it does not know about.
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 94]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 2. URI scheme check
+
+ If the Request-URI has a URI whose scheme is not understood by the
+ proxy, the proxy SHOULD reject the request with a 416 (Unsupported
+ URI Scheme) response.
+
+ 3. Max-Forwards check
+
+ The Max-Forwards header field (Section 20.22) is used to limit the
+ number of elements a SIP request can traverse.
+
+ If the request does not contain a Max-Forwards header field, this
+ check is passed.
+
+ If the request contains a Max-Forwards header field with a field
+ value greater than zero, the check is passed.
+
+ If the request contains a Max-Forwards header field with a field
+ value of zero (0), the element MUST NOT forward the request. If
+ the request was for OPTIONS, the element MAY act as the final
+ recipient and respond per Section 11. Otherwise, the element MUST
+ return a 483 (Too many hops) response.
+
+ 4. Optional Loop Detection check
+
+ An element MAY check for forwarding loops before forwarding a
+ request. If the request contains a Via header field with a sent-
+ by value that equals a value placed into previous requests by the
+ proxy, the request has been forwarded by this element before. The
+ request has either looped or is legitimately spiraling through the
+ element. To determine if the request has looped, the element MAY
+ perform the branch parameter calculation described in Step 8 of
+ Section 16.6 on this message and compare it to the parameter
+ received in that Via header field. If the parameters match, the
+ request has looped. If they differ, the request is spiraling, and
+ processing continues. If a loop is detected, the element MAY
+ return a 482 (Loop Detected) response.
+
+ 5. Proxy-Require check
+
+ Future extensions to this protocol may introduce features that
+ require special handling by proxies. Endpoints will include a
+ Proxy-Require header field in requests that use these features,
+ telling the proxy not to process the request unless the feature is
+ understood.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 95]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If the request contains a Proxy-Require header field (Section
+ 20.29) with one or more option-tags this element does not
+ understand, the element MUST return a 420 (Bad Extension)
+ response. The response MUST include an Unsupported (Section
+ 20.40) header field listing those option-tags the element did not
+ understand.
+
+ 6. Proxy-Authorization check
+
+ If an element requires credentials before forwarding a request,
+ the request MUST be inspected as described in Section 22.3. That
+ section also defines what the element must do if the inspection
+ fails.
+
+16.4 Route Information Preprocessing
+
+ The proxy MUST inspect the Request-URI of the request. If the
+ Request-URI of the request contains a value this proxy previously
+ placed into a Record-Route header field (see Section 16.6 item 4),
+ the proxy MUST replace the Request-URI in the request with the last
+ value from the Route header field, and remove that value from the
+ Route header field. The proxy MUST then proceed as if it received
+ this modified request.
+
+ This will only happen when the element sending the request to the
+ proxy (which may have been an endpoint) is a strict router. This
+ rewrite on receive is necessary to enable backwards compatibility
+ with those elements. It also allows elements following this
+ specification to preserve the Request-URI through strict-routing
+ proxies (see Section 12.2.1.1).
+
+ This requirement does not obligate a proxy to keep state in order
+ to detect URIs it previously placed in Record-Route header fields.
+ Instead, a proxy need only place enough information in those URIs
+ to recognize them as values it provided when they later appear.
+
+ If the Request-URI contains a maddr parameter, the proxy MUST check
+ to see if its value is in the set of addresses or domains the proxy
+ is configured to be responsible for. If the Request-URI has a maddr
+ parameter with a value the proxy is responsible for, and the request
+ was received using the port and transport indicated (explicitly or by
+ default) in the Request-URI, the proxy MUST strip the maddr and any
+ non-default port or transport parameter and continue processing as if
+ those values had not been present in the request.
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 96]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ A request may arrive with a maddr matching the proxy, but on a
+ port or transport different from that indicated in the URI. Such
+ a request needs to be forwarded to the proxy using the indicated
+ port and transport.
+
+ If the first value in the Route header field indicates this proxy,
+ the proxy MUST remove that value from the request.
+
+16.5 Determining Request Targets
+
+ Next, the proxy calculates the target(s) of the request. The set of
+ targets will either be predetermined by the contents of the request
+ or will be obtained from an abstract location service. Each target
+ in the set is represented as a URI.
+
+ If the Request-URI of the request contains an maddr parameter, the
+ Request-URI MUST be placed into the target set as the only target
+ URI, and the proxy MUST proceed to Section 16.6.
+
+ If the domain of the Request-URI indicates a domain this element is
+ not responsible for, the Request-URI MUST be placed into the target
+ set as the only target, and the element MUST proceed to the task of
+ Request Forwarding (Section 16.6).
+
+ There are many circumstances in which a proxy might receive a
+ request for a domain it is not responsible for. A firewall proxy
+ handling outgoing calls (the way HTTP proxies handle outgoing
+ requests) is an example of where this is likely to occur.
+
+ If the target set for the request has not been predetermined as
+ described above, this implies that the element is responsible for the
+ domain in the Request-URI, and the element MAY use whatever mechanism
+ it desires to determine where to send the request. Any of these
+ mechanisms can be modeled as accessing an abstract Location Service.
+ This may consist of obtaining information from a location service
+ created by a SIP Registrar, reading a database, consulting a presence
+ server, utilizing other protocols, or simply performing an
+ algorithmic substitution on the Request-URI. When accessing the
+ location service constructed by a registrar, the Request-URI MUST
+ first be canonicalized as described in Section 10.3 before being used
+ as an index. The output of these mechanisms is used to construct the
+ target set.
+
+ If the Request-URI does not provide sufficient information for the
+ proxy to determine the target set, it SHOULD return a 485 (Ambiguous)
+ response. This response SHOULD contain a Contact header field
+ containing URIs of new addresses to be tried. For example, an INVITE
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 97]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ to sip:John.Smith@company.com may be ambiguous at a proxy whose
+ location service has multiple John Smiths listed. See Section
+ 21.4.23 for details.
+
+ Any information in or about the request or the current environment of
+ the element MAY be used in the construction of the target set. For
+ instance, different sets may be constructed depending on contents or
+ the presence of header fields and bodies, the time of day of the
+ request's arrival, the interface on which the request arrived,
+ failure of previous requests, or even the element's current level of
+ utilization.
+
+ As potential targets are located through these services, their URIs
+ are added to the target set. Targets can only be placed in the
+ target set once. If a target URI is already present in the set
+ (based on the definition of equality for the URI type), it MUST NOT
+ be added again.
+
+ A proxy MUST NOT add additional targets to the target set if the
+ Request-URI of the original request does not indicate a resource this
+ proxy is responsible for.
+
+ A proxy can only change the Request-URI of a request during
+ forwarding if it is responsible for that URI. If the proxy is not
+ responsible for that URI, it will not recurse on 3xx or 416
+ responses as described below.
+
+ If the Request-URI of the original request indicates a resource this
+ proxy is responsible for, the proxy MAY continue to add targets to
+ the set after beginning Request Forwarding. It MAY use any
+ information obtained during that processing to determine new targets.
+ For instance, a proxy may choose to incorporate contacts obtained in
+ a redirect response (3xx) into the target set. If a proxy uses a
+ dynamic source of information while building the target set (for
+ instance, if it consults a SIP Registrar), it SHOULD monitor that
+ source for the duration of processing the request. New locations
+ SHOULD be added to the target set as they become available. As
+ above, any given URI MUST NOT be added to the set more than once.
+
+ Allowing a URI to be added to the set only once reduces
+ unnecessary network traffic, and in the case of incorporating
+ contacts from redirect requests prevents infinite recursion.
+
+ For example, a trivial location service is a "no-op", where the
+ target URI is equal to the incoming request URI. The request is sent
+ to a specific next hop proxy for further processing. During request
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 98]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ forwarding of Section 16.6, Item 6, the identity of that next hop,
+ expressed as a SIP or SIPS URI, is inserted as the top-most Route
+ header field value into the request.
+
+ If the Request-URI indicates a resource at this proxy that does not
+ exist, the proxy MUST return a 404 (Not Found) response.
+
+ If the target set remains empty after applying all of the above, the
+ proxy MUST return an error response, which SHOULD be the 480
+ (Temporarily Unavailable) response.
+
+16.6 Request Forwarding
+
+ As soon as the target set is non-empty, a proxy MAY begin forwarding
+ the request. A stateful proxy MAY process the set in any order. It
+ MAY process multiple targets serially, allowing each client
+ transaction to complete before starting the next. It MAY start
+ client transactions with every target in parallel. It also MAY
+ arbitrarily divide the set into groups, processing the groups
+ serially and processing the targets in each group in parallel.
+
+ A common ordering mechanism is to use the qvalue parameter of targets
+ obtained from Contact header fields (see Section 20.10). Targets are
+ processed from highest qvalue to lowest. Targets with equal qvalues
+ may be processed in parallel.
+
+ A stateful proxy must have a mechanism to maintain the target set as
+ responses are received and associate the responses to each forwarded
+ request with the original request. For the purposes of this model,
+ this mechanism is a "response context" created by the proxy layer
+ before forwarding the first request.
+
+ For each target, the proxy forwards the request following these
+ steps:
+
+ 1. Make a copy of the received request
+
+ 2. Update the Request-URI
+
+ 3. Update the Max-Forwards header field
+
+ 4. Optionally add a Record-route header field value
+
+ 5. Optionally add additional header fields
+
+ 6. Postprocess routing information
+
+ 7. Determine the next-hop address, port, and transport
+
+
+
+Rosenberg, et. al. Standards Track [Page 99]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 8. Add a Via header field value
+
+ 9. Add a Content-Length header field if necessary
+
+ 10. Forward the new request
+
+ 11. Set timer C
+
+ Each of these steps is detailed below:
+
+ 1. Copy request
+
+ The proxy starts with a copy of the received request. The copy
+ MUST initially contain all of the header fields from the
+ received request. Fields not detailed in the processing
+ described below MUST NOT be removed. The copy SHOULD maintain
+ the ordering of the header fields as in the received request.
+ The proxy MUST NOT reorder field values with a common field
+ name (See Section 7.3.1). The proxy MUST NOT add to, modify,
+ or remove the message body.
+
+ An actual implementation need not perform a copy; the primary
+ requirement is that the processing for each next hop begin with
+ the same request.
+
+ 2. Request-URI
+
+ The Request-URI in the copy's start line MUST be replaced with
+ the URI for this target. If the URI contains any parameters
+ not allowed in a Request-URI, they MUST be removed.
+
+ This is the essence of a proxy's role. This is the mechanism
+ through which a proxy routes a request toward its destination.
+
+ In some circumstances, the received Request-URI is placed into
+ the target set without being modified. For that target, the
+ replacement above is effectively a no-op.
+
+ 3. Max-Forwards
+
+ If the copy contains a Max-Forwards header field, the proxy
+ MUST decrement its value by one (1).
+
+ If the copy does not contain a Max-Forwards header field, the
+ proxy MUST add one with a field value, which SHOULD be 70.
+
+ Some existing UAs will not provide a Max-Forwards header field
+ in a request.
+
+
+
+Rosenberg, et. al. Standards Track [Page 100]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 4. Record-Route
+
+ If this proxy wishes to remain on the path of future requests
+ in a dialog created by this request (assuming the request
+ creates a dialog), it MUST insert a Record-Route header field
+ value into the copy before any existing Record-Route header
+ field values, even if a Route header field is already present.
+
+ Requests establishing a dialog may contain a preloaded Route
+ header field.
+
+ If this request is already part of a dialog, the proxy SHOULD
+ insert a Record-Route header field value if it wishes to remain
+ on the path of future requests in the dialog. In normal
+ endpoint operation as described in Section 12, these Record-
+ Route header field values will not have any effect on the route
+ sets used by the endpoints.
+
+ The proxy will remain on the path if it chooses to not insert a
+ Record-Route header field value into requests that are already
+ part of a dialog. However, it would be removed from the path
+ when an endpoint that has failed reconstitutes the dialog.
+
+ A proxy MAY insert a Record-Route header field value into any
+ request. If the request does not initiate a dialog, the
+ endpoints will ignore the value. See Section 12 for details on
+ how endpoints use the Record-Route header field values to
+ construct Route header fields.
+
+ Each proxy in the path of a request chooses whether to add a
+ Record-Route header field value independently - the presence of
+ a Record-Route header field in a request does not obligate this
+ proxy to add a value.
+
+ The URI placed in the Record-Route header field value MUST be a
+ SIP or SIPS URI. This URI MUST contain an lr parameter (see
+ Section 19.1.1). This URI MAY be different for each
+ destination the request is forwarded to. The URI SHOULD NOT
+ contain the transport parameter unless the proxy has knowledge
+ (such as in a private network) that the next downstream element
+ that will be in the path of subsequent requests supports that
+ transport.
+
+ The URI this proxy provides will be used by some other element
+ to make a routing decision. This proxy, in general, has no way
+ of knowing the capabilities of that element, so it must
+ restrict itself to the mandatory elements of a SIP
+ implementation: SIP URIs and either the TCP or UDP transports.
+
+
+
+Rosenberg, et. al. Standards Track [Page 101]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The URI placed in the Record-Route header field MUST resolve to
+ the element inserting it (or a suitable stand-in) when the
+ server location procedures of [4] are applied to it, so that
+ subsequent requests reach the same SIP element. If the
+ Request-URI contains a SIPS URI, or the topmost Route header
+ field value (after the post processing of bullet 6) contains a
+ SIPS URI, the URI placed into the Record-Route header field
+ MUST be a SIPS URI. Furthermore, if the request was not
+ received over TLS, the proxy MUST insert a Record-Route header
+ field. In a similar fashion, a proxy that receives a request
+ over TLS, but generates a request without a SIPS URI in the
+ Request-URI or topmost Route header field value (after the post
+ processing of bullet 6), MUST insert a Record-Route header
+ field that is not a SIPS URI.
+
+ A proxy at a security perimeter must remain on the perimeter
+ throughout the dialog.
+
+ If the URI placed in the Record-Route header field needs to be
+ rewritten when it passes back through in a response, the URI
+ MUST be distinct enough to locate at that time. (The request
+ may spiral through this proxy, resulting in more than one
+ Record-Route header field value being added). Item 8 of
+ Section 16.7 recommends a mechanism to make the URI
+ sufficiently distinct.
+
+ The proxy MAY include parameters in the Record-Route header
+ field value. These will be echoed in some responses to the
+ request such as the 200 (OK) responses to INVITE. Such
+ parameters may be useful for keeping state in the message
+ rather than the proxy.
+
+ If a proxy needs to be in the path of any type of dialog (such
+ as one straddling a firewall), it SHOULD add a Record-Route
+ header field value to every request with a method it does not
+ understand since that method may have dialog semantics.
+
+ The URI a proxy places into a Record-Route header field is only
+ valid for the lifetime of any dialog created by the transaction
+ in which it occurs. A dialog-stateful proxy, for example, MAY
+ refuse to accept future requests with that value in the
+ Request-URI after the dialog has terminated. Non-dialog-
+ stateful proxies, of course, have no concept of when the dialog
+ has terminated, but they MAY encode enough information in the
+ value to compare it against the dialog identifier of future
+ requests and MAY reject requests not matching that information.
+ Endpoints MUST NOT use a URI obtained from a Record-Route
+ header field outside the dialog in which it was provided. See
+
+
+
+Rosenberg, et. al. Standards Track [Page 102]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Section 12 for more information on an endpoint's use of
+ Record-Route header fields.
+
+ Record-routing may be required by certain services where the
+ proxy needs to observe all messages in a dialog. However, it
+ slows down processing and impairs scalability and thus proxies
+ should only record-route if required for a particular service.
+
+ The Record-Route process is designed to work for any SIP
+ request that initiates a dialog. INVITE is the only such
+ request in this specification, but extensions to the protocol
+ MAY define others.
+
+ 5. Add Additional Header Fields
+
+ The proxy MAY add any other appropriate header fields to the
+ copy at this point.
+
+ 6. Postprocess routing information
+
+ A proxy MAY have a local policy that mandates that a request
+ visit a specific set of proxies before being delivered to the
+ destination. A proxy MUST ensure that all such proxies are
+ loose routers. Generally, this can only be known with
+ certainty if the proxies are within the same administrative
+ domain. This set of proxies is represented by a set of URIs
+ (each of which contains the lr parameter). This set MUST be
+ pushed into the Route header field of the copy ahead of any
+ existing values, if present. If the Route header field is
+ absent, it MUST be added, containing that list of URIs.
+
+ If the proxy has a local policy that mandates that the request
+ visit one specific proxy, an alternative to pushing a Route
+ value into the Route header field is to bypass the forwarding
+ logic of item 10 below, and instead just send the request to
+ the address, port, and transport for that specific proxy. If
+ the request has a Route header field, this alternative MUST NOT
+ be used unless it is known that next hop proxy is a loose
+ router. Otherwise, this approach MAY be used, but the Route
+ insertion mechanism above is preferred for its robustness,
+ flexibility, generality and consistency of operation.
+ Furthermore, if the Request-URI contains a SIPS URI, TLS MUST
+ be used to communicate with that proxy.
+
+ If the copy contains a Route header field, the proxy MUST
+ inspect the URI in its first value. If that URI does not
+ contain an lr parameter, the proxy MUST modify the copy as
+ follows:
+
+
+
+Rosenberg, et. al. Standards Track [Page 103]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ - The proxy MUST place the Request-URI into the Route header
+ field as the last value.
+
+ - The proxy MUST then place the first Route header field value
+ into the Request-URI and remove that value from the Route
+ header field.
+
+ Appending the Request-URI to the Route header field is part of
+ a mechanism used to pass the information in that Request-URI
+ through strict-routing elements. "Popping" the first Route
+ header field value into the Request-URI formats the message the
+ way a strict-routing element expects to receive it (with its
+ own URI in the Request-URI and the next location to visit in
+ the first Route header field value).
+
+ 7. Determine Next-Hop Address, Port, and Transport
+
+ The proxy MAY have a local policy to send the request to a
+ specific IP address, port, and transport, independent of the
+ values of the Route and Request-URI. Such a policy MUST NOT be
+ used if the proxy is not certain that the IP address, port, and
+ transport correspond to a server that is a loose router.
+ However, this mechanism for sending the request through a
+ specific next hop is NOT RECOMMENDED; instead a Route header
+ field should be used for that purpose as described above.
+
+ In the absence of such an overriding mechanism, the proxy
+ applies the procedures listed in [4] as follows to determine
+ where to send the request. If the proxy has reformatted the
+ request to send to a strict-routing element as described in
+ step 6 above, the proxy MUST apply those procedures to the
+ Request-URI of the request. Otherwise, the proxy MUST apply
+ the procedures to the first value in the Route header field, if
+ present, else the Request-URI. The procedures will produce an
+ ordered set of (address, port, transport) tuples.
+ Independently of which URI is being used as input to the
+ procedures of [4], if the Request-URI specifies a SIPS
+ resource, the proxy MUST follow the procedures of [4] as if the
+ input URI were a SIPS URI.
+
+ As described in [4], the proxy MUST attempt to deliver the
+ message to the first tuple in that set, and proceed through the
+ set in order until the delivery attempt succeeds.
+
+ For each tuple attempted, the proxy MUST format the message as
+ appropriate for the tuple and send the request using a new
+ client transaction as detailed in steps 8 through 10.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 104]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Since each attempt uses a new client transaction, it represents
+ a new branch. Thus, the branch parameter provided with the Via
+ header field inserted in step 8 MUST be different for each
+ attempt.
+
+ If the client transaction reports failure to send the request
+ or a timeout from its state machine, the proxy continues to the
+ next address in that ordered set. If the ordered set is
+ exhausted, the request cannot be forwarded to this element in
+ the target set. The proxy does not need to place anything in
+ the response context, but otherwise acts as if this element of
+ the target set returned a 408 (Request Timeout) final response.
+
+ 8. Add a Via header field value
+
+ The proxy MUST insert a Via header field value into the copy
+ before the existing Via header field values. The construction
+ of this value follows the same guidelines of Section 8.1.1.7.
+ This implies that the proxy will compute its own branch
+ parameter, which will be globally unique for that branch, and
+ contain the requisite magic cookie. Note that this implies that
+ the branch parameter will be different for different instances
+ of a spiraled or looped request through a proxy.
+
+ Proxies choosing to detect loops have an additional constraint
+ in the value they use for construction of the branch parameter.
+ A proxy choosing to detect loops SHOULD create a branch
+ parameter separable into two parts by the implementation. The
+ first part MUST satisfy the constraints of Section 8.1.1.7 as
+ described above. The second is used to perform loop detection
+ and distinguish loops from spirals.
+
+ Loop detection is performed by verifying that, when a request
+ returns to a proxy, those fields having an impact on the
+ processing of the request have not changed. The value placed
+ in this part of the branch parameter SHOULD reflect all of
+ those fields (including any Route, Proxy-Require and Proxy-
+ Authorization header fields). This is to ensure that if the
+ request is routed back to the proxy and one of those fields
+ changes, it is treated as a spiral and not a loop (see Section
+ 16.3). A common way to create this value is to compute a
+ cryptographic hash of the To tag, From tag, Call-ID header
+ field, the Request-URI of the request received (before
+ translation), the topmost Via header, and the sequence number
+ from the CSeq header field, in addition to any Proxy-Require
+ and Proxy-Authorization header fields that may be present. The
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 105]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ algorithm used to compute the hash is implementation-dependent,
+ but MD5 (RFC 1321 [35]), expressed in hexadecimal, is a
+ reasonable choice. (Base64 is not permissible for a token.)
+
+ If a proxy wishes to detect loops, the "branch" parameter it
+ supplies MUST depend on all information affecting processing of
+ a request, including the incoming Request-URI and any header
+ fields affecting the request's admission or routing. This is
+ necessary to distinguish looped requests from requests whose
+ routing parameters have changed before returning to this
+ server.
+
+ The request method MUST NOT be included in the calculation of
+ the branch parameter. In particular, CANCEL and ACK requests
+ (for non-2xx responses) MUST have the same branch value as the
+ corresponding request they cancel or acknowledge. The branch
+ parameter is used in correlating those requests at the server
+ handling them (see Sections 17.2.3 and 9.2).
+
+ 9. Add a Content-Length header field if necessary
+
+ If the request will be sent to the next hop using a stream-
+ based transport and the copy contains no Content-Length header
+ field, the proxy MUST insert one with the correct value for the
+ body of the request (see Section 20.14).
+
+ 10. Forward Request
+
+ A stateful proxy MUST create a new client transaction for this
+ request as described in Section 17.1 and instructs the
+ transaction to send the request using the address, port and
+ transport determined in step 7.
+
+ 11. Set timer C
+
+ In order to handle the case where an INVITE request never
+ generates a final response, the TU uses a timer which is called
+ timer C. Timer C MUST be set for each client transaction when
+ an INVITE request is proxied. The timer MUST be larger than 3
+ minutes. Section 16.7 bullet 2 discusses how this timer is
+ updated with provisional responses, and Section 16.8 discusses
+ processing when it fires.
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 106]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+16.7 Response Processing
+
+ When a response is received by an element, it first tries to locate a
+ client transaction (Section 17.1.3) matching the response. If none
+ is found, the element MUST process the response (even if it is an
+ informational response) as a stateless proxy (described below). If a
+ match is found, the response is handed to the client transaction.
+
+ Forwarding responses for which a client transaction (or more
+ generally any knowledge of having sent an associated request) is
+ not found improves robustness. In particular, it ensures that
+ "late" 2xx responses to INVITE requests are forwarded properly.
+
+ As client transactions pass responses to the proxy layer, the
+ following processing MUST take place:
+
+ 1. Find the appropriate response context
+
+ 2. Update timer C for provisional responses
+
+ 3. Remove the topmost Via
+
+ 4. Add the response to the response context
+
+ 5. Check to see if this response should be forwarded immediately
+
+ 6. When necessary, choose the best final response from the
+ response context
+
+ If no final response has been forwarded after every client
+ transaction associated with the response context has been terminated,
+ the proxy must choose and forward the "best" response from those it
+ has seen so far.
+
+ The following processing MUST be performed on each response that is
+ forwarded. It is likely that more than one response to each request
+ will be forwarded: at least each provisional and one final response.
+
+ 7. Aggregate authorization header field values if necessary
+
+ 8. Optionally rewrite Record-Route header field values
+
+ 9. Forward the response
+
+ 10. Generate any necessary CANCEL requests
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 107]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Each of the above steps are detailed below:
+
+ 1. Find Context
+
+ The proxy locates the "response context" it created before
+ forwarding the original request using the key described in
+ Section 16.6. The remaining processing steps take place in
+ this context.
+
+ 2. Update timer C for provisional responses
+
+ For an INVITE transaction, if the response is a provisional
+ response with status codes 101 to 199 inclusive (i.e., anything
+ but 100), the proxy MUST reset timer C for that client
+ transaction. The timer MAY be reset to a different value, but
+ this value MUST be greater than 3 minutes.
+
+ 3. Via
+
+ The proxy removes the topmost Via header field value from the
+ response.
+
+ If no Via header field values remain in the response, the
+ response was meant for this element and MUST NOT be forwarded.
+ The remainder of the processing described in this section is
+ not performed on this message, the UAC processing rules
+ described in Section 8.1.3 are followed instead (transport
+ layer processing has already occurred).
+
+ This will happen, for instance, when the element generates
+ CANCEL requests as described in Section 10.
+
+ 4. Add response to context
+
+ Final responses received are stored in the response context
+ until a final response is generated on the server transaction
+ associated with this context. The response may be a candidate
+ for the best final response to be returned on that server
+ transaction. Information from this response may be needed in
+ forming the best response, even if this response is not chosen.
+
+ If the proxy chooses to recurse on any contacts in a 3xx
+ response by adding them to the target set, it MUST remove them
+ from the response before adding the response to the response
+ context. However, a proxy SHOULD NOT recurse to a non-SIPS URI
+ if the Request-URI of the original request was a SIPS URI. If
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 108]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ the proxy recurses on all of the contacts in a 3xx response,
+ the proxy SHOULD NOT add the resulting contactless response to
+ the response context.
+
+ Removing the contact before adding the response to the response
+ context prevents the next element upstream from retrying a
+ location this proxy has already attempted.
+
+ 3xx responses may contain a mixture of SIP, SIPS, and non-SIP
+ URIs. A proxy may choose to recurse on the SIP and SIPS URIs
+ and place the remainder into the response context to be
+ returned, potentially in the final response.
+
+ If a proxy receives a 416 (Unsupported URI Scheme) response to
+ a request whose Request-URI scheme was not SIP, but the scheme
+ in the original received request was SIP or SIPS (that is, the
+ proxy changed the scheme from SIP or SIPS to something else
+ when it proxied a request), the proxy SHOULD add a new URI to
+ the target set. This URI SHOULD be a SIP URI version of the
+ non-SIP URI that was just tried. In the case of the tel URL,
+ this is accomplished by placing the telephone-subscriber part
+ of the tel URL into the user part of the SIP URI, and setting
+ the hostpart to the domain where the prior request was sent.
+ See Section 19.1.6 for more detail on forming SIP URIs from tel
+ URLs.
+
+ As with a 3xx response, if a proxy "recurses" on the 416 by
+ trying a SIP or SIPS URI instead, the 416 response SHOULD NOT
+ be added to the response context.
+
+ 5. Check response for forwarding
+
+ Until a final response has been sent on the server transaction,
+ the following responses MUST be forwarded immediately:
+
+ - Any provisional response other than 100 (Trying)
+
+ - Any 2xx response
+
+ If a 6xx response is received, it is not immediately forwarded,
+ but the stateful proxy SHOULD cancel all client pending
+ transactions as described in Section 10, and it MUST NOT create
+ any new branches in this context.
+
+ This is a change from RFC 2543, which mandated that the proxy
+ was to forward the 6xx response immediately. For an INVITE
+ transaction, this approach had the problem that a 2xx response
+ could arrive on another branch, in which case the proxy would
+
+
+
+Rosenberg, et. al. Standards Track [Page 109]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ have to forward the 2xx. The result was that the UAC could
+ receive a 6xx response followed by a 2xx response, which should
+ never be allowed to happen. Under the new rules, upon
+ receiving a 6xx, a proxy will issue a CANCEL request, which
+ will generally result in 487 responses from all outstanding
+ client transactions, and then at that point the 6xx is
+ forwarded upstream.
+
+ After a final response has been sent on the server transaction,
+ the following responses MUST be forwarded immediately:
+
+ - Any 2xx response to an INVITE request
+
+ A stateful proxy MUST NOT immediately forward any other
+ responses. In particular, a stateful proxy MUST NOT forward
+ any 100 (Trying) response. Those responses that are candidates
+ for forwarding later as the "best" response have been gathered
+ as described in step "Add Response to Context".
+
+ Any response chosen for immediate forwarding MUST be processed
+ as described in steps "Aggregate Authorization Header Field
+ Values" through "Record-Route".
+
+ This step, combined with the next, ensures that a stateful
+ proxy will forward exactly one final response to a non-INVITE
+ request, and either exactly one non-2xx response or one or more
+ 2xx responses to an INVITE request.
+
+ 6. Choosing the best response
+
+ A stateful proxy MUST send a final response to a response
+ context's server transaction if no final responses have been
+ immediately forwarded by the above rules and all client
+ transactions in this response context have been terminated.
+
+ The stateful proxy MUST choose the "best" final response among
+ those received and stored in the response context.
+
+ If there are no final responses in the context, the proxy MUST
+ send a 408 (Request Timeout) response to the server
+ transaction.
+
+ Otherwise, the proxy MUST forward a response from the responses
+ stored in the response context. It MUST choose from the 6xx
+ class responses if any exist in the context. If no 6xx class
+ responses are present, the proxy SHOULD choose from the lowest
+ response class stored in the response context. The proxy MAY
+ select any response within that chosen class. The proxy SHOULD
+
+
+
+Rosenberg, et. al. Standards Track [Page 110]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ give preference to responses that provide information affecting
+ resubmission of this request, such as 401, 407, 415, 420, and
+ 484 if the 4xx class is chosen.
+
+ A proxy which receives a 503 (Service Unavailable) response
+ SHOULD NOT forward it upstream unless it can determine that any
+ subsequent requests it might proxy will also generate a 503.
+ In other words, forwarding a 503 means that the proxy knows it
+ cannot service any requests, not just the one for the Request-
+ URI in the request which generated the 503. If the only
+ response that was received is a 503, the proxy SHOULD generate
+ a 500 response and forward that upstream.
+
+ The forwarded response MUST be processed as described in steps
+ "Aggregate Authorization Header Field Values" through "Record-
+ Route".
+
+ For example, if a proxy forwarded a request to 4 locations, and
+ received 503, 407, 501, and 404 responses, it may choose to
+ forward the 407 (Proxy Authentication Required) response.
+
+ 1xx and 2xx responses may be involved in the establishment of
+ dialogs. When a request does not contain a To tag, the To tag
+ in the response is used by the UAC to distinguish multiple
+ responses to a dialog creating request. A proxy MUST NOT
+ insert a tag into the To header field of a 1xx or 2xx response
+ if the request did not contain one. A proxy MUST NOT modify
+ the tag in the To header field of a 1xx or 2xx response.
+
+ Since a proxy may not insert a tag into the To header field of
+ a 1xx response to a request that did not contain one, it cannot
+ issue non-100 provisional responses on its own. However, it
+ can branch the request to a UAS sharing the same element as the
+ proxy. This UAS can return its own provisional responses,
+ entering into an early dialog with the initiator of the
+ request. The UAS does not have to be a discreet process from
+ the proxy. It could be a virtual UAS implemented in the same
+ code space as the proxy.
+
+ 3-6xx responses are delivered hop-by-hop. When issuing a 3-6xx
+ response, the element is effectively acting as a UAS, issuing
+ its own response, usually based on the responses received from
+ downstream elements. An element SHOULD preserve the To tag
+ when simply forwarding a 3-6xx response to a request that did
+ not contain a To tag.
+
+ A proxy MUST NOT modify the To tag in any forwarded response to
+ a request that contains a To tag.
+
+
+
+Rosenberg, et. al. Standards Track [Page 111]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ While it makes no difference to the upstream elements if the
+ proxy replaced the To tag in a forwarded 3-6xx response,
+ preserving the original tag may assist with debugging.
+
+ When the proxy is aggregating information from several
+ responses, choosing a To tag from among them is arbitrary, and
+ generating a new To tag may make debugging easier. This
+ happens, for instance, when combining 401 (Unauthorized) and
+ 407 (Proxy Authentication Required) challenges, or combining
+ Contact values from unencrypted and unauthenticated 3xx
+ responses.
+
+ 7. Aggregate Authorization Header Field Values
+
+ If the selected response is a 401 (Unauthorized) or 407 (Proxy
+ Authentication Required), the proxy MUST collect any WWW-
+ Authenticate and Proxy-Authenticate header field values from
+ all other 401 (Unauthorized) and 407 (Proxy Authentication
+ Required) responses received so far in this response context
+ and add them to this response without modification before
+ forwarding. The resulting 401 (Unauthorized) or 407 (Proxy
+ Authentication Required) response could have several WWW-
+ Authenticate AND Proxy-Authenticate header field values.
+
+ This is necessary because any or all of the destinations the
+ request was forwarded to may have requested credentials. The
+ client needs to receive all of those challenges and supply
+ credentials for each of them when it retries the request.
+ Motivation for this behavior is provided in Section 26.
+
+ 8. Record-Route
+
+ If the selected response contains a Record-Route header field
+ value originally provided by this proxy, the proxy MAY choose
+ to rewrite the value before forwarding the response. This
+ allows the proxy to provide different URIs for itself to the
+ next upstream and downstream elements. A proxy may choose to
+ use this mechanism for any reason. For instance, it is useful
+ for multi-homed hosts.
+
+ If the proxy received the request over TLS, and sent it out
+ over a non-TLS connection, the proxy MUST rewrite the URI in
+ the Record-Route header field to be a SIPS URI. If the proxy
+ received the request over a non-TLS connection, and sent it out
+ over TLS, the proxy MUST rewrite the URI in the Record-Route
+ header field to be a SIP URI.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 112]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The new URI provided by the proxy MUST satisfy the same
+ constraints on URIs placed in Record-Route header fields in
+ requests (see Step 4 of Section 16.6) with the following
+ modifications:
+
+ The URI SHOULD NOT contain the transport parameter unless the
+ proxy has knowledge that the next upstream (as opposed to
+ downstream) element that will be in the path of subsequent
+ requests supports that transport.
+
+ When a proxy does decide to modify the Record-Route header
+ field in the response, one of the operations it performs is
+ locating the Record-Route value that it had inserted. If the
+ request spiraled, and the proxy inserted a Record-Route value
+ in each iteration of the spiral, locating the correct value in
+ the response (which must be the proper iteration in the reverse
+ direction) is tricky. The rules above recommend that a proxy
+ wishing to rewrite Record-Route header field values insert
+ sufficiently distinct URIs into the Record-Route header field
+ so that the right one may be selected for rewriting. A
+ RECOMMENDED mechanism to achieve this is for the proxy to
+ append a unique identifier for the proxy instance to the user
+ portion of the URI.
+
+ When the response arrives, the proxy modifies the first
+ Record-Route whose identifier matches the proxy instance. The
+ modification results in a URI without this piece of data
+ appended to the user portion of the URI. Upon the next
+ iteration, the same algorithm (find the topmost Record-Route
+ header field value with the parameter) will correctly extract
+ the next Record-Route header field value inserted by that
+ proxy.
+
+ Not every response to a request to which a proxy adds a
+ Record-Route header field value will contain a Record-Route
+ header field. If the response does contain a Record-Route
+ header field, it will contain the value the proxy added.
+
+ 9. Forward response
+
+ After performing the processing described in steps "Aggregate
+ Authorization Header Field Values" through "Record-Route", the
+ proxy MAY perform any feature specific manipulations on the
+ selected response. The proxy MUST NOT add to, modify, or
+ remove the message body. Unless otherwise specified, the proxy
+ MUST NOT remove any header field values other than the Via
+ header field value discussed in Section 16.7 Item 3. In
+ particular, the proxy MUST NOT remove any "received" parameter
+
+
+
+Rosenberg, et. al. Standards Track [Page 113]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ it may have added to the next Via header field value while
+ processing the request associated with this response. The
+ proxy MUST pass the response to the server transaction
+ associated with the response context. This will result in the
+ response being sent to the location now indicated in the
+ topmost Via header field value. If the server transaction is
+ no longer available to handle the transmission, the element
+ MUST forward the response statelessly by sending it to the
+ server transport. The server transaction might indicate
+ failure to send the response or signal a timeout in its state
+ machine. These errors would be logged for diagnostic purposes
+ as appropriate, but the protocol requires no remedial action
+ from the proxy.
+
+ The proxy MUST maintain the response context until all of its
+ associated transactions have been terminated, even after
+ forwarding a final response.
+
+ 10. Generate CANCELs
+
+ If the forwarded response was a final response, the proxy MUST
+ generate a CANCEL request for all pending client transactions
+ associated with this response context. A proxy SHOULD also
+ generate a CANCEL request for all pending client transactions
+ associated with this response context when it receives a 6xx
+ response. A pending client transaction is one that has
+ received a provisional response, but no final response (it is
+ in the proceeding state) and has not had an associated CANCEL
+ generated for it. Generating CANCEL requests is described in
+ Section 9.1.
+
+ The requirement to CANCEL pending client transactions upon
+ forwarding a final response does not guarantee that an endpoint
+ will not receive multiple 200 (OK) responses to an INVITE. 200
+ (OK) responses on more than one branch may be generated before
+ the CANCEL requests can be sent and processed. Further, it is
+ reasonable to expect that a future extension may override this
+ requirement to issue CANCEL requests.
+
+16.8 Processing Timer C
+
+ If timer C should fire, the proxy MUST either reset the timer with
+ any value it chooses, or terminate the client transaction. If the
+ client transaction has received a provisional response, the proxy
+ MUST generate a CANCEL request matching that transaction. If the
+ client transaction has not received a provisional response, the proxy
+ MUST behave as if the transaction received a 408 (Request Timeout)
+ response.
+
+
+
+Rosenberg, et. al. Standards Track [Page 114]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Allowing the proxy to reset the timer allows the proxy to dynamically
+ extend the transaction's lifetime based on current conditions (such
+ as utilization) when the timer fires.
+
+16.9 Handling Transport Errors
+
+ If the transport layer notifies a proxy of an error when it tries to
+ forward a request (see Section 18.4), the proxy MUST behave as if the
+ forwarded request received a 503 (Service Unavailable) response.
+
+ If the proxy is notified of an error when forwarding a response, it
+ drops the response. The proxy SHOULD NOT cancel any outstanding
+ client transactions associated with this response context due to this
+ notification.
+
+ If a proxy cancels its outstanding client transactions, a single
+ malicious or misbehaving client can cause all transactions to fail
+ through its Via header field.
+
+16.10 CANCEL Processing
+
+ A stateful proxy MAY generate a CANCEL to any other request it has
+ generated at any time (subject to receiving a provisional response to
+ that request as described in section 9.1). A proxy MUST cancel any
+ pending client transactions associated with a response context when
+ it receives a matching CANCEL request.
+
+ A stateful proxy MAY generate CANCEL requests for pending INVITE
+ client transactions based on the period specified in the INVITE's
+ Expires header field elapsing. However, this is generally
+ unnecessary since the endpoints involved will take care of signaling
+ the end of the transaction.
+
+ While a CANCEL request is handled in a stateful proxy by its own
+ server transaction, a new response context is not created for it.
+ Instead, the proxy layer searches its existing response contexts for
+ the server transaction handling the request associated with this
+ CANCEL. If a matching response context is found, the element MUST
+ immediately return a 200 (OK) response to the CANCEL request. In
+ this case, the element is acting as a user agent server as defined in
+ Section 8.2. Furthermore, the element MUST generate CANCEL requests
+ for all pending client transactions in the context as described in
+ Section 16.7 step 10.
+
+ If a response context is not found, the element does not have any
+ knowledge of the request to apply the CANCEL to. It MUST statelessly
+ forward the CANCEL request (it may have statelessly forwarded the
+ associated request previously).
+
+
+
+Rosenberg, et. al. Standards Track [Page 115]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+16.11 Stateless Proxy
+
+ When acting statelessly, a proxy is a simple message forwarder. Much
+ of the processing performed when acting statelessly is the same as
+ when behaving statefully. The differences are detailed here.
+
+ A stateless proxy does not have any notion of a transaction, or of
+ the response context used to describe stateful proxy behavior.
+ Instead, the stateless proxy takes messages, both requests and
+ responses, directly from the transport layer (See section 18). As a
+ result, stateless proxies do not retransmit messages on their own.
+ They do, however, forward all retransmissions they receive (they do
+ not have the ability to distinguish a retransmission from the
+ original message). Furthermore, when handling a request statelessly,
+ an element MUST NOT generate its own 100 (Trying) or any other
+ provisional response.
+
+ A stateless proxy MUST validate a request as described in Section
+ 16.3
+
+ A stateless proxy MUST follow the request processing steps described
+ in Sections 16.4 through 16.5 with the following exception:
+
+ o A stateless proxy MUST choose one and only one target from the
+ target set. This choice MUST only rely on fields in the
+ message and time-invariant properties of the server. In
+ particular, a retransmitted request MUST be forwarded to the
+ same destination each time it is processed. Furthermore,
+ CANCEL and non-Routed ACK requests MUST generate the same
+ choice as their associated INVITE.
+
+ A stateless proxy MUST follow the request processing steps described
+ in Section 16.6 with the following exceptions:
+
+ o The requirement for unique branch IDs across space and time
+ applies to stateless proxies as well. However, a stateless
+ proxy cannot simply use a random number generator to compute
+ the first component of the branch ID, as described in Section
+ 16.6 bullet 8. This is because retransmissions of a request
+ need to have the same value, and a stateless proxy cannot tell
+ a retransmission from the original request. Therefore, the
+ component of the branch parameter that makes it unique MUST be
+ the same each time a retransmitted request is forwarded. Thus
+ for a stateless proxy, the branch parameter MUST be computed as
+ a combinatoric function of message parameters which are
+ invariant on retransmission.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 116]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The stateless proxy MAY use any technique it likes to guarantee
+ uniqueness of its branch IDs across transactions. However, the
+ following procedure is RECOMMENDED. The proxy examines the
+ branch ID in the topmost Via header field of the received
+ request. If it begins with the magic cookie, the first
+ component of the branch ID of the outgoing request is computed
+ as a hash of the received branch ID. Otherwise, the first
+ component of the branch ID is computed as a hash of the topmost
+ Via, the tag in the To header field, the tag in the From header
+ field, the Call-ID header field, the CSeq number (but not
+ method), and the Request-URI from the received request. One of
+ these fields will always vary across two different
+ transactions.
+
+ o All other message transformations specified in Section 16.6
+ MUST result in the same transformation of a retransmitted
+ request. In particular, if the proxy inserts a Record-Route
+ value or pushes URIs into the Route header field, it MUST place
+ the same values in retransmissions of the request. As for the
+ Via branch parameter, this implies that the transformations
+ MUST be based on time-invariant configuration or
+ retransmission-invariant properties of the request.
+
+ o A stateless proxy determines where to forward the request as
+ described for stateful proxies in Section 16.6 Item 10. The
+ request is sent directly to the transport layer instead of
+ through a client transaction.
+
+ Since a stateless proxy must forward retransmitted requests to
+ the same destination and add identical branch parameters to
+ each of them, it can only use information from the message
+ itself and time-invariant configuration data for those
+ calculations. If the configuration state is not time-invariant
+ (for example, if a routing table is updated) any requests that
+ could be affected by the change may not be forwarded
+ statelessly during an interval equal to the transaction timeout
+ window before or after the change. The method of processing
+ the affected requests in that interval is an implementation
+ decision. A common solution is to forward them transaction
+ statefully.
+
+ Stateless proxies MUST NOT perform special processing for CANCEL
+ requests. They are processed by the above rules as any other
+ requests. In particular, a stateless proxy applies the same Route
+ header field processing to CANCEL requests that it applies to any
+ other request.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 117]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Response processing as described in Section 16.7 does not apply to a
+ proxy behaving statelessly. When a response arrives at a stateless
+ proxy, the proxy MUST inspect the sent-by value in the first
+ (topmost) Via header field value. If that address matches the proxy,
+ (it equals a value this proxy has inserted into previous requests)
+ the proxy MUST remove that header field value from the response and
+ forward the result to the location indicated in the next Via header
+ field value. The proxy MUST NOT add to, modify, or remove the
+ message body. Unless specified otherwise, the proxy MUST NOT remove
+ any other header field values. If the address does not match the
+ proxy, the message MUST be silently discarded.
+
+16.12 Summary of Proxy Route Processing
+
+ In the absence of local policy to the contrary, the processing a
+ proxy performs on a request containing a Route header field can be
+ summarized in the following steps.
+
+ 1. The proxy will inspect the Request-URI. If it indicates a
+ resource owned by this proxy, the proxy will replace it with
+ the results of running a location service. Otherwise, the
+ proxy will not change the Request-URI.
+
+ 2. The proxy will inspect the URI in the topmost Route header
+ field value. If it indicates this proxy, the proxy removes it
+ from the Route header field (this route node has been
+ reached).
+
+ 3. The proxy will forward the request to the resource indicated
+ by the URI in the topmost Route header field value or in the
+ Request-URI if no Route header field is present. The proxy
+ determines the address, port and transport to use when
+ forwarding the request by applying the procedures in [4] to
+ that URI.
+
+ If no strict-routing elements are encountered on the path of the
+ request, the Request-URI will always indicate the target of the
+ request.
+
+16.12.1 Examples
+
+16.12.1.1 Basic SIP Trapezoid
+
+ This scenario is the basic SIP trapezoid, U1 -> P1 -> P2 -> U2, with
+ both proxies record-routing. Here is the flow.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 118]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ U1 sends:
+
+ INVITE sip:callee@domain.com SIP/2.0
+ Contact: sip:caller@u1.example.com
+
+ to P1. P1 is an outbound proxy. P1 is not responsible for
+ domain.com, so it looks it up in DNS and sends it there. It also
+ adds a Record-Route header field value:
+
+ INVITE sip:callee@domain.com SIP/2.0
+ Contact: sip:caller@u1.example.com
+ Record-Route: <sip:p1.example.com;lr>
+
+ P2 gets this. It is responsible for domain.com so it runs a location
+ service and rewrites the Request-URI. It also adds a Record-Route
+ header field value. There is no Route header field, so it resolves
+ the new Request-URI to determine where to send the request:
+
+ INVITE sip:callee@u2.domain.com SIP/2.0
+ Contact: sip:caller@u1.example.com
+ Record-Route: <sip:p2.domain.com;lr>
+ Record-Route: <sip:p1.example.com;lr>
+
+ The callee at u2.domain.com gets this and responds with a 200 OK:
+
+ SIP/2.0 200 OK
+ Contact: sip:callee@u2.domain.com
+ Record-Route: <sip:p2.domain.com;lr>
+ Record-Route: <sip:p1.example.com;lr>
+
+ The callee at u2 also sets its dialog state's remote target URI to
+ sip:caller@u1.example.com and its route set to:
+
+ (<sip:p2.domain.com;lr>,<sip:p1.example.com;lr>)
+
+ This is forwarded by P2 to P1 to U1 as normal. Now, U1 sets its
+ dialog state's remote target URI to sip:callee@u2.domain.com and its
+ route set to:
+
+ (<sip:p1.example.com;lr>,<sip:p2.domain.com;lr>)
+
+ Since all the route set elements contain the lr parameter, U1
+ constructs the following BYE request:
+
+ BYE sip:callee@u2.domain.com SIP/2.0
+ Route: <sip:p1.example.com;lr>,<sip:p2.domain.com;lr>
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 119]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ As any other element (including proxies) would do, it resolves the
+ URI in the topmost Route header field value using DNS to determine
+ where to send the request. This goes to P1. P1 notices that it is
+ not responsible for the resource indicated in the Request-URI so it
+ doesn't change it. It does see that it is the first value in the
+ Route header field, so it removes that value, and forwards the
+ request to P2:
+
+ BYE sip:callee@u2.domain.com SIP/2.0
+ Route: <sip:p2.domain.com;lr>
+
+ P2 also notices it is not responsible for the resource indicated by
+ the Request-URI (it is responsible for domain.com, not
+ u2.domain.com), so it doesn't change it. It does see itself in the
+ first Route header field value, so it removes it and forwards the
+ following to u2.domain.com based on a DNS lookup against the
+ Request-URI:
+
+ BYE sip:callee@u2.domain.com SIP/2.0
+
+16.12.1.2 Traversing a Strict-Routing Proxy
+
+ In this scenario, a dialog is established across four proxies, each
+ of which adds Record-Route header field values. The third proxy
+ implements the strict-routing procedures specified in RFC 2543 and
+ many works in progress.
+
+ U1->P1->P2->P3->P4->U2
+
+ The INVITE arriving at U2 contains:
+
+ INVITE sip:callee@u2.domain.com SIP/2.0
+ Contact: sip:caller@u1.example.com
+ Record-Route: <sip:p4.domain.com;lr>
+ Record-Route: <sip:p3.middle.com>
+ Record-Route: <sip:p2.example.com;lr>
+ Record-Route: <sip:p1.example.com;lr>
+
+ Which U2 responds to with a 200 OK. Later, U2 sends the following
+ BYE request to P4 based on the first Route header field value.
+
+ BYE sip:caller@u1.example.com SIP/2.0
+ Route: <sip:p4.domain.com;lr>
+ Route: <sip:p3.middle.com>
+ Route: <sip:p2.example.com;lr>
+ Route: <sip:p1.example.com;lr>
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 120]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ P4 is not responsible for the resource indicated in the Request-URI
+ so it will leave it alone. It notices that it is the element in the
+ first Route header field value so it removes it. It then prepares to
+ send the request based on the now first Route header field value of
+ sip:p3.middle.com, but it notices that this URI does not contain the
+ lr parameter, so before sending, it reformats the request to be:
+
+ BYE sip:p3.middle.com SIP/2.0
+ Route: <sip:p2.example.com;lr>
+ Route: <sip:p1.example.com;lr>
+ Route: <sip:caller@u1.example.com>
+
+ P3 is a strict router, so it forwards the following to P2:
+
+ BYE sip:p2.example.com;lr SIP/2.0
+ Route: <sip:p1.example.com;lr>
+ Route: <sip:caller@u1.example.com>
+
+ P2 sees the request-URI is a value it placed into a Record-Route
+ header field, so before further processing, it rewrites the request
+ to be:
+
+ BYE sip:caller@u1.example.com SIP/2.0
+ Route: <sip:p1.example.com;lr>
+
+ P2 is not responsible for u1.example.com, so it sends the request to
+ P1 based on the resolution of the Route header field value.
+
+ P1 notices itself in the topmost Route header field value, so it
+ removes it, resulting in:
+
+ BYE sip:caller@u1.example.com SIP/2.0
+
+ Since P1 is not responsible for u1.example.com and there is no Route
+ header field, P1 will forward the request to u1.example.com based on
+ the Request-URI.
+
+16.12.1.3 Rewriting Record-Route Header Field Values
+
+ In this scenario, U1 and U2 are in different private namespaces and
+ they enter a dialog through a proxy P1, which acts as a gateway
+ between the namespaces.
+
+ U1->P1->U2
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 121]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ U1 sends:
+
+ INVITE sip:callee@gateway.leftprivatespace.com SIP/2.0
+ Contact: <sip:caller@u1.leftprivatespace.com>
+
+ P1 uses its location service and sends the following to U2:
+
+ INVITE sip:callee@rightprivatespace.com SIP/2.0
+ Contact: <sip:caller@u1.leftprivatespace.com>
+ Record-Route: <sip:gateway.rightprivatespace.com;lr>
+
+ U2 sends this 200 (OK) back to P1:
+
+ SIP/2.0 200 OK
+ Contact: <sip:callee@u2.rightprivatespace.com>
+ Record-Route: <sip:gateway.rightprivatespace.com;lr>
+
+ P1 rewrites its Record-Route header parameter to provide a value that
+ U1 will find useful, and sends the following to U1:
+
+ SIP/2.0 200 OK
+ Contact: <sip:callee@u2.rightprivatespace.com>
+ Record-Route: <sip:gateway.leftprivatespace.com;lr>
+
+ Later, U1 sends the following BYE request to P1:
+
+ BYE sip:callee@u2.rightprivatespace.com SIP/2.0
+ Route: <sip:gateway.leftprivatespace.com;lr>
+
+ which P1 forwards to U2 as:
+
+ BYE sip:callee@u2.rightprivatespace.com SIP/2.0
+
+17 Transactions
+
+ SIP is a transactional protocol: interactions between components take
+ place in a series of independent message exchanges. Specifically, a
+ SIP transaction consists of a single request and any responses to
+ that request, which include zero or more provisional responses and
+ one or more final responses. In the case of a transaction where the
+ request was an INVITE (known as an INVITE transaction), the
+ transaction also includes the ACK only if the final response was not
+ a 2xx response. If the response was a 2xx, the ACK is not considered
+ part of the transaction.
+
+ The reason for this separation is rooted in the importance of
+ delivering all 200 (OK) responses to an INVITE to the UAC. To
+ deliver them all to the UAC, the UAS alone takes responsibility
+
+
+
+Rosenberg, et. al. Standards Track [Page 122]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ for retransmitting them (see Section 13.3.1.4), and the UAC alone
+ takes responsibility for acknowledging them with ACK (see Section
+ 13.2.2.4). Since this ACK is retransmitted only by the UAC, it is
+ effectively considered its own transaction.
+
+ Transactions have a client side and a server side. The client side
+ is known as a client transaction and the server side as a server
+ transaction. The client transaction sends the request, and the
+ server transaction sends the response. The client and server
+ transactions are logical functions that are embedded in any number of
+ elements. Specifically, they exist within user agents and stateful
+ proxy servers. Consider the example in Section 4. In this example,
+ the UAC executes the client transaction, and its outbound proxy
+ executes the server transaction. The outbound proxy also executes a
+ client transaction, which sends the request to a server transaction
+ in the inbound proxy. That proxy also executes a client transaction,
+ which in turn sends the request to a server transaction in the UAS.
+ This is shown in Figure 4.
+
+ +---------+ +---------+ +---------+ +---------+
+ | +-+|Request |+-+ +-+|Request |+-+ +-+|Request |+-+ |
+ | |C||------->||S| |C||------->||S| |C||------->||S| |
+ | |l|| ||e| |l|| ||e| |l|| ||e| |
+ | |i|| ||r| |i|| ||r| |i|| ||r| |
+ | |e|| ||v| |e|| ||v| |e|| ||v| |
+ | |n|| ||e| |n|| ||e| |n|| ||e| |
+ | |t|| ||r| |t|| ||r| |t|| ||r| |
+ | | || || | | || || | | || || | |
+ | |T|| ||T| |T|| ||T| |T|| ||T| |
+ | |r|| ||r| |r|| ||r| |r|| ||r| |
+ | |a|| ||a| |a|| ||a| |a|| ||a| |
+ | |n|| ||n| |n|| ||n| |n|| ||n| |
+ | |s||Response||s| |s||Response||s| |s||Response||s| |
+ | +-+|<-------|+-+ +-+|<-------|+-+ +-+|<-------|+-+ |
+ +---------+ +---------+ +---------+ +---------+
+ UAC Outbound Inbound UAS
+ Proxy Proxy
+
+ Figure 4: Transaction relationships
+
+ A stateless proxy does not contain a client or server transaction.
+ The transaction exists between the UA or stateful proxy on one side,
+ and the UA or stateful proxy on the other side. As far as SIP
+ transactions are concerned, stateless proxies are effectively
+ transparent. The purpose of the client transaction is to receive a
+ request from the element in which the client is embedded (call this
+ element the "Transaction User" or TU; it can be a UA or a stateful
+ proxy), and reliably deliver the request to a server transaction.
+
+
+
+Rosenberg, et. al. Standards Track [Page 123]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The client transaction is also responsible for receiving responses
+ and delivering them to the TU, filtering out any response
+ retransmissions or disallowed responses (such as a response to ACK).
+ Additionally, in the case of an INVITE request, the client
+ transaction is responsible for generating the ACK request for any
+ final response accepting a 2xx response.
+
+ Similarly, the purpose of the server transaction is to receive
+ requests from the transport layer and deliver them to the TU. The
+ server transaction filters any request retransmissions from the
+ network. The server transaction accepts responses from the TU and
+ delivers them to the transport layer for transmission over the
+ network. In the case of an INVITE transaction, it absorbs the ACK
+ request for any final response excepting a 2xx response.
+
+ The 2xx response and its ACK receive special treatment. This
+ response is retransmitted only by a UAS, and its ACK generated only
+ by the UAC. This end-to-end treatment is needed so that a caller
+ knows the entire set of users that have accepted the call. Because
+ of this special handling, retransmissions of the 2xx response are
+ handled by the UA core, not the transaction layer. Similarly,
+ generation of the ACK for the 2xx is handled by the UA core. Each
+ proxy along the path merely forwards each 2xx response to INVITE and
+ its corresponding ACK.
+
+17.1 Client Transaction
+
+ The client transaction provides its functionality through the
+ maintenance of a state machine.
+
+ The TU communicates with the client transaction through a simple
+ interface. When the TU wishes to initiate a new transaction, it
+ creates a client transaction and passes it the SIP request to send
+ and an IP address, port, and transport to which to send it. The
+ client transaction begins execution of its state machine. Valid
+ responses are passed up to the TU from the client transaction.
+
+ There are two types of client transaction state machines, depending
+ on the method of the request passed by the TU. One handles client
+ transactions for INVITE requests. This type of machine is referred
+ to as an INVITE client transaction. Another type handles client
+ transactions for all requests except INVITE and ACK. This is
+ referred to as a non-INVITE client transaction. There is no client
+ transaction for ACK. If the TU wishes to send an ACK, it passes one
+ directly to the transport layer for transmission.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 124]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The INVITE transaction is different from those of other methods
+ because of its extended duration. Normally, human input is required
+ in order to respond to an INVITE. The long delays expected for
+ sending a response argue for a three-way handshake. On the other
+ hand, requests of other methods are expected to complete rapidly.
+ Because of the non-INVITE transaction's reliance on a two-way
+ handshake, TUs SHOULD respond immediately to non-INVITE requests.
+
+17.1.1 INVITE Client Transaction
+
+17.1.1.1 Overview of INVITE Transaction
+
+ The INVITE transaction consists of a three-way handshake. The client
+ transaction sends an INVITE, the server transaction sends responses,
+ and the client transaction sends an ACK. For unreliable transports
+ (such as UDP), the client transaction retransmits requests at an
+ interval that starts at T1 seconds and doubles after every
+ retransmission. T1 is an estimate of the round-trip time (RTT), and
+ it defaults to 500 ms. Nearly all of the transaction timers
+ described here scale with T1, and changing T1 adjusts their values.
+ The request is not retransmitted over reliable transports. After
+ receiving a 1xx response, any retransmissions cease altogether, and
+ the client waits for further responses. The server transaction can
+ send additional 1xx responses, which are not transmitted reliably by
+ the server transaction. Eventually, the server transaction decides
+ to send a final response. For unreliable transports, that response
+ is retransmitted periodically, and for reliable transports, it is
+ sent once. For each final response that is received at the client
+ transaction, the client transaction sends an ACK, the purpose of
+ which is to quench retransmissions of the response.
+
+17.1.1.2 Formal Description
+
+ The state machine for the INVITE client transaction is shown in
+ Figure 5. The initial state, "calling", MUST be entered when the TU
+ initiates a new client transaction with an INVITE request. The
+ client transaction MUST pass the request to the transport layer for
+ transmission (see Section 18). If an unreliable transport is being
+ used, the client transaction MUST start timer A with a value of T1.
+ If a reliable transport is being used, the client transaction SHOULD
+ NOT start timer A (Timer A controls request retransmissions). For
+ any transport, the client transaction MUST start timer B with a value
+ of 64*T1 seconds (Timer B controls transaction timeouts).
+
+ When timer A fires, the client transaction MUST retransmit the
+ request by passing it to the transport layer, and MUST reset the
+ timer with a value of 2*T1. The formal definition of retransmit
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 125]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ within the context of the transaction layer is to take the message
+ previously sent to the transport layer and pass it to the transport
+ layer once more.
+
+ When timer A fires 2*T1 seconds later, the request MUST be
+ retransmitted again (assuming the client transaction is still in this
+ state). This process MUST continue so that the request is
+ retransmitted with intervals that double after each transmission.
+ These retransmissions SHOULD only be done while the client
+ transaction is in the "calling" state.
+
+ The default value for T1 is 500 ms. T1 is an estimate of the RTT
+ between the client and server transactions. Elements MAY (though it
+ is NOT RECOMMENDED) use smaller values of T1 within closed, private
+ networks that do not permit general Internet connection. T1 MAY be
+ chosen larger, and this is RECOMMENDED if it is known in advance
+ (such as on high latency access links) that the RTT is larger.
+ Whatever the value of T1, the exponential backoffs on retransmissions
+ described in this section MUST be used.
+
+ If the client transaction is still in the "Calling" state when timer
+ B fires, the client transaction SHOULD inform the TU that a timeout
+ has occurred. The client transaction MUST NOT generate an ACK. The
+ value of 64*T1 is equal to the amount of time required to send seven
+ requests in the case of an unreliable transport.
+
+ If the client transaction receives a provisional response while in
+ the "Calling" state, it transitions to the "Proceeding" state. In the
+ "Proceeding" state, the client transaction SHOULD NOT retransmit the
+ request any longer. Furthermore, the provisional response MUST be
+ passed to the TU. Any further provisional responses MUST be passed
+ up to the TU while in the "Proceeding" state.
+
+ When in either the "Calling" or "Proceeding" states, reception of a
+ response with status code from 300-699 MUST cause the client
+ transaction to transition to "Completed". The client transaction
+ MUST pass the received response up to the TU, and the client
+ transaction MUST generate an ACK request, even if the transport is
+ reliable (guidelines for constructing the ACK from the response are
+ given in Section 17.1.1.3) and then pass the ACK to the transport
+ layer for transmission. The ACK MUST be sent to the same address,
+ port, and transport to which the original request was sent. The
+ client transaction SHOULD start timer D when it enters the
+ "Completed" state, with a value of at least 32 seconds for unreliable
+ transports, and a value of zero seconds for reliable transports.
+ Timer D reflects the amount of time that the server transaction can
+ remain in the "Completed" state when unreliable transports are used.
+ This is equal to Timer H in the INVITE server transaction, whose
+
+
+
+Rosenberg, et. al. Standards Track [Page 126]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ default is 64*T1. However, the client transaction does not know the
+ value of T1 in use by the server transaction, so an absolute minimum
+ of 32s is used instead of basing Timer D on T1.
+
+ Any retransmissions of the final response that are received while in
+ the "Completed" state MUST cause the ACK to be re-passed to the
+ transport layer for retransmission, but the newly received response
+ MUST NOT be passed up to the TU. A retransmission of the response is
+ defined as any response which would match the same client transaction
+ based on the rules of Section 17.1.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 127]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ |INVITE from TU
+ Timer A fires |INVITE sent
+ Reset A, V Timer B fires
+ INVITE sent +-----------+ or Transport Err.
+ +---------| |---------------+inform TU
+ | | Calling | |
+ +-------->| |-------------->|
+ +-----------+ 2xx |
+ | | 2xx to TU |
+ | |1xx |
+ 300-699 +---------------+ |1xx to TU |
+ ACK sent | | |
+resp. to TU | 1xx V |
+ | 1xx to TU -----------+ |
+ | +---------| | |
+ | | |Proceeding |-------------->|
+ | +-------->| | 2xx |
+ | +-----------+ 2xx to TU |
+ | 300-699 | |
+ | ACK sent, | |
+ | resp. to TU| |
+ | | | NOTE:
+ | 300-699 V |
+ | ACK sent +-----------+Transport Err. | transitions
+ | +---------| |Inform TU | labeled with
+ | | | Completed |-------------->| the event
+ | +-------->| | | over the action
+ | +-----------+ | to take
+ | ^ | |
+ | | | Timer D fires |
+ +--------------+ | - |
+ | |
+ V |
+ +-----------+ |
+ | | |
+ | Terminated|<--------------+
+ | |
+ +-----------+
+
+ Figure 5: INVITE client transaction
+
+ If timer D fires while the client transaction is in the "Completed"
+ state, the client transaction MUST move to the terminated state.
+
+ When in either the "Calling" or "Proceeding" states, reception of a
+ 2xx response MUST cause the client transaction to enter the
+ "Terminated" state, and the response MUST be passed up to the TU.
+ The handling of this response depends on whether the TU is a proxy
+
+
+
+Rosenberg, et. al. Standards Track [Page 128]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ core or a UAC core. A UAC core will handle generation of the ACK for
+ this response, while a proxy core will always forward the 200 (OK)
+ upstream. The differing treatment of 200 (OK) between proxy and UAC
+ is the reason that handling of it does not take place in the
+ transaction layer.
+
+ The client transaction MUST be destroyed the instant it enters the
+ "Terminated" state. This is actually necessary to guarantee correct
+ operation. The reason is that 2xx responses to an INVITE are treated
+ differently; each one is forwarded by proxies, and the ACK handling
+ in a UAC is different. Thus, each 2xx needs to be passed to a proxy
+ core (so that it can be forwarded) and to a UAC core (so it can be
+ acknowledged). No transaction layer processing takes place.
+ Whenever a response is received by the transport, if the transport
+ layer finds no matching client transaction (using the rules of
+ Section 17.1.3), the response is passed directly to the core. Since
+ the matching client transaction is destroyed by the first 2xx,
+ subsequent 2xx will find no match and therefore be passed to the
+ core.
+
+17.1.1.3 Construction of the ACK Request
+
+ This section specifies the construction of ACK requests sent within
+ the client transaction. A UAC core that generates an ACK for 2xx
+ MUST instead follow the rules described in Section 13.
+
+ The ACK request constructed by the client transaction MUST contain
+ values for the Call-ID, From, and Request-URI that are equal to the
+ values of those header fields in the request passed to the transport
+ by the client transaction (call this the "original request"). The To
+ header field in the ACK MUST equal the To header field in the
+ response being acknowledged, and therefore will usually differ from
+ the To header field in the original request by the addition of the
+ tag parameter. The ACK MUST contain a single Via header field, and
+ this MUST be equal to the top Via header field of the original
+ request. The CSeq header field in the ACK MUST contain the same
+ value for the sequence number as was present in the original request,
+ but the method parameter MUST be equal to "ACK".
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 129]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ If the INVITE request whose response is being acknowledged had Route
+ header fields, those header fields MUST appear in the ACK. This is
+ to ensure that the ACK can be routed properly through any downstream
+ stateless proxies.
+
+ Although any request MAY contain a body, a body in an ACK is special
+ since the request cannot be rejected if the body is not understood.
+ Therefore, placement of bodies in ACK for non-2xx is NOT RECOMMENDED,
+ but if done, the body types are restricted to any that appeared in
+ the INVITE, assuming that the response to the INVITE was not 415. If
+ it was, the body in the ACK MAY be any type listed in the Accept
+ header field in the 415.
+
+ For example, consider the following request:
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
+ To: Bob <sip:bob@biloxi.com>
+ From: Alice <sip:alice@atlanta.com>;tag=88sja8x
+ Max-Forwards: 70
+ Call-ID: 987asjd97y7atg
+ CSeq: 986759 INVITE
+
+ The ACK request for a non-2xx final response to this request would
+ look like this:
+
+ ACK sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
+ To: Bob <sip:bob@biloxi.com>;tag=99sa0xk
+ From: Alice <sip:alice@atlanta.com>;tag=88sja8x
+ Max-Forwards: 70
+ Call-ID: 987asjd97y7atg
+ CSeq: 986759 ACK
+
+17.1.2 Non-INVITE Client Transaction
+
+17.1.2.1 Overview of the non-INVITE Transaction
+
+ Non-INVITE transactions do not make use of ACK. They are simple
+ request-response interactions. For unreliable transports, requests
+ are retransmitted at an interval which starts at T1 and doubles until
+ it hits T2. If a provisional response is received, retransmissions
+ continue for unreliable transports, but at an interval of T2. The
+ server transaction retransmits the last response it sent, which can
+ be a provisional or final response, only when a retransmission of the
+ request is received. This is why request retransmissions need to
+ continue even after a provisional response; they are to ensure
+ reliable delivery of the final response.
+
+
+
+Rosenberg, et. al. Standards Track [Page 130]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Unlike an INVITE transaction, a non-INVITE transaction has no special
+ handling for the 2xx response. The result is that only a single 2xx
+ response to a non-INVITE is ever delivered to a UAC.
+
+17.1.2.2 Formal Description
+
+ The state machine for the non-INVITE client transaction is shown in
+ Figure 6. It is very similar to the state machine for INVITE.
+
+ The "Trying" state is entered when the TU initiates a new client
+ transaction with a request. When entering this state, the client
+ transaction SHOULD set timer F to fire in 64*T1 seconds. The request
+ MUST be passed to the transport layer for transmission. If an
+ unreliable transport is in use, the client transaction MUST set timer
+ E to fire in T1 seconds. If timer E fires while still in this state,
+ the timer is reset, but this time with a value of MIN(2*T1, T2).
+ When the timer fires again, it is reset to a MIN(4*T1, T2). This
+ process continues so that retransmissions occur with an exponentially
+ increasing interval that caps at T2. The default value of T2 is 4s,
+ and it represents the amount of time a non-INVITE server transaction
+ will take to respond to a request, if it does not respond
+ immediately. For the default values of T1 and T2, this results in
+ intervals of 500 ms, 1 s, 2 s, 4 s, 4 s, 4 s, etc.
+
+ If Timer F fires while the client transaction is still in the
+ "Trying" state, the client transaction SHOULD inform the TU about the
+ timeout, and then it SHOULD enter the "Terminated" state. If a
+ provisional response is received while in the "Trying" state, the
+ response MUST be passed to the TU, and then the client transaction
+ SHOULD move to the "Proceeding" state. If a final response (status
+ codes 200-699) is received while in the "Trying" state, the response
+ MUST be passed to the TU, and the client transaction MUST transition
+ to the "Completed" state.
+
+ If Timer E fires while in the "Proceeding" state, the request MUST be
+ passed to the transport layer for retransmission, and Timer E MUST be
+ reset with a value of T2 seconds. If timer F fires while in the
+ "Proceeding" state, the TU MUST be informed of a timeout, and the
+ client transaction MUST transition to the terminated state. If a
+ final response (status codes 200-699) is received while in the
+ "Proceeding" state, the response MUST be passed to the TU, and the
+ client transaction MUST transition to the "Completed" state.
+
+ Once the client transaction enters the "Completed" state, it MUST set
+ Timer K to fire in T4 seconds for unreliable transports, and zero
+ seconds for reliable transports. The "Completed" state exists to
+ buffer any additional response retransmissions that may be received
+ (which is why the client transaction remains there only for
+
+
+
+Rosenberg, et. al. Standards Track [Page 131]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ unreliable transports). T4 represents the amount of time the network
+ will take to clear messages between client and server transactions.
+ The default value of T4 is 5s. A response is a retransmission when
+ it matches the same transaction, using the rules specified in Section
+ 17.1.3. If Timer K fires while in this state, the client transaction
+ MUST transition to the "Terminated" state.
+
+ Once the transaction is in the terminated state, it MUST be destroyed
+ immediately.
+
+17.1.3 Matching Responses to Client Transactions
+
+ When the transport layer in the client receives a response, it has to
+ determine which client transaction will handle the response, so that
+ the processing of Sections 17.1.1 and 17.1.2 can take place. The
+ branch parameter in the top Via header field is used for this
+ purpose. A response matches a client transaction under two
+ conditions:
+
+ 1. If the response has the same value of the branch parameter in
+ the top Via header field as the branch parameter in the top
+ Via header field of the request that created the transaction.
+
+ 2. If the method parameter in the CSeq header field matches the
+ method of the request that created the transaction. The
+ method is needed since a CANCEL request constitutes a
+ different transaction, but shares the same value of the branch
+ parameter.
+
+ If a request is sent via multicast, it is possible that it will
+ generate multiple responses from different servers. These responses
+ will all have the same branch parameter in the topmost Via, but vary
+ in the To tag. The first response received, based on the rules
+ above, will be used, and others will be viewed as retransmissions.
+ That is not an error; multicast SIP provides only a rudimentary
+ "single-hop-discovery-like" service that is limited to processing a
+ single response. See Section 18.1.1 for details.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 132]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+17.1.4 Handling Transport Errors
+
+ |Request from TU
+ |send request
+ Timer E V
+ send request +-----------+
+ +---------| |-------------------+
+ | | Trying | Timer F |
+ +-------->| | or Transport Err.|
+ +-----------+ inform TU |
+ 200-699 | | |
+ resp. to TU | |1xx |
+ +---------------+ |resp. to TU |
+ | | |
+ | Timer E V Timer F |
+ | send req +-----------+ or Transport Err. |
+ | +---------| | inform TU |
+ | | |Proceeding |------------------>|
+ | +-------->| |-----+ |
+ | +-----------+ |1xx |
+ | | ^ |resp to TU |
+ | 200-699 | +--------+ |
+ | resp. to TU | |
+ | | |
+ | V |
+ | +-----------+ |
+ | | | |
+ | | Completed | |
+ | | | |
+ | +-----------+ |
+ | ^ | |
+ | | | Timer K |
+ +--------------+ | - |
+ | |
+ V |
+ NOTE: +-----------+ |
+ | | |
+ transitions | Terminated|<------------------+
+ labeled with | |
+ the event +-----------+
+ over the action
+ to take
+
+ Figure 6: non-INVITE client transaction
+
+ When the client transaction sends a request to the transport layer to
+ be sent, the following procedures are followed if the transport layer
+ indicates a failure.
+
+
+
+Rosenberg, et. al. Standards Track [Page 133]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The client transaction SHOULD inform the TU that a transport failure
+ has occurred, and the client transaction SHOULD transition directly
+ to the "Terminated" state. The TU will handle the failover
+ mechanisms described in [4].
+
+17.2 Server Transaction
+
+ The server transaction is responsible for the delivery of requests to
+ the TU and the reliable transmission of responses. It accomplishes
+ this through a state machine. Server transactions are created by the
+ core when a request is received, and transaction handling is desired
+ for that request (this is not always the case).
+
+ As with the client transactions, the state machine depends on whether
+ the received request is an INVITE request.
+
+17.2.1 INVITE Server Transaction
+
+ The state diagram for the INVITE server transaction is shown in
+ Figure 7.
+
+ When a server transaction is constructed for a request, it enters the
+ "Proceeding" state. The server transaction MUST generate a 100
+ (Trying) response unless it knows that the TU will generate a
+ provisional or final response within 200 ms, in which case it MAY
+ generate a 100 (Trying) response. This provisional response is
+ needed to quench request retransmissions rapidly in order to avoid
+ network congestion. The 100 (Trying) response is constructed
+ according to the procedures in Section 8.2.6, except that the
+ insertion of tags in the To header field of the response (when none
+ was present in the request) is downgraded from MAY to SHOULD NOT.
+ The request MUST be passed to the TU.
+
+ The TU passes any number of provisional responses to the server
+ transaction. So long as the server transaction is in the
+ "Proceeding" state, each of these MUST be passed to the transport
+ layer for transmission. They are not sent reliably by the
+ transaction layer (they are not retransmitted by it) and do not cause
+ a change in the state of the server transaction. If a request
+ retransmission is received while in the "Proceeding" state, the most
+ recent provisional response that was received from the TU MUST be
+ passed to the transport layer for retransmission. A request is a
+ retransmission if it matches the same server transaction based on the
+ rules of Section 17.2.3.
+
+ If, while in the "Proceeding" state, the TU passes a 2xx response to
+ the server transaction, the server transaction MUST pass this
+ response to the transport layer for transmission. It is not
+
+
+
+Rosenberg, et. al. Standards Track [Page 134]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ retransmitted by the server transaction; retransmissions of 2xx
+ responses are handled by the TU. The server transaction MUST then
+ transition to the "Terminated" state.
+
+ While in the "Proceeding" state, if the TU passes a response with
+ status code from 300 to 699 to the server transaction, the response
+ MUST be passed to the transport layer for transmission, and the state
+ machine MUST enter the "Completed" state. For unreliable transports,
+ timer G is set to fire in T1 seconds, and is not set to fire for
+ reliable transports.
+
+ This is a change from RFC 2543, where responses were always
+ retransmitted, even over reliable transports.
+
+ When the "Completed" state is entered, timer H MUST be set to fire in
+ 64*T1 seconds for all transports. Timer H determines when the server
+ transaction abandons retransmitting the response. Its value is
+ chosen to equal Timer B, the amount of time a client transaction will
+ continue to retry sending a request. If timer G fires, the response
+ is passed to the transport layer once more for retransmission, and
+ timer G is set to fire in MIN(2*T1, T2) seconds. From then on, when
+ timer G fires, the response is passed to the transport again for
+ transmission, and timer G is reset with a value that doubles, unless
+ that value exceeds T2, in which case it is reset with the value of
+ T2. This is identical to the retransmit behavior for requests in the
+ "Trying" state of the non-INVITE client transaction. Furthermore,
+ while in the "Completed" state, if a request retransmission is
+ received, the server SHOULD pass the response to the transport for
+ retransmission.
+
+ If an ACK is received while the server transaction is in the
+ "Completed" state, the server transaction MUST transition to the
+ "Confirmed" state. As Timer G is ignored in this state, any
+ retransmissions of the response will cease.
+
+ If timer H fires while in the "Completed" state, it implies that the
+ ACK was never received. In this case, the server transaction MUST
+ transition to the "Terminated" state, and MUST indicate to the TU
+ that a transaction failure has occurred.
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 135]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ |INVITE
+ |pass INV to TU
+ INVITE V send 100 if TU won't in 200ms
+ send response+-----------+
+ +--------| |--------+101-199 from TU
+ | | Proceeding| |send response
+ +------->| |<-------+
+ | | Transport Err.
+ | | Inform TU
+ | |--------------->+
+ +-----------+ |
+ 300-699 from TU | |2xx from TU |
+ send response | |send response |
+ | +------------------>+
+ | |
+ INVITE V Timer G fires |
+ send response+-----------+ send response |
+ +--------| |--------+ |
+ | | Completed | | |
+ +------->| |<-------+ |
+ +-----------+ |
+ | | |
+ ACK | | |
+ - | +------------------>+
+ | Timer H fires |
+ V or Transport Err.|
+ +-----------+ Inform TU |
+ | | |
+ | Confirmed | |
+ | | |
+ +-----------+ |
+ | |
+ |Timer I fires |
+ |- |
+ | |
+ V |
+ +-----------+ |
+ | | |
+ | Terminated|<---------------+
+ | |
+ +-----------+
+
+ Figure 7: INVITE server transaction
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 136]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The purpose of the "Confirmed" state is to absorb any additional ACK
+ messages that arrive, triggered from retransmissions of the final
+ response. When this state is entered, timer I is set to fire in T4
+ seconds for unreliable transports, and zero seconds for reliable
+ transports. Once timer I fires, the server MUST transition to the
+ "Terminated" state.
+
+ Once the transaction is in the "Terminated" state, it MUST be
+ destroyed immediately. As with client transactions, this is needed
+ to ensure reliability of the 2xx responses to INVITE.
+
+17.2.2 Non-INVITE Server Transaction
+
+ The state machine for the non-INVITE server transaction is shown in
+ Figure 8.
+
+ The state machine is initialized in the "Trying" state and is passed
+ a request other than INVITE or ACK when initialized. This request is
+ passed up to the TU. Once in the "Trying" state, any further request
+ retransmissions are discarded. A request is a retransmission if it
+ matches the same server transaction, using the rules specified in
+ Section 17.2.3.
+
+ While in the "Trying" state, if the TU passes a provisional response
+ to the server transaction, the server transaction MUST enter the
+ "Proceeding" state. The response MUST be passed to the transport
+ layer for transmission. Any further provisional responses that are
+ received from the TU while in the "Proceeding" state MUST be passed
+ to the transport layer for transmission. If a retransmission of the
+ request is received while in the "Proceeding" state, the most
+ recently sent provisional response MUST be passed to the transport
+ layer for retransmission. If the TU passes a final response (status
+ codes 200-699) to the server while in the "Proceeding" state, the
+ transaction MUST enter the "Completed" state, and the response MUST
+ be passed to the transport layer for transmission.
+
+ When the server transaction enters the "Completed" state, it MUST set
+ Timer J to fire in 64*T1 seconds for unreliable transports, and zero
+ seconds for reliable transports. While in the "Completed" state, the
+ server transaction MUST pass the final response to the transport
+ layer for retransmission whenever a retransmission of the request is
+ received. Any other final responses passed by the TU to the server
+ transaction MUST be discarded while in the "Completed" state. The
+ server transaction remains in this state until Timer J fires, at
+ which point it MUST transition to the "Terminated" state.
+
+ The server transaction MUST be destroyed the instant it enters the
+ "Terminated" state.
+
+
+
+Rosenberg, et. al. Standards Track [Page 137]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+17.2.3 Matching Requests to Server Transactions
+
+ When a request is received from the network by the server, it has to
+ be matched to an existing transaction. This is accomplished in the
+ following manner.
+
+ The branch parameter in the topmost Via header field of the request
+ is examined. If it is present and begins with the magic cookie
+ "z9hG4bK", the request was generated by a client transaction
+ compliant to this specification. Therefore, the branch parameter
+ will be unique across all transactions sent by that client. The
+ request matches a transaction if:
+
+ 1. the branch parameter in the request is equal to the one in the
+ top Via header field of the request that created the
+ transaction, and
+
+ 2. the sent-by value in the top Via of the request is equal to the
+ one in the request that created the transaction, and
+
+ 3. the method of the request matches the one that created the
+ transaction, except for ACK, where the method of the request
+ that created the transaction is INVITE.
+
+ This matching rule applies to both INVITE and non-INVITE transactions
+ alike.
+
+ The sent-by value is used as part of the matching process because
+ there could be accidental or malicious duplication of branch
+ parameters from different clients.
+
+ If the branch parameter in the top Via header field is not present,
+ or does not contain the magic cookie, the following procedures are
+ used. These exist to handle backwards compatibility with RFC 2543
+ compliant implementations.
+
+ The INVITE request matches a transaction if the Request-URI, To tag,
+ From tag, Call-ID, CSeq, and top Via header field match those of the
+ INVITE request which created the transaction. In this case, the
+ INVITE is a retransmission of the original one that created the
+ transaction. The ACK request matches a transaction if the Request-
+ URI, From tag, Call-ID, CSeq number (not the method), and top Via
+ header field match those of the INVITE request which created the
+ transaction, and the To tag of the ACK matches the To tag of the
+ response sent by the server transaction. Matching is done based on
+ the matching rules defined for each of those header fields.
+ Inclusion of the tag in the To header field in the ACK matching
+ process helps disambiguate ACK for 2xx from ACK for other responses
+
+
+
+Rosenberg, et. al. Standards Track [Page 138]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ at a proxy, which may have forwarded both responses (This can occur
+ in unusual conditions. Specifically, when a proxy forked a request,
+ and then crashes, the responses may be delivered to another proxy,
+ which might end up forwarding multiple responses upstream). An ACK
+ request that matches an INVITE transaction matched by a previous ACK
+ is considered a retransmission of that previous ACK.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 139]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ |Request received
+ |pass to TU
+ V
+ +-----------+
+ | |
+ | Trying |-------------+
+ | | |
+ +-----------+ |200-699 from TU
+ | |send response
+ |1xx from TU |
+ |send response |
+ | |
+ Request V 1xx from TU |
+ send response+-----------+send response|
+ +--------| |--------+ |
+ | | Proceeding| | |
+ +------->| |<-------+ |
+ +<--------------| | |
+ |Trnsprt Err +-----------+ |
+ |Inform TU | |
+ | | |
+ | |200-699 from TU |
+ | |send response |
+ | Request V |
+ | send response+-----------+ |
+ | +--------| | |
+ | | | Completed |<------------+
+ | +------->| |
+ +<--------------| |
+ |Trnsprt Err +-----------+
+ |Inform TU |
+ | |Timer J fires
+ | |-
+ | |
+ | V
+ | +-----------+
+ | | |
+ +-------------->| Terminated|
+ | |
+ +-----------+
+
+ Figure 8: non-INVITE server transaction
+
+ For all other request methods, a request is matched to a transaction
+ if the Request-URI, To tag, From tag, Call-ID, CSeq (including the
+ method), and top Via header field match those of the request that
+ created the transaction. Matching is done based on the matching
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 140]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ rules defined for each of those header fields. When a non-INVITE
+ request matches an existing transaction, it is a retransmission of
+ the request that created that transaction.
+
+ Because the matching rules include the Request-URI, the server cannot
+ match a response to a transaction. When the TU passes a response to
+ the server transaction, it must pass it to the specific server
+ transaction for which the response is targeted.
+
+17.2.4 Handling Transport Errors
+
+ When the server transaction sends a response to the transport layer
+ to be sent, the following procedures are followed if the transport
+ layer indicates a failure.
+
+ First, the procedures in [4] are followed, which attempt to deliver
+ the response to a backup. If those should all fail, based on the
+ definition of failure in [4], the server transaction SHOULD inform
+ the TU that a failure has occurred, and SHOULD transition to the
+ terminated state.
+
+18 Transport
+
+ The transport layer is responsible for the actual transmission of
+ requests and responses over network transports. This includes
+ determination of the connection to use for a request or response in
+ the case of connection-oriented transports.
+
+ The transport layer is responsible for managing persistent
+ connections for transport protocols like TCP and SCTP, or TLS over
+ those, including ones opened to the transport layer. This includes
+ connections opened by the client or server transports, so that
+ connections are shared between client and server transport functions.
+ These connections are indexed by the tuple formed from the address,
+ port, and transport protocol at the far end of the connection. When
+ a connection is opened by the transport layer, this index is set to
+ the destination IP, port and transport. When the connection is
+ accepted by the transport layer, this index is set to the source IP
+ address, port number, and transport. Note that, because the source
+ port is often ephemeral, but it cannot be known whether it is
+ ephemeral or selected through procedures in [4], connections accepted
+ by the transport layer will frequently not be reused. The result is
+ that two proxies in a "peering" relationship using a connection-
+ oriented transport frequently will have two connections in use, one
+ for transactions initiated in each direction.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 141]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ It is RECOMMENDED that connections be kept open for some
+ implementation-defined duration after the last message was sent or
+ received over that connection. This duration SHOULD at least equal
+ the longest amount of time the element would need in order to bring a
+ transaction from instantiation to the terminated state. This is to
+ make it likely that transactions are completed over the same
+ connection on which they are initiated (for example, request,
+ response, and in the case of INVITE, ACK for non-2xx responses).
+ This usually means at least 64*T1 (see Section 17.1.1.1 for a
+ definition of T1). However, it could be larger in an element that
+ has a TU using a large value for timer C (bullet 11 of Section 16.6),
+ for example.
+
+ All SIP elements MUST implement UDP and TCP. SIP elements MAY
+ implement other protocols.
+
+ Making TCP mandatory for the UA is a substantial change from RFC
+ 2543. It has arisen out of the need to handle larger messages,
+ which MUST use TCP, as discussed below. Thus, even if an element
+ never sends large messages, it may receive one and needs to be
+ able to handle them.
+
+18.1 Clients
+
+18.1.1 Sending Requests
+
+ The client side of the transport layer is responsible for sending the
+ request and receiving responses. The user of the transport layer
+ passes the client transport the request, an IP address, port,
+ transport, and possibly TTL for multicast destinations.
+
+ If a request is within 200 bytes of the path MTU, or if it is larger
+ than 1300 bytes and the path MTU is unknown, the request MUST be sent
+ using an RFC 2914 [43] congestion controlled transport protocol, such
+ as TCP. If this causes a change in the transport protocol from the
+ one indicated in the top Via, the value in the top Via MUST be
+ changed. This prevents fragmentation of messages over UDP and
+ provides congestion control for larger messages. However,
+ implementations MUST be able to handle messages up to the maximum
+ datagram packet size. For UDP, this size is 65,535 bytes, including
+ IP and UDP headers.
+
+ The 200 byte "buffer" between the message size and the MTU
+ accommodates the fact that the response in SIP can be larger than
+ the request. This happens due to the addition of Record-Route
+ header field values to the responses to INVITE, for example. With
+ the extra buffer, the response can be about 170 bytes larger than
+ the request, and still not be fragmented on IPv4 (about 30 bytes
+
+
+
+Rosenberg, et. al. Standards Track [Page 142]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ is consumed by IP/UDP, assuming no IPSec). 1300 is chosen when
+ path MTU is not known, based on the assumption of a 1500 byte
+ Ethernet MTU.
+
+ If an element sends a request over TCP because of these message size
+ constraints, and that request would have otherwise been sent over
+ UDP, if the attempt to establish the connection generates either an
+ ICMP Protocol Not Supported, or results in a TCP reset, the element
+ SHOULD retry the request, using UDP. This is only to provide
+ backwards compatibility with RFC 2543 compliant implementations that
+ do not support TCP. It is anticipated that this behavior will be
+ deprecated in a future revision of this specification.
+
+ A client that sends a request to a multicast address MUST add the
+ "maddr" parameter to its Via header field value containing the
+ destination multicast address, and for IPv4, SHOULD add the "ttl"
+ parameter with a value of 1. Usage of IPv6 multicast is not defined
+ in this specification, and will be a subject of future
+ standardization when the need arises.
+
+ These rules result in a purposeful limitation of multicast in SIP.
+ Its primary function is to provide a "single-hop-discovery-like"
+ service, delivering a request to a group of homogeneous servers,
+ where it is only required to process the response from any one of
+ them. This functionality is most useful for registrations. In fact,
+ based on the transaction processing rules in Section 17.1.3, the
+ client transaction will accept the first response, and view any
+ others as retransmissions because they all contain the same Via
+ branch identifier.
+
+ Before a request is sent, the client transport MUST insert a value of
+ the "sent-by" field into the Via header field. This field contains
+ an IP address or host name, and port. The usage of an FQDN is
+ RECOMMENDED. This field is used for sending responses under certain
+ conditions, described below. If the port is absent, the default
+ value depends on the transport. It is 5060 for UDP, TCP and SCTP,
+ 5061 for TLS.
+
+ For reliable transports, the response is normally sent on the
+ connection on which the request was received. Therefore, the client
+ transport MUST be prepared to receive the response on the same
+ connection used to send the request. Under error conditions, the
+ server may attempt to open a new connection to send the response. To
+ handle this case, the transport layer MUST also be prepared to
+ receive an incoming connection on the source IP address from which
+ the request was sent and port number in the "sent-by" field. It also
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 143]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ MUST be prepared to receive incoming connections on any address and
+ port that would be selected by a server based on the procedures
+ described in Section 5 of [4].
+
+ For unreliable unicast transports, the client transport MUST be
+ prepared to receive responses on the source IP address from which the
+ request is sent (as responses are sent back to the source address)
+ and the port number in the "sent-by" field. Furthermore, as with
+ reliable transports, in certain cases the response will be sent
+ elsewhere. The client MUST be prepared to receive responses on any
+ address and port that would be selected by a server based on the
+ procedures described in Section 5 of [4].
+
+ For multicast, the client transport MUST be prepared to receive
+ responses on the same multicast group and port to which the request
+ is sent (that is, it needs to be a member of the multicast group it
+ sent the request to.)
+
+ If a request is destined to an IP address, port, and transport to
+ which an existing connection is open, it is RECOMMENDED that this
+ connection be used to send the request, but another connection MAY be
+ opened and used.
+
+ If a request is sent using multicast, it is sent to the group
+ address, port, and TTL provided by the transport user. If a request
+ is sent using unicast unreliable transports, it is sent to the IP
+ address and port provided by the transport user.
+
+18.1.2 Receiving Responses
+
+ When a response is received, the client transport examines the top
+ Via header field value. If the value of the "sent-by" parameter in
+ that header field value does not correspond to a value that the
+ client transport is configured to insert into requests, the response
+ MUST be silently discarded.
+
+ If there are any client transactions in existence, the client
+ transport uses the matching procedures of Section 17.1.3 to attempt
+ to match the response to an existing transaction. If there is a
+ match, the response MUST be passed to that transaction. Otherwise,
+ the response MUST be passed to the core (whether it be stateless
+ proxy, stateful proxy, or UA) for further processing. Handling of
+ these "stray" responses is dependent on the core (a proxy will
+ forward them, while a UA will discard, for example).
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 144]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+18.2 Servers
+
+18.2.1 Receiving Requests
+
+ A server SHOULD be prepared to receive requests on any IP address,
+ port and transport combination that can be the result of a DNS lookup
+ on a SIP or SIPS URI [4] that is handed out for the purposes of
+ communicating with that server. In this context, "handing out"
+ includes placing a URI in a Contact header field in a REGISTER
+ request or a redirect response, or in a Record-Route header field in
+ a request or response. A URI can also be "handed out" by placing it
+ on a web page or business card. It is also RECOMMENDED that a server
+ listen for requests on the default SIP ports (5060 for TCP and UDP,
+ 5061 for TLS over TCP) on all public interfaces. The typical
+ exception would be private networks, or when multiple server
+ instances are running on the same host. For any port and interface
+ that a server listens on for UDP, it MUST listen on that same port
+ and interface for TCP. This is because a message may need to be sent
+ using TCP, rather than UDP, if it is too large. As a result, the
+ converse is not true. A server need not listen for UDP on a
+ particular address and port just because it is listening on that same
+ address and port for TCP. There may, of course, be other reasons why
+ a server needs to listen for UDP on a particular address and port.
+
+ When the server transport receives a request over any transport, it
+ MUST examine the value of the "sent-by" parameter in the top Via
+ header field value. If the host portion of the "sent-by" parameter
+ contains a domain name, or if it contains an IP address that differs
+ from the packet source address, the server MUST add a "received"
+ parameter to that Via header field value. This parameter MUST
+ contain the source address from which the packet was received. This
+ is to assist the server transport layer in sending the response,
+ since it must be sent to the source IP address from which the request
+ came.
+
+ Consider a request received by the server transport which looks like,
+ in part:
+
+ INVITE sip:bob@Biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP bobspc.biloxi.com:5060
+
+ The request is received with a source IP address of 192.0.2.4.
+ Before passing the request up, the transport adds a "received"
+ parameter, so that the request would look like, in part:
+
+ INVITE sip:bob@Biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP bobspc.biloxi.com:5060;received=192.0.2.4
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 145]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Next, the server transport attempts to match the request to a server
+ transaction. It does so using the matching rules described in
+ Section 17.2.3. If a matching server transaction is found, the
+ request is passed to that transaction for processing. If no match is
+ found, the request is passed to the core, which may decide to
+ construct a new server transaction for that request. Note that when
+ a UAS core sends a 2xx response to INVITE, the server transaction is
+ destroyed. This means that when the ACK arrives, there will be no
+ matching server transaction, and based on this rule, the ACK is
+ passed to the UAS core, where it is processed.
+
+18.2.2 Sending Responses
+
+ The server transport uses the value of the top Via header field in
+ order to determine where to send a response. It MUST follow the
+ following process:
+
+ o If the "sent-protocol" is a reliable transport protocol such as
+ TCP or SCTP, or TLS over those, the response MUST be sent using
+ the existing connection to the source of the original request
+ that created the transaction, if that connection is still open.
+ This requires the server transport to maintain an association
+ between server transactions and transport connections. If that
+ connection is no longer open, the server SHOULD open a
+ connection to the IP address in the "received" parameter, if
+ present, using the port in the "sent-by" value, or the default
+ port for that transport, if no port is specified. If that
+ connection attempt fails, the server SHOULD use the procedures
+ in [4] for servers in order to determine the IP address and
+ port to open the connection and send the response to.
+
+ o Otherwise, if the Via header field value contains a "maddr"
+ parameter, the response MUST be forwarded to the address listed
+ there, using the port indicated in "sent-by", or port 5060 if
+ none is present. If the address is a multicast address, the
+ response SHOULD be sent using the TTL indicated in the "ttl"
+ parameter, or with a TTL of 1 if that parameter is not present.
+
+ o Otherwise (for unreliable unicast transports), if the top Via
+ has a "received" parameter, the response MUST be sent to the
+ address in the "received" parameter, using the port indicated
+ in the "sent-by" value, or using port 5060 if none is specified
+ explicitly. If this fails, for example, elicits an ICMP "port
+ unreachable" response, the procedures of Section 5 of [4]
+ SHOULD be used to determine where to send the response.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 146]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o Otherwise, if it is not receiver-tagged, the response MUST be
+ sent to the address indicated by the "sent-by" value, using the
+ procedures in Section 5 of [4].
+
+18.3 Framing
+
+ In the case of message-oriented transports (such as UDP), if the
+ message has a Content-Length header field, the message body is
+ assumed to contain that many bytes. If there are additional bytes in
+ the transport packet beyond the end of the body, they MUST be
+ discarded. If the transport packet ends before the end of the
+ message body, this is considered an error. If the message is a
+ response, it MUST be discarded. If the message is a request, the
+ element SHOULD generate a 400 (Bad Request) response. If the message
+ has no Content-Length header field, the message body is assumed to
+ end at the end of the transport packet.
+
+ In the case of stream-oriented transports such as TCP, the Content-
+ Length header field indicates the size of the body. The Content-
+ Length header field MUST be used with stream oriented transports.
+
+18.4 Error Handling
+
+ Error handling is independent of whether the message was a request or
+ response.
+
+ If the transport user asks for a message to be sent over an
+ unreliable transport, and the result is an ICMP error, the behavior
+ depends on the type of ICMP error. Host, network, port or protocol
+ unreachable errors, or parameter problem errors SHOULD cause the
+ transport layer to inform the transport user of a failure in sending.
+ Source quench and TTL exceeded ICMP errors SHOULD be ignored.
+
+ If the transport user asks for a request to be sent over a reliable
+ transport, and the result is a connection failure, the transport
+ layer SHOULD inform the transport user of a failure in sending.
+
+19 Common Message Components
+
+ There are certain components of SIP messages that appear in various
+ places within SIP messages (and sometimes, outside of them) that
+ merit separate discussion.
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 147]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+19.1 SIP and SIPS Uniform Resource Indicators
+
+ A SIP or SIPS URI identifies a communications resource. Like all
+ URIs, SIP and SIPS URIs may be placed in web pages, email messages,
+ or printed literature. They contain sufficient information to
+ initiate and maintain a communication session with the resource.
+
+ Examples of communications resources include the following:
+
+ o a user of an online service
+
+ o an appearance on a multi-line phone
+
+ o a mailbox on a messaging system
+
+ o a PSTN number at a gateway service
+
+ o a group (such as "sales" or "helpdesk") in an organization
+
+ A SIPS URI specifies that the resource be contacted securely. This
+ means, in particular, that TLS is to be used between the UAC and the
+ domain that owns the URI. From there, secure communications are used
+ to reach the user, where the specific security mechanism depends on
+ the policy of the domain. Any resource described by a SIP URI can be
+ "upgraded" to a SIPS URI by just changing the scheme, if it is
+ desired to communicate with that resource securely.
+
+19.1.1 SIP and SIPS URI Components
+
+ The "sip:" and "sips:" schemes follow the guidelines in RFC 2396 [5].
+ They use a form similar to the mailto URL, allowing the specification
+ of SIP request-header fields and the SIP message-body. This makes it
+ possible to specify the subject, media type, or urgency of sessions
+ initiated by using a URI on a web page or in an email message. The
+ formal syntax for a SIP or SIPS URI is presented in Section 25. Its
+ general form, in the case of a SIP URI, is:
+
+ sip:user:password@host:port;uri-parameters?headers
+
+ The format for a SIPS URI is the same, except that the scheme is
+ "sips" instead of sip. These tokens, and some of the tokens in their
+ expansions, have the following meanings:
+
+ user: The identifier of a particular resource at the host being
+ addressed. The term "host" in this context frequently refers
+ to a domain. The "userinfo" of a URI consists of this user
+ field, the password field, and the @ sign following them. The
+ userinfo part of a URI is optional and MAY be absent when the
+
+
+
+Rosenberg, et. al. Standards Track [Page 148]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ destination host does not have a notion of users or when the
+ host itself is the resource being identified. If the @ sign is
+ present in a SIP or SIPS URI, the user field MUST NOT be empty.
+
+ If the host being addressed can process telephone numbers, for
+ instance, an Internet telephony gateway, a telephone-
+ subscriber field defined in RFC 2806 [9] MAY be used to
+ populate the user field. There are special escaping rules for
+ encoding telephone-subscriber fields in SIP and SIPS URIs
+ described in Section 19.1.2.
+
+ password: A password associated with the user. While the SIP and
+ SIPS URI syntax allows this field to be present, its use is NOT
+ RECOMMENDED, because the passing of authentication information
+ in clear text (such as URIs) has proven to be a security risk
+ in almost every case where it has been used. For instance,
+ transporting a PIN number in this field exposes the PIN.
+
+ Note that the password field is just an extension of the user
+ portion. Implementations not wishing to give special
+ significance to the password portion of the field MAY simply
+ treat "user:password" as a single string.
+
+ host: The host providing the SIP resource. The host part contains
+ either a fully-qualified domain name or numeric IPv4 or IPv6
+ address. Using the fully-qualified domain name form is
+ RECOMMENDED whenever possible.
+
+ port: The port number where the request is to be sent.
+
+ URI parameters: Parameters affecting a request constructed from
+ the URI.
+
+ URI parameters are added after the hostport component and are
+ separated by semi-colons.
+
+ URI parameters take the form:
+
+ parameter-name "=" parameter-value
+
+ Even though an arbitrary number of URI parameters may be
+ included in a URI, any given parameter-name MUST NOT appear
+ more than once.
+
+ This extensible mechanism includes the transport, maddr, ttl,
+ user, method and lr parameters.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 149]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The transport parameter determines the transport mechanism to
+ be used for sending SIP messages, as specified in [4]. SIP can
+ use any network transport protocol. Parameter names are
+ defined for UDP (RFC 768 [14]), TCP (RFC 761 [15]), and SCTP
+ (RFC 2960 [16]). For a SIPS URI, the transport parameter MUST
+ indicate a reliable transport.
+
+ The maddr parameter indicates the server address to be
+ contacted for this user, overriding any address derived from
+ the host field. When an maddr parameter is present, the port
+ and transport components of the URI apply to the address
+ indicated in the maddr parameter value. [4] describes the
+ proper interpretation of the transport, maddr, and hostport in
+ order to obtain the destination address, port, and transport
+ for sending a request.
+
+ The maddr field has been used as a simple form of loose source
+ routing. It allows a URI to specify a proxy that must be
+ traversed en-route to the destination. Continuing to use the
+ maddr parameter this way is strongly discouraged (the
+ mechanisms that enable it are deprecated). Implementations
+ should instead use the Route mechanism described in this
+ document, establishing a pre-existing route set if necessary
+ (see Section 8.1.1.1). This provides a full URI to describe
+ the node to be traversed.
+
+ The ttl parameter determines the time-to-live value of the UDP
+ multicast packet and MUST only be used if maddr is a multicast
+ address and the transport protocol is UDP. For example, to
+ specify a call to alice@atlanta.com using multicast to
+ 239.255.255.1 with a ttl of 15, the following URI would be
+ used:
+
+ sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15
+
+ The set of valid telephone-subscriber strings is a subset of
+ valid user strings. The user URI parameter exists to
+ distinguish telephone numbers from user names that happen to
+ look like telephone numbers. If the user string contains a
+ telephone number formatted as a telephone-subscriber, the user
+ parameter value "phone" SHOULD be present. Even without this
+ parameter, recipients of SIP and SIPS URIs MAY interpret the
+ pre-@ part as a telephone number if local restrictions on the
+ name space for user name allow it.
+
+ The method of the SIP request constructed from the URI can be
+ specified with the method parameter.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 150]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The lr parameter, when present, indicates that the element
+ responsible for this resource implements the routing mechanisms
+ specified in this document. This parameter will be used in the
+ URIs proxies place into Record-Route header field values, and
+ may appear in the URIs in a pre-existing route set.
+
+ This parameter is used to achieve backwards compatibility with
+ systems implementing the strict-routing mechanisms of RFC 2543
+ and the rfc2543bis drafts up to bis-05. An element preparing
+ to send a request based on a URI not containing this parameter
+ can assume the receiving element implements strict-routing and
+ reformat the message to preserve the information in the
+ Request-URI.
+
+ Since the uri-parameter mechanism is extensible, SIP elements
+ MUST silently ignore any uri-parameters that they do not
+ understand.
+
+ Headers: Header fields to be included in a request constructed
+ from the URI.
+
+ Headers fields in the SIP request can be specified with the "?"
+ mechanism within a URI. The header names and values are
+ encoded in ampersand separated hname = hvalue pairs. The
+ special hname "body" indicates that the associated hvalue is
+ the message-body of the SIP request.
+
+ Table 1 summarizes the use of SIP and SIPS URI components based on
+ the context in which the URI appears. The external column describes
+ URIs appearing anywhere outside of a SIP message, for instance on a
+ web page or business card. Entries marked "m" are mandatory, those
+ marked "o" are optional, and those marked "-" are not allowed.
+ Elements processing URIs SHOULD ignore any disallowed components if
+ they are present. The second column indicates the default value of
+ an optional element if it is not present. "--" indicates that the
+ element is either not optional, or has no default value.
+
+ URIs in Contact header fields have different restrictions depending
+ on the context in which the header field appears. One set applies to
+ messages that establish and maintain dialogs (INVITE and its 200 (OK)
+ response). The other applies to registration and redirection
+ messages (REGISTER, its 200 (OK) response, and 3xx class responses to
+ any method).
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 151]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+19.1.2 Character Escaping Requirements
+
+ dialog
+ reg./redir. Contact/
+ default Req.-URI To From Contact R-R/Route external
+user -- o o o o o o
+password -- o o o o o o
+host -- m m m m m m
+port (1) o - - o o o
+user-param ip o o o o o o
+method INVITE - - - - - o
+maddr-param -- o - - o o o
+ttl-param 1 o - - o - o
+transp.-param (2) o - - o o o
+lr-param -- o - - - o o
+other-param -- o o o o o o
+headers -- - - - o - o
+
+ (1): The default port value is transport and scheme dependent. The
+ default is 5060 for sip: using UDP, TCP, or SCTP. The default is
+ 5061 for sip: using TLS over TCP and sips: over TCP.
+
+ (2): The default transport is scheme dependent. For sip:, it is UDP.
+ For sips:, it is TCP.
+
+ Table 1: Use and default values of URI components for SIP header
+ field values, Request-URI and references
+
+ SIP follows the requirements and guidelines of RFC 2396 [5] when
+ defining the set of characters that must be escaped in a SIP URI, and
+ uses its ""%" HEX HEX" mechanism for escaping. From RFC 2396 [5]:
+
+ The set of characters actually reserved within any given URI
+ component is defined by that component. In general, a character
+ is reserved if the semantics of the URI changes if the character
+ is replaced with its escaped US-ASCII encoding [5]. Excluded US-
+ ASCII characters (RFC 2396 [5]), such as space and control
+ characters and characters used as URI delimiters, also MUST be
+ escaped. URIs MUST NOT contain unescaped space and control
+ characters.
+
+ For each component, the set of valid BNF expansions defines exactly
+ which characters may appear unescaped. All other characters MUST be
+ escaped.
+
+ For example, "@" is not in the set of characters in the user
+ component, so the user "j@s0n" must have at least the @ sign encoded,
+ as in "j%40s0n".
+
+
+
+Rosenberg, et. al. Standards Track [Page 152]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Expanding the hname and hvalue tokens in Section 25 show that all URI
+ reserved characters in header field names and values MUST be escaped.
+
+ The telephone-subscriber subset of the user component has special
+ escaping considerations. The set of characters not reserved in the
+ RFC 2806 [9] description of telephone-subscriber contains a number of
+ characters in various syntax elements that need to be escaped when
+ used in SIP URIs. Any characters occurring in a telephone-subscriber
+ that do not appear in an expansion of the BNF for the user rule MUST
+ be escaped.
+
+ Note that character escaping is not allowed in the host component of
+ a SIP or SIPS URI (the % character is not valid in its expansion).
+ This is likely to change in the future as requirements for
+ Internationalized Domain Names are finalized. Current
+ implementations MUST NOT attempt to improve robustness by treating
+ received escaped characters in the host component as literally
+ equivalent to their unescaped counterpart. The behavior required to
+ meet the requirements of IDN may be significantly different.
+
+19.1.3 Example SIP and SIPS URIs
+
+ sip:alice@atlanta.com
+ sip:alice:secretword@atlanta.com;transport=tcp
+ sips:alice@atlanta.com?subject=project%20x&priority=urgent
+ sip:+1-212-555-1212:1234@gateway.com;user=phone
+ sips:1212@gateway.com
+ sip:alice@192.0.2.4
+ sip:atlanta.com;method=REGISTER?to=alice%40atlanta.com
+ sip:alice;day=tuesday@atlanta.com
+
+ The last sample URI above has a user field value of
+ "alice;day=tuesday". The escaping rules defined above allow a
+ semicolon to appear unescaped in this field. For the purposes of
+ this protocol, the field is opaque. The structure of that value is
+ only useful to the SIP element responsible for the resource.
+
+19.1.4 URI Comparison
+
+ Some operations in this specification require determining whether two
+ SIP or SIPS URIs are equivalent. In this specification, registrars
+ need to compare bindings in Contact URIs in REGISTER requests (see
+ Section 10.3.). SIP and SIPS URIs are compared for equality
+ according to the following rules:
+
+ o A SIP and SIPS URI are never equivalent.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 153]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o Comparison of the userinfo of SIP and SIPS URIs is case-
+ sensitive. This includes userinfo containing passwords or
+ formatted as telephone-subscribers. Comparison of all other
+ components of the URI is case-insensitive unless explicitly
+ defined otherwise.
+
+ o The ordering of parameters and header fields is not significant
+ in comparing SIP and SIPS URIs.
+
+ o Characters other than those in the "reserved" set (see RFC 2396
+ [5]) are equivalent to their ""%" HEX HEX" encoding.
+
+ o An IP address that is the result of a DNS lookup of a host name
+ does not match that host name.
+
+ o For two URIs to be equal, the user, password, host, and port
+ components must match.
+
+ A URI omitting the user component will not match a URI that
+ includes one. A URI omitting the password component will not
+ match a URI that includes one.
+
+ A URI omitting any component with a default value will not
+ match a URI explicitly containing that component with its
+ default value. For instance, a URI omitting the optional port
+ component will not match a URI explicitly declaring port 5060.
+ The same is true for the transport-parameter, ttl-parameter,
+ user-parameter, and method components.
+
+ Defining sip:user@host to not be equivalent to
+ sip:user@host:5060 is a change from RFC 2543. When deriving
+ addresses from URIs, equivalent addresses are expected from
+ equivalent URIs. The URI sip:user@host:5060 will always
+ resolve to port 5060. The URI sip:user@host may resolve to
+ other ports through the DNS SRV mechanisms detailed in [4].
+
+ o URI uri-parameter components are compared as follows:
+
+ - Any uri-parameter appearing in both URIs must match.
+
+ - A user, ttl, or method uri-parameter appearing in only one
+ URI never matches, even if it contains the default value.
+
+ - A URI that includes an maddr parameter will not match a URI
+ that contains no maddr parameter.
+
+ - All other uri-parameters appearing in only one URI are
+ ignored when comparing the URIs.
+
+
+
+Rosenberg, et. al. Standards Track [Page 154]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o URI header components are never ignored. Any present header
+ component MUST be present in both URIs and match for the URIs
+ to match. The matching rules are defined for each header field
+ in Section 20.
+
+ The URIs within each of the following sets are equivalent:
+
+ sip:%61lice@atlanta.com;transport=TCP
+ sip:alice@AtLanTa.CoM;Transport=tcp
+
+ sip:carol@chicago.com
+ sip:carol@chicago.com;newparam=5
+ sip:carol@chicago.com;security=on
+
+ sip:biloxi.com;transport=tcp;method=REGISTER?to=sip:bob%40biloxi.com
+ sip:biloxi.com;method=REGISTER;transport=tcp?to=sip:bob%40biloxi.com
+
+ sip:alice@atlanta.com?subject=project%20x&priority=urgent
+ sip:alice@atlanta.com?priority=urgent&subject=project%20x
+
+ The URIs within each of the following sets are not equivalent:
+
+ SIP:ALICE@AtLanTa.CoM;Transport=udp (different usernames)
+ sip:alice@AtLanTa.CoM;Transport=UDP
+
+ sip:bob@biloxi.com (can resolve to different ports)
+ sip:bob@biloxi.com:5060
+
+ sip:bob@biloxi.com (can resolve to different transports)
+ sip:bob@biloxi.com;transport=udp
+
+ sip:bob@biloxi.com (can resolve to different port and transports)
+ sip:bob@biloxi.com:6000;transport=tcp
+
+ sip:carol@chicago.com (different header component)
+ sip:carol@chicago.com?Subject=next%20meeting
+
+ sip:bob@phone21.boxesbybob.com (even though that's what
+ sip:bob@192.0.2.4 phone21.boxesbybob.com resolves to)
+
+ Note that equality is not transitive:
+
+ o sip:carol@chicago.com and sip:carol@chicago.com;security=on are
+ equivalent
+
+ o sip:carol@chicago.com and sip:carol@chicago.com;security=off
+ are equivalent
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 155]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o sip:carol@chicago.com;security=on and
+ sip:carol@chicago.com;security=off are not equivalent
+
+19.1.5 Forming Requests from a URI
+
+ An implementation needs to take care when forming requests directly
+ from a URI. URIs from business cards, web pages, and even from
+ sources inside the protocol such as registered contacts may contain
+ inappropriate header fields or body parts.
+
+ An implementation MUST include any provided transport, maddr, ttl, or
+ user parameter in the Request-URI of the formed request. If the URI
+ contains a method parameter, its value MUST be used as the method of
+ the request. The method parameter MUST NOT be placed in the
+ Request-URI. Unknown URI parameters MUST be placed in the message's
+ Request-URI.
+
+ An implementation SHOULD treat the presence of any headers or body
+ parts in the URI as a desire to include them in the message, and
+ choose to honor the request on a per-component basis.
+
+ An implementation SHOULD NOT honor these obviously dangerous header
+ fields: From, Call-ID, CSeq, Via, and Record-Route.
+
+ An implementation SHOULD NOT honor any requested Route header field
+ values in order to not be used as an unwitting agent in malicious
+ attacks.
+
+ An implementation SHOULD NOT honor requests to include header fields
+ that may cause it to falsely advertise its location or capabilities.
+ These include: Accept, Accept-Encoding, Accept-Language, Allow,
+ Contact (in its dialog usage), Organization, Supported, and User-
+ Agent.
+
+ An implementation SHOULD verify the accuracy of any requested
+ descriptive header fields, including: Content-Disposition, Content-
+ Encoding, Content-Language, Content-Length, Content-Type, Date,
+ Mime-Version, and Timestamp.
+
+ If the request formed from constructing a message from a given URI is
+ not a valid SIP request, the URI is invalid. An implementation MUST
+ NOT proceed with transmitting the request. It should instead pursue
+ the course of action due an invalid URI in the context it occurs.
+
+ The constructed request can be invalid in many ways. These
+ include, but are not limited to, syntax error in header fields,
+ invalid combinations of URI parameters, or an incorrect
+ description of the message body.
+
+
+
+Rosenberg, et. al. Standards Track [Page 156]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Sending a request formed from a given URI may require capabilities
+ unavailable to the implementation. The URI might indicate use of an
+ unimplemented transport or extension, for example. An implementation
+ SHOULD refuse to send these requests rather than modifying them to
+ match their capabilities. An implementation MUST NOT send a request
+ requiring an extension that it does not support.
+
+ For example, such a request can be formed through the presence of
+ a Require header parameter or a method URI parameter with an
+ unknown or explicitly unsupported value.
+
+19.1.6 Relating SIP URIs and tel URLs
+
+ When a tel URL (RFC 2806 [9]) is converted to a SIP or SIPS URI, the
+ entire telephone-subscriber portion of the tel URL, including any
+ parameters, is placed into the userinfo part of the SIP or SIPS URI.
+
+ Thus, tel:+358-555-1234567;postd=pp22 becomes
+
+ sip:+358-555-1234567;postd=pp22@foo.com;user=phone
+
+ or
+ sips:+358-555-1234567;postd=pp22@foo.com;user=phone
+
+ not
+ sip:+358-555-1234567@foo.com;postd=pp22;user=phone
+
+ or
+
+ sips:+358-555-1234567@foo.com;postd=pp22;user=phone
+
+ In general, equivalent "tel" URLs converted to SIP or SIPS URIs in
+ this fashion may not produce equivalent SIP or SIPS URIs. The
+ userinfo of SIP and SIPS URIs are compared as a case-sensitive
+ string. Variance in case-insensitive portions of tel URLs and
+ reordering of tel URL parameters does not affect tel URL equivalence,
+ but does affect the equivalence of SIP URIs formed from them.
+
+ For example,
+
+ tel:+358-555-1234567;postd=pp22
+ tel:+358-555-1234567;POSTD=PP22
+
+ are equivalent, while
+
+ sip:+358-555-1234567;postd=pp22@foo.com;user=phone
+ sip:+358-555-1234567;POSTD=PP22@foo.com;user=phone
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 157]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ are not.
+
+ Likewise,
+
+ tel:+358-555-1234567;postd=pp22;isub=1411
+ tel:+358-555-1234567;isub=1411;postd=pp22
+
+ are equivalent, while
+
+ sip:+358-555-1234567;postd=pp22;isub=1411@foo.com;user=phone
+ sip:+358-555-1234567;isub=1411;postd=pp22@foo.com;user=phone
+
+ are not.
+
+ To mitigate this problem, elements constructing telephone-subscriber
+ fields to place in the userinfo part of a SIP or SIPS URI SHOULD fold
+ any case-insensitive portion of telephone-subscriber to lower case,
+ and order the telephone-subscriber parameters lexically by parameter
+ name, excepting isdn-subaddress and post-dial, which occur first and
+ in that order. (All components of a tel URL except for future-
+ extension parameters are defined to be compared case-insensitive.)
+
+ Following this suggestion, both
+
+ tel:+358-555-1234567;postd=pp22
+ tel:+358-555-1234567;POSTD=PP22
+
+ become
+
+ sip:+358-555-1234567;postd=pp22@foo.com;user=phone
+
+ and both
+
+ tel:+358-555-1234567;tsp=a.b;phone-context=5
+ tel:+358-555-1234567;phone-context=5;tsp=a.b
+
+ become
+
+ sip:+358-555-1234567;phone-context=5;tsp=a.b@foo.com;user=phone
+
+19.2 Option Tags
+
+ Option tags are unique identifiers used to designate new options
+ (extensions) in SIP. These tags are used in Require (Section 20.32),
+ Proxy-Require (Section 20.29), Supported (Section 20.37) and
+ Unsupported (Section 20.40) header fields. Note that these options
+ appear as parameters in those header fields in an option-tag = token
+ form (see Section 25 for the definition of token).
+
+
+
+Rosenberg, et. al. Standards Track [Page 158]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Option tags are defined in standards track RFCs. This is a change
+ from past practice, and is instituted to ensure continuing multi-
+ vendor interoperability (see discussion in Section 20.32 and Section
+ 20.37). An IANA registry of option tags is used to ensure easy
+ reference.
+
+19.3 Tags
+
+ The "tag" parameter is used in the To and From header fields of SIP
+ messages. It serves as a general mechanism to identify a dialog,
+ which is the combination of the Call-ID along with two tags, one from
+ each participant in the dialog. When a UA sends a request outside of
+ a dialog, it contains a From tag only, providing "half" of the dialog
+ ID. The dialog is completed from the response(s), each of which
+ contributes the second half in the To header field. The forking of
+ SIP requests means that multiple dialogs can be established from a
+ single request. This also explains the need for the two-sided dialog
+ identifier; without a contribution from the recipients, the
+ originator could not disambiguate the multiple dialogs established
+ from a single request.
+
+ When a tag is generated by a UA for insertion into a request or
+ response, it MUST be globally unique and cryptographically random
+ with at least 32 bits of randomness. A property of this selection
+ requirement is that a UA will place a different tag into the From
+ header of an INVITE than it would place into the To header of the
+ response to the same INVITE. This is needed in order for a UA to
+ invite itself to a session, a common case for "hairpinning" of calls
+ in PSTN gateways. Similarly, two INVITEs for different calls will
+ have different From tags, and two responses for different calls will
+ have different To tags.
+
+ Besides the requirement for global uniqueness, the algorithm for
+ generating a tag is implementation-specific. Tags are helpful in
+ fault tolerant systems, where a dialog is to be recovered on an
+ alternate server after a failure. A UAS can select the tag in such a
+ way that a backup can recognize a request as part of a dialog on the
+ failed server, and therefore determine that it should attempt to
+ recover the dialog and any other state associated with it.
+
+20 Header Fields
+
+ The general syntax for header fields is covered in Section 7.3. This
+ section lists the full set of header fields along with notes on
+ syntax, meaning, and usage. Throughout this section, we use [HX.Y]
+ to refer to Section X.Y of the current HTTP/1.1 specification RFC
+ 2616 [8]. Examples of each header field are given.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 159]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Information about header fields in relation to methods and proxy
+ processing is summarized in Tables 2 and 3.
+
+ The "where" column describes the request and response types in which
+ the header field can be used. Values in this column are:
+
+ R: header field may only appear in requests;
+
+ r: header field may only appear in responses;
+
+ 2xx, 4xx, etc.: A numerical value or range indicates response
+ codes with which the header field can be used;
+
+ c: header field is copied from the request to the response.
+
+ An empty entry in the "where" column indicates that the header
+ field may be present in all requests and responses.
+
+ The "proxy" column describes the operations a proxy may perform on a
+ header field:
+
+ a: A proxy can add or concatenate the header field if not present.
+
+ m: A proxy can modify an existing header field value.
+
+ d: A proxy can delete a header field value.
+
+ r: A proxy must be able to read the header field, and thus this
+ header field cannot be encrypted.
+
+ The next six columns relate to the presence of a header field in a
+ method:
+
+ c: Conditional; requirements on the header field depend on the
+ context of the message.
+
+ m: The header field is mandatory.
+
+ m*: The header field SHOULD be sent, but clients/servers need to
+ be prepared to receive messages without that header field.
+
+ o: The header field is optional.
+
+ t: The header field SHOULD be sent, but clients/servers need to be
+ prepared to receive messages without that header field.
+
+ If a stream-based protocol (such as TCP) is used as a
+ transport, then the header field MUST be sent.
+
+
+
+Rosenberg, et. al. Standards Track [Page 160]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ *: The header field is required if the message body is not empty.
+ See Sections 20.14, 20.15 and 7.4 for details.
+
+ -: The header field is not applicable.
+
+ "Optional" means that an element MAY include the header field in a
+ request or response, and a UA MAY ignore the header field if present
+ in the request or response (The exception to this rule is the Require
+ header field discussed in 20.32). A "mandatory" header field MUST be
+ present in a request, and MUST be understood by the UAS receiving the
+ request. A mandatory response header field MUST be present in the
+ response, and the header field MUST be understood by the UAC
+ processing the response. "Not applicable" means that the header
+ field MUST NOT be present in a request. If one is placed in a
+ request by mistake, it MUST be ignored by the UAS receiving the
+ request. Similarly, a header field labeled "not applicable" for a
+ response means that the UAS MUST NOT place the header field in the
+ response, and the UAC MUST ignore the header field in the response.
+
+ A UA SHOULD ignore extension header parameters that are not
+ understood.
+
+ A compact form of some common header field names is also defined for
+ use when overall message size is an issue.
+
+ The Contact, From, and To header fields contain a URI. If the URI
+ contains a comma, question mark or semicolon, the URI MUST be
+ enclosed in angle brackets (< and >). Any URI parameters are
+ contained within these brackets. If the URI is not enclosed in angle
+ brackets, any semicolon-delimited parameters are header-parameters,
+ not URI parameters.
+
+20.1 Accept
+
+ The Accept header field follows the syntax defined in [H14.1]. The
+ semantics are also identical, with the exception that if no Accept
+ header field is present, the server SHOULD assume a default value of
+ application/sdp.
+
+ An empty Accept header field means that no formats are acceptable.
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 161]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example:
+
+ Header field where proxy ACK BYE CAN INV OPT REG
+ ___________________________________________________________
+ Accept R - o - o m* o
+ Accept 2xx - - - o m* o
+ Accept 415 - c - c c c
+ Accept-Encoding R - o - o o o
+ Accept-Encoding 2xx - - - o m* o
+ Accept-Encoding 415 - c - c c c
+ Accept-Language R - o - o o o
+ Accept-Language 2xx - - - o m* o
+ Accept-Language 415 - c - c c c
+ Alert-Info R ar - - - o - -
+ Alert-Info 180 ar - - - o - -
+ Allow R - o - o o o
+ Allow 2xx - o - m* m* o
+ Allow r - o - o o o
+ Allow 405 - m - m m m
+ Authentication-Info 2xx - o - o o o
+ Authorization R o o o o o o
+ Call-ID c r m m m m m m
+ Call-Info ar - - - o o o
+ Contact R o - - m o o
+ Contact 1xx - - - o - -
+ Contact 2xx - - - m o o
+ Contact 3xx d - o - o o o
+ Contact 485 - o - o o o
+ Content-Disposition o o - o o o
+ Content-Encoding o o - o o o
+ Content-Language o o - o o o
+ Content-Length ar t t t t t t
+ Content-Type * * - * * *
+ CSeq c r m m m m m m
+ Date a o o o o o o
+ Error-Info 300-699 a - o o o o o
+ Expires - - - o - o
+ From c r m m m m m m
+ In-Reply-To R - - - o - -
+ Max-Forwards R amr m m m m m m
+ Min-Expires 423 - - - - - m
+ MIME-Version o o - o o o
+ Organization ar - - - o o o
+
+ Table 2: Summary of header fields, A--O
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 162]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Header field where proxy ACK BYE CAN INV OPT REG
+ ___________________________________________________________________
+ Priority R ar - - - o - -
+ Proxy-Authenticate 407 ar - m - m m m
+ Proxy-Authenticate 401 ar - o o o o o
+ Proxy-Authorization R dr o o - o o o
+ Proxy-Require R ar - o - o o o
+ Record-Route R ar o o o o o -
+ Record-Route 2xx,18x mr - o o o o -
+ Reply-To - - - o - -
+ Require ar - c - c c c
+ Retry-After 404,413,480,486 - o o o o o
+ 500,503 - o o o o o
+ 600,603 - o o o o o
+ Route R adr c c c c c c
+ Server r - o o o o o
+ Subject R - - - o - -
+ Supported R - o o m* o o
+ Supported 2xx - o o m* m* o
+ Timestamp o o o o o o
+ To c(1) r m m m m m m
+ Unsupported 420 - m - m m m
+ User-Agent o o o o o o
+ Via R amr m m m m m m
+ Via rc dr m m m m m m
+ Warning r - o o o o o
+ WWW-Authenticate 401 ar - m - m m m
+ WWW-Authenticate 407 ar - o - o o o
+
+ Table 3: Summary of header fields, P--Z; (1): copied with possible
+ addition of tag
+
+ Accept: application/sdp;level=1, application/x-private, text/html
+
+20.2 Accept-Encoding
+
+ The Accept-Encoding header field is similar to Accept, but restricts
+ the content-codings [H3.5] that are acceptable in the response. See
+ [H14.3]. The semantics in SIP are identical to those defined in
+ [H14.3].
+
+ An empty Accept-Encoding header field is permissible. It is
+ equivalent to Accept-Encoding: identity, that is, only the identity
+ encoding, meaning no encoding, is permissible.
+
+ If no Accept-Encoding header field is present, the server SHOULD
+ assume a default value of identity.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 163]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ This differs slightly from the HTTP definition, which indicates that
+ when not present, any encoding can be used, but the identity encoding
+ is preferred.
+
+ Example:
+
+ Accept-Encoding: gzip
+
+20.3 Accept-Language
+
+ The Accept-Language header field is used in requests to indicate the
+ preferred languages for reason phrases, session descriptions, or
+ status responses carried as message bodies in the response. If no
+ Accept-Language header field is present, the server SHOULD assume all
+ languages are acceptable to the client.
+
+ The Accept-Language header field follows the syntax defined in
+ [H14.4]. The rules for ordering the languages based on the "q"
+ parameter apply to SIP as well.
+
+ Example:
+
+ Accept-Language: da, en-gb;q=0.8, en;q=0.7
+
+20.4 Alert-Info
+
+ When present in an INVITE request, the Alert-Info header field
+ specifies an alternative ring tone to the UAS. When present in a 180
+ (Ringing) response, the Alert-Info header field specifies an
+ alternative ringback tone to the UAC. A typical usage is for a proxy
+ to insert this header field to provide a distinctive ring feature.
+
+ The Alert-Info header field can introduce security risks. These
+ risks and the ways to handle them are discussed in Section 20.9,
+ which discusses the Call-Info header field since the risks are
+ identical.
+
+ In addition, a user SHOULD be able to disable this feature
+ selectively.
+
+ This helps prevent disruptions that could result from the use of
+ this header field by untrusted elements.
+
+ Example:
+
+ Alert-Info: <http://www.example.com/sounds/moo.wav>
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 164]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+20.5 Allow
+
+ The Allow header field lists the set of methods supported by the UA
+ generating the message.
+
+ All methods, including ACK and CANCEL, understood by the UA MUST be
+ included in the list of methods in the Allow header field, when
+ present. The absence of an Allow header field MUST NOT be
+ interpreted to mean that the UA sending the message supports no
+ methods. Rather, it implies that the UA is not providing any
+ information on what methods it supports.
+
+ Supplying an Allow header field in responses to methods other than
+ OPTIONS reduces the number of messages needed.
+
+ Example:
+
+ Allow: INVITE, ACK, OPTIONS, CANCEL, BYE
+
+20.6 Authentication-Info
+
+ The Authentication-Info header field provides for mutual
+ authentication with HTTP Digest. A UAS MAY include this header field
+ in a 2xx response to a request that was successfully authenticated
+ using digest based on the Authorization header field.
+
+ Syntax and semantics follow those specified in RFC 2617 [17].
+
+ Example:
+
+ Authentication-Info: nextnonce="47364c23432d2e131a5fb210812c"
+
+20.7 Authorization
+
+ The Authorization header field contains authentication credentials of
+ a UA. Section 22.2 overviews the use of the Authorization header
+ field, and Section 22.4 describes the syntax and semantics when used
+ with HTTP authentication.
+
+ This header field, along with Proxy-Authorization, breaks the general
+ rules about multiple header field values. Although not a comma-
+ separated list, this header field name may be present multiple times,
+ and MUST NOT be combined into a single header line using the usual
+ rules described in Section 7.3.
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 165]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ In the example below, there are no quotes around the Digest
+ parameter:
+
+ Authorization: Digest username="Alice", realm="atlanta.com",
+ nonce="84a4cc6f3082121f32b42a2187831a9e",
+ response="7587245234b3434cc3412213e5f113a5432"
+
+20.8 Call-ID
+
+ The Call-ID header field uniquely identifies a particular invitation
+ or all registrations of a particular client. A single multimedia
+ conference can give rise to several calls with different Call-IDs,
+ for example, if a user invites a single individual several times to
+ the same (long-running) conference. Call-IDs are case-sensitive and
+ are simply compared byte-by-byte.
+
+ The compact form of the Call-ID header field is i.
+
+ Examples:
+
+ Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@biloxi.com
+ i:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@192.0.2.4
+
+20.9 Call-Info
+
+ The Call-Info header field provides additional information about the
+ caller or callee, depending on whether it is found in a request or
+ response. The purpose of the URI is described by the "purpose"
+ parameter. The "icon" parameter designates an image suitable as an
+ iconic representation of the caller or callee. The "info" parameter
+ describes the caller or callee in general, for example, through a web
+ page. The "card" parameter provides a business card, for example, in
+ vCard [36] or LDIF [37] formats. Additional tokens can be registered
+ using IANA and the procedures in Section 27.
+
+ Use of the Call-Info header field can pose a security risk. If a
+ callee fetches the URIs provided by a malicious caller, the callee
+ may be at risk for displaying inappropriate or offensive content,
+ dangerous or illegal content, and so on. Therefore, it is
+ RECOMMENDED that a UA only render the information in the Call-Info
+ header field if it can verify the authenticity of the element that
+ originated the header field and trusts that element. This need not
+ be the peer UA; a proxy can insert this header field into requests.
+
+ Example:
+
+ Call-Info: <http://wwww.example.com/alice/photo.jpg> ;purpose=icon,
+ <http://www.example.com/alice/> ;purpose=info
+
+
+
+Rosenberg, et. al. Standards Track [Page 166]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+20.10 Contact
+
+ A Contact header field value provides a URI whose meaning depends on
+ the type of request or response it is in.
+
+ A Contact header field value can contain a display name, a URI with
+ URI parameters, and header parameters.
+
+ This document defines the Contact parameters "q" and "expires".
+ These parameters are only used when the Contact is present in a
+ REGISTER request or response, or in a 3xx response. Additional
+ parameters may be defined in other specifications.
+
+ When the header field value contains a display name, the URI
+ including all URI parameters is enclosed in "<" and ">". If no "<"
+ and ">" are present, all parameters after the URI are header
+ parameters, not URI parameters. The display name can be tokens, or a
+ quoted string, if a larger character set is desired.
+
+ Even if the "display-name" is empty, the "name-addr" form MUST be
+ used if the "addr-spec" contains a comma, semicolon, or question
+ mark. There may or may not be LWS between the display-name and the
+ "<".
+
+ These rules for parsing a display name, URI and URI parameters, and
+ header parameters also apply for the header fields To and From.
+
+ The Contact header field has a role similar to the Location header
+ field in HTTP. However, the HTTP header field only allows one
+ address, unquoted. Since URIs can contain commas and semicolons
+ as reserved characters, they can be mistaken for header or
+ parameter delimiters, respectively.
+
+ The compact form of the Contact header field is m (for "moved").
+
+ Examples:
+
+ Contact: "Mr. Watson" <sip:watson@worcester.bell-telephone.com>
+ ;q=0.7; expires=3600,
+ "Mr. Watson" <mailto:watson@bell-telephone.com> ;q=0.1
+ m: <sips:bob@192.0.2.4>;expires=60
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 167]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+20.11 Content-Disposition
+
+ The Content-Disposition header field describes how the message body
+ or, for multipart messages, a message body part is to be interpreted
+ by the UAC or UAS. This SIP header field extends the MIME Content-
+ Type (RFC 2183 [18]).
+
+ Several new "disposition-types" of the Content-Disposition header are
+ defined by SIP. The value "session" indicates that the body part
+ describes a session, for either calls or early (pre-call) media. The
+ value "render" indicates that the body part should be displayed or
+ otherwise rendered to the user. Note that the value "render" is used
+ rather than "inline" to avoid the connotation that the MIME body is
+ displayed as a part of the rendering of the entire message (since the
+ MIME bodies of SIP messages oftentimes are not displayed to users).
+ For backward-compatibility, if the Content-Disposition header field
+ is missing, the server SHOULD assume bodies of Content-Type
+ application/sdp are the disposition "session", while other content
+ types are "render".
+
+ The disposition type "icon" indicates that the body part contains an
+ image suitable as an iconic representation of the caller or callee
+ that could be rendered informationally by a user agent when a message
+ has been received, or persistently while a dialog takes place. The
+ value "alert" indicates that the body part contains information, such
+ as an audio clip, that should be rendered by the user agent in an
+ attempt to alert the user to the receipt of a request, generally a
+ request that initiates a dialog; this alerting body could for example
+ be rendered as a ring tone for a phone call after a 180 Ringing
+ provisional response has been sent.
+
+ Any MIME body with a "disposition-type" that renders content to the
+ user should only be processed when a message has been properly
+ authenticated.
+
+ The handling parameter, handling-param, describes how the UAS should
+ react if it receives a message body whose content type or disposition
+ type it does not understand. The parameter has defined values of
+ "optional" and "required". If the handling parameter is missing, the
+ value "required" SHOULD be assumed. The handling parameter is
+ described in RFC 3204 [19].
+
+ If this header field is missing, the MIME type determines the default
+ content disposition. If there is none, "render" is assumed.
+
+ Example:
+
+ Content-Disposition: session
+
+
+
+Rosenberg, et. al. Standards Track [Page 168]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+20.12 Content-Encoding
+
+ The Content-Encoding header field is used as a modifier to the
+ "media-type". When present, its value indicates what additional
+ content codings have been applied to the entity-body, and thus what
+ decoding mechanisms MUST be applied in order to obtain the media-type
+ referenced by the Content-Type header field. Content-Encoding is
+ primarily used to allow a body to be compressed without losing the
+ identity of its underlying media type.
+
+ If multiple encodings have been applied to an entity-body, the
+ content codings MUST be listed in the order in which they were
+ applied.
+
+ All content-coding values are case-insensitive. IANA acts as a
+ registry for content-coding value tokens. See [H3.5] for a
+ definition of the syntax for content-coding.
+
+ Clients MAY apply content encodings to the body in requests. A
+ server MAY apply content encodings to the bodies in responses. The
+ server MUST only use encodings listed in the Accept-Encoding header
+ field in the request.
+
+ The compact form of the Content-Encoding header field is e.
+ Examples:
+
+ Content-Encoding: gzip
+ e: tar
+
+20.13 Content-Language
+
+ See [H14.12]. Example:
+
+ Content-Language: fr
+
+20.14 Content-Length
+
+ The Content-Length header field indicates the size of the message-
+ body, in decimal number of octets, sent to the recipient.
+ Applications SHOULD use this field to indicate the size of the
+ message-body to be transferred, regardless of the media type of the
+ entity. If a stream-based protocol (such as TCP) is used as
+ transport, the header field MUST be used.
+
+ The size of the message-body does not include the CRLF separating
+ header fields and body. Any Content-Length greater than or equal to
+ zero is a valid value. If no body is present in a message, then the
+ Content-Length header field value MUST be set to zero.
+
+
+
+Rosenberg, et. al. Standards Track [Page 169]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The ability to omit Content-Length simplifies the creation of
+ cgi-like scripts that dynamically generate responses.
+
+ The compact form of the header field is l.
+
+ Examples:
+
+ Content-Length: 349
+ l: 173
+
+20.15 Content-Type
+
+ The Content-Type header field indicates the media type of the
+ message-body sent to the recipient. The "media-type" element is
+ defined in [H3.7]. The Content-Type header field MUST be present if
+ the body is not empty. If the body is empty, and a Content-Type
+ header field is present, it indicates that the body of the specific
+ type has zero length (for example, an empty audio file).
+
+ The compact form of the header field is c.
+
+ Examples:
+
+ Content-Type: application/sdp
+ c: text/html; charset=ISO-8859-4
+
+20.16 CSeq
+
+ A CSeq header field in a request contains a single decimal sequence
+ number and the request method. The sequence number MUST be
+ expressible as a 32-bit unsigned integer. The method part of CSeq is
+ case-sensitive. The CSeq header field serves to order transactions
+ within a dialog, to provide a means to uniquely identify
+ transactions, and to differentiate between new requests and request
+ retransmissions. Two CSeq header fields are considered equal if the
+ sequence number and the request method are identical. Example:
+
+ CSeq: 4711 INVITE
+
+20.17 Date
+
+ The Date header field contains the date and time. Unlike HTTP/1.1,
+ SIP only supports the most recent RFC 1123 [20] format for dates. As
+ in [H3.3], SIP restricts the time zone in SIP-date to "GMT", while
+ RFC 1123 allows any time zone. An RFC 1123 date is case-sensitive.
+
+ The Date header field reflects the time when the request or response
+ is first sent.
+
+
+
+Rosenberg, et. al. Standards Track [Page 170]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The Date header field can be used by simple end systems without a
+ battery-backed clock to acquire a notion of current time.
+ However, in its GMT form, it requires clients to know their offset
+ from GMT.
+
+ Example:
+
+ Date: Sat, 13 Nov 2010 23:29:00 GMT
+
+20.18 Error-Info
+
+ The Error-Info header field provides a pointer to additional
+ information about the error status response.
+
+ SIP UACs have user interface capabilities ranging from pop-up
+ windows and audio on PC softclients to audio-only on "black"
+ phones or endpoints connected via gateways. Rather than forcing a
+ server generating an error to choose between sending an error
+ status code with a detailed reason phrase and playing an audio
+ recording, the Error-Info header field allows both to be sent.
+ The UAC then has the choice of which error indicator to render to
+ the caller.
+
+ A UAC MAY treat a SIP or SIPS URI in an Error-Info header field as if
+ it were a Contact in a redirect and generate a new INVITE, resulting
+ in a recorded announcement session being established. A non-SIP URI
+ MAY be rendered to the user.
+
+ Examples:
+
+ SIP/2.0 404 The number you have dialed is not in service
+ Error-Info: <sip:not-in-service-recording@atlanta.com>
+
+20.19 Expires
+
+ The Expires header field gives the relative time after which the
+ message (or content) expires.
+
+ The precise meaning of this is method dependent.
+
+ The expiration time in an INVITE does not affect the duration of the
+ actual session that may result from the invitation. Session
+ description protocols may offer the ability to express time limits on
+ the session duration, however.
+
+ The value of this field is an integral number of seconds (in decimal)
+ between 0 and (2**32)-1, measured from the receipt of the request.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 171]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example:
+
+ Expires: 5
+
+20.20 From
+
+ The From header field indicates the initiator of the request. This
+ may be different from the initiator of the dialog. Requests sent by
+ the callee to the caller use the callee's address in the From header
+ field.
+
+ The optional "display-name" is meant to be rendered by a human user
+ interface. A system SHOULD use the display name "Anonymous" if the
+ identity of the client is to remain hidden. Even if the "display-
+ name" is empty, the "name-addr" form MUST be used if the "addr-spec"
+ contains a comma, question mark, or semicolon. Syntax issues are
+ discussed in Section 7.3.1.
+
+ Two From header fields are equivalent if their URIs match, and their
+ parameters match. Extension parameters in one header field, not
+ present in the other are ignored for the purposes of comparison. This
+ means that the display name and presence or absence of angle brackets
+ do not affect matching.
+
+ See Section 20.10 for the rules for parsing a display name, URI and
+ URI parameters, and header field parameters.
+
+ The compact form of the From header field is f.
+
+ Examples:
+
+ From: "A. G. Bell" <sip:agb@bell-telephone.com> ;tag=a48s
+ From: sip:+12125551212@server.phone2net.com;tag=887s
+ f: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8
+
+20.21 In-Reply-To
+
+ The In-Reply-To header field enumerates the Call-IDs that this call
+ references or returns. These Call-IDs may have been cached by the
+ client then included in this header field in a return call.
+
+ This allows automatic call distribution systems to route return
+ calls to the originator of the first call. This also allows
+ callees to filter calls, so that only return calls for calls they
+ originated will be accepted. This field is not a substitute for
+ request authentication.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 172]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example:
+
+ In-Reply-To: 70710@saturn.bell-tel.com, 17320@saturn.bell-tel.com
+
+20.22 Max-Forwards
+
+ The Max-Forwards header field must be used with any SIP method to
+ limit the number of proxies or gateways that can forward the request
+ to the next downstream server. This can also be useful when the
+ client is attempting to trace a request chain that appears to be
+ failing or looping in mid-chain.
+
+ The Max-Forwards value is an integer in the range 0-255 indicating
+ the remaining number of times this request message is allowed to be
+ forwarded. This count is decremented by each server that forwards
+ the request. The recommended initial value is 70.
+
+ This header field should be inserted by elements that can not
+ otherwise guarantee loop detection. For example, a B2BUA should
+ insert a Max-Forwards header field.
+
+ Example:
+
+ Max-Forwards: 6
+
+20.23 Min-Expires
+
+ The Min-Expires header field conveys the minimum refresh interval
+ supported for soft-state elements managed by that server. This
+ includes Contact header fields that are stored by a registrar. The
+ header field contains a decimal integer number of seconds from 0 to
+ (2**32)-1. The use of the header field in a 423 (Interval Too Brief)
+ response is described in Sections 10.2.8, 10.3, and 21.4.17.
+
+ Example:
+
+ Min-Expires: 60
+
+20.24 MIME-Version
+
+ See [H19.4.1].
+
+ Example:
+
+ MIME-Version: 1.0
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 173]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+20.25 Organization
+
+ The Organization header field conveys the name of the organization to
+ which the SIP element issuing the request or response belongs.
+
+ The field MAY be used by client software to filter calls.
+
+ Example:
+
+ Organization: Boxes by Bob
+
+20.26 Priority
+
+ The Priority header field indicates the urgency of the request as
+ perceived by the client. The Priority header field describes the
+ priority that the SIP request should have to the receiving human or
+ its agent. For example, it may be factored into decisions about call
+ routing and acceptance. For these decisions, a message containing no
+ Priority header field SHOULD be treated as if it specified a Priority
+ of "normal". The Priority header field does not influence the use of
+ communications resources such as packet forwarding priority in
+ routers or access to circuits in PSTN gateways. The header field can
+ have the values "non-urgent", "normal", "urgent", and "emergency",
+ but additional values can be defined elsewhere. It is RECOMMENDED
+ that the value of "emergency" only be used when life, limb, or
+ property are in imminent danger. Otherwise, there are no semantics
+ defined for this header field.
+
+ These are the values of RFC 2076 [38], with the addition of
+ "emergency".
+
+ Examples:
+
+ Subject: A tornado is heading our way!
+ Priority: emergency
+
+ or
+
+ Subject: Weekend plans
+ Priority: non-urgent
+
+20.27 Proxy-Authenticate
+
+ A Proxy-Authenticate header field value contains an authentication
+ challenge.
+
+ The use of this header field is defined in [H14.33]. See Section
+ 22.3 for further details on its usage.
+
+
+
+Rosenberg, et. al. Standards Track [Page 174]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example:
+
+ Proxy-Authenticate: Digest realm="atlanta.com",
+ domain="sip:ss1.carrier.com", qop="auth",
+ nonce="f84f1cec41e6cbe5aea9c8e88d359",
+ opaque="", stale=FALSE, algorithm=MD5
+
+20.28 Proxy-Authorization
+
+ The Proxy-Authorization header field allows the client to identify
+ itself (or its user) to a proxy that requires authentication. A
+ Proxy-Authorization field value consists of credentials containing
+ the authentication information of the user agent for the proxy and/or
+ realm of the resource being requested.
+
+ See Section 22.3 for a definition of the usage of this header field.
+
+ This header field, along with Authorization, breaks the general rules
+ about multiple header field names. Although not a comma-separated
+ list, this header field name may be present multiple times, and MUST
+ NOT be combined into a single header line using the usual rules
+ described in Section 7.3.1.
+
+ Example:
+
+ Proxy-Authorization: Digest username="Alice", realm="atlanta.com",
+ nonce="c60f3082ee1212b402a21831ae",
+ response="245f23415f11432b3434341c022"
+
+20.29 Proxy-Require
+
+ The Proxy-Require header field is used to indicate proxy-sensitive
+ features that must be supported by the proxy. See Section 20.32 for
+ more details on the mechanics of this message and a usage example.
+
+ Example:
+
+ Proxy-Require: foo
+
+20.30 Record-Route
+
+ The Record-Route header field is inserted by proxies in a request to
+ force future requests in the dialog to be routed through the proxy.
+
+ Examples of its use with the Route header field are described in
+ Sections 16.12.1.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 175]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example:
+
+ Record-Route: <sip:server10.biloxi.com;lr>,
+ <sip:bigbox3.site3.atlanta.com;lr>
+
+20.31 Reply-To
+
+ The Reply-To header field contains a logical return URI that may be
+ different from the From header field. For example, the URI MAY be
+ used to return missed calls or unestablished sessions. If the user
+ wished to remain anonymous, the header field SHOULD either be omitted
+ from the request or populated in such a way that does not reveal any
+ private information.
+
+ Even if the "display-name" is empty, the "name-addr" form MUST be
+ used if the "addr-spec" contains a comma, question mark, or
+ semicolon. Syntax issues are discussed in Section 7.3.1.
+
+ Example:
+
+ Reply-To: Bob <sip:bob@biloxi.com>
+
+20.32 Require
+
+ The Require header field is used by UACs to tell UASs about options
+ that the UAC expects the UAS to support in order to process the
+ request. Although an optional header field, the Require MUST NOT be
+ ignored if it is present.
+
+ The Require header field contains a list of option tags, described in
+ Section 19.2. Each option tag defines a SIP extension that MUST be
+ understood to process the request. Frequently, this is used to
+ indicate that a specific set of extension header fields need to be
+ understood. A UAC compliant to this specification MUST only include
+ option tags corresponding to standards-track RFCs.
+
+ Example:
+
+ Require: 100rel
+
+20.33 Retry-After
+
+ The Retry-After header field can be used with a 500 (Server Internal
+ Error) or 503 (Service Unavailable) response to indicate how long the
+ service is expected to be unavailable to the requesting client and
+ with a 404 (Not Found), 413 (Request Entity Too Large), 480
+ (Temporarily Unavailable), 486 (Busy Here), 600 (Busy), or 603
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 176]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ (Decline) response to indicate when the called party anticipates
+ being available again. The value of this field is a positive integer
+ number of seconds (in decimal) after the time of the response.
+
+ An optional comment can be used to indicate additional information
+ about the time of callback. An optional "duration" parameter
+ indicates how long the called party will be reachable starting at the
+ initial time of availability. If no duration parameter is given, the
+ service is assumed to be available indefinitely.
+
+ Examples:
+
+ Retry-After: 18000;duration=3600
+ Retry-After: 120 (I'm in a meeting)
+
+20.34 Route
+
+ The Route header field is used to force routing for a request through
+ the listed set of proxies. Examples of the use of the Route header
+ field are in Section 16.12.1.
+
+ Example:
+
+ Route: <sip:bigbox3.site3.atlanta.com;lr>,
+ <sip:server10.biloxi.com;lr>
+
+20.35 Server
+
+ The Server header field contains information about the software used
+ by the UAS to handle the request.
+
+ Revealing the specific software version of the server might allow the
+ server to become more vulnerable to attacks against software that is
+ known to contain security holes. Implementers SHOULD make the Server
+ header field a configurable option.
+
+ Example:
+
+ Server: HomeServer v2
+
+20.36 Subject
+
+ The Subject header field provides a summary or indicates the nature
+ of the call, allowing call filtering without having to parse the
+ session description. The session description does not have to use
+ the same subject indication as the invitation.
+
+ The compact form of the Subject header field is s.
+
+
+
+Rosenberg, et. al. Standards Track [Page 177]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Example:
+
+ Subject: Need more boxes
+ s: Tech Support
+
+20.37 Supported
+
+ The Supported header field enumerates all the extensions supported by
+ the UAC or UAS.
+
+ The Supported header field contains a list of option tags, described
+ in Section 19.2, that are understood by the UAC or UAS. A UA
+ compliant to this specification MUST only include option tags
+ corresponding to standards-track RFCs. If empty, it means that no
+ extensions are supported.
+
+ The compact form of the Supported header field is k.
+
+ Example:
+
+ Supported: 100rel
+
+20.38 Timestamp
+
+ The Timestamp header field describes when the UAC sent the request to
+ the UAS.
+
+ See Section 8.2.6 for details on how to generate a response to a
+ request that contains the header field. Although there is no
+ normative behavior defined here that makes use of the header, it
+ allows for extensions or SIP applications to obtain RTT estimates.
+
+ Example:
+
+ Timestamp: 54
+
+20.39 To
+
+ The To header field specifies the logical recipient of the request.
+
+ The optional "display-name" is meant to be rendered by a human-user
+ interface. The "tag" parameter serves as a general mechanism for
+ dialog identification.
+
+ See Section 19.3 for details of the "tag" parameter.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 178]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Comparison of To header fields for equality is identical to
+ comparison of From header fields. See Section 20.10 for the rules
+ for parsing a display name, URI and URI parameters, and header field
+ parameters.
+
+ The compact form of the To header field is t.
+
+ The following are examples of valid To header fields:
+
+ To: The Operator <sip:operator@cs.columbia.edu>;tag=287447
+ t: sip:+12125551212@server.phone2net.com
+
+20.40 Unsupported
+
+ The Unsupported header field lists the features not supported by the
+ UAS. See Section 20.32 for motivation.
+
+ Example:
+
+ Unsupported: foo
+
+20.41 User-Agent
+
+ The User-Agent header field contains information about the UAC
+ originating the request. The semantics of this header field are
+ defined in [H14.43].
+
+ Revealing the specific software version of the user agent might allow
+ the user agent to become more vulnerable to attacks against software
+ that is known to contain security holes. Implementers SHOULD make
+ the User-Agent header field a configurable option.
+
+ Example:
+
+ User-Agent: Softphone Beta1.5
+
+20.42 Via
+
+ The Via header field indicates the path taken by the request so far
+ and indicates the path that should be followed in routing responses.
+ The branch ID parameter in the Via header field values serves as a
+ transaction identifier, and is used by proxies to detect loops.
+
+ A Via header field value contains the transport protocol used to send
+ the message, the client's host name or network address, and possibly
+ the port number at which it wishes to receive responses. A Via
+ header field value can also contain parameters such as "maddr",
+ "ttl", "received", and "branch", whose meaning and use are described
+
+
+
+Rosenberg, et. al. Standards Track [Page 179]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ in other sections. For implementations compliant to this
+ specification, the value of the branch parameter MUST start with the
+ magic cookie "z9hG4bK", as discussed in Section 8.1.1.7.
+
+ Transport protocols defined here are "UDP", "TCP", "TLS", and "SCTP".
+ "TLS" means TLS over TCP. When a request is sent to a SIPS URI, the
+ protocol still indicates "SIP", and the transport protocol is TLS.
+
+Via: SIP/2.0/UDP erlang.bell-telephone.com:5060;branch=z9hG4bK87asdks7
+Via: SIP/2.0/UDP 192.0.2.1:5060 ;received=192.0.2.207
+ ;branch=z9hG4bK77asjd
+
+ The compact form of the Via header field is v.
+
+ In this example, the message originated from a multi-homed host with
+ two addresses, 192.0.2.1 and 192.0.2.207. The sender guessed wrong
+ as to which network interface would be used. Erlang.bell-
+ telephone.com noticed the mismatch and added a parameter to the
+ previous hop's Via header field value, containing the address that
+ the packet actually came from.
+
+ The host or network address and port number are not required to
+ follow the SIP URI syntax. Specifically, LWS on either side of the
+ ":" or "/" is allowed, as shown here:
+
+ Via: SIP / 2.0 / UDP first.example.com: 4000;ttl=16
+ ;maddr=224.2.0.1 ;branch=z9hG4bKa7c6a8dlze.1
+
+ Even though this specification mandates that the branch parameter be
+ present in all requests, the BNF for the header field indicates that
+ it is optional. This allows interoperation with RFC 2543 elements,
+ which did not have to insert the branch parameter.
+
+ Two Via header fields are equal if their sent-protocol and sent-by
+ fields are equal, both have the same set of parameters, and the
+ values of all parameters are equal.
+
+20.43 Warning
+
+ The Warning header field is used to carry additional information
+ about the status of a response. Warning header field values are sent
+ with responses and contain a three-digit warning code, host name, and
+ warning text.
+
+ The "warn-text" should be in a natural language that is most likely
+ to be intelligible to the human user receiving the response. This
+ decision can be based on any available knowledge, such as the
+ location of the user, the Accept-Language field in a request, or the
+
+
+
+Rosenberg, et. al. Standards Track [Page 180]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Content-Language field in a response. The default language is i-
+ default [21].
+
+ The currently-defined "warn-code"s are listed below, with a
+ recommended warn-text in English and a description of their meaning.
+ These warnings describe failures induced by the session description.
+ The first digit of warning codes beginning with "3" indicates
+ warnings specific to SIP. Warnings 300 through 329 are reserved for
+ indicating problems with keywords in the session description, 330
+ through 339 are warnings related to basic network services requested
+ in the session description, 370 through 379 are warnings related to
+ quantitative QoS parameters requested in the session description, and
+ 390 through 399 are miscellaneous warnings that do not fall into one
+ of the above categories.
+
+ 300 Incompatible network protocol: One or more network protocols
+ contained in the session description are not available.
+
+ 301 Incompatible network address formats: One or more network
+ address formats contained in the session description are not
+ available.
+
+ 302 Incompatible transport protocol: One or more transport
+ protocols described in the session description are not
+ available.
+
+ 303 Incompatible bandwidth units: One or more bandwidth
+ measurement units contained in the session description were
+ not understood.
+
+ 304 Media type not available: One or more media types contained in
+ the session description are not available.
+
+ 305 Incompatible media format: One or more media formats contained
+ in the session description are not available.
+
+ 306 Attribute not understood: One or more of the media attributes
+ in the session description are not supported.
+
+ 307 Session description parameter not understood: A parameter
+ other than those listed above was not understood.
+
+ 330 Multicast not available: The site where the user is located
+ does not support multicast.
+
+ 331 Unicast not available: The site where the user is located does
+ not support unicast communication (usually due to the presence
+ of a firewall).
+
+
+
+Rosenberg, et. al. Standards Track [Page 181]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ 370 Insufficient bandwidth: The bandwidth specified in the session
+ description or defined by the media exceeds that known to be
+ available.
+
+ 399 Miscellaneous warning: The warning text can include arbitrary
+ information to be presented to a human user or logged. A
+ system receiving this warning MUST NOT take any automated
+ action.
+
+ 1xx and 2xx have been taken by HTTP/1.1.
+
+ Additional "warn-code"s can be defined through IANA, as defined in
+ Section 27.2.
+
+ Examples:
+
+ Warning: 307 isi.edu "Session parameter 'foo' not understood"
+ Warning: 301 isi.edu "Incompatible network address type 'E.164'"
+
+20.44 WWW-Authenticate
+
+ A WWW-Authenticate header field value contains an authentication
+ challenge. See Section 22.2 for further details on its usage.
+
+ Example:
+
+ WWW-Authenticate: Digest realm="atlanta.com",
+ domain="sip:boxesbybob.com", qop="auth",
+ nonce="f84f1cec41e6cbe5aea9c8e88d359",
+ opaque="", stale=FALSE, algorithm=MD5
+
+21 Response Codes
+
+ The response codes are consistent with, and extend, HTTP/1.1 response
+ codes. Not all HTTP/1.1 response codes are appropriate, and only
+ those that are appropriate are given here. Other HTTP/1.1 response
+ codes SHOULD NOT be used. Also, SIP defines a new class, 6xx.
+
+21.1 Provisional 1xx
+
+ Provisional responses, also known as informational responses,
+ indicate that the server contacted is performing some further action
+ and does not yet have a definitive response. A server sends a 1xx
+ response if it expects to take more than 200 ms to obtain a final
+ response. Note that 1xx responses are not transmitted reliably.
+ They never cause the client to send an ACK. Provisional (1xx)
+ responses MAY contain message bodies, including session descriptions.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 182]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.1.1 100 Trying
+
+ This response indicates that the request has been received by the
+ next-hop server and that some unspecified action is being taken on
+ behalf of this call (for example, a database is being consulted).
+ This response, like all other provisional responses, stops
+ retransmissions of an INVITE by a UAC. The 100 (Trying) response is
+ different from other provisional responses, in that it is never
+ forwarded upstream by a stateful proxy.
+
+21.1.2 180 Ringing
+
+ The UA receiving the INVITE is trying to alert the user. This
+ response MAY be used to initiate local ringback.
+
+21.1.3 181 Call Is Being Forwarded
+
+ A server MAY use this status code to indicate that the call is being
+ forwarded to a different set of destinations.
+
+21.1.4 182 Queued
+
+ The called party is temporarily unavailable, but the server has
+ decided to queue the call rather than reject it. When the callee
+ becomes available, it will return the appropriate final status
+ response. The reason phrase MAY give further details about the
+ status of the call, for example, "5 calls queued; expected waiting
+ time is 15 minutes". The server MAY issue several 182 (Queued)
+ responses to update the caller about the status of the queued call.
+
+21.1.5 183 Session Progress
+
+ The 183 (Session Progress) response is used to convey information
+ about the progress of the call that is not otherwise classified. The
+ Reason-Phrase, header fields, or message body MAY be used to convey
+ more details about the call progress.
+
+21.2 Successful 2xx
+
+ The request was successful.
+
+21.2.1 200 OK
+
+ The request has succeeded. The information returned with the
+ response depends on the method used in the request.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 183]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.3 Redirection 3xx
+
+ 3xx responses give information about the user's new location, or
+ about alternative services that might be able to satisfy the call.
+
+21.3.1 300 Multiple Choices
+
+ The address in the request resolved to several choices, each with its
+ own specific location, and the user (or UA) can select a preferred
+ communication end point and redirect its request to that location.
+
+ The response MAY include a message body containing a list of resource
+ characteristics and location(s) from which the user or UA can choose
+ the one most appropriate, if allowed by the Accept request header
+ field. However, no MIME types have been defined for this message
+ body.
+
+ The choices SHOULD also be listed as Contact fields (Section 20.10).
+ Unlike HTTP, the SIP response MAY contain several Contact fields or a
+ list of addresses in a Contact field. UAs MAY use the Contact header
+ field value for automatic redirection or MAY ask the user to confirm
+ a choice. However, this specification does not define any standard
+ for such automatic selection.
+
+ This status response is appropriate if the callee can be reached
+ at several different locations and the server cannot or prefers
+ not to proxy the request.
+
+21.3.2 301 Moved Permanently
+
+ The user can no longer be found at the address in the Request-URI,
+ and the requesting client SHOULD retry at the new address given by
+ the Contact header field (Section 20.10). The requestor SHOULD
+ update any local directories, address books, and user location caches
+ with this new value and redirect future requests to the address(es)
+ listed.
+
+21.3.3 302 Moved Temporarily
+
+ The requesting client SHOULD retry the request at the new address(es)
+ given by the Contact header field (Section 20.10). The Request-URI
+ of the new request uses the value of the Contact header field in the
+ response.
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 184]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The duration of the validity of the Contact URI can be indicated
+ through an Expires (Section 20.19) header field or an expires
+ parameter in the Contact header field. Both proxies and UAs MAY
+ cache this URI for the duration of the expiration time. If there is
+ no explicit expiration time, the address is only valid once for
+ recursing, and MUST NOT be cached for future transactions.
+
+ If the URI cached from the Contact header field fails, the Request-
+ URI from the redirected request MAY be tried again a single time.
+
+ The temporary URI may have become out-of-date sooner than the
+ expiration time, and a new temporary URI may be available.
+
+21.3.4 305 Use Proxy
+
+ The requested resource MUST be accessed through the proxy given by
+ the Contact field. The Contact field gives the URI of the proxy.
+ The recipient is expected to repeat this single request via the
+ proxy. 305 (Use Proxy) responses MUST only be generated by UASs.
+
+21.3.5 380 Alternative Service
+
+ The call was not successful, but alternative services are possible.
+
+ The alternative services are described in the message body of the
+ response. Formats for such bodies are not defined here, and may be
+ the subject of future standardization.
+
+21.4 Request Failure 4xx
+
+ 4xx responses are definite failure responses from a particular
+ server. The client SHOULD NOT retry the same request without
+ modification (for example, adding appropriate authorization).
+ However, the same request to a different server might be successful.
+
+21.4.1 400 Bad Request
+
+ The request could not be understood due to malformed syntax. The
+ Reason-Phrase SHOULD identify the syntax problem in more detail, for
+ example, "Missing Call-ID header field".
+
+21.4.2 401 Unauthorized
+
+ The request requires user authentication. This response is issued by
+ UASs and registrars, while 407 (Proxy Authentication Required) is
+ used by proxy servers.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 185]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.4.3 402 Payment Required
+
+ Reserved for future use.
+
+21.4.4 403 Forbidden
+
+ The server understood the request, but is refusing to fulfill it.
+ Authorization will not help, and the request SHOULD NOT be repeated.
+
+21.4.5 404 Not Found
+
+ The server has definitive information that the user does not exist at
+ the domain specified in the Request-URI. This status is also
+ returned if the domain in the Request-URI does not match any of the
+ domains handled by the recipient of the request.
+
+21.4.6 405 Method Not Allowed
+
+ The method specified in the Request-Line is understood, but not
+ allowed for the address identified by the Request-URI.
+
+ The response MUST include an Allow header field containing a list of
+ valid methods for the indicated address.
+
+21.4.7 406 Not Acceptable
+
+ The resource identified by the request is only capable of generating
+ response entities that have content characteristics not acceptable
+ according to the Accept header field sent in the request.
+
+21.4.8 407 Proxy Authentication Required
+
+ This code is similar to 401 (Unauthorized), but indicates that the
+ client MUST first authenticate itself with the proxy. SIP access
+ authentication is explained in Sections 26 and 22.3.
+
+ This status code can be used for applications where access to the
+ communication channel (for example, a telephony gateway) rather than
+ the callee requires authentication.
+
+21.4.9 408 Request Timeout
+
+ The server could not produce a response within a suitable amount of
+ time, for example, if it could not determine the location of the user
+ in time. The client MAY repeat the request without modifications at
+ any later time.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 186]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.4.10 410 Gone
+
+ The requested resource is no longer available at the server and no
+ forwarding address is known. This condition is expected to be
+ considered permanent. If the server does not know, or has no
+ facility to determine, whether or not the condition is permanent, the
+ status code 404 (Not Found) SHOULD be used instead.
+
+21.4.11 413 Request Entity Too Large
+
+ The server is refusing to process a request because the request
+ entity-body is larger than the server is willing or able to process.
+ The server MAY close the connection to prevent the client from
+ continuing the request.
+
+ If the condition is temporary, the server SHOULD include a Retry-
+ After header field to indicate that it is temporary and after what
+ time the client MAY try again.
+
+21.4.12 414 Request-URI Too Long
+
+ The server is refusing to service the request because the Request-URI
+ is longer than the server is willing to interpret.
+
+21.4.13 415 Unsupported Media Type
+
+ The server is refusing to service the request because the message
+ body of the request is in a format not supported by the server for
+ the requested method. The server MUST return a list of acceptable
+ formats using the Accept, Accept-Encoding, or Accept-Language header
+ field, depending on the specific problem with the content. UAC
+ processing of this response is described in Section 8.1.3.5.
+
+21.4.14 416 Unsupported URI Scheme
+
+ The server cannot process the request because the scheme of the URI
+ in the Request-URI is unknown to the server. Client processing of
+ this response is described in Section 8.1.3.5.
+
+21.4.15 420 Bad Extension
+
+ The server did not understand the protocol extension specified in a
+ Proxy-Require (Section 20.29) or Require (Section 20.32) header
+ field. The server MUST include a list of the unsupported extensions
+ in an Unsupported header field in the response. UAC processing of
+ this response is described in Section 8.1.3.5.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 187]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.4.16 421 Extension Required
+
+ The UAS needs a particular extension to process the request, but this
+ extension is not listed in a Supported header field in the request.
+ Responses with this status code MUST contain a Require header field
+ listing the required extensions.
+
+ A UAS SHOULD NOT use this response unless it truly cannot provide any
+ useful service to the client. Instead, if a desirable extension is
+ not listed in the Supported header field, servers SHOULD process the
+ request using baseline SIP capabilities and any extensions supported
+ by the client.
+
+21.4.17 423 Interval Too Brief
+
+ The server is rejecting the request because the expiration time of
+ the resource refreshed by the request is too short. This response
+ can be used by a registrar to reject a registration whose Contact
+ header field expiration time was too small. The use of this response
+ and the related Min-Expires header field are described in Sections
+ 10.2.8, 10.3, and 20.23.
+
+21.4.18 480 Temporarily Unavailable
+
+ The callee's end system was contacted successfully but the callee is
+ currently unavailable (for example, is not logged in, logged in but
+ in a state that precludes communication with the callee, or has
+ activated the "do not disturb" feature). The response MAY indicate a
+ better time to call in the Retry-After header field. The user could
+ also be available elsewhere (unbeknownst to this server). The reason
+ phrase SHOULD indicate a more precise cause as to why the callee is
+ unavailable. This value SHOULD be settable by the UA. Status 486
+ (Busy Here) MAY be used to more precisely indicate a particular
+ reason for the call failure.
+
+ This status is also returned by a redirect or proxy server that
+ recognizes the user identified by the Request-URI, but does not
+ currently have a valid forwarding location for that user.
+
+21.4.19 481 Call/Transaction Does Not Exist
+
+ This status indicates that the UAS received a request that does not
+ match any existing dialog or transaction.
+
+21.4.20 482 Loop Detected
+
+ The server has detected a loop (Section 16.3 Item 4).
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 188]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.4.21 483 Too Many Hops
+
+ The server received a request that contains a Max-Forwards (Section
+ 20.22) header field with the value zero.
+
+21.4.22 484 Address Incomplete
+
+ The server received a request with a Request-URI that was incomplete.
+ Additional information SHOULD be provided in the reason phrase.
+
+ This status code allows overlapped dialing. With overlapped
+ dialing, the client does not know the length of the dialing
+ string. It sends strings of increasing lengths, prompting the
+ user for more input, until it no longer receives a 484 (Address
+ Incomplete) status response.
+
+21.4.23 485 Ambiguous
+
+ The Request-URI was ambiguous. The response MAY contain a listing of
+ possible unambiguous addresses in Contact header fields. Revealing
+ alternatives can infringe on privacy of the user or the organization.
+ It MUST be possible to configure a server to respond with status 404
+ (Not Found) or to suppress the listing of possible choices for
+ ambiguous Request-URIs.
+
+ Example response to a request with the Request-URI
+ sip:lee@example.com:
+
+ SIP/2.0 485 Ambiguous
+ Contact: Carol Lee <sip:carol.lee@example.com>
+ Contact: Ping Lee <sip:p.lee@example.com>
+ Contact: Lee M. Foote <sips:lee.foote@example.com>
+
+ Some email and voice mail systems provide this functionality. A
+ status code separate from 3xx is used since the semantics are
+ different: for 300, it is assumed that the same person or service
+ will be reached by the choices provided. While an automated
+ choice or sequential search makes sense for a 3xx response, user
+ intervention is required for a 485 (Ambiguous) response.
+
+21.4.24 486 Busy Here
+
+ The callee's end system was contacted successfully, but the callee is
+ currently not willing or able to take additional calls at this end
+ system. The response MAY indicate a better time to call in the
+ Retry-After header field. The user could also be available
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 189]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ elsewhere, such as through a voice mail service. Status 600 (Busy
+ Everywhere) SHOULD be used if the client knows that no other end
+ system will be able to accept this call.
+
+21.4.25 487 Request Terminated
+
+ The request was terminated by a BYE or CANCEL request. This response
+ is never returned for a CANCEL request itself.
+
+21.4.26 488 Not Acceptable Here
+
+ The response has the same meaning as 606 (Not Acceptable), but only
+ applies to the specific resource addressed by the Request-URI and the
+ request may succeed elsewhere.
+
+ A message body containing a description of media capabilities MAY be
+ present in the response, which is formatted according to the Accept
+ header field in the INVITE (or application/sdp if not present), the
+ same as a message body in a 200 (OK) response to an OPTIONS request.
+
+21.4.27 491 Request Pending
+
+ The request was received by a UAS that had a pending request within
+ the same dialog. Section 14.2 describes how such "glare" situations
+ are resolved.
+
+21.4.28 493 Undecipherable
+
+ The request was received by a UAS that contained an encrypted MIME
+ body for which the recipient does not possess or will not provide an
+ appropriate decryption key. This response MAY have a single body
+ containing an appropriate public key that should be used to encrypt
+ MIME bodies sent to this UA. Details of the usage of this response
+ code can be found in Section 23.2.
+
+21.5 Server Failure 5xx
+
+ 5xx responses are failure responses given when a server itself has
+ erred.
+
+21.5.1 500 Server Internal Error
+
+ The server encountered an unexpected condition that prevented it from
+ fulfilling the request. The client MAY display the specific error
+ condition and MAY retry the request after several seconds.
+
+ If the condition is temporary, the server MAY indicate when the
+ client may retry the request using the Retry-After header field.
+
+
+
+Rosenberg, et. al. Standards Track [Page 190]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.5.2 501 Not Implemented
+
+ The server does not support the functionality required to fulfill the
+ request. This is the appropriate response when a UAS does not
+ recognize the request method and is not capable of supporting it for
+ any user. (Proxies forward all requests regardless of method.)
+
+ Note that a 405 (Method Not Allowed) is sent when the server
+ recognizes the request method, but that method is not allowed or
+ supported.
+
+21.5.3 502 Bad Gateway
+
+ The server, while acting as a gateway or proxy, received an invalid
+ response from the downstream server it accessed in attempting to
+ fulfill the request.
+
+21.5.4 503 Service Unavailable
+
+ The server is temporarily unable to process the request due to a
+ temporary overloading or maintenance of the server. The server MAY
+ indicate when the client should retry the request in a Retry-After
+ header field. If no Retry-After is given, the client MUST act as if
+ it had received a 500 (Server Internal Error) response.
+
+ A client (proxy or UAC) receiving a 503 (Service Unavailable) SHOULD
+ attempt to forward the request to an alternate server. It SHOULD NOT
+ forward any other requests to that server for the duration specified
+ in the Retry-After header field, if present.
+
+ Servers MAY refuse the connection or drop the request instead of
+ responding with 503 (Service Unavailable).
+
+21.5.5 504 Server Time-out
+
+ The server did not receive a timely response from an external server
+ it accessed in attempting to process the request. 408 (Request
+ Timeout) should be used instead if there was no response within the
+ period specified in the Expires header field from the upstream
+ server.
+
+21.5.6 505 Version Not Supported
+
+ The server does not support, or refuses to support, the SIP protocol
+ version that was used in the request. The server is indicating that
+ it is unable or unwilling to complete the request using the same
+ major version as the client, other than with this error message.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 191]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+21.5.7 513 Message Too Large
+
+ The server was unable to process the request since the message length
+ exceeded its capabilities.
+
+21.6 Global Failures 6xx
+
+ 6xx responses indicate that a server has definitive information about
+ a particular user, not just the particular instance indicated in the
+ Request-URI.
+
+21.6.1 600 Busy Everywhere
+
+ The callee's end system was contacted successfully but the callee is
+ busy and does not wish to take the call at this time. The response
+ MAY indicate a better time to call in the Retry-After header field.
+ If the callee does not wish to reveal the reason for declining the
+ call, the callee uses status code 603 (Decline) instead. This status
+ response is returned only if the client knows that no other end point
+ (such as a voice mail system) will answer the request. Otherwise,
+ 486 (Busy Here) should be returned.
+
+21.6.2 603 Decline
+
+ The callee's machine was successfully contacted but the user
+ explicitly does not wish to or cannot participate. The response MAY
+ indicate a better time to call in the Retry-After header field. This
+ status response is returned only if the client knows that no other
+ end point will answer the request.
+
+21.6.3 604 Does Not Exist Anywhere
+
+ The server has authoritative information that the user indicated in
+ the Request-URI does not exist anywhere.
+
+21.6.4 606 Not Acceptable
+
+ The user's agent was contacted successfully but some aspects of the
+ session description such as the requested media, bandwidth, or
+ addressing style were not acceptable.
+
+ A 606 (Not Acceptable) response means that the user wishes to
+ communicate, but cannot adequately support the session described.
+ The 606 (Not Acceptable) response MAY contain a list of reasons in a
+ Warning header field describing why the session described cannot be
+ supported. Warning reason codes are listed in Section 20.43.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 192]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ A message body containing a description of media capabilities MAY be
+ present in the response, which is formatted according to the Accept
+ header field in the INVITE (or application/sdp if not present), the
+ same as a message body in a 200 (OK) response to an OPTIONS request.
+
+ It is hoped that negotiation will not frequently be needed, and when
+ a new user is being invited to join an already existing conference,
+ negotiation may not be possible. It is up to the invitation
+ initiator to decide whether or not to act on a 606 (Not Acceptable)
+ response.
+
+ This status response is returned only if the client knows that no
+ other end point will answer the request.
+
+22 Usage of HTTP Authentication
+
+ SIP provides a stateless, challenge-based mechanism for
+ authentication that is based on authentication in HTTP. Any time
+ that a proxy server or UA receives a request (with the exceptions
+ given in Section 22.1), it MAY challenge the initiator of the request
+ to provide assurance of its identity. Once the originator has been
+ identified, the recipient of the request SHOULD ascertain whether or
+ not this user is authorized to make the request in question. No
+ authorization systems are recommended or discussed in this document.
+
+ The "Digest" authentication mechanism described in this section
+ provides message authentication and replay protection only, without
+ message integrity or confidentiality. Protective measures above and
+ beyond those provided by Digest need to be taken to prevent active
+ attackers from modifying SIP requests and responses.
+
+ Note that due to its weak security, the usage of "Basic"
+ authentication has been deprecated. Servers MUST NOT accept
+ credentials using the "Basic" authorization scheme, and servers also
+ MUST NOT challenge with "Basic". This is a change from RFC 2543.
+
+22.1 Framework
+
+ The framework for SIP authentication closely parallels that of HTTP
+ (RFC 2617 [17]). In particular, the BNF for auth-scheme, auth-param,
+ challenge, realm, realm-value, and credentials is identical (although
+ the usage of "Basic" as a scheme is not permitted). In SIP, a UAS
+ uses the 401 (Unauthorized) response to challenge the identity of a
+ UAC. Additionally, registrars and redirect servers MAY make use of
+ 401 (Unauthorized) responses for authentication, but proxies MUST
+ NOT, and instead MAY use the 407 (Proxy Authentication Required)
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 193]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ response. The requirements for inclusion of the Proxy-Authenticate,
+ Proxy-Authorization, WWW-Authenticate, and Authorization in the
+ various messages are identical to those described in RFC 2617 [17].
+
+ Since SIP does not have the concept of a canonical root URL, the
+ notion of protection spaces is interpreted differently in SIP. The
+ realm string alone defines the protection domain. This is a change
+ from RFC 2543, in which the Request-URI and the realm together
+ defined the protection domain.
+
+ This previous definition of protection domain caused some amount
+ of confusion since the Request-URI sent by the UAC and the
+ Request-URI received by the challenging server might be different,
+ and indeed the final form of the Request-URI might not be known to
+ the UAC. Also, the previous definition depended on the presence
+ of a SIP URI in the Request-URI and seemed to rule out alternative
+ URI schemes (for example, the tel URL).
+
+ Operators of user agents or proxy servers that will authenticate
+ received requests MUST adhere to the following guidelines for
+ creation of a realm string for their server:
+
+ o Realm strings MUST be globally unique. It is RECOMMENDED that
+ a realm string contain a hostname or domain name, following the
+ recommendation in Section 3.2.1 of RFC 2617 [17].
+
+ o Realm strings SHOULD present a human-readable identifier that
+ can be rendered to a user.
+
+ For example:
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Authorization: Digest realm="biloxi.com", <...>
+
+ Generally, SIP authentication is meaningful for a specific realm, a
+ protection domain. Thus, for Digest authentication, each such
+ protection domain has its own set of usernames and passwords. If a
+ server does not require authentication for a particular request, it
+ MAY accept a default username, "anonymous", which has no password
+ (password of ""). Similarly, UACs representing many users, such as
+ PSTN gateways, MAY have their own device-specific username and
+ password, rather than accounts for particular users, for their realm.
+
+ While a server can legitimately challenge most SIP requests, there
+ are two requests defined by this document that require special
+ handling for authentication: ACK and CANCEL.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 194]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Under an authentication scheme that uses responses to carry values
+ used to compute nonces (such as Digest), some problems come up for
+ any requests that take no response, including ACK. For this reason,
+ any credentials in the INVITE that were accepted by a server MUST be
+ accepted by that server for the ACK. UACs creating an ACK message
+ will duplicate all of the Authorization and Proxy-Authorization
+ header field values that appeared in the INVITE to which the ACK
+ corresponds. Servers MUST NOT attempt to challenge an ACK.
+
+ Although the CANCEL method does take a response (a 2xx), servers MUST
+ NOT attempt to challenge CANCEL requests since these requests cannot
+ be resubmitted. Generally, a CANCEL request SHOULD be accepted by a
+ server if it comes from the same hop that sent the request being
+ canceled (provided that some sort of transport or network layer
+ security association, as described in Section 26.2.1, is in place).
+
+ When a UAC receives a challenge, it SHOULD render to the user the
+ contents of the "realm" parameter in the challenge (which appears in
+ either a WWW-Authenticate header field or Proxy-Authenticate header
+ field) if the UAC device does not already know of a credential for
+ the realm in question. A service provider that pre-configures UAs
+ with credentials for its realm should be aware that users will not
+ have the opportunity to present their own credentials for this realm
+ when challenged at a pre-configured device.
+
+ Finally, note that even if a UAC can locate credentials that are
+ associated with the proper realm, the potential exists that these
+ credentials may no longer be valid or that the challenging server
+ will not accept these credentials for whatever reason (especially
+ when "anonymous" with no password is submitted). In this instance a
+ server may repeat its challenge, or it may respond with a 403
+ Forbidden. A UAC MUST NOT re-attempt requests with the credentials
+ that have just been rejected (though the request may be retried if
+ the nonce was stale).
+
+22.2 User-to-User Authentication
+
+ When a UAS receives a request from a UAC, the UAS MAY authenticate
+ the originator before the request is processed. If no credentials
+ (in the Authorization header field) are provided in the request, the
+ UAS can challenge the originator to provide credentials by rejecting
+ the request with a 401 (Unauthorized) status code.
+
+ The WWW-Authenticate response-header field MUST be included in 401
+ (Unauthorized) response messages. The field value consists of at
+ least one challenge that indicates the authentication scheme(s) and
+ parameters applicable to the realm.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 195]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ An example of the WWW-Authenticate header field in a 401 challenge
+ is:
+
+ WWW-Authenticate: Digest
+ realm="biloxi.com",
+ qop="auth,auth-int",
+ nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ opaque="5ccc069c403ebaf9f0171e9517f40e41"
+
+ When the originating UAC receives the 401 (Unauthorized), it SHOULD,
+ if it is able, re-originate the request with the proper credentials.
+ The UAC may require input from the originating user before
+ proceeding. Once authentication credentials have been supplied
+ (either directly by the user, or discovered in an internal keyring),
+ UAs SHOULD cache the credentials for a given value of the To header
+ field and "realm" and attempt to re-use these values on the next
+ request for that destination. UAs MAY cache credentials in any way
+ they would like.
+
+ If no credentials for a realm can be located, UACs MAY attempt to
+ retry the request with a username of "anonymous" and no password (a
+ password of "").
+
+ Once credentials have been located, any UA that wishes to
+ authenticate itself with a UAS or registrar -- usually, but not
+ necessarily, after receiving a 401 (Unauthorized) response -- MAY do
+ so by including an Authorization header field with the request. The
+ Authorization field value consists of credentials containing the
+ authentication information of the UA for the realm of the resource
+ being requested as well as parameters required in support of
+ authentication and replay protection.
+
+ An example of the Authorization header field is:
+
+ Authorization: Digest username="bob",
+ realm="biloxi.com",
+ nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ uri="sip:bob@biloxi.com",
+ qop=auth,
+ nc=00000001,
+ cnonce="0a4f113b",
+ response="6629fae49393a05397450978507c4ef1",
+ opaque="5ccc069c403ebaf9f0171e9517f40e41"
+
+ When a UAC resubmits a request with its credentials after receiving a
+ 401 (Unauthorized) or 407 (Proxy Authentication Required) response,
+ it MUST increment the CSeq header field value as it would normally
+ when sending an updated request.
+
+
+
+Rosenberg, et. al. Standards Track [Page 196]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+22.3 Proxy-to-User Authentication
+
+ Similarly, when a UAC sends a request to a proxy server, the proxy
+ server MAY authenticate the originator before the request is
+ processed. If no credentials (in the Proxy-Authorization header
+ field) are provided in the request, the proxy can challenge the
+ originator to provide credentials by rejecting the request with a 407
+ (Proxy Authentication Required) status code. The proxy MUST populate
+ the 407 (Proxy Authentication Required) message with a Proxy-
+ Authenticate header field value applicable to the proxy for the
+ requested resource.
+
+ The use of Proxy-Authenticate and Proxy-Authorization parallel that
+ described in [17], with one difference. Proxies MUST NOT add values
+ to the Proxy-Authorization header field. All 407 (Proxy
+ Authentication Required) responses MUST be forwarded upstream toward
+ the UAC following the procedures for any other response. It is the
+ UAC's responsibility to add the Proxy-Authorization header field
+ value containing credentials for the realm of the proxy that has
+ asked for authentication.
+
+ If a proxy were to resubmit a request adding a Proxy-Authorization
+ header field value, it would need to increment the CSeq in the new
+ request. However, this would cause the UAC that submitted the
+ original request to discard a response from the UAS, as the CSeq
+ value would be different.
+
+ When the originating UAC receives the 407 (Proxy Authentication
+ Required) it SHOULD, if it is able, re-originate the request with the
+ proper credentials. It should follow the same procedures for the
+ display of the "realm" parameter that are given above for responding
+ to 401.
+
+ If no credentials for a realm can be located, UACs MAY attempt to
+ retry the request with a username of "anonymous" and no password (a
+ password of "").
+
+ The UAC SHOULD also cache the credentials used in the re-originated
+ request.
+
+ The following rule is RECOMMENDED for proxy credential caching:
+
+ If a UA receives a Proxy-Authenticate header field value in a 401/407
+ response to a request with a particular Call-ID, it should
+ incorporate credentials for that realm in all subsequent requests
+ that contain the same Call-ID. These credentials MUST NOT be cached
+ across dialogs; however, if a UA is configured with the realm of its
+ local outbound proxy, when one exists, then the UA MAY cache
+
+
+
+Rosenberg, et. al. Standards Track [Page 197]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ credentials for that realm across dialogs. Note that this does mean
+ a future request in a dialog could contain credentials that are not
+ needed by any proxy along the Route header path.
+
+ Any UA that wishes to authenticate itself to a proxy server --
+ usually, but not necessarily, after receiving a 407 (Proxy
+ Authentication Required) response -- MAY do so by including a Proxy-
+ Authorization header field value with the request. The Proxy-
+ Authorization request-header field allows the client to identify
+ itself (or its user) to a proxy that requires authentication. The
+ Proxy-Authorization header field value consists of credentials
+ containing the authentication information of the UA for the proxy
+ and/or realm of the resource being requested.
+
+ A Proxy-Authorization header field value applies only to the proxy
+ whose realm is identified in the "realm" parameter (this proxy may
+ previously have demanded authentication using the Proxy-Authenticate
+ field). When multiple proxies are used in a chain, a Proxy-
+ Authorization header field value MUST NOT be consumed by any proxy
+ whose realm does not match the "realm" parameter specified in that
+ value.
+
+ Note that if an authentication scheme that does not support realms is
+ used in the Proxy-Authorization header field, a proxy server MUST
+ attempt to parse all Proxy-Authorization header field values to
+ determine whether one of them has what the proxy server considers to
+ be valid credentials. Because this is potentially very time-
+ consuming in large networks, proxy servers SHOULD use an
+ authentication scheme that supports realms in the Proxy-Authorization
+ header field.
+
+ If a request is forked (as described in Section 16.7), various proxy
+ servers and/or UAs may wish to challenge the UAC. In this case, the
+ forking proxy server is responsible for aggregating these challenges
+ into a single response. Each WWW-Authenticate and Proxy-Authenticate
+ value received in responses to the forked request MUST be placed into
+ the single response that is sent by the forking proxy to the UA; the
+ ordering of these header field values is not significant.
+
+ When a proxy server issues a challenge in response to a request,
+ it will not proxy the request until the UAC has retried the
+ request with valid credentials. A forking proxy may forward a
+ request simultaneously to multiple proxy servers that require
+ authentication, each of which in turn will not forward the request
+ until the originating UAC has authenticated itself in their
+ respective realm. If the UAC does not provide credentials for
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 198]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ each challenge, the proxy servers that issued the challenges will
+ not forward requests to the UA where the destination user might be
+ located, and therefore, the virtues of forking are largely lost.
+
+ When resubmitting its request in response to a 401 (Unauthorized) or
+ 407 (Proxy Authentication Required) that contains multiple
+ challenges, a UAC MAY include an Authorization value for each WWW-
+ Authenticate value and a Proxy-Authorization value for each Proxy-
+ Authenticate value for which the UAC wishes to supply a credential.
+ As noted above, multiple credentials in a request SHOULD be
+ differentiated by the "realm" parameter.
+
+ It is possible for multiple challenges associated with the same realm
+ to appear in the same 401 (Unauthorized) or 407 (Proxy Authentication
+ Required). This can occur, for example, when multiple proxies within
+ the same administrative domain, which use a common realm, are reached
+ by a forking request. When it retries a request, a UAC MAY therefore
+ supply multiple credentials in Authorization or Proxy-Authorization
+ header fields with the same "realm" parameter value. The same
+ credentials SHOULD be used for the same realm.
+
+22.4 The Digest Authentication Scheme
+
+ This section describes the modifications and clarifications required
+ to apply the HTTP Digest authentication scheme to SIP. The SIP
+ scheme usage is almost completely identical to that for HTTP [17].
+
+ Since RFC 2543 is based on HTTP Digest as defined in RFC 2069 [39],
+ SIP servers supporting RFC 2617 MUST ensure they are backwards
+ compatible with RFC 2069. Procedures for this backwards
+ compatibility are specified in RFC 2617. Note, however, that SIP
+ servers MUST NOT accept or request Basic authentication.
+
+ The rules for Digest authentication follow those defined in [17],
+ with "HTTP/1.1" replaced by "SIP/2.0" in addition to the following
+ differences:
+
+ 1. The URI included in the challenge has the following BNF:
+
+ URI = SIP-URI / SIPS-URI
+
+ 2. The BNF in RFC 2617 has an error in that the 'uri' parameter
+ of the Authorization header field for HTTP Digest
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 199]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ authentication is not enclosed in quotation marks. (The
+ example in Section 3.5 of RFC 2617 is correct.) For SIP, the
+ 'uri' MUST be enclosed in quotation marks.
+
+ 3. The BNF for digest-uri-value is:
+
+ digest-uri-value = Request-URI ; as defined in Section 25
+
+ 4. The example procedure for choosing a nonce based on Etag does
+ not work for SIP.
+
+ 5. The text in RFC 2617 [17] regarding cache operation does not
+ apply to SIP.
+
+ 6. RFC 2617 [17] requires that a server check that the URI in the
+ request line and the URI included in the Authorization header
+ field point to the same resource. In a SIP context, these two
+ URIs may refer to different users, due to forwarding at some
+ proxy. Therefore, in SIP, a server MAY check that the
+ Request-URI in the Authorization header field value
+ corresponds to a user for whom the server is willing to accept
+ forwarded or direct requests, but it is not necessarily a
+ failure if the two fields are not equivalent.
+
+ 7. As a clarification to the calculation of the A2 value for
+ message integrity assurance in the Digest authentication
+ scheme, implementers should assume, when the entity-body is
+ empty (that is, when SIP messages have no body) that the hash
+ of the entity-body resolves to the MD5 hash of an empty
+ string, or:
+
+ H(entity-body) = MD5("") =
+ "d41d8cd98f00b204e9800998ecf8427e"
+
+ 8. RFC 2617 notes that a cnonce value MUST NOT be sent in an
+ Authorization (and by extension Proxy-Authorization) header
+ field if no qop directive has been sent. Therefore, any
+ algorithms that have a dependency on the cnonce (including
+ "MD5-Sess") require that the qop directive be sent. Use of
+ the "qop" parameter is optional in RFC 2617 for the purposes
+ of backwards compatibility with RFC 2069; since RFC 2543 was
+ based on RFC 2069, the "qop" parameter must unfortunately
+ remain optional for clients and servers to receive. However,
+ servers MUST always send a "qop" parameter in WWW-Authenticate
+ and Proxy-Authenticate header field values. If a client
+ receives a "qop" parameter in a challenge header field, it
+ MUST send the "qop" parameter in any resulting authorization
+ header field.
+
+
+
+Rosenberg, et. al. Standards Track [Page 200]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ RFC 2543 did not allow usage of the Authentication-Info header field
+ (it effectively used RFC 2069). However, we now allow usage of this
+ header field, since it provides integrity checks over the bodies and
+ provides mutual authentication. RFC 2617 [17] defines mechanisms for
+ backwards compatibility using the qop attribute in the request.
+ These mechanisms MUST be used by a server to determine if the client
+ supports the new mechanisms in RFC 2617 that were not specified in
+ RFC 2069.
+
+23 S/MIME
+
+ SIP messages carry MIME bodies and the MIME standard includes
+ mechanisms for securing MIME contents to ensure both integrity and
+ confidentiality (including the 'multipart/signed' and
+ 'application/pkcs7-mime' MIME types, see RFC 1847 [22], RFC 2630 [23]
+ and RFC 2633 [24]). Implementers should note, however, that there
+ may be rare network intermediaries (not typical proxy servers) that
+ rely on viewing or modifying the bodies of SIP messages (especially
+ SDP), and that secure MIME may prevent these sorts of intermediaries
+ from functioning.
+
+ This applies particularly to certain types of firewalls.
+
+ The PGP mechanism for encrypting the header fields and bodies of
+ SIP messages described in RFC 2543 has been deprecated.
+
+23.1 S/MIME Certificates
+
+ The certificates that are used to identify an end-user for the
+ purposes of S/MIME differ from those used by servers in one important
+ respect - rather than asserting that the identity of the holder
+ corresponds to a particular hostname, these certificates assert that
+ the holder is identified by an end-user address. This address is
+ composed of the concatenation of the "userinfo" "@" and "domainname"
+ portions of a SIP or SIPS URI (in other words, an email address of
+ the form "bob@biloxi.com"), most commonly corresponding to a user's
+ address-of-record.
+
+ These certificates are also associated with keys that are used to
+ sign or encrypt bodies of SIP messages. Bodies are signed with the
+ private key of the sender (who may include their public key with the
+ message as appropriate), but bodies are encrypted with the public key
+ of the intended recipient. Obviously, senders must have
+ foreknowledge of the public key of recipients in order to encrypt
+ message bodies. Public keys can be stored within a UA on a virtual
+ keyring.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 201]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Each user agent that supports S/MIME MUST contain a keyring
+ specifically for end-users' certificates. This keyring should map
+ between addresses of record and corresponding certificates. Over
+ time, users SHOULD use the same certificate when they populate the
+ originating URI of signaling (the From header field) with the same
+ address-of-record.
+
+ Any mechanisms depending on the existence of end-user certificates
+ are seriously limited in that there is virtually no consolidated
+ authority today that provides certificates for end-user applications.
+ However, users SHOULD acquire certificates from known public
+ certificate authorities. As an alternative, users MAY create self-
+ signed certificates. The implications of self-signed certificates
+ are explored further in Section 26.4.2. Implementations may also use
+ pre-configured certificates in deployments in which a previous trust
+ relationship exists between all SIP entities.
+
+ Above and beyond the problem of acquiring an end-user certificate,
+ there are few well-known centralized directories that distribute
+ end-user certificates. However, the holder of a certificate SHOULD
+ publish their certificate in any public directories as appropriate.
+ Similarly, UACs SHOULD support a mechanism for importing (manually or
+ automatically) certificates discovered in public directories
+ corresponding to the target URIs of SIP requests.
+
+23.2 S/MIME Key Exchange
+
+ SIP itself can also be used as a means to distribute public keys in
+ the following manner.
+
+ Whenever the CMS SignedData message is used in S/MIME for SIP, it
+ MUST contain the certificate bearing the public key necessary to
+ verify the signature.
+
+ When a UAC sends a request containing an S/MIME body that initiates a
+ dialog, or sends a non-INVITE request outside the context of a
+ dialog, the UAC SHOULD structure the body as an S/MIME
+ 'multipart/signed' CMS SignedData body. If the desired CMS service
+ is EnvelopedData (and the public key of the target user is known),
+ the UAC SHOULD send the EnvelopedData message encapsulated within a
+ SignedData message.
+
+ When a UAS receives a request containing an S/MIME CMS body that
+ includes a certificate, the UAS SHOULD first validate the
+ certificate, if possible, with any available root certificates for
+ certificate authorities. The UAS SHOULD also determine the subject
+ of the certificate (for S/MIME, the SubjectAltName will contain the
+ appropriate identity) and compare this value to the From header field
+
+
+
+Rosenberg, et. al. Standards Track [Page 202]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ of the request. If the certificate cannot be verified, because it is
+ self-signed, or signed by no known authority, or if it is verifiable
+ but its subject does not correspond to the From header field of
+ request, the UAS MUST notify its user of the status of the
+ certificate (including the subject of the certificate, its signer,
+ and any key fingerprint information) and request explicit permission
+ before proceeding. If the certificate was successfully verified and
+ the subject of the certificate corresponds to the From header field
+ of the SIP request, or if the user (after notification) explicitly
+ authorizes the use of the certificate, the UAS SHOULD add this
+ certificate to a local keyring, indexed by the address-of-record of
+ the holder of the certificate.
+
+ When a UAS sends a response containing an S/MIME body that answers
+ the first request in a dialog, or a response to a non-INVITE request
+ outside the context of a dialog, the UAS SHOULD structure the body as
+ an S/MIME 'multipart/signed' CMS SignedData body. If the desired CMS
+ service is EnvelopedData, the UAS SHOULD send the EnvelopedData
+ message encapsulated within a SignedData message.
+
+ When a UAC receives a response containing an S/MIME CMS body that
+ includes a certificate, the UAC SHOULD first validate the
+ certificate, if possible, with any appropriate root certificate. The
+ UAC SHOULD also determine the subject of the certificate and compare
+ this value to the To field of the response; although the two may very
+ well be different, and this is not necessarily indicative of a
+ security breach. If the certificate cannot be verified because it is
+ self-signed, or signed by no known authority, the UAC MUST notify its
+ user of the status of the certificate (including the subject of the
+ certificate, its signator, and any key fingerprint information) and
+ request explicit permission before proceeding. If the certificate
+ was successfully verified, and the subject of the certificate
+ corresponds to the To header field in the response, or if the user
+ (after notification) explicitly authorizes the use of the
+ certificate, the UAC SHOULD add this certificate to a local keyring,
+ indexed by the address-of-record of the holder of the certificate.
+ If the UAC had not transmitted its own certificate to the UAS in any
+ previous transaction, it SHOULD use a CMS SignedData body for its
+ next request or response.
+
+ On future occasions, when the UA receives requests or responses that
+ contain a From header field corresponding to a value in its keyring,
+ the UA SHOULD compare the certificate offered in these messages with
+ the existing certificate in its keyring. If there is a discrepancy,
+ the UA MUST notify its user of a change of the certificate
+ (preferably in terms that indicate that this is a potential security
+ breach) and acquire the user's permission before continuing to
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 203]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ process the signaling. If the user authorizes this certificate, it
+ SHOULD be added to the keyring alongside any previous value(s) for
+ this address-of-record.
+
+ Note well however, that this key exchange mechanism does not
+ guarantee the secure exchange of keys when self-signed certificates,
+ or certificates signed by an obscure authority, are used - it is
+ vulnerable to well-known attacks. In the opinion of the authors,
+ however, the security it provides is proverbially better than
+ nothing; it is in fact comparable to the widely used SSH application.
+ These limitations are explored in greater detail in Section 26.4.2.
+
+ If a UA receives an S/MIME body that has been encrypted with a public
+ key unknown to the recipient, it MUST reject the request with a 493
+ (Undecipherable) response. This response SHOULD contain a valid
+ certificate for the respondent (corresponding, if possible, to any
+ address of record given in the To header field of the rejected
+ request) within a MIME body with a 'certs-only' "smime-type"
+ parameter.
+
+ A 493 (Undecipherable) sent without any certificate indicates that
+ the respondent cannot or will not utilize S/MIME encrypted messages,
+ though they may still support S/MIME signatures.
+
+ Note that a user agent that receives a request containing an S/MIME
+ body that is not optional (with a Content-Disposition header
+ "handling" parameter of "required") MUST reject the request with a
+ 415 Unsupported Media Type response if the MIME type is not
+ understood. A user agent that receives such a response when S/MIME
+ is sent SHOULD notify its user that the remote device does not
+ support S/MIME, and it MAY subsequently resend the request without
+ S/MIME, if appropriate; however, this 415 response may constitute a
+ downgrade attack.
+
+ If a user agent sends an S/MIME body in a request, but receives a
+ response that contains a MIME body that is not secured, the UAC
+ SHOULD notify its user that the session could not be secured.
+ However, if a user agent that supports S/MIME receives a request with
+ an unsecured body, it SHOULD NOT respond with a secured body, but if
+ it expects S/MIME from the sender (for example, because the sender's
+ From header field value corresponds to an identity on its keychain),
+ the UAS SHOULD notify its user that the session could not be secured.
+
+ A number of conditions that arise in the previous text call for the
+ notification of the user when an anomalous certificate-management
+ event occurs. Users might well ask what they should do under these
+ circumstances. First and foremost, an unexpected change in a
+ certificate, or an absence of security when security is expected, are
+
+
+
+Rosenberg, et. al. Standards Track [Page 204]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ causes for caution but not necessarily indications that an attack is
+ in progress. Users might abort any connection attempt or refuse a
+ connection request they have received; in telephony parlance, they
+ could hang up and call back. Users may wish to find an alternate
+ means to contact the other party and confirm that their key has
+ legitimately changed. Note that users are sometimes compelled to
+ change their certificates, for example when they suspect that the
+ secrecy of their private key has been compromised. When their
+ private key is no longer private, users must legitimately generate a
+ new key and re-establish trust with any users that held their old
+ key.
+
+ Finally, if during the course of a dialog a UA receives a certificate
+ in a CMS SignedData message that does not correspond with the
+ certificates previously exchanged during a dialog, the UA MUST notify
+ its user of the change, preferably in terms that indicate that this
+ is a potential security breach.
+
+23.3 Securing MIME bodies
+
+ There are two types of secure MIME bodies that are of interest to
+ SIP: use of these bodies should follow the S/MIME specification [24]
+ with a few variations.
+
+ o "multipart/signed" MUST be used only with CMS detached
+ signatures.
+
+ This allows backwards compatibility with non-S/MIME-
+ compliant recipients.
+
+ o S/MIME bodies SHOULD have a Content-Disposition header field,
+ and the value of the "handling" parameter SHOULD be "required."
+
+ o If a UAC has no certificate on its keyring associated with the
+ address-of-record to which it wants to send a request, it
+ cannot send an encrypted "application/pkcs7-mime" MIME message.
+ UACs MAY send an initial request such as an OPTIONS message
+ with a CMS detached signature in order to solicit the
+ certificate of the remote side (the signature SHOULD be over a
+ "message/sip" body of the type described in Section 23.4).
+
+ Note that future standardization work on S/MIME may define
+ non-certificate based keys.
+
+ o Senders of S/MIME bodies SHOULD use the "SMIMECapabilities"
+ (see Section 2.5.2 of [24]) attribute to express their
+ capabilities and preferences for further communications. Note
+ especially that senders MAY use the "preferSignedData"
+
+
+
+Rosenberg, et. al. Standards Track [Page 205]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ capability to encourage receivers to respond with CMS
+ SignedData messages (for example, when sending an OPTIONS
+ request as described above).
+
+ o S/MIME implementations MUST at a minimum support SHA1 as a
+ digital signature algorithm, and 3DES as an encryption
+ algorithm. All other signature and encryption algorithms MAY
+ be supported. Implementations can negotiate support for these
+ algorithms with the "SMIMECapabilities" attribute.
+
+ o Each S/MIME body in a SIP message SHOULD be signed with only
+ one certificate. If a UA receives a message with multiple
+ signatures, the outermost signature should be treated as the
+ single certificate for this body. Parallel signatures SHOULD
+ NOT be used.
+
+ The following is an example of an encrypted S/MIME SDP body
+ within a SIP message:
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ To: Bob <sip:bob@biloxi.com>
+ From: Alice <sip:alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710
+ CSeq: 314159 INVITE
+ Max-Forwards: 70
+ Contact: <sip:alice@pc33.atlanta.com>
+ Content-Type: application/pkcs7-mime; smime-type=enveloped-data;
+ name=smime.p7m
+ Content-Disposition: attachment; filename=smime.p7m
+ handling=required
+
+ *******************************************************
+ * Content-Type: application/sdp *
+ * *
+ * v=0 *
+ * o=alice 53655765 2353687637 IN IP4 pc33.atlanta.com *
+ * s=- *
+ * t=0 0 *
+ * c=IN IP4 pc33.atlanta.com *
+ * m=audio 3456 RTP/AVP 0 1 3 99 *
+ * a=rtpmap:0 PCMU/8000 *
+ *******************************************************
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 206]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+23.4 SIP Header Privacy and Integrity using S/MIME: Tunneling SIP
+
+ As a means of providing some degree of end-to-end authentication,
+ integrity or confidentiality for SIP header fields, S/MIME can
+ encapsulate entire SIP messages within MIME bodies of type
+ "message/sip" and then apply MIME security to these bodies in the
+ same manner as typical SIP bodies. These encapsulated SIP requests
+ and responses do not constitute a separate dialog or transaction,
+ they are a copy of the "outer" message that is used to verify
+ integrity or to supply additional information.
+
+ If a UAS receives a request that contains a tunneled "message/sip"
+ S/MIME body, it SHOULD include a tunneled "message/sip" body in the
+ response with the same smime-type.
+
+ Any traditional MIME bodies (such as SDP) SHOULD be attached to the
+ "inner" message so that they can also benefit from S/MIME security.
+ Note that "message/sip" bodies can be sent as a part of a MIME
+ "multipart/mixed" body if any unsecured MIME types should also be
+ transmitted in a request.
+
+23.4.1 Integrity and Confidentiality Properties of SIP Headers
+
+ When the S/MIME integrity or confidentiality mechanisms are used,
+ there may be discrepancies between the values in the "inner" message
+ and values in the "outer" message. The rules for handling any such
+ differences for all of the header fields described in this document
+ are given in this section.
+
+ Note that for the purposes of loose timestamping, all SIP messages
+ that tunnel "message/sip" SHOULD contain a Date header in both the
+ "inner" and "outer" headers.
+
+23.4.1.1 Integrity
+
+ Whenever integrity checks are performed, the integrity of a header
+ field should be determined by matching the value of the header field
+ in the signed body with that in the "outer" messages using the
+ comparison rules of SIP as described in 20.
+
+ Header fields that can be legitimately modified by proxy servers are:
+ Request-URI, Via, Record-Route, Route, Max-Forwards, and Proxy-
+ Authorization. If these header fields are not intact end-to-end,
+ implementations SHOULD NOT consider this a breach of security.
+ Changes to any other header fields defined in this document
+ constitute an integrity violation; users MUST be notified of a
+ discrepancy.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 207]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+23.4.1.2 Confidentiality
+
+ When messages are encrypted, header fields may be included in the
+ encrypted body that are not present in the "outer" message.
+
+ Some header fields must always have a plaintext version because they
+ are required header fields in requests and responses - these include:
+
+ To, From, Call-ID, CSeq, Contact. While it is probably not useful to
+ provide an encrypted alternative for the Call-ID, CSeq, or Contact,
+ providing an alternative to the information in the "outer" To or From
+ is permitted. Note that the values in an encrypted body are not used
+ for the purposes of identifying transactions or dialogs - they are
+ merely informational. If the From header field in an encrypted body
+ differs from the value in the "outer" message, the value within the
+ encrypted body SHOULD be displayed to the user, but MUST NOT be used
+ in the "outer" header fields of any future messages.
+
+ Primarily, a user agent will want to encrypt header fields that have
+ an end-to-end semantic, including: Subject, Reply-To, Organization,
+ Accept, Accept-Encoding, Accept-Language, Alert-Info, Error-Info,
+ Authentication-Info, Expires, In-Reply-To, Require, Supported,
+ Unsupported, Retry-After, User-Agent, Server, and Warning. If any of
+ these header fields are present in an encrypted body, they should be
+ used instead of any "outer" header fields, whether this entails
+ displaying the header field values to users or setting internal
+ states in the UA. They SHOULD NOT however be used in the "outer"
+ headers of any future messages.
+
+ If present, the Date header field MUST always be the same in the
+ "inner" and "outer" headers.
+
+ Since MIME bodies are attached to the "inner" message,
+ implementations will usually encrypt MIME-specific header fields,
+ including: MIME-Version, Content-Type, Content-Length, Content-
+ Language, Content-Encoding and Content-Disposition. The "outer"
+ message will have the proper MIME header fields for S/MIME bodies.
+ These header fields (and any MIME bodies they preface) should be
+ treated as normal MIME header fields and bodies received in a SIP
+ message.
+
+ It is not particularly useful to encrypt the following header fields:
+ Min-Expires, Timestamp, Authorization, Priority, and WWW-
+ Authenticate. This category also includes those header fields that
+ can be changed by proxy servers (described in the preceding section).
+ UAs SHOULD never include these in an "inner" message if they are not
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 208]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ included in the "outer" message. UAs that receive any of these
+ header fields in an encrypted body SHOULD ignore the encrypted
+ values.
+
+ Note that extensions to SIP may define additional header fields; the
+ authors of these extensions should describe the integrity and
+ confidentiality properties of such header fields. If a SIP UA
+ encounters an unknown header field with an integrity violation, it
+ MUST ignore the header field.
+
+23.4.2 Tunneling Integrity and Authentication
+
+ Tunneling SIP messages within S/MIME bodies can provide integrity for
+ SIP header fields if the header fields that the sender wishes to
+ secure are replicated in a "message/sip" MIME body signed with a CMS
+ detached signature.
+
+ Provided that the "message/sip" body contains at least the
+ fundamental dialog identifiers (To, From, Call-ID, CSeq), then a
+ signed MIME body can provide limited authentication. At the very
+ least, if the certificate used to sign the body is unknown to the
+ recipient and cannot be verified, the signature can be used to
+ ascertain that a later request in a dialog was transmitted by the
+ same certificate-holder that initiated the dialog. If the recipient
+ of the signed MIME body has some stronger incentive to trust the
+ certificate (they were able to validate it, they acquired it from a
+ trusted repository, or they have used it frequently) then the
+ signature can be taken as a stronger assertion of the identity of the
+ subject of the certificate.
+
+ In order to eliminate possible confusions about the addition or
+ subtraction of entire header fields, senders SHOULD replicate all
+ header fields from the request within the signed body. Any message
+ bodies that require integrity protection MUST be attached to the
+ "inner" message.
+
+ If a Date header is present in a message with a signed body, the
+ recipient SHOULD compare the header field value with its own internal
+ clock, if applicable. If a significant time discrepancy is detected
+ (on the order of an hour or more), the user agent SHOULD alert the
+ user to the anomaly, and note that it is a potential security breach.
+
+ If an integrity violation in a message is detected by its recipient,
+ the message MAY be rejected with a 403 (Forbidden) response if it is
+ a request, or any existing dialog MAY be terminated. UAs SHOULD
+ notify users of this circumstance and request explicit guidance on
+ how to proceed.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 209]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The following is an example of the use of a tunneled "message/sip"
+ body:
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ To: Bob <sip:bob@biloxi.com>
+ From: Alice <sip:alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710
+ CSeq: 314159 INVITE
+ Max-Forwards: 70
+ Date: Thu, 21 Feb 2002 13:02:03 GMT
+ Contact: <sip:alice@pc33.atlanta.com>
+ Content-Type: multipart/signed;
+ protocol="application/pkcs7-signature";
+ micalg=sha1; boundary=boundary42
+ Content-Length: 568
+
+ --boundary42
+ Content-Type: message/sip
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ To: Bob <bob@biloxi.com>
+ From: Alice <alice@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710
+ CSeq: 314159 INVITE
+ Max-Forwards: 70
+ Date: Thu, 21 Feb 2002 13:02:03 GMT
+ Contact: <sip:alice@pc33.atlanta.com>
+ Content-Type: application/sdp
+ Content-Length: 147
+
+ v=0
+ o=UserA 2890844526 2890844526 IN IP4 here.com
+ s=Session SDP
+ c=IN IP4 pc33.atlanta.com
+ t=0 0
+ m=audio 49172 RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ --boundary42
+ Content-Type: application/pkcs7-signature; name=smime.p7s
+ Content-Transfer-Encoding: base64
+ Content-Disposition: attachment; filename=smime.p7s;
+ handling=required
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 210]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6
+ 4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj
+ n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4
+ 7GhIGfHfYT64VQbnj756
+
+ --boundary42-
+
+23.4.3 Tunneling Encryption
+
+ It may also be desirable to use this mechanism to encrypt a
+ "message/sip" MIME body within a CMS EnvelopedData message S/MIME
+ body, but in practice, most header fields are of at least some use to
+ the network; the general use of encryption with S/MIME is to secure
+ message bodies like SDP rather than message headers. Some
+ informational header fields, such as the Subject or Organization
+ could perhaps warrant end-to-end security. Headers defined by future
+ SIP applications might also require obfuscation.
+
+ Another possible application of encrypting header fields is selective
+ anonymity. A request could be constructed with a From header field
+ that contains no personal information (for example,
+ sip:anonymous@anonymizer.invalid). However, a second From header
+ field containing the genuine address-of-record of the originator
+ could be encrypted within a "message/sip" MIME body where it will
+ only be visible to the endpoints of a dialog.
+
+ Note that if this mechanism is used for anonymity, the From header
+ field will no longer be usable by the recipient of a message as an
+ index to their certificate keychain for retrieving the proper
+ S/MIME key to associated with the sender. The message must first
+ be decrypted, and the "inner" From header field MUST be used as an
+ index.
+
+ In order to provide end-to-end integrity, encrypted "message/sip"
+ MIME bodies SHOULD be signed by the sender. This creates a
+ "multipart/signed" MIME body that contains an encrypted body and a
+ signature, both of type "application/pkcs7-mime".
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 211]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ In the following example, of an encrypted and signed message, the
+ text boxed in asterisks ("*") is encrypted:
+
+ INVITE sip:bob@biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ To: Bob <sip:bob@biloxi.com>
+ From: Anonymous <sip:anonymous@atlanta.com>;tag=1928301774
+ Call-ID: a84b4c76e66710
+ CSeq: 314159 INVITE
+ Max-Forwards: 70
+ Date: Thu, 21 Feb 2002 13:02:03 GMT
+ Contact: <sip:pc33.atlanta.com>
+ Content-Type: multipart/signed;
+ protocol="application/pkcs7-signature";
+ micalg=sha1; boundary=boundary42
+ Content-Length: 568
+
+ --boundary42
+ Content-Type: application/pkcs7-mime; smime-type=enveloped-data;
+ name=smime.p7m
+ Content-Transfer-Encoding: base64
+ Content-Disposition: attachment; filename=smime.p7m
+ handling=required
+ Content-Length: 231
+
+ ***********************************************************
+ * Content-Type: message/sip *
+ * *
+ * INVITE sip:bob@biloxi.com SIP/2.0 *
+ * Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8 *
+ * To: Bob <bob@biloxi.com> *
+ * From: Alice <alice@atlanta.com>;tag=1928301774 *
+ * Call-ID: a84b4c76e66710 *
+ * CSeq: 314159 INVITE *
+ * Max-Forwards: 70 *
+ * Date: Thu, 21 Feb 2002 13:02:03 GMT *
+ * Contact: <sip:alice@pc33.atlanta.com> *
+ * *
+ * Content-Type: application/sdp *
+ * *
+ * v=0 *
+ * o=alice 53655765 2353687637 IN IP4 pc33.atlanta.com *
+ * s=Session SDP *
+ * t=0 0 *
+ * c=IN IP4 pc33.atlanta.com *
+ * m=audio 3456 RTP/AVP 0 1 3 99 *
+ * a=rtpmap:0 PCMU/8000 *
+ ***********************************************************
+
+
+
+Rosenberg, et. al. Standards Track [Page 212]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ --boundary42
+ Content-Type: application/pkcs7-signature; name=smime.p7s
+ Content-Transfer-Encoding: base64
+ Content-Disposition: attachment; filename=smime.p7s;
+ handling=required
+
+ ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6
+ 4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj
+ n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4
+ 7GhIGfHfYT64VQbnj756
+
+ --boundary42-
+
+24 Examples
+
+ In the following examples, we often omit the message body and the
+ corresponding Content-Length and Content-Type header fields for
+ brevity.
+
+24.1 Registration
+
+ Bob registers on start-up. The message flow is shown in Figure 9.
+ Note that the authentication usually required for registration is not
+ shown for simplicity.
+
+ biloxi.com Bob's
+ registrar softphone
+ | |
+ | REGISTER F1 |
+ |<---------------|
+ | 200 OK F2 |
+ |--------------->|
+
+ Figure 9: SIP Registration Example
+
+ F1 REGISTER Bob -> Registrar
+
+ REGISTER sip:registrar.biloxi.com SIP/2.0
+ Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7
+ Max-Forwards: 70
+ To: Bob <sip:bob@biloxi.com>
+ From: Bob <sip:bob@biloxi.com>;tag=456248
+ Call-ID: 843817637684230@998sdasdh09
+ CSeq: 1826 REGISTER
+ Contact: <sip:bob@192.0.2.4>
+ Expires: 7200
+ Content-Length: 0
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 213]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The registration expires after two hours. The registrar responds
+ with a 200 OK:
+
+ F2 200 OK Registrar -> Bob
+
+ SIP/2.0 200 OK
+ Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7
+ ;received=192.0.2.4
+ To: Bob <sip:bob@biloxi.com>;tag=2493k59kd
+ From: Bob <sip:bob@biloxi.com>;tag=456248
+ Call-ID: 843817637684230@998sdasdh09
+ CSeq: 1826 REGISTER
+ Contact: <sip:bob@192.0.2.4>
+ Expires: 7200
+ Content-Length: 0
+
+24.2 Session Setup
+
+ This example contains the full details of the example session setup
+ in Section 4. The message flow is shown in Figure 1. Note that
+ these flows show the minimum required set of header fields - some
+ other header fields such as Allow and Supported would normally be
+ present.
+
+F1 INVITE Alice -> atlanta.com proxy
+
+INVITE sip:bob@biloxi.com SIP/2.0
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+Max-Forwards: 70
+To: Bob <sip:bob@biloxi.com>
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Contact: <sip:alice@pc33.atlanta.com>
+Content-Type: application/sdp
+Content-Length: 142
+
+(Alice's SDP not shown)
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 214]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+F2 100 Trying atlanta.com proxy -> Alice
+
+SIP/2.0 100 Trying
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Content-Length: 0
+
+F3 INVITE atlanta.com proxy -> biloxi.com proxy
+
+INVITE sip:bob@biloxi.com SIP/2.0
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+Max-Forwards: 69
+To: Bob <sip:bob@biloxi.com>
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Contact: <sip:alice@pc33.atlanta.com>
+Content-Type: application/sdp
+Content-Length: 142
+
+(Alice's SDP not shown)
+
+F4 100 Trying biloxi.com proxy -> atlanta.com proxy
+
+SIP/2.0 100 Trying
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+ ;received=192.0.2.2
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Content-Length: 0
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 215]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+F5 INVITE biloxi.com proxy -> Bob
+
+INVITE sip:bob@192.0.2.4 SIP/2.0
+Via: SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bK4b43c2ff8.1
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+ ;received=192.0.2.2
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+Max-Forwards: 68
+To: Bob <sip:bob@biloxi.com>
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Contact: <sip:alice@pc33.atlanta.com>
+Content-Type: application/sdp
+Content-Length: 142
+
+(Alice's SDP not shown)
+
+F6 180 Ringing Bob -> biloxi.com proxy
+
+SIP/2.0 180 Ringing
+Via: SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bK4b43c2ff8.1
+ ;received=192.0.2.3
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+ ;received=192.0.2.2
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+Contact: <sip:bob@192.0.2.4>
+CSeq: 314159 INVITE
+Content-Length: 0
+
+F7 180 Ringing biloxi.com proxy -> atlanta.com proxy
+
+SIP/2.0 180 Ringing
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+ ;received=192.0.2.2
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+Contact: <sip:bob@192.0.2.4>
+CSeq: 314159 INVITE
+Content-Length: 0
+
+
+
+Rosenberg, et. al. Standards Track [Page 216]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+F8 180 Ringing atlanta.com proxy -> Alice
+
+SIP/2.0 180 Ringing
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+Contact: <sip:bob@192.0.2.4>
+CSeq: 314159 INVITE
+Content-Length: 0
+
+F9 200 OK Bob -> biloxi.com proxy
+
+SIP/2.0 200 OK
+Via: SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bK4b43c2ff8.1
+ ;received=192.0.2.3
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+ ;received=192.0.2.2
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Contact: <sip:bob@192.0.2.4>
+Content-Type: application/sdp
+Content-Length: 131
+
+(Bob's SDP not shown)
+
+F10 200 OK biloxi.com proxy -> atlanta.com proxy
+
+SIP/2.0 200 OK
+Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1
+ ;received=192.0.2.2
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Contact: <sip:bob@192.0.2.4>
+Content-Type: application/sdp
+Content-Length: 131
+
+(Bob's SDP not shown)
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 217]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+F11 200 OK atlanta.com proxy -> Alice
+
+SIP/2.0 200 OK
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
+ ;received=192.0.2.1
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 INVITE
+Contact: <sip:bob@192.0.2.4>
+Content-Type: application/sdp
+Content-Length: 131
+
+(Bob's SDP not shown)
+
+F12 ACK Alice -> Bob
+
+ACK sip:bob@192.0.2.4 SIP/2.0
+Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9
+Max-Forwards: 70
+To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+From: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 314159 ACK
+Content-Length: 0
+
+ The media session between Alice and Bob is now established.
+
+ Bob hangs up first. Note that Bob's SIP phone maintains its own CSeq
+ numbering space, which, in this example, begins with 231. Since Bob
+ is making the request, the To and From URIs and tags have been
+ swapped.
+
+F13 BYE Bob -> Alice
+
+BYE sip:alice@pc33.atlanta.com SIP/2.0
+Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10
+Max-Forwards: 70
+From: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+To: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 231 BYE
+Content-Length: 0
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 218]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+F14 200 OK Alice -> Bob
+
+SIP/2.0 200 OK
+Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10
+From: Bob <sip:bob@biloxi.com>;tag=a6c85cf
+To: Alice <sip:alice@atlanta.com>;tag=1928301774
+Call-ID: a84b4c76e66710
+CSeq: 231 BYE
+Content-Length: 0
+
+ The SIP Call Flows document [40] contains further examples of SIP
+ messages.
+
+25 Augmented BNF for the SIP Protocol
+
+ All of the mechanisms specified in this document are described in
+ both prose and an augmented Backus-Naur Form (BNF) defined in RFC
+ 2234 [10]. Section 6.1 of RFC 2234 defines a set of core rules that
+ are used by this specification, and not repeated here. Implementers
+ need to be familiar with the notation and content of RFC 2234 in
+ order to understand this specification. Certain basic rules are in
+ uppercase, such as SP, LWS, HTAB, CRLF, DIGIT, ALPHA, etc. Angle
+ brackets are used within definitions to clarify the use of rule
+ names.
+
+ The use of square brackets is redundant syntactically. It is used as
+ a semantic hint that the specific parameter is optional to use.
+
+25.1 Basic Rules
+
+ The following rules are used throughout this specification to
+ describe basic parsing constructs. The US-ASCII coded character set
+ is defined by ANSI X3.4-1986.
+
+ alphanum = ALPHA / DIGIT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 219]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Several rules are incorporated from RFC 2396 [5] but are updated to
+ make them compliant with RFC 2234 [10]. These include:
+
+ reserved = ";" / "/" / "?" / ":" / "@" / "&" / "=" / "+"
+ / "$" / ","
+ unreserved = alphanum / mark
+ mark = "-" / "_" / "." / "!" / "~" / "*" / "'"
+ / "(" / ")"
+ escaped = "%" HEXDIG HEXDIG
+
+ SIP header field values can be folded onto multiple lines if the
+ continuation line begins with a space or horizontal tab. All linear
+ white space, including folding, has the same semantics as SP. A
+ recipient MAY replace any linear white space with a single SP before
+ interpreting the field value or forwarding the message downstream.
+ This is intended to behave exactly as HTTP/1.1 as described in RFC
+ 2616 [8]. The SWS construct is used when linear white space is
+ optional, generally between tokens and separators.
+
+ LWS = [*WSP CRLF] 1*WSP ; linear whitespace
+ SWS = [LWS] ; sep whitespace
+
+ To separate the header name from the rest of value, a colon is used,
+ which, by the above rule, allows whitespace before, but no line
+ break, and whitespace after, including a linebreak. The HCOLON
+ defines this construct.
+
+ HCOLON = *( SP / HTAB ) ":" SWS
+
+ The TEXT-UTF8 rule is only used for descriptive field contents and
+ values that are not intended to be interpreted by the message parser.
+ Words of *TEXT-UTF8 contain characters from the UTF-8 charset (RFC
+ 2279 [7]). The TEXT-UTF8-TRIM rule is used for descriptive field
+ contents that are n t quoted strings, where leading and trailing LWS
+ is not meaningful. In this regard, SIP differs from HTTP, which uses
+ the ISO 8859-1 character set.
+
+ TEXT-UTF8-TRIM = 1*TEXT-UTF8char *(*LWS TEXT-UTF8char)
+ TEXT-UTF8char = %x21-7E / UTF8-NONASCII
+ UTF8-NONASCII = %xC0-DF 1UTF8-CONT
+ / %xE0-EF 2UTF8-CONT
+ / %xF0-F7 3UTF8-CONT
+ / %xF8-Fb 4UTF8-CONT
+ / %xFC-FD 5UTF8-CONT
+ UTF8-CONT = %x80-BF
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 220]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ A CRLF is allowed in the definition of TEXT-UTF8-TRIM only as part of
+ a header field continuation. It is expected that the folding LWS
+ will be replaced with a single SP before interpretation of the TEXT-
+ UTF8-TRIM value.
+
+ Hexadecimal numeric characters are used in several protocol elements.
+ Some elements (authentication) force hex alphas to be lower case.
+
+ LHEX = DIGIT / %x61-66 ;lowercase a-f
+
+ Many SIP header field values consist of words separated by LWS or
+ special characters. Unless otherwise stated, tokens are case-
+ insensitive. These special characters MUST be in a quoted string to
+ be used within a parameter value. The word construct is used in
+ Call-ID to allow most separators to be used.
+
+ token = 1*(alphanum / "-" / "." / "!" / "%" / "*"
+ / "_" / "+" / "`" / "'" / "~" )
+ separators = "(" / ")" / "<" / ">" / "@" /
+ "," / ";" / ":" / "\" / DQUOTE /
+ "/" / "[" / "]" / "?" / "=" /
+ "{" / "}" / SP / HTAB
+ word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
+ "_" / "+" / "`" / "'" / "~" /
+ "(" / ")" / "<" / ">" /
+ ":" / "\" / DQUOTE /
+ "/" / "[" / "]" / "?" /
+ "{" / "}" )
+
+ When tokens are used or separators are used between elements,
+ whitespace is often allowed before or after these characters:
+
+ STAR = SWS "*" SWS ; asterisk
+ SLASH = SWS "/" SWS ; slash
+ EQUAL = SWS "=" SWS ; equal
+ LPAREN = SWS "(" SWS ; left parenthesis
+ RPAREN = SWS ")" SWS ; right parenthesis
+ RAQUOT = ">" SWS ; right angle quote
+ LAQUOT = SWS "<"; left angle quote
+ COMMA = SWS "," SWS ; comma
+ SEMI = SWS ";" SWS ; semicolon
+ COLON = SWS ":" SWS ; colon
+ LDQUOT = SWS DQUOTE; open double quotation mark
+ RDQUOT = DQUOTE SWS ; close double quotation mark
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 221]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Comments can be included in some SIP header fields by surrounding the
+ comment text with parentheses. Comments are only allowed in fields
+ containing "comment" as part of their field value definition. In all
+ other fields, parentheses are considered part of the field value.
+
+ comment = LPAREN *(ctext / quoted-pair / comment) RPAREN
+ ctext = %x21-27 / %x2A-5B / %x5D-7E / UTF8-NONASCII
+ / LWS
+
+ ctext includes all chars except left and right parens and backslash.
+ A string of text is parsed as a single word if it is quoted using
+ double-quote marks. In quoted strings, quotation marks (") and
+ backslashes (\) need to be escaped.
+
+ quoted-string = SWS DQUOTE *(qdtext / quoted-pair ) DQUOTE
+ qdtext = LWS / %x21 / %x23-5B / %x5D-7E
+ / UTF8-NONASCII
+
+ The backslash character ("\") MAY be used as a single-character
+ quoting mechanism only within quoted-string and comment constructs.
+ Unlike HTTP/1.1, the characters CR and LF cannot be escaped by this
+ mechanism to avoid conflict with line folding and header separation.
+
+quoted-pair = "\" (%x00-09 / %x0B-0C
+ / %x0E-7F)
+
+SIP-URI = "sip:" [ userinfo ] hostport
+ uri-parameters [ headers ]
+SIPS-URI = "sips:" [ userinfo ] hostport
+ uri-parameters [ headers ]
+userinfo = ( user / telephone-subscriber ) [ ":" password ] "@"
+user = 1*( unreserved / escaped / user-unreserved )
+user-unreserved = "&" / "=" / "+" / "$" / "," / ";" / "?" / "/"
+password = *( unreserved / escaped /
+ "&" / "=" / "+" / "$" / "," )
+hostport = host [ ":" port ]
+host = hostname / IPv4address / IPv6reference
+hostname = *( domainlabel "." ) toplabel [ "." ]
+domainlabel = alphanum
+ / alphanum *( alphanum / "-" ) alphanum
+toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 222]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
+IPv6reference = "[" IPv6address "]"
+IPv6address = hexpart [ ":" IPv4address ]
+hexpart = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ]
+hexseq = hex4 *( ":" hex4)
+hex4 = 1*4HEXDIG
+port = 1*DIGIT
+
+ The BNF for telephone-subscriber can be found in RFC 2806 [9]. Note,
+ however, that any characters allowed there that are not allowed in
+ the user part of the SIP URI MUST be escaped.
+
+uri-parameters = *( ";" uri-parameter)
+uri-parameter = transport-param / user-param / method-param
+ / ttl-param / maddr-param / lr-param / other-param
+transport-param = "transport="
+ ( "udp" / "tcp" / "sctp" / "tls"
+ / other-transport)
+other-transport = token
+user-param = "user=" ( "phone" / "ip" / other-user)
+other-user = token
+method-param = "method=" Method
+ttl-param = "ttl=" ttl
+maddr-param = "maddr=" host
+lr-param = "lr"
+other-param = pname [ "=" pvalue ]
+pname = 1*paramchar
+pvalue = 1*paramchar
+paramchar = param-unreserved / unreserved / escaped
+param-unreserved = "[" / "]" / "/" / ":" / "&" / "+" / "$"
+
+headers = "?" header *( "&" header )
+header = hname "=" hvalue
+hname = 1*( hnv-unreserved / unreserved / escaped )
+hvalue = *( hnv-unreserved / unreserved / escaped )
+hnv-unreserved = "[" / "]" / "/" / "?" / ":" / "+" / "$"
+
+SIP-message = Request / Response
+Request = Request-Line
+ *( message-header )
+ CRLF
+ [ message-body ]
+Request-Line = Method SP Request-URI SP SIP-Version CRLF
+Request-URI = SIP-URI / SIPS-URI / absoluteURI
+absoluteURI = scheme ":" ( hier-part / opaque-part )
+hier-part = ( net-path / abs-path ) [ "?" query ]
+net-path = "//" authority [ abs-path ]
+abs-path = "/" path-segments
+
+
+
+Rosenberg, et. al. Standards Track [Page 223]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+opaque-part = uric-no-slash *uric
+uric = reserved / unreserved / escaped
+uric-no-slash = unreserved / escaped / ";" / "?" / ":" / "@"
+ / "&" / "=" / "+" / "$" / ","
+path-segments = segment *( "/" segment )
+segment = *pchar *( ";" param )
+param = *pchar
+pchar = unreserved / escaped /
+ ":" / "@" / "&" / "=" / "+" / "$" / ","
+scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+authority = srvr / reg-name
+srvr = [ [ userinfo "@" ] hostport ]
+reg-name = 1*( unreserved / escaped / "$" / ","
+ / ";" / ":" / "@" / "&" / "=" / "+" )
+query = *uric
+SIP-Version = "SIP" "/" 1*DIGIT "." 1*DIGIT
+
+message-header = (Accept
+ / Accept-Encoding
+ / Accept-Language
+ / Alert-Info
+ / Allow
+ / Authentication-Info
+ / Authorization
+ / Call-ID
+ / Call-Info
+ / Contact
+ / Content-Disposition
+ / Content-Encoding
+ / Content-Language
+ / Content-Length
+ / Content-Type
+ / CSeq
+ / Date
+ / Error-Info
+ / Expires
+ / From
+ / In-Reply-To
+ / Max-Forwards
+ / MIME-Version
+ / Min-Expires
+ / Organization
+ / Priority
+ / Proxy-Authenticate
+ / Proxy-Authorization
+ / Proxy-Require
+ / Record-Route
+ / Reply-To
+
+
+
+Rosenberg, et. al. Standards Track [Page 224]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ / Require
+ / Retry-After
+ / Route
+ / Server
+ / Subject
+ / Supported
+ / Timestamp
+ / To
+ / Unsupported
+ / User-Agent
+ / Via
+ / Warning
+ / WWW-Authenticate
+ / extension-header) CRLF
+
+INVITEm = %x49.4E.56.49.54.45 ; INVITE in caps
+ACKm = %x41.43.4B ; ACK in caps
+OPTIONSm = %x4F.50.54.49.4F.4E.53 ; OPTIONS in caps
+BYEm = %x42.59.45 ; BYE in caps
+CANCELm = %x43.41.4E.43.45.4C ; CANCEL in caps
+REGISTERm = %x52.45.47.49.53.54.45.52 ; REGISTER in caps
+Method = INVITEm / ACKm / OPTIONSm / BYEm
+ / CANCELm / REGISTERm
+ / extension-method
+extension-method = token
+Response = Status-Line
+ *( message-header )
+ CRLF
+ [ message-body ]
+
+Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
+Status-Code = Informational
+ / Redirection
+ / Success
+ / Client-Error
+ / Server-Error
+ / Global-Failure
+ / extension-code
+extension-code = 3DIGIT
+Reason-Phrase = *(reserved / unreserved / escaped
+ / UTF8-NONASCII / UTF8-CONT / SP / HTAB)
+
+Informational = "100" ; Trying
+ / "180" ; Ringing
+ / "181" ; Call Is Being Forwarded
+ / "182" ; Queued
+ / "183" ; Session Progress
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 225]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Success = "200" ; OK
+
+Redirection = "300" ; Multiple Choices
+ / "301" ; Moved Permanently
+ / "302" ; Moved Temporarily
+ / "305" ; Use Proxy
+ / "380" ; Alternative Service
+
+Client-Error = "400" ; Bad Request
+ / "401" ; Unauthorized
+ / "402" ; Payment Required
+ / "403" ; Forbidden
+ / "404" ; Not Found
+ / "405" ; Method Not Allowed
+ / "406" ; Not Acceptable
+ / "407" ; Proxy Authentication Required
+ / "408" ; Request Timeout
+ / "410" ; Gone
+ / "413" ; Request Entity Too Large
+ / "414" ; Request-URI Too Large
+ / "415" ; Unsupported Media Type
+ / "416" ; Unsupported URI Scheme
+ / "420" ; Bad Extension
+ / "421" ; Extension Required
+ / "423" ; Interval Too Brief
+ / "480" ; Temporarily not available
+ / "481" ; Call Leg/Transaction Does Not Exist
+ / "482" ; Loop Detected
+ / "483" ; Too Many Hops
+ / "484" ; Address Incomplete
+ / "485" ; Ambiguous
+ / "486" ; Busy Here
+ / "487" ; Request Terminated
+ / "488" ; Not Acceptable Here
+ / "491" ; Request Pending
+ / "493" ; Undecipherable
+
+Server-Error = "500" ; Internal Server Error
+ / "501" ; Not Implemented
+ / "502" ; Bad Gateway
+ / "503" ; Service Unavailable
+ / "504" ; Server Time-out
+ / "505" ; SIP Version not supported
+ / "513" ; Message Too Large
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 226]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Global-Failure = "600" ; Busy Everywhere
+ / "603" ; Decline
+ / "604" ; Does not exist anywhere
+ / "606" ; Not Acceptable
+
+Accept = "Accept" HCOLON
+ [ accept-range *(COMMA accept-range) ]
+accept-range = media-range *(SEMI accept-param)
+media-range = ( "*/*"
+ / ( m-type SLASH "*" )
+ / ( m-type SLASH m-subtype )
+ ) *( SEMI m-parameter )
+accept-param = ("q" EQUAL qvalue) / generic-param
+qvalue = ( "0" [ "." 0*3DIGIT ] )
+ / ( "1" [ "." 0*3("0") ] )
+generic-param = token [ EQUAL gen-value ]
+gen-value = token / host / quoted-string
+
+Accept-Encoding = "Accept-Encoding" HCOLON
+ [ encoding *(COMMA encoding) ]
+encoding = codings *(SEMI accept-param)
+codings = content-coding / "*"
+content-coding = token
+
+Accept-Language = "Accept-Language" HCOLON
+ [ language *(COMMA language) ]
+language = language-range *(SEMI accept-param)
+language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*" )
+
+Alert-Info = "Alert-Info" HCOLON alert-param *(COMMA alert-param)
+alert-param = LAQUOT absoluteURI RAQUOT *( SEMI generic-param )
+
+Allow = "Allow" HCOLON [Method *(COMMA Method)]
+
+Authorization = "Authorization" HCOLON credentials
+credentials = ("Digest" LWS digest-response)
+ / other-response
+digest-response = dig-resp *(COMMA dig-resp)
+dig-resp = username / realm / nonce / digest-uri
+ / dresponse / algorithm / cnonce
+ / opaque / message-qop
+ / nonce-count / auth-param
+username = "username" EQUAL username-value
+username-value = quoted-string
+digest-uri = "uri" EQUAL LDQUOT digest-uri-value RDQUOT
+digest-uri-value = rquest-uri ; Equal to request-uri as specified
+ by HTTP/1.1
+message-qop = "qop" EQUAL qop-value
+
+
+
+Rosenberg, et. al. Standards Track [Page 227]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+cnonce = "cnonce" EQUAL cnonce-value
+cnonce-value = nonce-value
+nonce-count = "nc" EQUAL nc-value
+nc-value = 8LHEX
+dresponse = "response" EQUAL request-digest
+request-digest = LDQUOT 32LHEX RDQUOT
+auth-param = auth-param-name EQUAL
+ ( token / quoted-string )
+auth-param-name = token
+other-response = auth-scheme LWS auth-param
+ *(COMMA auth-param)
+auth-scheme = token
+
+Authentication-Info = "Authentication-Info" HCOLON ainfo
+ *(COMMA ainfo)
+ainfo = nextnonce / message-qop
+ / response-auth / cnonce
+ / nonce-count
+nextnonce = "nextnonce" EQUAL nonce-value
+response-auth = "rspauth" EQUAL response-digest
+response-digest = LDQUOT *LHEX RDQUOT
+
+Call-ID = ( "Call-ID" / "i" ) HCOLON callid
+callid = word [ "@" word ]
+
+Call-Info = "Call-Info" HCOLON info *(COMMA info)
+info = LAQUOT absoluteURI RAQUOT *( SEMI info-param)
+info-param = ( "purpose" EQUAL ( "icon" / "info"
+ / "card" / token ) ) / generic-param
+
+Contact = ("Contact" / "m" ) HCOLON
+ ( STAR / (contact-param *(COMMA contact-param)))
+contact-param = (name-addr / addr-spec) *(SEMI contact-params)
+name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
+addr-spec = SIP-URI / SIPS-URI / absoluteURI
+display-name = *(token LWS)/ quoted-string
+
+contact-params = c-p-q / c-p-expires
+ / contact-extension
+c-p-q = "q" EQUAL qvalue
+c-p-expires = "expires" EQUAL delta-seconds
+contact-extension = generic-param
+delta-seconds = 1*DIGIT
+
+Content-Disposition = "Content-Disposition" HCOLON
+ disp-type *( SEMI disp-param )
+disp-type = "render" / "session" / "icon" / "alert"
+ / disp-extension-token
+
+
+
+Rosenberg, et. al. Standards Track [Page 228]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+disp-param = handling-param / generic-param
+handling-param = "handling" EQUAL
+ ( "optional" / "required"
+ / other-handling )
+other-handling = token
+disp-extension-token = token
+
+Content-Encoding = ( "Content-Encoding" / "e" ) HCOLON
+ content-coding *(COMMA content-coding)
+
+Content-Language = "Content-Language" HCOLON
+ language-tag *(COMMA language-tag)
+language-tag = primary-tag *( "-" subtag )
+primary-tag = 1*8ALPHA
+subtag = 1*8ALPHA
+
+Content-Length = ( "Content-Length" / "l" ) HCOLON 1*DIGIT
+Content-Type = ( "Content-Type" / "c" ) HCOLON media-type
+media-type = m-type SLASH m-subtype *(SEMI m-parameter)
+m-type = discrete-type / composite-type
+discrete-type = "text" / "image" / "audio" / "video"
+ / "application" / extension-token
+composite-type = "message" / "multipart" / extension-token
+extension-token = ietf-token / x-token
+ietf-token = token
+x-token = "x-" token
+m-subtype = extension-token / iana-token
+iana-token = token
+m-parameter = m-attribute EQUAL m-value
+m-attribute = token
+m-value = token / quoted-string
+
+CSeq = "CSeq" HCOLON 1*DIGIT LWS Method
+
+Date = "Date" HCOLON SIP-date
+SIP-date = rfc1123-date
+rfc1123-date = wkday "," SP date1 SP time SP "GMT"
+date1 = 2DIGIT SP month SP 4DIGIT
+ ; day month year (e.g., 02 Jun 1982)
+time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
+ ; 00:00:00 - 23:59:59
+wkday = "Mon" / "Tue" / "Wed"
+ / "Thu" / "Fri" / "Sat" / "Sun"
+month = "Jan" / "Feb" / "Mar" / "Apr"
+ / "May" / "Jun" / "Jul" / "Aug"
+ / "Sep" / "Oct" / "Nov" / "Dec"
+
+Error-Info = "Error-Info" HCOLON error-uri *(COMMA error-uri)
+
+
+
+Rosenberg, et. al. Standards Track [Page 229]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+error-uri = LAQUOT absoluteURI RAQUOT *( SEMI generic-param )
+
+Expires = "Expires" HCOLON delta-seconds
+From = ( "From" / "f" ) HCOLON from-spec
+from-spec = ( name-addr / addr-spec )
+ *( SEMI from-param )
+from-param = tag-param / generic-param
+tag-param = "tag" EQUAL token
+
+In-Reply-To = "In-Reply-To" HCOLON callid *(COMMA callid)
+
+Max-Forwards = "Max-Forwards" HCOLON 1*DIGIT
+
+MIME-Version = "MIME-Version" HCOLON 1*DIGIT "." 1*DIGIT
+
+Min-Expires = "Min-Expires" HCOLON delta-seconds
+
+Organization = "Organization" HCOLON [TEXT-UTF8-TRIM]
+
+Priority = "Priority" HCOLON priority-value
+priority-value = "emergency" / "urgent" / "normal"
+ / "non-urgent" / other-priority
+other-priority = token
+
+Proxy-Authenticate = "Proxy-Authenticate" HCOLON challenge
+challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
+ / other-challenge
+other-challenge = auth-scheme LWS auth-param
+ *(COMMA auth-param)
+digest-cln = realm / domain / nonce
+ / opaque / stale / algorithm
+ / qop-options / auth-param
+realm = "realm" EQUAL realm-value
+realm-value = quoted-string
+domain = "domain" EQUAL LDQUOT URI
+ *( 1*SP URI ) RDQUOT
+URI = absoluteURI / abs-path
+nonce = "nonce" EQUAL nonce-value
+nonce-value = quoted-string
+opaque = "opaque" EQUAL quoted-string
+stale = "stale" EQUAL ( "true" / "false" )
+algorithm = "algorithm" EQUAL ( "MD5" / "MD5-sess"
+ / token )
+qop-options = "qop" EQUAL LDQUOT qop-value
+ *("," qop-value) RDQUOT
+qop-value = "auth" / "auth-int" / token
+
+Proxy-Authorization = "Proxy-Authorization" HCOLON credentials
+
+
+
+Rosenberg, et. al. Standards Track [Page 230]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Proxy-Require = "Proxy-Require" HCOLON option-tag
+ *(COMMA option-tag)
+option-tag = token
+
+Record-Route = "Record-Route" HCOLON rec-route *(COMMA rec-route)
+rec-route = name-addr *( SEMI rr-param )
+rr-param = generic-param
+
+Reply-To = "Reply-To" HCOLON rplyto-spec
+rplyto-spec = ( name-addr / addr-spec )
+ *( SEMI rplyto-param )
+rplyto-param = generic-param
+Require = "Require" HCOLON option-tag *(COMMA option-tag)
+
+Retry-After = "Retry-After" HCOLON delta-seconds
+ [ comment ] *( SEMI retry-param )
+
+retry-param = ("duration" EQUAL delta-seconds)
+ / generic-param
+
+Route = "Route" HCOLON route-param *(COMMA route-param)
+route-param = name-addr *( SEMI rr-param )
+
+Server = "Server" HCOLON server-val *(LWS server-val)
+server-val = product / comment
+product = token [SLASH product-version]
+product-version = token
+
+Subject = ( "Subject" / "s" ) HCOLON [TEXT-UTF8-TRIM]
+
+Supported = ( "Supported" / "k" ) HCOLON
+ [option-tag *(COMMA option-tag)]
+
+Timestamp = "Timestamp" HCOLON 1*(DIGIT)
+ [ "." *(DIGIT) ] [ LWS delay ]
+delay = *(DIGIT) [ "." *(DIGIT) ]
+
+To = ( "To" / "t" ) HCOLON ( name-addr
+ / addr-spec ) *( SEMI to-param )
+to-param = tag-param / generic-param
+
+Unsupported = "Unsupported" HCOLON option-tag *(COMMA option-tag)
+User-Agent = "User-Agent" HCOLON server-val *(LWS server-val)
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 231]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
+via-parm = sent-protocol LWS sent-by *( SEMI via-params )
+via-params = via-ttl / via-maddr
+ / via-received / via-branch
+ / via-extension
+via-ttl = "ttl" EQUAL ttl
+via-maddr = "maddr" EQUAL host
+via-received = "received" EQUAL (IPv4address / IPv6address)
+via-branch = "branch" EQUAL token
+via-extension = generic-param
+sent-protocol = protocol-name SLASH protocol-version
+ SLASH transport
+protocol-name = "SIP" / token
+protocol-version = token
+transport = "UDP" / "TCP" / "TLS" / "SCTP"
+ / other-transport
+sent-by = host [ COLON port ]
+ttl = 1*3DIGIT ; 0 to 255
+
+Warning = "Warning" HCOLON warning-value *(COMMA warning-value)
+warning-value = warn-code SP warn-agent SP warn-text
+warn-code = 3DIGIT
+warn-agent = hostport / pseudonym
+ ; the name or pseudonym of the server adding
+ ; the Warning header, for use in debugging
+warn-text = quoted-string
+pseudonym = token
+
+WWW-Authenticate = "WWW-Authenticate" HCOLON challenge
+
+extension-header = header-name HCOLON header-value
+header-name = token
+header-value = *(TEXT-UTF8char / UTF8-CONT / LWS)
+message-body = *OCTET
+
+26 Security Considerations: Threat Model and Security Usage
+ Recommendations
+
+ SIP is not an easy protocol to secure. Its use of intermediaries,
+ its multi-faceted trust relationships, its expected usage between
+ elements with no trust at all, and its user-to-user operation make
+ security far from trivial. Security solutions are needed that are
+ deployable today, without extensive coordination, in a wide variety
+ of environments and usages. In order to meet these diverse needs,
+ several distinct mechanisms applicable to different aspects and
+ usages of SIP will be required.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 232]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Note that the security of SIP signaling itself has no bearing on the
+ security of protocols used in concert with SIP such as RTP, or with
+ the security implications of any specific bodies SIP might carry
+ (although MIME security plays a substantial role in securing SIP).
+ Any media associated with a session can be encrypted end-to-end
+ independently of any associated SIP signaling. Media encryption is
+ outside the scope of this document.
+
+ The considerations that follow first examine a set of classic threat
+ models that broadly identify the security needs of SIP. The set of
+ security services required to address these threats is then detailed,
+ followed by an explanation of several security mechanisms that can be
+ used to provide these services. Next, the requirements for
+ implementers of SIP are enumerated, along with exemplary deployments
+ in which these security mechanisms could be used to improve the
+ security of SIP. Some notes on privacy conclude this section.
+
+26.1 Attacks and Threat Models
+
+ This section details some threats that should be common to most
+ deployments of SIP. These threats have been chosen specifically to
+ illustrate each of the security services that SIP requires.
+
+ The following examples by no means provide an exhaustive list of the
+ threats against SIP; rather, these are "classic" threats that
+ demonstrate the need for particular security services that can
+ potentially prevent whole categories of threats.
+
+ These attacks assume an environment in which attackers can
+ potentially read any packet on the network - it is anticipated that
+ SIP will frequently be used on the public Internet. Attackers on the
+ network may be able to modify packets (perhaps at some compromised
+ intermediary). Attackers may wish to steal services, eavesdrop on
+ communications, or disrupt sessions.
+
+26.1.1 Registration Hijacking
+
+ The SIP registration mechanism allows a user agent to identify itself
+ to a registrar as a device at which a user (designated by an address
+ of record) is located. A registrar assesses the identity asserted in
+ the From header field of a REGISTER message to determine whether this
+ request can modify the contact addresses associated with the
+ address-of-record in the To header field. While these two fields are
+ frequently the same, there are many valid deployments in which a
+ third-party may register contacts on a user's behalf.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 233]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The From header field of a SIP request, however, can be modified
+ arbitrarily by the owner of a UA, and this opens the door to
+ malicious registrations. An attacker that successfully impersonates
+ a party authorized to change contacts associated with an address-of-
+ record could, for example, de-register all existing contacts for a
+ URI and then register their own device as the appropriate contact
+ address, thereby directing all requests for the affected user to the
+ attacker's device.
+
+ This threat belongs to a family of threats that rely on the absence
+ of cryptographic assurance of a request's originator. Any SIP UAS
+ that represents a valuable service (a gateway that interworks SIP
+ requests with traditional telephone calls, for example) might want to
+ control access to its resources by authenticating requests that it
+ receives. Even end-user UAs, for example SIP phones, have an
+ interest in ascertaining the identities of originators of requests.
+
+ This threat demonstrates the need for security services that enable
+ SIP entities to authenticate the originators of requests.
+
+26.1.2 Impersonating a Server
+
+ The domain to which a request is destined is generally specified in
+ the Request-URI. UAs commonly contact a server in this domain
+ directly in order to deliver a request. However, there is always a
+ possibility that an attacker could impersonate the remote server, and
+ that the UA's request could be intercepted by some other party.
+
+ For example, consider a case in which a redirect server at one
+ domain, chicago.com, impersonates a redirect server at another
+ domain, biloxi.com. A user agent sends a request to biloxi.com, but
+ the redirect server at chicago.com answers with a forged response
+ that has appropriate SIP header fields for a response from
+ biloxi.com. The forged contact addresses in the redirection response
+ could direct the originating UA to inappropriate or insecure
+ resources, or simply prevent requests for biloxi.com from succeeding.
+
+ This family of threats has a vast membership, many of which are
+ critical. As a converse to the registration hijacking threat,
+ consider the case in which a registration sent to biloxi.com is
+ intercepted by chicago.com, which replies to the intercepted
+ registration with a forged 301 (Moved Permanently) response. This
+ response might seem to come from biloxi.com yet designate chicago.com
+ as the appropriate registrar. All future REGISTER requests from the
+ originating UA would then go to chicago.com.
+
+ Prevention of this threat requires a means by which UAs can
+ authenticate the servers to whom they send requests.
+
+
+
+Rosenberg, et. al. Standards Track [Page 234]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+26.1.3 Tampering with Message Bodies
+
+ As a matter of course, SIP UAs route requests through trusted proxy
+ servers. Regardless of how that trust is established (authentication
+ of proxies is discussed elsewhere in this section), a UA may trust a
+ proxy server to route a request, but not to inspect or possibly
+ modify the bodies contained in that request.
+
+ Consider a UA that is using SIP message bodies to communicate session
+ encryption keys for a media session. Although it trusts the proxy
+ server of the domain it is contacting to deliver signaling properly,
+ it may not want the administrators of that domain to be capable of
+ decrypting any subsequent media session. Worse yet, if the proxy
+ server were actively malicious, it could modify the session key,
+ either acting as a man-in-the-middle, or perhaps changing the
+ security characteristics requested by the originating UA.
+
+ This family of threats applies not only to session keys, but to most
+ conceivable forms of content carried end-to-end in SIP. These might
+ include MIME bodies that should be rendered to the user, SDP, or
+ encapsulated telephony signals, among others. Attackers might
+ attempt to modify SDP bodies, for example, in order to point RTP
+ media streams to a wiretapping device in order to eavesdrop on
+ subsequent voice communications.
+
+ Also note that some header fields in SIP are meaningful end-to-end,
+ for example, Subject. UAs might be protective of these header fields
+ as well as bodies (a malicious intermediary changing the Subject
+ header field might make an important request appear to be spam, for
+ example). However, since many header fields are legitimately
+ inspected or altered by proxy servers as a request is routed, not all
+ header fields should be secured end-to-end.
+
+ For these reasons, the UA might want to secure SIP message bodies,
+ and in some limited cases header fields, end-to-end. The security
+ services required for bodies include confidentiality, integrity, and
+ authentication. These end-to-end services should be independent of
+ the means used to secure interactions with intermediaries such as
+ proxy servers.
+
+26.1.4 Tearing Down Sessions
+
+ Once a dialog has been established by initial messaging, subsequent
+ requests can be sent that modify the state of the dialog and/or
+ session. It is critical that principals in a session can be certain
+ that such requests are not forged by attackers.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 235]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Consider a case in which a third-party attacker captures some initial
+ messages in a dialog shared by two parties in order to learn the
+ parameters of the session (To tag, From tag, and so forth) and then
+ inserts a BYE request into the session. The attacker could opt to
+ forge the request such that it seemed to come from either
+ participant. Once the BYE is received by its target, the session
+ will be torn down prematurely.
+
+ Similar mid-session threats include the transmission of forged re-
+ INVITEs that alter the session (possibly to reduce session security
+ or redirect media streams as part of a wiretapping attack).
+
+ The most effective countermeasure to this threat is the
+ authentication of the sender of the BYE. In this instance, the
+ recipient needs only know that the BYE came from the same party with
+ whom the corresponding dialog was established (as opposed to
+ ascertaining the absolute identity of the sender). Also, if the
+ attacker is unable to learn the parameters of the session due to
+ confidentiality, it would not be possible to forge the BYE. However,
+ some intermediaries (like proxy servers) will need to inspect those
+ parameters as the session is established.
+
+26.1.5 Denial of Service and Amplification
+
+ Denial-of-service attacks focus on rendering a particular network
+ element unavailable, usually by directing an excessive amount of
+ network traffic at its interfaces. A distributed denial-of-service
+ attack allows one network user to cause multiple network hosts to
+ flood a target host with a large amount of network traffic.
+
+ In many architectures, SIP proxy servers face the public Internet in
+ order to accept requests from worldwide IP endpoints. SIP creates a
+ number of potential opportunities for distributed denial-of-service
+ attacks that must be recognized and addressed by the implementers and
+ operators of SIP systems.
+
+ Attackers can create bogus requests that contain a falsified source
+ IP address and a corresponding Via header field that identify a
+ targeted host as the originator of the request and then send this
+ request to a large number of SIP network elements, thereby using
+ hapless SIP UAs or proxies to generate denial-of-service traffic
+ aimed at the target.
+
+ Similarly, attackers might use falsified Route header field values in
+ a request that identify the target host and then send such messages
+ to forking proxies that will amplify messaging sent to the target.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 236]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Record-Route could be used to similar effect when the attacker is
+ certain that the SIP dialog initiated by the request will result in
+ numerous transactions originating in the backwards direction.
+
+ A number of denial-of-service attacks open up if REGISTER requests
+ are not properly authenticated and authorized by registrars.
+ Attackers could de-register some or all users in an administrative
+ domain, thereby preventing these users from being invited to new
+ sessions. An attacker could also register a large number of contacts
+ designating the same host for a given address-of-record in order to
+ use the registrar and any associated proxy servers as amplifiers in a
+ denial-of-service attack. Attackers might also attempt to deplete
+ available memory and disk resources of a registrar by registering
+ huge numbers of bindings.
+
+ The use of multicast to transmit SIP requests can greatly increase
+ the potential for denial-of-service attacks.
+
+ These problems demonstrate a general need to define architectures
+ that minimize the risks of denial-of-service, and the need to be
+ mindful in recommendations for security mechanisms of this class of
+ attacks.
+
+26.2 Security Mechanisms
+
+ From the threats described above, we gather that the fundamental
+ security services required for the SIP protocol are: preserving the
+ confidentiality and integrity of messaging, preventing replay attacks
+ or message spoofing, providing for the authentication and privacy of
+ the participants in a session, and preventing denial-of-service
+ attacks. Bodies within SIP messages separately require the security
+ services of confidentiality, integrity, and authentication.
+
+ Rather than defining new security mechanisms specific to SIP, SIP
+ reuses wherever possible existing security models derived from the
+ HTTP and SMTP space.
+
+ Full encryption of messages provides the best means to preserve the
+ confidentiality of signaling - it can also guarantee that messages
+ are not modified by any malicious intermediaries. However, SIP
+ requests and responses cannot be naively encrypted end-to-end in
+ their entirety because message fields such as the Request-URI, Route,
+ and Via need to be visible to proxies in most network architectures
+ so that SIP requests are routed correctly. Note that proxy servers
+ need to modify some features of messages as well (such as adding Via
+ header field values) in order for SIP to function. Proxy servers
+ must therefore be trusted, to some degree, by SIP UAs. To this
+ purpose, low-layer security mechanisms for SIP are recommended, which
+
+
+
+Rosenberg, et. al. Standards Track [Page 237]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ encrypt the entire SIP requests or responses on the wire on a hop-
+ by-hop basis, and that allow endpoints to verify the identity of
+ proxy servers to whom they send requests.
+
+ SIP entities also have a need to identify one another in a secure
+ fashion. When a SIP endpoint asserts the identity of its user to a
+ peer UA or to a proxy server, that identity should in some way be
+ verifiable. A cryptographic authentication mechanism is provided in
+ SIP to address this requirement.
+
+ An independent security mechanism for SIP message bodies supplies an
+ alternative means of end-to-end mutual authentication, as well as
+ providing a limit on the degree to which user agents must trust
+ intermediaries.
+
+26.2.1 Transport and Network Layer Security
+
+ Transport or network layer security encrypts signaling traffic,
+ guaranteeing message confidentiality and integrity.
+
+ Oftentimes, certificates are used in the establishment of lower-layer
+ security, and these certificates can also be used to provide a means
+ of authentication in many architectures.
+
+ Two popular alternatives for providing security at the transport and
+ network layer are, respectively, TLS [25] and IPSec [26].
+
+ IPSec is a set of network-layer protocol tools that collectively can
+ be used as a secure replacement for traditional IP (Internet
+ Protocol). IPSec is most commonly used in architectures in which a
+ set of hosts or administrative domains have an existing trust
+ relationship with one another. IPSec is usually implemented at the
+ operating system level in a host, or on a security gateway that
+ provides confidentiality and integrity for all traffic it receives
+ from a particular interface (as in a VPN architecture). IPSec can
+ also be used on a hop-by-hop basis.
+
+ In many architectures IPSec does not require integration with SIP
+ applications; IPSec is perhaps best suited to deployments in which
+ adding security directly to SIP hosts would be arduous. UAs that
+ have a pre-shared keying relationship with their first-hop proxy
+ server are also good candidates to use IPSec. Any deployment of
+ IPSec for SIP would require an IPSec profile describing the protocol
+ tools that would be required to secure SIP. No such profile is given
+ in this document.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 238]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ TLS provides transport-layer security over connection-oriented
+ protocols (for the purposes of this document, TCP); "tls" (signifying
+ TLS over TCP) can be specified as the desired transport protocol
+ within a Via header field value or a SIP-URI. TLS is most suited to
+ architectures in which hop-by-hop security is required between hosts
+ with no pre-existing trust association. For example, Alice trusts
+ her local proxy server, which after a certificate exchange decides to
+ trust Bob's local proxy server, which Bob trusts, hence Bob and Alice
+ can communicate securely.
+
+ TLS must be tightly coupled with a SIP application. Note that
+ transport mechanisms are specified on a hop-by-hop basis in SIP, thus
+ a UA that sends requests over TLS to a proxy server has no assurance
+ that TLS will be used end-to-end.
+
+ The TLS_RSA_WITH_AES_128_CBC_SHA ciphersuite [6] MUST be supported at
+ a minimum by implementers when TLS is used in a SIP application. For
+ purposes of backwards compatibility, proxy servers, redirect servers,
+ and registrars SHOULD support TLS_RSA_WITH_3DES_EDE_CBC_SHA.
+ Implementers MAY also support any other ciphersuite.
+
+26.2.2 SIPS URI Scheme
+
+ The SIPS URI scheme adheres to the syntax of the SIP URI (described
+ in 19), although the scheme string is "sips" rather than "sip". The
+ semantics of SIPS are very different from the SIP URI, however. SIPS
+ allows resources to specify that they should be reached securely.
+
+ A SIPS URI can be used as an address-of-record for a particular user
+ - the URI by which the user is canonically known (on their business
+ cards, in the From header field of their requests, in the To header
+ field of REGISTER requests). When used as the Request-URI of a
+ request, the SIPS scheme signifies that each hop over which the
+ request is forwarded, until the request reaches the SIP entity
+ responsible for the domain portion of the Request-URI, must be
+ secured with TLS; once it reaches the domain in question it is
+ handled in accordance with local security and routing policy, quite
+ possibly using TLS for any last hop to a UAS. When used by the
+ originator of a request (as would be the case if they employed a SIPS
+ URI as the address-of-record of the target), SIPS dictates that the
+ entire request path to the target domain be so secured.
+
+ The SIPS scheme is applicable to many of the other ways in which SIP
+ URIs are used in SIP today in addition to the Request-URI, including
+ in addresses-of-record, contact addresses (the contents of Contact
+ headers, including those of REGISTER methods), and Route headers. In
+ each instance, the SIPS URI scheme allows these existing fields to
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 239]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ designate secure resources. The manner in which a SIPS URI is
+ dereferenced in any of these contexts has its own security properties
+ which are detailed in [4].
+
+ The use of SIPS in particular entails that mutual TLS authentication
+ SHOULD be employed, as SHOULD the ciphersuite
+ TLS_RSA_WITH_AES_128_CBC_SHA. Certificates received in the
+ authentication process SHOULD be validated with root certificates
+ held by the client; failure to validate a certificate SHOULD result
+ in the failure of the request.
+
+ Note that in the SIPS URI scheme, transport is independent of TLS,
+ and thus "sips:alice@atlanta.com;transport=tcp" and
+ "sips:alice@atlanta.com;transport=sctp" are both valid (although
+ note that UDP is not a valid transport for SIPS). The use of
+ "transport=tls" has consequently been deprecated, partly because
+ it was specific to a single hop of the request. This is a change
+ since RFC 2543.
+
+ Users that distribute a SIPS URI as an address-of-record may elect to
+ operate devices that refuse requests over insecure transports.
+
+26.2.3 HTTP Authentication
+
+ SIP provides a challenge capability, based on HTTP authentication,
+ that relies on the 401 and 407 response codes as well as header
+ fields for carrying challenges and credentials. Without significant
+ modification, the reuse of the HTTP Digest authentication scheme in
+ SIP allows for replay protection and one-way authentication.
+
+ The usage of Digest authentication in SIP is detailed in Section 22.
+
+26.2.4 S/MIME
+
+ As is discussed above, encrypting entire SIP messages end-to-end for
+ the purpose of confidentiality is not appropriate because network
+ intermediaries (like proxy servers) need to view certain header
+ fields in order to route messages correctly, and if these
+ intermediaries are excluded from security associations, then SIP
+ messages will essentially be non-routable.
+
+ However, S/MIME allows SIP UAs to encrypt MIME bodies within SIP,
+ securing these bodies end-to-end without affecting message headers.
+ S/MIME can provide end-to-end confidentiality and integrity for
+ message bodies, as well as mutual authentication. It is also
+ possible to use S/MIME to provide a form of integrity and
+ confidentiality for SIP header fields through SIP message tunneling.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 240]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The usage of S/MIME in SIP is detailed in Section 23.
+
+26.3 Implementing Security Mechanisms
+
+26.3.1 Requirements for Implementers of SIP
+
+ Proxy servers, redirect servers, and registrars MUST implement TLS,
+ and MUST support both mutual and one-way authentication. It is
+ strongly RECOMMENDED that UAs be capable initiating TLS; UAs MAY also
+ be capable of acting as a TLS server. Proxy servers, redirect
+ servers, and registrars SHOULD possess a site certificate whose
+ subject corresponds to their canonical hostname. UAs MAY have
+ certificates of their own for mutual authentication with TLS, but no
+ provisions are set forth in this document for their use. All SIP
+ elements that support TLS MUST have a mechanism for validating
+ certificates received during TLS negotiation; this entails possession
+ of one or more root certificates issued by certificate authorities
+ (preferably well-known distributors of site certificates comparable
+ to those that issue root certificates for web browsers).
+
+ All SIP elements that support TLS MUST also support the SIPS URI
+ scheme.
+
+ Proxy servers, redirect servers, registrars, and UAs MAY also
+ implement IPSec or other lower-layer security protocols.
+
+ When a UA attempts to contact a proxy server, redirect server, or
+ registrar, the UAC SHOULD initiate a TLS connection over which it
+ will send SIP messages. In some architectures, UASs MAY receive
+ requests over such TLS connections as well.
+
+ Proxy servers, redirect servers, registrars, and UAs MUST implement
+ Digest Authorization, encompassing all of the aspects required in 22.
+ Proxy servers, redirect servers, and registrars SHOULD be configured
+ with at least one Digest realm, and at least one "realm" string
+ supported by a given server SHOULD correspond to the server's
+ hostname or domainname.
+
+ UAs MAY support the signing and encrypting of MIME bodies, and
+ transference of credentials with S/MIME as described in Section 23.
+ If a UA holds one or more root certificates of certificate
+ authorities in order to validate certificates for TLS or IPSec, it
+ SHOULD be capable of reusing these to verify S/MIME certificates, as
+ appropriate. A UA MAY hold root certificates specifically for
+ validating S/MIME certificates.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 241]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Note that is it anticipated that future security extensions may
+ upgrade the normative strength associated with S/MIME as S/MIME
+ implementations appear and the problem space becomes better
+ understood.
+
+26.3.2 Security Solutions
+
+ The operation of these security mechanisms in concert can follow the
+ existing web and email security models to some degree. At a high
+ level, UAs authenticate themselves to servers (proxy servers,
+ redirect servers, and registrars) with a Digest username and
+ password; servers authenticate themselves to UAs one hop away, or to
+ another server one hop away (and vice versa), with a site certificate
+ delivered by TLS.
+
+ On a peer-to-peer level, UAs trust the network to authenticate one
+ another ordinarily; however, S/MIME can also be used to provide
+ direct authentication when the network does not, or if the network
+ itself is not trusted.
+
+ The following is an illustrative example in which these security
+ mechanisms are used by various UAs and servers to prevent the sorts
+ of threats described in Section 26.1. While implementers and network
+ administrators MAY follow the normative guidelines given in the
+ remainder of this section, these are provided only as example
+ implementations.
+
+26.3.2.1 Registration
+
+ When a UA comes online and registers with its local administrative
+ domain, it SHOULD establish a TLS connection with its registrar
+ (Section 10 describes how the UA reaches its registrar). The
+ registrar SHOULD offer a certificate to the UA, and the site
+ identified by the certificate MUST correspond with the domain in
+ which the UA intends to register; for example, if the UA intends to
+ register the address-of-record 'alice@atlanta.com', the site
+ certificate must identify a host within the atlanta.com domain (such
+ as sip.atlanta.com). When it receives the TLS Certificate message,
+ the UA SHOULD verify the certificate and inspect the site identified
+ by the certificate. If the certificate is invalid, revoked, or if it
+ does not identify the appropriate party, the UA MUST NOT send the
+ REGISTER message and otherwise proceed with the registration.
+
+ When a valid certificate has been provided by the registrar, the
+ UA knows that the registrar is not an attacker who might redirect
+ the UA, steal passwords, or attempt any similar attacks.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 242]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The UA then creates a REGISTER request that SHOULD be addressed to a
+ Request-URI corresponding to the site certificate received from the
+ registrar. When the UA sends the REGISTER request over the existing
+ TLS connection, the registrar SHOULD challenge the request with a 401
+ (Proxy Authentication Required) response. The "realm" parameter
+ within the Proxy-Authenticate header field of the response SHOULD
+ correspond to the domain previously given by the site certificate.
+ When the UAC receives the challenge, it SHOULD either prompt the user
+ for credentials or take an appropriate credential from a keyring
+ corresponding to the "realm" parameter in the challenge. The
+ username of this credential SHOULD correspond with the "userinfo"
+ portion of the URI in the To header field of the REGISTER request.
+ Once the Digest credentials have been inserted into an appropriate
+ Proxy-Authorization header field, the REGISTER should be resubmitted
+ to the registrar.
+
+ Since the registrar requires the user agent to authenticate
+ itself, it would be difficult for an attacker to forge REGISTER
+ requests for the user's address-of-record. Also note that since
+ the REGISTER is sent over a confidential TLS connection, attackers
+ will not be able to intercept the REGISTER to record credentials
+ for any possible replay attack.
+
+ Once the registration has been accepted by the registrar, the UA
+ SHOULD leave this TLS connection open provided that the registrar
+ also acts as the proxy server to which requests are sent for users in
+ this administrative domain. The existing TLS connection will be
+ reused to deliver incoming requests to the UA that has just completed
+ registration.
+
+ Because the UA has already authenticated the server on the other
+ side of the TLS connection, all requests that come over this
+ connection are known to have passed through the proxy server -
+ attackers cannot create spoofed requests that appear to have been
+ sent through that proxy server.
+
+26.3.2.2 Interdomain Requests
+
+ Now let's say that Alice's UA would like to initiate a session with a
+ user in a remote administrative domain, namely "bob@biloxi.com". We
+ will also say that the local administrative domain (atlanta.com) has
+ a local outbound proxy.
+
+ The proxy server that handles inbound requests for an administrative
+ domain MAY also act as a local outbound proxy; for simplicity's sake
+ we'll assume this to be the case for atlanta.com (otherwise the user
+ agent would initiate a new TLS connection to a separate server at
+ this point). Assuming that the client has completed the registration
+
+
+
+Rosenberg, et. al. Standards Track [Page 243]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ process described in the preceding section, it SHOULD reuse the TLS
+ connection to the local proxy server when it sends an INVITE request
+ to another user. The UA SHOULD reuse cached credentials in the
+ INVITE to avoid prompting the user unnecessarily.
+
+ When the local outbound proxy server has validated the credentials
+ presented by the UA in the INVITE, it SHOULD inspect the Request-URI
+ to determine how the message should be routed (see [4]). If the
+ "domainname" portion of the Request-URI had corresponded to the local
+ domain (atlanta.com) rather than biloxi.com, then the proxy server
+ would have consulted its location service to determine how best to
+ reach the requested user.
+
+ Had "alice@atlanta.com" been attempting to contact, say,
+ "alex@atlanta.com", the local proxy would have proxied to the
+ request to the TLS connection Alex had established with the
+ registrar when he registered. Since Alex would receive this
+ request over his authenticated channel, he would be assured that
+ Alice's request had been authorized by the proxy server of the
+ local administrative domain.
+
+ However, in this instance the Request-URI designates a remote domain.
+ The local outbound proxy server at atlanta.com SHOULD therefore
+ establish a TLS connection with the remote proxy server at
+ biloxi.com. Since both of the participants in this TLS connection
+ are servers that possess site certificates, mutual TLS authentication
+ SHOULD occur. Each side of the connection SHOULD verify and inspect
+ the certificate of the other, noting the domain name that appears in
+ the certificate for comparison with the header fields of SIP
+ messages. The atlanta.com proxy server, for example, SHOULD verify
+ at this stage that the certificate received from the remote side
+ corresponds with the biloxi.com domain. Once it has done so, and TLS
+ negotiation has completed, resulting in a secure channel between the
+ two proxies, the atlanta.com proxy can forward the INVITE request to
+ biloxi.com.
+
+ The proxy server at biloxi.com SHOULD inspect the certificate of the
+ proxy server at atlanta.com in turn and compare the domain asserted
+ by the certificate with the "domainname" portion of the From header
+ field in the INVITE request. The biloxi proxy MAY have a strict
+ security policy that requires it to reject requests that do not match
+ the administrative domain from which they have been proxied.
+
+ Such security policies could be instituted to prevent the SIP
+ equivalent of SMTP 'open relays' that are frequently exploited to
+ generate spam.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 244]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ This policy, however, only guarantees that the request came from the
+ domain it ascribes to itself; it does not allow biloxi.com to
+ ascertain how atlanta.com authenticated Alice. Only if biloxi.com
+ has some other way of knowing atlanta.com's authentication policies
+ could it possibly ascertain how Alice proved her identity.
+ biloxi.com might then institute an even stricter policy that forbids
+ requests that come from domains that are not known administratively
+ to share a common authentication policy with biloxi.com.
+
+ Once the INVITE has been approved by the biloxi proxy, the proxy
+ server SHOULD identify the existing TLS channel, if any, associated
+ with the user targeted by this request (in this case
+ "bob@biloxi.com"). The INVITE should be proxied through this channel
+ to Bob. Since the request is received over a TLS connection that had
+ previously been authenticated as the biloxi proxy, Bob knows that the
+ From header field was not tampered with and that atlanta.com has
+ validated Alice, although not necessarily whether or not to trust
+ Alice's identity.
+
+ Before they forward the request, both proxy servers SHOULD add a
+ Record-Route header field to the request so that all future requests
+ in this dialog will pass through the proxy servers. The proxy
+ servers can thereby continue to provide security services for the
+ lifetime of this dialog. If the proxy servers do not add themselves
+ to the Record-Route, future messages will pass directly end-to-end
+ between Alice and Bob without any security services (unless the two
+ parties agree on some independent end-to-end security such as
+ S/MIME). In this respect the SIP trapezoid model can provide a nice
+ structure where conventions of agreement between the site proxies can
+ provide a reasonably secure channel between Alice and Bob.
+
+ An attacker preying on this architecture would, for example, be
+ unable to forge a BYE request and insert it into the signaling
+ stream between Bob and Alice because the attacker has no way of
+ ascertaining the parameters of the session and also because the
+ integrity mechanism transitively protects the traffic between
+ Alice and Bob.
+
+26.3.2.3 Peer-to-Peer Requests
+
+ Alternatively, consider a UA asserting the identity
+ "carol@chicago.com" that has no local outbound proxy. When Carol
+ wishes to send an INVITE to "bob@biloxi.com", her UA SHOULD initiate
+ a TLS connection with the biloxi proxy directly (using the mechanism
+ described in [4] to determine how to best to reach the given
+ Request-URI). When her UA receives a certificate from the biloxi
+ proxy, it SHOULD be verified normally before she passes her INVITE
+ across the TLS connection. However, Carol has no means of proving
+
+
+
+Rosenberg, et. al. Standards Track [Page 245]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ her identity to the biloxi proxy, but she does have a CMS-detached
+ signature over a "message/sip" body in the INVITE. It is unlikely in
+ this instance that Carol would have any credentials in the biloxi.com
+ realm, since she has no formal association with biloxi.com. The
+ biloxi proxy MAY also have a strict policy that precludes it from
+ even bothering to challenge requests that do not have biloxi.com in
+ the "domainname" portion of the From header field - it treats these
+ users as unauthenticated.
+
+ The biloxi proxy has a policy for Bob that all non-authenticated
+ requests should be redirected to the appropriate contact address
+ registered against 'bob@biloxi.com', namely <sip:bob@192.0.2.4>.
+ Carol receives the redirection response over the TLS connection she
+ established with the biloxi proxy, so she trusts the veracity of the
+ contact address.
+
+ Carol SHOULD then establish a TCP connection with the designated
+ address and send a new INVITE with a Request-URI containing the
+ received contact address (recomputing the signature in the body as
+ the request is readied). Bob receives this INVITE on an insecure
+ interface, but his UA inspects and, in this instance, recognizes the
+ From header field of the request and subsequently matches a locally
+ cached certificate with the one presented in the signature of the
+ body of the INVITE. He replies in similar fashion, authenticating
+ himself to Carol, and a secure dialog begins.
+
+ Sometimes firewalls or NATs in an administrative domain could
+ preclude the establishment of a direct TCP connection to a UA. In
+ these cases, proxy servers could also potentially relay requests
+ to UAs in a way that has no trust implications (for example,
+ forgoing an existing TLS connection and forwarding the request
+ over cleartext TCP) as local policy dictates.
+
+26.3.2.4 DoS Protection
+
+ In order to minimize the risk of a denial-of-service attack against
+ architectures using these security solutions, implementers should
+ take note of the following guidelines.
+
+ When the host on which a SIP proxy server is operating is routable
+ from the public Internet, it SHOULD be deployed in an administrative
+ domain with defensive operational policies (blocking source-routed
+ traffic, preferably filtering ping traffic). Both TLS and IPSec can
+ also make use of bastion hosts at the edges of administrative domains
+ that participate in the security associations to aggregate secure
+ tunnels and sockets. These bastion hosts can also take the brunt of
+ denial-of-service attacks, ensuring that SIP hosts within the
+ administrative domain are not encumbered with superfluous messaging.
+
+
+
+Rosenberg, et. al. Standards Track [Page 246]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ No matter what security solutions are deployed, floods of messages
+ directed at proxy servers can lock up proxy server resources and
+ prevent desirable traffic from reaching its destination. There is a
+ computational expense associated with processing a SIP transaction at
+ a proxy server, and that expense is greater for stateful proxy
+ servers than it is for stateless proxy servers. Therefore, stateful
+ proxies are more susceptible to flooding than stateless proxy
+ servers.
+
+ UAs and proxy servers SHOULD challenge questionable requests with
+ only a single 401 (Unauthorized) or 407 (Proxy Authentication
+ Required), forgoing the normal response retransmission algorithm, and
+ thus behaving statelessly towards unauthenticated requests.
+
+ Retransmitting the 401 (Unauthorized) or 407 (Proxy Authentication
+ Required) status response amplifies the problem of an attacker
+ using a falsified header field value (such as Via) to direct
+ traffic to a third party.
+
+ In summary, the mutual authentication of proxy servers through
+ mechanisms such as TLS significantly reduces the potential for rogue
+ intermediaries to introduce falsified requests or responses that can
+ deny service. This commensurately makes it harder for attackers to
+ make innocent SIP nodes into agents of amplification.
+
+26.4 Limitations
+
+ Although these security mechanisms, when applied in a judicious
+ manner, can thwart many threats, there are limitations in the scope
+ of the mechanisms that must be understood by implementers and network
+ operators.
+
+26.4.1 HTTP Digest
+
+ One of the primary limitations of using HTTP Digest in SIP is that
+ the integrity mechanisms in Digest do not work very well for SIP.
+ Specifically, they offer protection of the Request-URI and the method
+ of a message, but not for any of the header fields that UAs would
+ most likely wish to secure.
+
+ The existing replay protection mechanisms described in RFC 2617 also
+ have some limitations for SIP. The next-nonce mechanism, for
+ example, does not support pipelined requests. The nonce-count
+ mechanism should be used for replay protection.
+
+ Another limitation of HTTP Digest is the scope of realms. Digest is
+ valuable when a user wants to authenticate themselves to a resource
+ with which they have a pre-existing association, like a service
+
+
+
+Rosenberg, et. al. Standards Track [Page 247]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ provider of which the user is a customer (which is quite a common
+ scenario and thus Digest provides an extremely useful function). By
+ way of contrast, the scope of TLS is interdomain or multirealm, since
+ certificates are often globally verifiable, so that the UA can
+ authenticate the server with no pre-existing association.
+
+26.4.2 S/MIME
+
+ The largest outstanding defect with the S/MIME mechanism is the lack
+ of a prevalent public key infrastructure for end users. If self-
+ signed certificates (or certificates that cannot be verified by one
+ of the participants in a dialog) are used, the SIP-based key exchange
+ mechanism described in Section 23.2 is susceptible to a man-in-the-
+ middle attack with which an attacker can potentially inspect and
+ modify S/MIME bodies. The attacker needs to intercept the first
+ exchange of keys between the two parties in a dialog, remove the
+ existing CMS-detached signatures from the request and response, and
+ insert a different CMS-detached signature containing a certificate
+ supplied by the attacker (but which seems to be a certificate for the
+ proper address-of-record). Each party will think they have exchanged
+ keys with the other, when in fact each has the public key of the
+ attacker.
+
+ It is important to note that the attacker can only leverage this
+ vulnerability on the first exchange of keys between two parties - on
+ subsequent occasions, the alteration of the key would be noticeable
+ to the UAs. It would also be difficult for the attacker to remain in
+ the path of all future dialogs between the two parties over time (as
+ potentially days, weeks, or years pass).
+
+ SSH is susceptible to the same man-in-the-middle attack on the first
+ exchange of keys; however, it is widely acknowledged that while SSH
+ is not perfect, it does improve the security of connections. The use
+ of key fingerprints could provide some assistance to SIP, just as it
+ does for SSH. For example, if two parties use SIP to establish a
+ voice communications session, each could read off the fingerprint of
+ the key they received from the other, which could be compared against
+ the original. It would certainly be more difficult for the man-in-
+ the-middle to emulate the voices of the participants than their
+ signaling (a practice that was used with the Clipper chip-based
+ secure telephone).
+
+ The S/MIME mechanism allows UAs to send encrypted requests without
+ preamble if they possess a certificate for the destination address-
+ of-record on their keyring. However, it is possible that any
+ particular device registered for an address-of-record will not hold
+ the certificate that has been previously employed by the device's
+ current user, and that it will therefore be unable to process an
+
+
+
+Rosenberg, et. al. Standards Track [Page 248]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ encrypted request properly, which could lead to some avoidable error
+ signaling. This is especially likely when an encrypted request is
+ forked.
+
+ The keys associated with S/MIME are most useful when associated with
+ a particular user (an address-of-record) rather than a device (a UA).
+ When users move between devices, it may be difficult to transport
+ private keys securely between UAs; how such keys might be acquired by
+ a device is outside the scope of this document.
+
+ Another, more prosaic difficulty with the S/MIME mechanism is that it
+ can result in very large messages, especially when the SIP tunneling
+ mechanism described in Section 23.4 is used. For that reason, it is
+ RECOMMENDED that TCP should be used as a transport protocol when
+ S/MIME tunneling is employed.
+
+26.4.3 TLS
+
+ The most commonly voiced concern about TLS is that it cannot run over
+ UDP; TLS requires a connection-oriented underlying transport
+ protocol, which for the purposes of this document means TCP.
+
+ It may also be arduous for a local outbound proxy server and/or
+ registrar to maintain many simultaneous long-lived TLS connections
+ with numerous UAs. This introduces some valid scalability concerns,
+ especially for intensive ciphersuites. Maintaining redundancy of
+ long-lived TLS connections, especially when a UA is solely
+ responsible for their establishment, could also be cumbersome.
+
+ TLS only allows SIP entities to authenticate servers to which they
+ are adjacent; TLS offers strictly hop-by-hop security. Neither TLS,
+ nor any other mechanism specified in this document, allows clients to
+ authenticate proxy servers to whom they cannot form a direct TCP
+ connection.
+
+26.4.4 SIPS URIs
+
+ Actually using TLS on every segment of a request path entails that
+ the terminating UAS must be reachable over TLS (perhaps registering
+ with a SIPS URI as a contact address). This is the preferred use of
+ SIPS. Many valid architectures, however, use TLS to secure part of
+ the request path, but rely on some other mechanism for the final hop
+ to a UAS, for example. Thus SIPS cannot guarantee that TLS usage
+ will be truly end-to-end. Note that since many UAs will not accept
+ incoming TLS connections, even those UAs that do support TLS may be
+ required to maintain persistent TLS connections as described in the
+ TLS limitations section above in order to receive requests over TLS
+ as a UAS.
+
+
+
+Rosenberg, et. al. Standards Track [Page 249]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Location services are not required to provide a SIPS binding for a
+ SIPS Request-URI. Although location services are commonly populated
+ by user registrations (as described in Section 10.2.1), various other
+ protocols and interfaces could conceivably supply contact addresses
+ for an AOR, and these tools are free to map SIPS URIs to SIP URIs as
+ appropriate. When queried for bindings, a location service returns
+ its contact addresses without regard for whether it received a
+ request with a SIPS Request-URI. If a redirect server is accessing
+ the location service, it is up to the entity that processes the
+ Contact header field of a redirection to determine the propriety of
+ the contact addresses.
+
+ Ensuring that TLS will be used for all of the request segments up to
+ the target domain is somewhat complex. It is possible that
+ cryptographically authenticated proxy servers along the way that are
+ non-compliant or compromised may choose to disregard the forwarding
+ rules associated with SIPS (and the general forwarding rules in
+ Section 16.6). Such malicious intermediaries could, for example,
+ retarget a request from a SIPS URI to a SIP URI in an attempt to
+ downgrade security.
+
+ Alternatively, an intermediary might legitimately retarget a request
+ from a SIP to a SIPS URI. Recipients of a request whose Request-URI
+ uses the SIPS URI scheme thus cannot assume on the basis of the
+ Request-URI alone that SIPS was used for the entire request path
+ (from the client onwards).
+
+ To address these concerns, it is RECOMMENDED that recipients of a
+ request whose Request-URI contains a SIP or SIPS URI inspect the To
+ header field value to see if it contains a SIPS URI (though note that
+ it does not constitute a breach of security if this URI has the same
+ scheme but is not equivalent to the URI in the To header field).
+ Although clients may choose to populate the Request-URI and To header
+ field of a request differently, when SIPS is used this disparity
+ could be interpreted as a possible security violation, and the
+ request could consequently be rejected by its recipient. Recipients
+ MAY also inspect the Via header chain in order to double-check
+ whether or not TLS was used for the entire request path until the
+ local administrative domain was reached. S/MIME may also be used by
+ the originating UAC to help ensure that the original form of the To
+ header field is carried end-to-end.
+
+ If the UAS has reason to believe that the scheme of the Request-URI
+ has been improperly modified in transit, the UA SHOULD notify its
+ user of a potential security breach.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 250]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ As a further measure to prevent downgrade attacks, entities that
+ accept only SIPS requests MAY also refuse connections on insecure
+ ports.
+
+ End users will undoubtedly discern the difference between SIPS and
+ SIP URIs, and they may manually edit them in response to stimuli.
+ This can either benefit or degrade security. For example, if an
+ attacker corrupts a DNS cache, inserting a fake record set that
+ effectively removes all SIPS records for a proxy server, then any
+ SIPS requests that traverse this proxy server may fail. When a user,
+ however, sees that repeated calls to a SIPS AOR are failing, they
+ could on some devices manually convert the scheme from SIPS to SIP
+ and retry. Of course, there are some safeguards against this (if the
+ destination UA is truly paranoid it could refuse all non-SIPS
+ requests), but it is a limitation worth noting. On the bright side,
+ users might also divine that 'SIPS' would be valid even when they are
+ presented only with a SIP URI.
+
+26.5 Privacy
+
+ SIP messages frequently contain sensitive information about their
+ senders - not just what they have to say, but with whom they
+ communicate, when they communicate and for how long, and from where
+ they participate in sessions. Many applications and their users
+ require that this sort of private information be hidden from any
+ parties that do not need to know it.
+
+ Note that there are also less direct ways in which private
+ information can be divulged. If a user or service chooses to be
+ reachable at an address that is guessable from the person's name and
+ organizational affiliation (which describes most addresses-of-
+ record), the traditional method of ensuring privacy by having an
+ unlisted "phone number" is compromised. A user location service can
+ infringe on the privacy of the recipient of a session invitation by
+ divulging their specific whereabouts to the caller; an implementation
+ consequently SHOULD be able to restrict, on a per-user basis, what
+ kind of location and availability information is given out to certain
+ classes of callers. This is a whole class of problem that is
+ expected to be studied further in ongoing SIP work.
+
+ In some cases, users may want to conceal personal information in
+ header fields that convey identity. This can apply not only to the
+ From and related headers representing the originator of the request,
+ but also the To - it may not be appropriate to convey to the final
+ destination a speed-dialing nickname, or an unexpanded identifier for
+ a group of targets, either of which would be removed from the
+ Request-URI as the request is routed, but not changed in the To
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 251]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ header field if the two were initially identical. Thus it MAY be
+ desirable for privacy reasons to create a To header field that
+ differs from the Request-URI.
+
+27 IANA Considerations
+
+ All method names, header field names, status codes, and option tags
+ used in SIP applications are registered with IANA through
+ instructions in an IANA Considerations section in an RFC.
+
+ The specification instructs the IANA to create four new sub-
+ registries under http://www.iana.org/assignments/sip-parameters:
+ Option Tags, Warning Codes (warn-codes), Methods and Response Codes,
+ added to the sub-registry of Header Fields that is already present
+ there.
+
+27.1 Option Tags
+
+ This specification establishes the Option Tags sub-registry under
+ http://www.iana.org/assignments/sip-parameters.
+
+ Option tags are used in header fields such as Require, Supported,
+ Proxy-Require, and Unsupported in support of SIP compatibility
+ mechanisms for extensions (Section 19.2). The option tag itself is a
+ string that is associated with a particular SIP option (that is, an
+ extension). It identifies the option to SIP endpoints.
+
+ Option tags are registered by the IANA when they are published in
+ standards track RFCs. The IANA Considerations section of the RFC
+ must include the following information, which appears in the IANA
+ registry along with the RFC number of the publication.
+
+ o Name of the option tag. The name MAY be of any length, but
+ SHOULD be no more than twenty characters long. The name MUST
+ consist of alphanum (Section 25) characters only.
+
+ o Descriptive text that describes the extension.
+
+27.2 Warn-Codes
+
+ This specification establishes the Warn-codes sub-registry under
+ http://www.iana.org/assignments/sip-parameters and initiates its
+ population with the warn-codes listed in Section 20.43. Additional
+ warn-codes are registered by RFC publication.
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 252]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ The descriptive text for the table of warn-codes is:
+
+ Warning codes provide information supplemental to the status code in
+ SIP response messages when the failure of the transaction results
+ from a Session Description Protocol (SDP) (RFC 2327 [1]) problem.
+
+ The "warn-code" consists of three digits. A first digit of "3"
+ indicates warnings specific to SIP. Until a future specification
+ describes uses of warn-codes other than 3xx, only 3xx warn-codes may
+ be registered.
+
+ Warnings 300 through 329 are reserved for indicating problems with
+ keywords in the session description, 330 through 339 are warnings
+ related to basic network services requested in the session
+ description, 370 through 379 are warnings related to quantitative QoS
+ parameters requested in the session description, and 390 through 399
+ are miscellaneous warnings that do not fall into one of the above
+ categories.
+
+27.3 Header Field Names
+
+ This obsoletes the IANA instructions about the header sub-registry
+ under http://www.iana.org/assignments/sip-parameters.
+
+ The following information needs to be provided in an RFC publication
+ in order to register a new header field name:
+
+ o The RFC number in which the header is registered;
+
+ o the name of the header field being registered;
+
+ o a compact form version for that header field, if one is
+ defined;
+
+ Some common and widely used header fields MAY be assigned one-letter
+ compact forms (Section 7.3.3). Compact forms can only be assigned
+ after SIP working group review, followed by RFC publication.
+
+27.4 Method and Response Codes
+
+ This specification establishes the Method and Response-Code sub-
+ registries under http://www.iana.org/assignments/sip-parameters and
+ initiates their population as follows. The initial Methods table is:
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 253]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ INVITE [RFC3261]
+ ACK [RFC3261]
+ BYE [RFC3261]
+ CANCEL [RFC3261]
+ REGISTER [RFC3261]
+ OPTIONS [RFC3261]
+ INFO [RFC2976]
+
+ The response code table is initially populated from Section 21, the
+ portions labeled Informational, Success, Redirection, Client-Error,
+ Server-Error, and Global-Failure. The table has the following
+ format:
+
+ Type (e.g., Informational)
+ Number Default Reason Phrase [RFC3261]
+
+ The following information needs to be provided in an RFC publication
+ in order to register a new response code or method:
+
+ o The RFC number in which the method or response code is
+ registered;
+
+ o the number of the response code or name of the method being
+ registered;
+
+ o the default reason phrase for that response code, if
+ applicable;
+
+27.5 The "message/sip" MIME type.
+
+ This document registers the "message/sip" MIME media type in order to
+ allow SIP messages to be tunneled as bodies within SIP, primarily for
+ end-to-end security purposes. This media type is defined by the
+ following information:
+
+ Media type name: message
+ Media subtype name: sip
+ Required parameters: none
+
+ Optional parameters: version
+ version: The SIP-Version number of the enclosed message (e.g.,
+ "2.0"). If not present, the version defaults to "2.0".
+ Encoding scheme: SIP messages consist of an 8-bit header
+ optionally followed by a binary MIME data object. As such, SIP
+ messages must be treated as binary. Under normal circumstances
+ SIP messages are transported over binary-capable transports, no
+ special encodings are needed.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 254]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Security considerations: see below
+ Motivation and examples of this usage as a security mechanism
+ in concert with S/MIME are given in 23.4.
+
+27.6 New Content-Disposition Parameter Registrations
+
+ This document also registers four new Content-Disposition header
+ "disposition-types": alert, icon, session and render. The authors
+ request that these values be recorded in the IANA registry for
+ Content-Dispositions.
+
+ Descriptions of these "disposition-types", including motivation and
+ examples, are given in Section 20.11.
+
+ Short descriptions suitable for the IANA registry are:
+
+ alert the body is a custom ring tone to alert the user
+ icon the body is displayed as an icon to the user
+ render the body should be displayed to the user
+ session the body describes a communications session, for
+ example, as RFC 2327 SDP body
+
+28 Changes From RFC 2543
+
+ This RFC revises RFC 2543. It is mostly backwards compatible with
+ RFC 2543. The changes described here fix many errors discovered in
+ RFC 2543 and provide information on scenarios not detailed in RFC
+ 2543. The protocol has been presented in a more cleanly layered
+ model here.
+
+ We break the differences into functional behavior that is a
+ substantial change from RFC 2543, which has impact on
+ interoperability or correct operation in some cases, and functional
+ behavior that is different from RFC 2543 but not a potential source
+ of interoperability problems. There have been countless
+ clarifications as well, which are not documented here.
+
+28.1 Major Functional Changes
+
+ o When a UAC wishes to terminate a call before it has been answered,
+ it sends CANCEL. If the original INVITE still returns a 2xx, the
+ UAC then sends BYE. BYE can only be sent on an existing call leg
+ (now called a dialog in this RFC), whereas it could be sent at any
+ time in RFC 2543.
+
+ o The SIP BNF was converted to be RFC 2234 compliant.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 255]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o SIP URL BNF was made more general, allowing a greater set of
+ characters in the user part. Furthermore, comparison rules were
+ simplified to be primarily case-insensitive, and detailed handling
+ of comparison in the presence of parameters was described. The
+ most substantial change is that a URI with a parameter with the
+ default value does not match a URI without that parameter.
+
+ o Removed Via hiding. It had serious trust issues, since it relied
+ on the next hop to perform the obfuscation process. Instead, Via
+ hiding can be done as a local implementation choice in stateful
+ proxies, and thus is no longer documented.
+
+ o In RFC 2543, CANCEL and INVITE transactions were intermingled.
+ They are separated now. When a user sends an INVITE and then a
+ CANCEL, the INVITE transaction still terminates normally. A UAS
+ needs to respond to the original INVITE request with a 487
+ response.
+
+ o Similarly, CANCEL and BYE transactions were intermingled; RFC 2543
+ allowed the UAS not to send a response to INVITE when a BYE was
+ received. That is disallowed here. The original INVITE needs a
+ response.
+
+ o In RFC 2543, UAs needed to support only UDP. In this RFC, UAs
+ need to support both UDP and TCP.
+
+ o In RFC 2543, a forking proxy only passed up one challenge from
+ downstream elements in the event of multiple challenges. In this
+ RFC, proxies are supposed to collect all challenges and place them
+ into the forwarded response.
+
+ o In Digest credentials, the URI needs to be quoted; this is unclear
+ from RFC 2617 and RFC 2069 which are both inconsistent on it.
+
+ o SDP processing has been split off into a separate specification
+ [13], and more fully specified as a formal offer/answer exchange
+ process that is effectively tunneled through SIP. SDP is allowed
+ in INVITE/200 or 200/ACK for baseline SIP implementations; RFC
+ 2543 alluded to the ability to use it in INVITE, 200, and ACK in a
+ single transaction, but this was not well specified. More complex
+ SDP usages are allowed in extensions.
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 256]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o Added full support for IPv6 in URIs and in the Via header field.
+ Support for IPv6 in Via has required that its header field
+ parameters allow the square bracket and colon characters. These
+ characters were previously not permitted. In theory, this could
+ cause interop problems with older implementations. However, we
+ have observed that most implementations accept any non-control
+ ASCII character in these parameters.
+
+ o DNS SRV procedure is now documented in a separate specification
+ [4]. This procedure uses both SRV and NAPTR resource records and
+ no longer combines data from across SRV records as described in
+ RFC 2543.
+
+ o Loop detection has been made optional, supplanted by a mandatory
+ usage of Max-Forwards. The loop detection procedure in RFC 2543
+ had a serious bug which would report "spirals" as an error
+ condition when it was not. The optional loop detection procedure
+ is more fully and correctly specified here.
+
+ o Usage of tags is now mandatory (they were optional in RFC 2543),
+ as they are now the fundamental building blocks of dialog
+ identification.
+
+ o Added the Supported header field, allowing for clients to indicate
+ what extensions are supported to a server, which can apply those
+ extensions to the response, and indicate their usage with a
+ Require in the response.
+
+ o Extension parameters were missing from the BNF for several header
+ fields, and they have been added.
+
+ o Handling of Route and Record-Route construction was very
+ underspecified in RFC 2543, and also not the right approach. It
+ has been substantially reworked in this specification (and made
+ vastly simpler), and this is arguably the largest change.
+ Backwards compatibility is still provided for deployments that do
+ not use "pre-loaded routes", where the initial request has a set
+ of Route header field values obtained in some way outside of
+ Record-Route. In those situations, the new mechanism is not
+ interoperable.
+
+ o In RFC 2543, lines in a message could be terminated with CR, LF,
+ or CRLF. This specification only allows CRLF.
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 257]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o Usage of Route in CANCEL and ACK was not well defined in RFC 2543.
+ It is now well specified; if a request had a Route header field,
+ its CANCEL or ACK for a non-2xx response to the request need to
+ carry the same Route header field values. ACKs for 2xx responses
+ use the Route values learned from the Record-Route of the 2xx
+ responses.
+
+ o RFC 2543 allowed multiple requests in a single UDP packet. This
+ usage has been removed.
+
+ o Usage of absolute time in the Expires header field and parameter
+ has been removed. It caused interoperability problems in elements
+ that were not time synchronized, a common occurrence. Relative
+ times are used instead.
+
+ o The branch parameter of the Via header field value is now
+ mandatory for all elements to use. It now plays the role of a
+ unique transaction identifier. This avoids the complex and bug-
+ laden transaction identification rules from RFC 2543. A magic
+ cookie is used in the parameter value to determine if the previous
+ hop has made the parameter globally unique, and comparison falls
+ back to the old rules when it is not present. Thus,
+ interoperability is assured.
+
+ o In RFC 2543, closure of a TCP connection was made equivalent to a
+ CANCEL. This was nearly impossible to implement (and wrong) for
+ TCP connections between proxies. This has been eliminated, so
+ that there is no coupling between TCP connection state and SIP
+ processing.
+
+ o RFC 2543 was silent on whether a UA could initiate a new
+ transaction to a peer while another was in progress. That is now
+ specified here. It is allowed for non-INVITE requests, disallowed
+ for INVITE.
+
+ o PGP was removed. It was not sufficiently specified, and not
+ compatible with the more complete PGP MIME. It was replaced with
+ S/MIME.
+
+ o Added the "sips" URI scheme for end-to-end TLS. This scheme is
+ not backwards compatible with RFC 2543. Existing elements that
+ receive a request with a SIPS URI scheme in the Request-URI will
+ likely reject the request. This is actually a feature; it ensures
+ that a call to a SIPS URI is only delivered if all path hops can
+ be secured.
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 258]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o Additional security features were added with TLS, and these are
+ described in a much larger and complete security considerations
+ section.
+
+ o In RFC 2543, a proxy was not required to forward provisional
+ responses from 101 to 199 upstream. This was changed to MUST.
+ This is important, since many subsequent features depend on
+ delivery of all provisional responses from 101 to 199.
+
+ o Little was said about the 503 response code in RFC 2543. It has
+ since found substantial use in indicating failure or overload
+ conditions in proxies. This requires somewhat special treatment.
+ Specifically, receipt of a 503 should trigger an attempt to
+ contact the next element in the result of a DNS SRV lookup. Also,
+ 503 response is only forwarded upstream by a proxy under certain
+ conditions.
+
+ o RFC 2543 defined, but did no sufficiently specify, a mechanism for
+ UA authentication of a server. That has been removed. Instead,
+ the mutual authentication procedures of RFC 2617 are allowed.
+
+ o A UA cannot send a BYE for a call until it has received an ACK for
+ the initial INVITE. This was allowed in RFC 2543 but leads to a
+ potential race condition.
+
+ o A UA or proxy cannot send CANCEL for a transaction until it gets a
+ provisional response for the request. This was allowed in RFC
+ 2543 but leads to potential race conditions.
+
+ o The action parameter in registrations has been deprecated. It was
+ insufficient for any useful services, and caused conflicts when
+ application processing was applied in proxies.
+
+ o RFC 2543 had a number of special cases for multicast. For
+ example, certain responses were suppressed, timers were adjusted,
+ and so on. Multicast now plays a more limited role, and the
+ protocol operation is unaffected by usage of multicast as opposed
+ to unicast. The limitations as a result of that are documented.
+
+ o Basic authentication has been removed entirely and its usage
+ forbidden.
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 259]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ o Proxies no longer forward a 6xx immediately on receiving it.
+ Instead, they CANCEL pending branches immediately. This avoids a
+ potential race condition that would result in a UAC getting a 6xx
+ followed by a 2xx. In all cases except this race condition, the
+ result will be the same - the 6xx is forwarded upstream.
+
+ o RFC 2543 did not address the problem of request merging. This
+ occurs when a request forks at a proxy and later rejoins at an
+ element. Handling of merging is done only at a UA, and procedures
+ are defined for rejecting all but the first request.
+
+28.2 Minor Functional Changes
+
+ o Added the Alert-Info, Error-Info, and Call-Info header fields for
+ optional content presentation to users.
+
+ o Added the Content-Language, Content-Disposition and MIME-Version
+ header fields.
+
+ o Added a "glare handling" mechanism to deal with the case where
+ both parties send each other a re-INVITE simultaneously. It uses
+ the new 491 (Request Pending) error code.
+
+ o Added the In-Reply-To and Reply-To header fields for supporting
+ the return of missed calls or messages at a later time.
+
+ o Added TLS and SCTP as valid SIP transports.
+
+ o There were a variety of mechanisms described for handling failures
+ at any time during a call; those are now generally unified. BYE
+ is sent to terminate.
+
+ o RFC 2543 mandated retransmission of INVITE responses over TCP, but
+ noted it was really only needed for 2xx. That was an artifact of
+ insufficient protocol layering. With a more coherent transaction
+ layer defined here, that is no longer needed. Only 2xx responses
+ to INVITEs are retransmitted over TCP.
+
+ o Client and server transaction machines are now driven based on
+ timeouts rather than retransmit counts. This allows the state
+ machines to be properly specified for TCP and UDP.
+
+ o The Date header field is used in REGISTER responses to provide a
+ simple means for auto-configuration of dates in user agents.
+
+ o Allowed a registrar to reject registrations with expirations that
+ are too short in duration. Defined the 423 response code and the
+ Min-Expires for this purpose.
+
+
+
+Rosenberg, et. al. Standards Track [Page 260]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+29 Normative References
+
+ [1] Handley, M. and V. Jacobson, "SDP: Session Description
+ Protocol", RFC 2327, April 1998.
+
+ [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [3] Resnick, P., "Internet Message Format", RFC 2822, April 2001.
+
+ [4] Rosenberg, J. and H. Schulzrinne, "SIP: Locating SIP Servers",
+ RFC 3263, June 2002.
+
+ [5] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource
+ Identifiers (URI): Generic Syntax", RFC 2396, August 1998.
+
+ [6] Chown, P., "Advanced Encryption Standard (AES) Ciphersuites for
+ Transport Layer Security (TLS)", RFC 3268, June 2002.
+
+ [7] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC
+ 2279, January 1998.
+
+ [8] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L.,
+ Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol --
+ HTTP/1.1", RFC 2616, June 1999.
+
+ [9] Vaha-Sipila, A., "URLs for Telephone Calls", RFC 2806, April
+ 2000.
+
+ [10] Crocker, D. and P. Overell, "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997.
+
+ [11] Freed, F. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046, November
+ 1996.
+
+ [12] Eastlake, D., Crocker, S. and J. Schiller, "Randomness
+ Recommendations for Security", RFC 1750, December 1994.
+
+ [13] Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model with
+ SDP", RFC 3264, June 2002.
+
+ [14] Postel, J., "User Datagram Protocol", STD 6, RFC 768, August
+ 1980.
+
+ [15] Postel, J., "DoD Standard Transmission Control Protocol", RFC
+ 761, January 1980.
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 261]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ [16] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+ H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+ "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+ [17] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S.,
+ Leach, P., Luotonen, A. and L. Stewart, "HTTP authentication:
+ Basic and Digest Access Authentication", RFC 2617, June 1999.
+
+ [18] Troost, R., Dorner, S. and K. Moore, "Communicating Presentation
+ Information in Internet Messages: The Content-Disposition Header
+ Field", RFC 2183, August 1997.
+
+ [19] Zimmerer, E., Peterson, J., Vemuri, A., Ong, L., Audet, F.,
+ Watson, M. and M. Zonoun, "MIME media types for ISUP and QSIG
+ Objects", RFC 3204, December 2001.
+
+ [20] Braden, R., "Requirements for Internet Hosts - Application and
+ Support", STD 3, RFC 1123, October 1989.
+
+ [21] Alvestrand, H., "IETF Policy on Character Sets and Languages",
+ BCP 18, RFC 2277, January 1998.
+
+ [22] Galvin, J., Murphy, S., Crocker, S. and N. Freed, "Security
+ Multiparts for MIME: Multipart/Signed and Multipart/Encrypted",
+ RFC 1847, October 1995.
+
+ [23] Housley, R., "Cryptographic Message Syntax", RFC 2630, June
+ 1999.
+
+ [24] Ramsdell B., "S/MIME Version 3 Message Specification", RFC 2633,
+ June 1999.
+
+ [25] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC
+ 2246, January 1999.
+
+ [26] Kent, S. and R. Atkinson, "Security Architecture for the
+ Internet Protocol", RFC 2401, November 1998.
+
+30 Informative References
+
+ [27] R. Pandya, "Emerging mobile and personal communication systems,"
+ IEEE Communications Magazine, Vol. 33, pp. 44--52, June 1995.
+
+ [28] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson,
+ "RTP: A Transport Protocol for Real-Time Applications", RFC
+ 1889, January 1996.
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 262]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ [29] Schulzrinne, H., Rao, R. and R. Lanphier, "Real Time Streaming
+ Protocol (RTSP)", RFC 2326, April 1998.
+
+ [30] Cuervo, F., Greene, N., Rayhan, A., Huitema, C., Rosen, B. and
+ J. Segers, "Megaco Protocol Version 1.0", RFC 3015, November
+ 2000.
+
+ [31] Handley, M., Schulzrinne, H., Schooler, E. and J. Rosenberg,
+ "SIP: Session Initiation Protocol", RFC 2543, March 1999.
+
+ [32] Hoffman, P., Masinter, L. and J. Zawinski, "The mailto URL
+ scheme", RFC 2368, July 1998.
+
+ [33] E. M. Schooler, "A multicast user directory service for
+ synchronous rendezvous," Master's Thesis CS-TR-96-18, Department
+ of Computer Science, California Institute of Technology,
+ Pasadena, California, Aug. 1996.
+
+ [34] Donovan, S., "The SIP INFO Method", RFC 2976, October 2000.
+
+ [35] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April
+ 1992.
+
+ [36] Dawson, F. and T. Howes, "vCard MIME Directory Profile", RFC
+ 2426, September 1998.
+
+ [37] Good, G., "The LDAP Data Interchange Format (LDIF) - Technical
+ Specification", RFC 2849, June 2000.
+
+ [38] Palme, J., "Common Internet Message Headers", RFC 2076,
+ February 1997.
+
+ [39] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
+ Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP:
+ Digest Access Authentication", RFC 2069, January 1997.
+
+ [40] Johnston, A., Donovan, S., Sparks, R., Cunningham, C., Willis,
+ D., Rosenberg, J., Summers, K. and H. Schulzrinne, "SIP Call
+ Flow Examples", Work in Progress.
+
+ [41] E. M. Schooler, "Case study: multimedia conference control in a
+ packet-switched teleconferencing system," Journal of
+ Internetworking: Research and Experience, Vol. 4, pp. 99--120,
+ June 1993. ISI reprint series ISI/RS-93-359.
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 263]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ [42] H. Schulzrinne, "Personal mobility for multimedia services in
+ the Internet," in European Workshop on Interactive Distributed
+ Multimedia Systems and Services (IDMS), (Berlin, Germany), Mar.
+ 1996.
+
+ [43] Floyd, S., "Congestion Control Principles", RFC 2914, September
+ 2000.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 264]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+A Table of Timer Values
+
+ Table 4 summarizes the meaning and defaults of the various timers
+ used by this specification.
+
+Timer Value Section Meaning
+----------------------------------------------------------------------
+T1 500ms default Section 17.1.1.1 RTT Estimate
+T2 4s Section 17.1.2.2 The maximum retransmit
+ interval for non-INVITE
+ requests and INVITE
+ responses
+T4 5s Section 17.1.2.2 Maximum duration a
+ message will
+ remain in the network
+Timer A initially T1 Section 17.1.1.2 INVITE request retransmit
+ interval, for UDP only
+Timer B 64*T1 Section 17.1.1.2 INVITE transaction
+ timeout timer
+Timer C > 3min Section 16.6 proxy INVITE transaction
+ bullet 11 timeout
+Timer D > 32s for UDP Section 17.1.1.2 Wait time for response
+ 0s for TCP/SCTP retransmits
+Timer E initially T1 Section 17.1.2.2 non-INVITE request
+ retransmit interval,
+ UDP only
+Timer F 64*T1 Section 17.1.2.2 non-INVITE transaction
+ timeout timer
+Timer G initially T1 Section 17.2.1 INVITE response
+ retransmit interval
+Timer H 64*T1 Section 17.2.1 Wait time for
+ ACK receipt
+Timer I T4 for UDP Section 17.2.1 Wait time for
+ 0s for TCP/SCTP ACK retransmits
+Timer J 64*T1 for UDP Section 17.2.2 Wait time for
+ 0s for TCP/SCTP non-INVITE request
+ retransmits
+Timer K T4 for UDP Section 17.1.2.2 Wait time for
+ 0s for TCP/SCTP response retransmits
+
+ Table 4: Summary of timers
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 265]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Acknowledgments
+
+ We wish to thank the members of the IETF MMUSIC and SIP WGs for their
+ comments and suggestions. Detailed comments were provided by Ofir
+ Arkin, Brian Bidulock, Jim Buller, Neil Deason, Dave Devanathan,
+ Keith Drage, Bill Fenner, Cedric Fluckiger, Yaron Goland, John
+ Hearty, Bernie Hoeneisen, Jo Hornsby, Phil Hoffer, Christian Huitema,
+ Hisham Khartabil, Jean Jervis, Gadi Karmi, Peter Kjellerstedt, Anders
+ Kristensen, Jonathan Lennox, Gethin Liddell, Allison Mankin, William
+ Marshall, Rohan Mahy, Keith Moore, Vern Paxson, Bob Penfield, Moshe
+ J. Sambol, Chip Sharp, Igor Slepchin, Eric Tremblay, and Rick
+ Workman.
+
+ Brian Rosen provided the compiled BNF.
+
+ Jean Mahoney provided technical writing assistance.
+
+ This work is based, inter alia, on [41,42].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 266]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Authors' Addresses
+
+ Authors addresses are listed alphabetically for the editors, the
+ writers, and then the original authors of RFC 2543. All listed
+ authors actively contributed large amounts of text to this document.
+
+ Jonathan Rosenberg
+ dynamicsoft
+ 72 Eagle Rock Ave
+ East Hanover, NJ 07936
+ USA
+
+ EMail: jdrosen@dynamicsoft.com
+
+
+ Henning Schulzrinne
+ Dept. of Computer Science
+ Columbia University
+ 1214 Amsterdam Avenue
+ New York, NY 10027
+ USA
+
+ EMail: schulzrinne@cs.columbia.edu
+
+
+ Gonzalo Camarillo
+ Ericsson
+ Advanced Signalling Research Lab.
+ FIN-02420 Jorvas
+ Finland
+
+ EMail: Gonzalo.Camarillo@ericsson.com
+
+
+ Alan Johnston
+ WorldCom
+ 100 South 4th Street
+ St. Louis, MO 63102
+ USA
+
+ EMail: alan.johnston@wcom.com
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 267]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+ Jon Peterson
+ NeuStar, Inc
+ 1800 Sutter Street, Suite 570
+ Concord, CA 94520
+ USA
+
+ EMail: jon.peterson@neustar.com
+
+
+ Robert Sparks
+ dynamicsoft, Inc.
+ 5100 Tennyson Parkway
+ Suite 1200
+ Plano, Texas 75024
+ USA
+
+ EMail: rsparks@dynamicsoft.com
+
+
+ Mark Handley
+ International Computer Science Institute
+ 1947 Center St, Suite 600
+ Berkeley, CA 94704
+ USA
+
+ EMail: mjh@icir.org
+
+
+ Eve Schooler
+ AT&T Labs-Research
+ 75 Willow Road
+ Menlo Park, CA 94025
+ USA
+
+ EMail: schooler@research.att.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 268]
+
+RFC 3261 SIP: Session Initiation Protocol June 2002
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rosenberg, et. al. Standards Track [Page 269]
+
diff --git a/tests/auto/corelib/io/qtextstream/shift-jis.txt b/tests/auto/corelib/io/qtextstream/shift-jis.txt
new file mode 100644
index 0000000000..51f161ab1a
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/shift-jis.txt
@@ -0,0 +1,764 @@
+Shift-JISƒeƒLƒXƒg‚𐳂µ‚­ˆµ‚€
+Å‹ß‚̍XV—š—ð
+2005-03-26: uÅ‰‚Ɂv’†AXML“ú–{Œêƒvƒƒtƒ@ƒCƒ‹‘æ2”Å‚ÉŠî‚«AŽáŠ±’Ç‹LB
+2005-03-09: uÅ‰‚Ɂv’†A•¶Í‚ðŽáŠ±C³B
+2003-06-24: Shift-JIS‚ÌŠ¿Žš‚ðŠÜ‚Þƒtƒ@ƒCƒ‹–Œ/ƒpƒX–Œ
+2003-05-31: uÅ‰‚Ɂv’†AuƒVƒtƒgJISv‚È‚Ç‚Ì•\‹L‚ɂ‚¢‚āB
+2003-05-24: CP932d•¡’è‹`•¶Žš‚Ì•ÏŠ·
+2002-08-30: Perl 5.8.0 ‚ɂ‚¢‚āB
+2002-01-17: ’·‚¢•¶Žš—ñ‚ɑ΂·‚鐳‹K•\Œ»ŒŸõ
+2001-12-15: ShiftJIS::Collate ‚ª overrideCJK ƒpƒ‰ƒ[ƒ^‚ð”pŽ~‚µ‚œ‚±‚Æ‚É”º‚€ “ú–{Œê•¶Žš—ñ‚ð•À‚Ñ‘Ö‚Š‚é‚̏‘‚«Š·‚ŠB
+Å‰‚É
+‚ ‚肪‚¿‚ȃGƒ‰[
+ƒGƒ‰[‚âŠÔˆá‚¢‚ð–h‚®‘΍ô
+•¶Žš—ñƒŠƒeƒ‰ƒ‹‚̍ì‚è•û
+³‹K•\Œ»‚ƃ}ƒbƒ`
+ƒOƒ[ƒoƒ‹ƒ}ƒbƒ`
+ƒAƒ‹ƒtƒ@ƒxƒbƒg‚̑啶Žš‚Ə¬•¶Žš
+’·‚¢•¶Žš—ñ‚ɑ΂·‚鐳‹K•\Œ»ŒŸõ
+ŠOŽš‚Ì•ÏŠ·
+CP932d•¡’è‹`•¶Žš‚Ì•ÏŠ·
+•¶Žš”‚𐔂Š‚é
+•¶Žš’PˆÊ‚É•ªŠ„‚·‚é
+‚¢‚ë‚¢‚ë‚È•ªŠ„
+“Á’è‚Ì’·‚³‚Ő؂肻‚ë‚Š‚é
+“ú–{Œê•¶Žš—ñ‚ð•À‚Ñ‘Ö‚Š‚é
+Shift-JIS‚ÌŠ¿Žš‚ðŠÜ‚Þƒtƒ@ƒCƒ‹–Œ/ƒpƒX–Œ
+Å‰‚É
+“ú–{Œê‚Ì•¶ŽšƒR[ƒh‚É‚Í‚¢‚­‚‚©‚Ì‚à‚Ì‚ªŽg‚í‚ê‚Ä‚¢‚Ü‚·B‚ ‚é’ö“xˆê”Ê“I‚È‚à‚Ì‚È‚çA‚Ç‚ê‚ðŽg‚Á‚Ä‚à‚æ‚¢‚Å‚µ‚å‚€i‚Ç‚Ì•¶ŽšƒR[ƒh‚Å•„†‰»‚³‚ê‚Ä‚¢‚é‚©‚̏î•ñ‚ªŽž‚í‚ꂳ‚Š‚µ‚È‚¯‚ê‚΁jB
+—á‚Š‚΁A“ú–{Œê”ÅWindows‚ł́Aƒƒ‚’ ‚Å‚àDOS‘‹‚Å‚àShift-JIS‚ªŽg‚í‚ê‚Ä‚¢‚Ü‚·B‚±‚€‚¢‚€ê‡Aˆ—‚Ì“r’†‚Å‚í‚Ž‚í‚ŽEUC-JP‚âUTF-8‚É•ÏŠ·‚·‚é‚Æ‚µ‚œ‚ç–Ê“|‚Å‚·BƒfƒoƒbƒO‚Ì‚Æ‚«Au‚±‚Ì’iŠK‚Å‚Í‚±‚̕ϐ”‚ɂ͉œ‚ª“ü‚Á‚Ä‚¢‚é‚Ì‚©vo—Í‚µ‚Ä“_ŒŸ‚·‚é‚Ì‚Í‚æ‚­s‚í‚ê‚Ü‚·‚ªA‚±‚Ì‚Æ‚«EUC-JP‚Æ‚µ‚ÄŽû‚ß‚ç‚ê‚Ä‚¢‚œ‚çAì‹Æ‚ÍŽèŠÔ‚Ç‚é‚Å‚µ‚å‚€B“ü—Í‚ào—Í‚àShift-JIS‚ōs‚€‚‚à‚è‚È‚çAˆ—‚Ì‘S‘Ì‚ÅShift-JIS‚̂܂܈µ‚Š‚œ‚ç‚«‚Á‚Æ•Ö—˜‚Å‚µ‚å‚€B
+’F "ƒVƒtƒgJIS", "Shift_JIS", "Shift-JIS" ‚È‚Ç‚Ì•\‹L‚̈Ⴂ‚ɂ‚¢‚Ä‚Í‚æ‚­‚í‚©‚Á‚Ä‚¢‚Ü‚¹‚ñB¡‚Ì‚Æ‚±‚땪‚©‚Á‚Ä‚¢‚邱‚Ƃ́F
+JIS X 0208:1997‚Ì•‘®‘1iƒVƒtƒg•„†‰»•\Œ»j‚ɂ́AuŽQlv‚Æ‚µ‚āu‚±‚Ì•„†‰»•\Œ»‚͒ʏígƒVƒtƒgJISƒR[ƒhh‚ƌĂ΂ê‚Ä‚¢‚év‚Ì‹Lq‚ª‚ ‚è‚Ü‚·B
+IANA ‚Ì CHARACTER SETS ‚ɂ́AShift_JIS ‚Æ Windows-31J ‚Æ‚ª•Ê‚É“o˜^‚³‚ê‚Ä‚¢‚Ü‚·B‚Ü‚œAShift_JIS‚ɂ‚¢‚āAuCCSi•„†‰»•¶ŽšW‡j‚ÍJIS X0201:1997‚ÆJIS X0208:1997‚Å‚ ‚èAŠ®‘S‚È’è‹`‚ÍJIS X 0208:1997‚Ì•‘®‘1‚ÉŽŠ‚³‚ê‚Ä‚¢‚éBv‚Æ‹L‚µ‚Ä‚¢‚Ü‚·B
+W3C ‚Ì XML Japanese Profile ‚ɂ́AShift-JIS‚ÉUnicode‚Ö‚Ì•ÏŠ·•\‚ª•¡”‚ ‚éŽ|‚Ì‹LÚ‚ª‚ ‚è‚Ü‚·BXML Japanese Profile (Second Edition)‚ł́AUnicode Consortium‚ÅŒöŠJ‚³‚ê‚Ä‚¢‚éMicrosoft CP932‚Ì•ÏŠ·•\‚É‚æ‚écharset‚Ì–ŒÌ "x-sjis-cp932" ‚ð "Windows-31J" ‚ɕύX‚µ‚Ä‚¢‚Ü‚·B
+MicrosoftŽÐ‚Ì Global Dev ‚ł́ACodepage 932 ‚ð "Japanese Shift-JIS" ‚Æ’‹L‚µ‚Ä‚¢‚Ü‚·B
+‚µ‚©‚µAShift-JIS‚É‚Í‚ ‚éŽí‚Ì•È‚ª‚ ‚Á‚āA‚¿‚å‚Á‚Æ‚µ‚œ‚±‚Æ‚ªƒoƒO‚âƒGƒ‰[‚╶Žš‰»‚¯‚ÌŒŽˆö‚Æ‚È‚è‚Ü‚·B‚È‚ñ‚Æ‚©‚È‚ç‚È‚¢‚à‚Ì‚Å‚µ‚å‚€‚©B
+Perl‚͐§Œä•¶Žš‚âƒiƒ‹•¶Žš‚ðŠÜ‚ÞƒoƒCƒiƒŠƒf[ƒ^‚Å‚·‚琳‚µ‚­ˆ—‚Å‚«‚é‚æ‚€‚ɐ݌v‚³‚ê‚Ä‚¢‚é‚̂ŁAƒXƒNƒŠƒvƒg‚âƒeƒLƒXƒg‚ðShift-JIS‚ŏ‘‚¢‚œ‚­‚ç‚¢‚Å–â‘è‚ɂȂ邱‚Æ‚Í‚ ‚è‚Ü‚¹‚ñB
+‚µ‚©‚µAperl‚ªƒXƒNƒŠƒvƒg‚ð‰ðŽß‚·‚é‚Æ‚«‚́i’ʏíjƒoƒCƒg’PˆÊ‚Å’²‚ׂé‚̂ŁAShift-JIS‚Ì‚æ‚€‚ȃ}ƒ‹ƒ`ƒoƒCƒg•¶Žš‚ðŠÜ‚Þ•„†‚Í‚»‚Ì‚Ü‚Ü‚Å‚Í’ŒÚ—‰ð‚Å‚«‚Ü‚¹‚ñB
+‚œ‚Æ‚Š‚΁AShift-JIS‚Å '‚ ' ‚Æ‚¢‚€•¶Žš‚́A16i”‚Å82 A0‚Æ‚¢‚€‚QƒoƒCƒg‚Å•\‚³‚ê‚Ü‚·B‚±‚ê‚ð "\x82\xA0" ‚Ə‘‚¢‚Ä‚àperl‚É‚Æ‚Á‚Ä‚Í“¯‚¶‚Å‚·B‚±‚ꂪ“ú–{‚́icountryj“ú–{Œê‚́ilanguagej•¶Žš‚Å‚ ‚é‚Æ‚©AShift-JIS‚ŏ‘‚©‚ê‚Ä‚¢‚éicharsetj‚Æ‚©‚¢‚€î•ñ‚Í‚Ç‚±‚É‚àŠÜ‚Ü‚ê‚Ä‚¢‚Ü‚¹‚ñB
+‚»‚Ì‚œ‚߁AShift-JIS‚ŏ‘‚«‚œ‚¢‚Æ‚«‚ɂ́Aperl‚ÌŒë‰ð‚ðŽó‚¯‚È‚¢‚æ‚€‚ɏ‘‚¢‚Ä‚â‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB‚»‚Ì”z—¶‚́AƒvƒƒOƒ‰ƒ}‚ª‚µ‚Ä‚â‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB‚±‚Ì•¶‘‚Ì‹Lq‚́A‚»‚Ì‚æ‚€‚ÈŽèŠÔ‚ð‚©‚¯‚Ä‚àAShift-JIS‚ð—p‚¢‚邱‚ƂɈӋ`‚ª‚ ‚é‚ƍl‚Š‚Ä‚¢‚él‚É‚ÍŽQl‚É‚È‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB
+‚»‚ñ‚ÈŽèŠÔ‚ðŠ|‚¯‚œ‚­‚È‚¢l‚́A
+Perl 5.8.xˆÈ~‚ðŽg‚€B
+—˜“_Fperl5-porters@perl.org ‚ŃTƒ|[ƒg‚³‚ê‚Ä‚¢‚éB
+Œ‡“_F“Æ“Á‚̍l‚Š•û‚ª‚ ‚èA]—ˆ‚Ì“ú–{Œêˆ—‚Æ‚Í‘Š—e‚ê‚È‚¢‚Æ‚±‚낪‚ ‚éi‚à‚Á‚Æ‚àA‚»‚Ì‚€‚¿Šµ‚ê‚Ä‹C‚É‚È‚ç‚È‚­‚È‚é‚©‚à‚µ‚ê‚È‚¢jB
+jperl‚ðŽg‚€B
+—˜“_FShift-JIS ‚𕶎š‚Æ‚µ‚Ä’ŒÚˆµ‚€‚±‚Æ‚ª‚Å‚«‚éB
+Œ‡“_FŒ»ÝAˆÛŽ‚·‚él‚ª‚¢‚È‚¢B
+•¶ŽšƒR[ƒh‚ðUTF-8‚©EUC-JP‚É•ÏŠ·‚µ‚Ä‚©‚珈—‚·‚éB
+—˜“_FPerl 5.8.xˆÈ~‚Å‚È‚­‚Ä‚à“®ì‚·‚é•ÏŠ·—p‚̃‚ƒWƒ…[ƒ‹(.pm)‚⃉ƒCƒuƒ‰ƒŠ(.pl)‚ª‚¢‚ë‚¢‚ë“üŽè‰Â”\B
+Œ‡“_FShift-JIS‚قLj«‚­‚È‚¢‚É‚µ‚Ä‚àAƒ}ƒ‹ƒ`ƒoƒCƒg•¶Žš‚ðƒVƒ“ƒOƒ‹ƒoƒCƒg•¶Žš‚Æ‹æ•Ê‚¹‚žA‚Æ‚à‚ɈꕶŽš‚Æ‚µ‚ďˆ—‚·‚é‚Ì‚Í–Ê“|‚Å‚ ‚éB
+ ‚Æ‚¢‚€‘Ώˆ‚ð‚Æ‚Á‚œ‚Ù‚€‚ª‚æ‚¢‚Å‚µ‚å‚€B‚±‚ê‚ç‚̃vƒƒOƒ‰ƒ€‚Í—L–Œ‚Ȃ̂ŁA’T‚¹‚΂·‚®Œ©‚‚©‚é‚Å‚µ‚å‚€‚©‚çA“üŽèæ‚Í‚±‚±‚É‚ÍŽŠ‚µ‚Ü‚¹‚ñB
+‚È‚šA‚±‚Ì•¶‘‚ɏ‘‚©‚ê‚Ä‚¢‚鎖‚ªAÅ‚àŠ©‚ß‚ç‚ê‚È‚¢•û–@‚Ȃ̂ŁA‚±‚±‚©‚çæ‚́A‚»‚̂‚à‚è‚Å‚š“ǂ݉º‚³‚¢B‚±‚Ì•û–@‚ɂ‚¢‚ĉœ‚©‹^–₪¶‚¶‚œ‚Æ‚µ‚Ä‚àA‚»‚ê‚ɂ‚¢‚Ä‘Œ‚Ì‚Æ‚±‚ë‚ÅŽ¿–â‚·‚é‚ƁA‰œ‚Å‚»‚ñ‚È‚â‚è•û‚ð‚µ‚Ä‚¢‚é‚Ì‚©‚ƁA‚«‚Á‚Æ”ñ“‚ê‚é‚Å‚µ‚å‚€B‚©‚Æ‚¢‚Á‚āAŽ„‚É‚àu‚©‚È‚¢‚ʼnº‚³‚¢B
+Shift-JIS‚ðŽg‚Á‚œ‚Æ‚«‚É‚ ‚肪‚¿‚ȁiHjƒGƒ‰[
+Shift-JIS‚ɂ́A‘æ‚QƒoƒCƒg‚ª [@-~]iASCII 10i”‚Å64-126j‚͈̔͂ɓü‚é‚à‚Ì‚ª‚ ‚è‚Ü‚·B‚±‚ê‚ç‚ÌASCII•¶Žš‚́Aperl‚É‚Æ‚Á‚Ä“Á•Ê‚ȈӖ¡‚ð‚à‚‚±‚Æ‚ª‚ ‚é‚œ‚߁A‚µ‚΂µ‚΃Gƒ‰[‚ÌŒŽˆö‚Æ‚È‚è‚Ü‚·BShift-JIS‚ł́A‚QƒoƒCƒg•¶Žš‚Ì‘æ‚QƒoƒCƒg‚́A[\x40-\x7E\x80-\xFC])‚͈̔͂ɂ ‚é‚œ‚߁AŽÀ‚É188•ª‚Ì63A–ñ‚R•ª‚Ì‚P‚Ì•¶Žš‚ª‰œ‚ç‚©‚Ì–â‘è‚ð‹N‚±‚µ“Ÿ‚é‚Æ‚¢‚Š‚Ü‚·B
+ŽŸ‚ɁAShift-JIS‚ðŽg‚Á‚œ‚Æ‚«‚É‹N‚±‚肪‚¿‚ȃGƒ‰[‚Æ‚»‚ÌŒŽˆö‚ðŽŠ‚µ‚Ü‚·BƒGƒ‰[ƒƒbƒZ[ƒW‚Íperl‚̈Ⴂiƒo[ƒWƒ‡ƒ“‚â‚ǂ̃vƒ‰ƒbƒgƒtƒH[ƒ€—p‚Ì‚à‚Ì‚Å‚ ‚é‚©“™j‚É‚æ‚è‘œ­‚̈Ⴂ‚ª‚ ‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB
+ƒGƒ‰[‚É‚È‚ç‚È‚­‚Ä‚àA•¶Žš‰»‚¯‚µ‚œ‚èAŠú‘Ò‚µ‚œ‚æ‚€‚È“®ì‚ð‚µ‚È‚©‚Á‚œ‚è‚ŁA‚€‚Ü‚­‚¢‚©‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚·B‚±‚̏ꍇAƒGƒ‰[‚ªo‚È‚¢•ªAŒŽˆö‚ðŽ©•ª‚Å’T‚³‚È‚¯‚ê‚΂Ȃç‚È‚­‚È‚é‚œ‚߃oƒOŽæ‚è‚Í‚µ‚΂µ‚΍¢“ï‚Å‚·B
+‚±‚±‚ł̓Gƒ‰[‚ɑ΂·‚é‘΍ô‚Í’ñŽŠ‚µ‚Ü‚¹‚ñB‘΍ô‚Í‚ ‚Ƃł܂Ƃ߂ď‘‚«‚Ü‚·B
+‚È‚šA‚±‚±‚É‚Í•¶ŽšƒR[ƒh‚ðEUC-JP‚É‚µ‚Ä‚à‹N‚±‚é‚æ‚€‚È–â‘è‚âƒGƒ‰[‚ÍŽŠ‚µ‚Ü‚¹‚ñBŠî–{“I‚ɁAEUC-JP‚È‚ç‹N‚«‚È‚¢‚ªAShift-JIS‚Ì‚Æ‚«‚É‚Í‹N‚±‚é‚æ‚€‚ÈŽ–•¿‚ÉŒÀ‚è‚Ü‚·B
+ƒGƒ‰[‚É‚Í‚È‚ç‚È‚¢‚¯‚Ç•¶Žš‰»‚¯‚·‚éi‚Pj
+—á‚Š‚΁A"•\ŽŠ" ‚Æ‚© "–\—Í" ‚Æ‚©‚¢‚€ƒŠƒeƒ‰ƒ‹‚ª•¶Žš‰»‚¯‚ð‹N‚±‚µ‚Ü‚·B‚±‚ê‚ç‚Í "•ŽŠ" ‚Æ‚© "–—Í" ‚É‚È‚è‚Ü‚·B‚±‚ê‚́A"•\" ‚â "–\"‚Ì•¶Žš‚Ì‘æ‚QƒoƒCƒg‚ª \ ‚Å‚ ‚é‚œ‚߁Aƒ_ƒuƒ‹ƒNƒI[ƒg•¶Žš‚Ì’†‚Å‚ÍŽŸ‚Ì•¶Žš‚̃GƒXƒP[ƒv‚ð‚·‚é‚±‚Æ‚É‚È‚é‚̂ŁA•\ŽŠ  0x955C8EA6 ‚Å‚ ‚Á‚Ä‚àAƒNƒI[ƒg‚ÌŒ‹‰Ê‚Í "•\ŽŠ"  0x958EA6 ‚Æ‚È‚é‚©‚ç‚Å‚·B'•\ŽŠ' ‚Æ‚·‚ê‚Ε¶Žš‰»‚¯‚Í‹N‚±‚è‚Ü‚¹‚ñ‚ªAƒVƒ“ƒOƒ‹ƒNƒI[ƒg‚Å‚à–h‚°‚È‚¢•¶Žš‰»‚¯‚âƒGƒ‰[‚ª‚ ‚è‚Ü‚·iŽŸ—ájB
+ƒGƒ‰[‚É‚Í‚È‚ç‚È‚¢‚¯‚Ç•¶Žš‰»‚¯‚·‚éi‚Qj
+—á‚Š‚΁A"ƒ~ƒ\\500" ‚Æ‚¢‚€ƒŠƒeƒ‰ƒ‹‚ł́A\ ‚ª’E—Ž‚µ‚Ä‚µ‚Ü‚¢‚Ü‚·B‚±‚ê‚́A'ƒ~ƒ\\500' ‚â q(ƒ~ƒ\\500) ‚È‚Ç‚Æ‚µ‚Ä‚à–h‚®‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñB‚»‚ê‚Í \\ ‚Æ‚¢‚€˜A‘±‚ª‚ ‚é‚Æ \ ‚PŒÂ‚É‚È‚Á‚Ä‚µ‚Ü‚€‚Æ‚¢‚€‹K‘¥‚ª‚ ‚é‚©‚ç‚Å‚·B
+ƒNƒI[ƒg‚âƒNƒI[ƒg•—‰‰ŽZŽq‚Ì’†‚ł́A•¶Žš—ñ‚ɃNƒI[ƒg‚Æ“¯‚¶•¶Žš‚ðŠÜ‚ß‚ç‚ê‚é‚æ‚€‚ɁA\ ‚É‚æ‚éƒGƒXƒP[ƒv‚ð•t‚¯‚ê‚΃NƒI[ƒg‚̏I’[•¶Žš‚Å‚Í‚È‚­A•¶Žš—ñ‚̈ꕔ‚Æ‚Ý‚È‚µ‚Ü‚·B‚»‚Ì‚œ‚߁A\\ ‚ª \ ‚Ì•¶Žš‚ð•\‚·ƒGƒXƒP[ƒv‚É‚È‚è‚Ü‚·B‚±‚ê‚̓NƒI[ƒg‚ÌŽn’[EI’[•¶Žš‚ð‰œ‚É‚µ‚Ä‚à“¯‚¶‚±‚Æ‚Å‚·B
+ƒGƒ‰[‚É‚Í‚È‚ç‚È‚¢‚¯‚Ç•¶Žš‰»‚¯‚·‚éi‚Rj
+—á‚Š‚΁A"ŠÛ\net" ‚Æ‚¢‚€ƒŠƒeƒ‰ƒ‹‚ª•¶Žš‰»‚¯‚ð‹N‚±‚µ‚Ü‚·B‚±‚ê‚Í "ŠÛ¥
+et" ‚Ì‚æ‚€‚É“r’†‚ʼnüs‚³‚ê‚Ä‚µ‚Ü‚¢‚Ü‚·B‚±‚ê‚́A"\" ‚Ì‘æ‚QƒoƒCƒg‚ª \ ‚Å‚ ‚é‚œ‚߁Aƒ_ƒuƒ‹ƒNƒI[ƒg•¶Žš‚Ì’†‚Å‚ÍŽŸ‚Ì 'n' ‚ƍ‡‚킹‚Ä\n‚Ì‚·‚È‚í‚¿‰üs•¶Žš‚ð•\‚·ƒƒ^•¶Žš‚Æ‚µ‚ĉðŽß‚³‚ê‚é‚©‚ç‚Å‚·B
+ƒGƒ‰[‚É‚Í‚È‚ç‚È‚¢‚¯‚Ç•¶Žš‰»‚¯‚·‚éi‚Sj
+—á‚Š‚΁A"ˆø”@ARGV" ‚Æ‚¢‚€ƒŠƒeƒ‰ƒ‹‚ª•¶Žš‰»‚¯‚ð‹N‚±‚µ‚Ü‚·B‚±‚ê‚́A"@"i‘SŠpƒXƒy[ƒXj‚Ì‘æ‚QƒoƒCƒg‚ª @ ‚Å‚ ‚é‚œ‚߁Aƒ_ƒuƒ‹ƒNƒI[ƒg•¶Žš‚Ì’†‚Å‚ÍŽŸ‚Ì ARGV ‚ƍ‡‚킹‚Ä "@ARGV" ‚Æ‚¢‚€”z—ñ‚Æ‚µ‚ĕϐ”“WŠJ‚ðs‚€‚©‚ç‚Å‚·B@ARGV‚Ì‚æ‚€‚É•K‚ž’è‹`‚³‚ê‚é‚æ‚€‚È”z—ñ‚È‚çA“WŠJ‚³‚ê‚Ü‚·‚ªA•Ê‚̏ꍇ‚ł̓Gƒ‰[‚É‚È‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñi‚»‚ê‚ÍŽŸ€‚ðŽQÆjB
+In string, @dog now must be written as \@dog (Perl 5.6.0‚Ü‚Å)
+u•¶Žš—ñ‚Ì’†‚ł́A@dog‚͍¡‚Í\@dog‚Ə‘‚©‚È‚¯‚ê‚΂Ȃç‚È‚¢v
+‘O—á‚Å‚Ý‚œ‚æ‚€‚ɁA‘SŠpƒXƒy[ƒX "@"‚Ì‘æ‚QƒoƒCƒg‚Í @ ‚Å‚ ‚é‚œ‚߁AŒã‚ë‚Ì•¶Žš‚ƍ‡‚킹‚Ä”z—ñ‚Å‚ ‚é‚©‚Ì‚æ‚€‚ɉðŽß‚µ‚æ‚€‚Æ‚µ‚Ü‚·B"Œ¢@dog" ‚Ì‚æ‚€‚ȏꍇA@dog ‚Æ‚¢‚€”z—ñ‚ª’è‹`‚³‚ê‚Ä‚¢‚ê‚΂»‚ê‚ð—p‚¢‚ĕϐ”“WŠJ‚µ‚Ü‚·‚ªA’è‹`‚³‚ê‚Ä‚¢‚È‚¢ê‡AƒGƒ‰[ƒƒbƒZ[ƒW‚ðo‚µ‚Ü‚·B
+``now must be written as''u¡‚Í‚±‚€‘‚©‚È‚¯‚ê‚΂Ȃç‚È‚¢v‚Ƃ́APerl4‚Ü‚Å‚Í”z—ñ‚̕ϐ”“WŠJ‚͍s‚í‚È‚©‚Á‚œ‚œ‚߁A"hoge@foo.bar" ‚Ì‚æ‚€‚ȏ‘‚«•û‚ð‚·‚é‚±‚Æ‚ª‚Å‚«‚œ‚Ì‚Ÿ‚ªA¡ Perl‚Å‚Í @foo ‚ª“WŠJ‚³‚ê‚Ä‚µ‚Ü‚€‚̂ŁA’ˆÓ‚ðŠ«‹N‚·‚é‚œ‚߃Gƒ‰[‚ðo‚·‚æ‚€‚É‚µ‚Ä‚¢‚é‚æ‚€‚Å‚·i‚à‚µPerl‚ªÌ‚©‚ç”z—ñ‚Ì“WŠJ‚ðƒTƒ|[ƒg‚µ‚Ä‚¢‚œ‚çAƒGƒ‰[‚ðo‚·‚±‚Æ‚È‚­A–Ù‚Á‚Ä“WŠJ‚·‚é‚Ÿ‚¯‚Ÿ‚Á‚œ‚©‚à‚µ‚ê‚Ü‚¹‚ñBŽŸ€‚àŽQÆjB
+"Œ¢@\dog" ‚Æ‚·‚ê‚΂¢‚¢‚Æ‚¢‚€ˆÓŒ©‚à‚ ‚è‚Ü‚·‚ªA\d ‚ªƒƒ^•¶Žš‚Æ‚µ‚Ä“Á•ÊˆÓ–¡‚ª‚È‚¢‚œ‚ß‚É‚€‚Ü‚­‚¢‚­‚Ì‚Å‚ ‚Á‚āiPerl 5.6ˆÈ~‚ł́AŒx Unrecognized escape \d passed through u”FŽ¯‚Å‚«‚È‚¢ƒGƒXƒP[ƒv \d ‚ª“n‚³‚ê‚œv‚ðˆø‚«‹N‚±‚µ‚Ü‚·jA—á‚Š‚Î "‰Ô@\flower" ‚Ì‚Æ‚«‚́A\f ‚ª‰üƒy[ƒW•¶Žš‚Æ‚µ‚ĉðŽß‚³‚êA•¶Žš‰»‚¯‚µ‚Ü‚·B
+Possible unintended interpolation of @dog in string (Perl 5.6.1ˆÈ~)
+•¶Žš—ñ‚Ì’†‚ŁA@dog‚ª—\Šú‚¹‚ž‚É“WŠJ‚³‚ê‚é
+‘O€‚Æ“¯‚¶‚­A"Œ¢@dog" ‚Å‚·‚ªAPerl 5.6.1iActivePerl 626jˆÈ~‚ł́A’è‹`‚³‚ê‚Ä‚¢‚È‚¢”z—ñ‚Å‚à–Ù‚Á‚Ä“WŠJ‚µ‚Ü‚·B”z—ñ @dog ‚ª“WŠJ‚³‚ê‚é‚̂ŁA"Œ¢\x81" ‚Æ“¯‚¶‚É‚È‚è‚Ü‚·B
+‚±‚ê‚̓Gƒ‰[‚Å‚Í‚È‚­AŒx‚É‚È‚è‚Ü‚·B
+Can't find string terminator '"' anywhere before EOF
+uI’[•¶Žš '"'‚ªƒtƒ@ƒCƒ‹‚̏I‚è EOF ‚Ü‚Å‚ÉŒ©‚‚©‚ç‚È‚©‚Á‚œv
+—á‚Š‚΁A"‘Ήž•\" ‚Ì‚æ‚€‚ȃŠƒeƒ‰ƒ‹‚ł́A'•\' ‚Ì‘æ‚QƒoƒCƒg‚ª \ ‚Å‚ ‚é‚œ‚߁A‚€‚µ‚ë‚Ì " ‚ðƒGƒXƒP[ƒv‚µ‚Ä‚µ‚Ü‚¢‚Ü‚·B‚±‚Ì‚œ‚ßperl‚́A‚»‚Ì " ‚̓NƒI[ƒg•¶Žš—ñ‚̏I’[•¶Žš‚Æ‚Í‚Ý‚È‚³‚ž‚ɁA•¶Žš—ñ‚ª‚³‚ç‚É‘±‚­‚ƍl‚Š‚Ä‚µ‚Ü‚¢‚Ü‚·B‚±‚êˆÈ~AƒXƒNƒŠƒvƒg‚Ì’†‚É " ‚Ì•¶Žš‚ª‘S‚­ŠÜ‚Ü‚ê‚È‚¯‚ê‚΁A‚±‚Ì‚æ‚€‚ɃGƒ‰[•ñ‚ð‚µ‚Ü‚·B
+qq{ "“ú–{Œê" }‚Ì‚æ‚€‚ȏꍇ‚É‚à’ˆÓ‚µ‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB"–{" ‚Ì‘æ“ñƒoƒCƒg‚Í { ‚Ȃ̂ŁA‚±‚Ì‚Ü‚Ü‚Å‚Í { }‚̃lƒXƒg‚ª‚ž‚ê‚Ä‚µ‚Ü‚¢A“¯—l‚̃Gƒ‰[‚ª”­¶‚µ‚Ü‚·B
+Bareword found where operator expected
+u—‡‚̌ꂪ‰‰ŽZŽq‚ª‚ ‚Á‚Ä‚Ù‚µ‚¢ˆÊ’u‚ÉŒ©‚‚©‚Á‚œv
+—á‚Š‚΁Aprint "<img alt=\"‘Ήž•\\" height=115 width=150>"; ‚Ì‚æ‚€‚ȏꍇA\" ‚É‚æ‚éˆø—p•„‚̃GƒXƒP[ƒv‚́A•\ ‚Ì‘æ‚QƒoƒCƒg‚Ì\‚Ì‚œ‚߁A\\ " ‚Æ‚¢‚€‘g‚ݍ‡‚킹‚É‚È‚èAƒGƒXƒP[ƒv‚ª‘Å‚¿Á‚³‚ê‚Ä‚¢‚Ü‚·B‚»‚Ì‚œ‚߁A‚±‚̃Šƒeƒ‰ƒ‹‚́Aperl‚©‚猩‚é‚ƁA"<img alt=\"‘Ήž•\\" ‚ŏI‚í‚Á‚Ä‚¢‚Ü‚·B‚»‚Ì‚œ‚߁AƒŠƒeƒ‰ƒ‹‚ÌŒã‚ɁAheight ‚Æ‚¢‚€u—‡‚ÌŒêviƒNƒI[ƒg‚ň͂܂ê‚Ä‚¢‚È‚¢•¶Žš—ñj‚ª‚ ‚é‚æ‚€‚ɂ݂āA‚±‚±‚É‚Í—‡‚ÌŒê‚Å‚Í‚È‚­A‰‰ŽZŽq‚ª‚ ‚é‚ׂ«‚Å‚Í‚È‚¢‚©H‚Æperl‚͍l‚Š‚Ü‚·B
+Unrecognized character \x82
+u”FŽ¯‚³‚ê‚È‚¢•¶Žš \x82v
+‚±‚ê‚́A”ñASCII•¶Žš‚â‚»‚Ì‘Œ‚Ì•¶Žš‚ðu—‡‚ÌŒêv‚É‚µ‚œ‚Æ‚«‚ɏo‚郁ƒbƒZ[ƒW‚Å‚·B"‘Ήž•\" ‚Ì‚æ‚€‚ȃŠƒeƒ‰ƒ‹‚ª‚ ‚Á‚āA‚»‚Ì‚ ‚Æ‚É "‚È‚ñ‚Å‚à‚¢‚¢‚¯‚Ç" ‚Ì‚æ‚€‚ȃŠƒeƒ‰ƒ‹‚ª‚ ‚Á‚œ‚Æ‚«A‘O—á‚Æ“¯‚¶——R‚©‚ç‹N‚±‚é‚à‚Ì‚Å‚·B
+‚Ü‚œAq{ƒ}ƒbƒ`} ‚Ì‚æ‚€‚ȏꍇ‚É‚àA'ƒ}' ‚Ì‘æ“ñƒoƒCƒg‚ª } ‚Ȃ̂ŁA{ } ‚̃JƒbƒR‚Í‚»‚±‚ŏI‚í‚Á‚Ä‚µ‚Ü‚¢A“¯—l‚ȃGƒ‰[‚É‚È‚è‚Ü‚·B
+ƒ}ƒbƒ`‚µ‚È‚¢‚Í‚ž‚Ȃ̂Ƀ}ƒbƒ`‚·‚éi‚Pj
+"ƒ„ƒJƒ“" =~ /ƒ|ƒbƒg/ ‚̓}ƒbƒ`‚µ‚Ü‚·B‚»‚ê‚́A'ƒ|' ‚Ì‘æ“ñƒoƒCƒg‚ª | ‚Ȃ̂ŁA/ƒ|ƒbƒg/ ‚Í /\x83|ƒbƒg/ ‚Æ‚Ý‚È‚³‚êA\x83 ‚Ÿ‚¯ƒ}ƒbƒ`‚·‚ê‚΂悢‚©‚ç‚Å‚·B
+ƒ}ƒbƒ`‚µ‚È‚¢‚Í‚ž‚Ȃ̂Ƀ}ƒbƒ`‚·‚éi‚Qj
+"ŒZ’í" =~ /Z/ ‚̓}ƒbƒ`‚µ‚Ü‚·B‚»‚ê‚́A'ŒZ' ‚Ì‘æ“ñƒoƒCƒg‚ª 'Z' ‚Ÿ‚©‚ç‚Å‚·B‘æ“ñƒoƒCƒg‚ªƒAƒ‹ƒtƒ@ƒxƒbƒg‚ɂȂ镶Žš‚É‚Í’ˆÓ‚ª•K—v‚Å‚·B
+ƒ}ƒbƒ`‚·‚é‚Í‚ž‚Ȃ̂Ƀ}ƒbƒ`‚µ‚È‚¢i‚Pj
+"‰^“]–Æ‹–" =~ /‰^“]/ ‚̓}ƒbƒ`‚µ‚Ü‚¹‚ñB‚»‚ê‚́A'‰^' ‚Ì‘æ“ñƒoƒCƒg‚ª '^'‚Ȃ̂ŁA/‰^“]/ ‚Í /\x89^“]/ ‚Æ‚Ý‚È‚³‚êA•¶Žš—ñ‚ÌŽn‚ß ^ ‚Ì‘O‚É \x89 ‚Í‚È‚¢‚©‚ç‚Å‚·B
+Search pattern not terminated
+uƒT[ƒ`ƒpƒ^[ƒ“‚ªI—¹‚µ‚È‚¢v
+‚±‚ê‚́A/•\/ ‚Ì‚æ‚€‚ɁA‘æ“ñƒoƒCƒg‚ª \ ‚Å‚ ‚镶Žš‚ŃT[ƒ`ƒpƒ^[ƒ“‚ðI‚í‚点‚æ‚€‚Æ‚µ‚œ‚Æ‚«‚É‹N‚±‚è‚Ü‚·Bƒ}ƒbƒ`‰‰ŽZŽq‚̏I’[•¶Žš / ‚ðƒGƒXƒP[ƒv‚µ‚Ä‚µ‚Ü‚€‚̂ŁAƒT[ƒ`ƒpƒ^[ƒ“‚ª‚³‚ç‚ɐæ‚É‘±‚­‚æ‚€‚ɉðŽß‚³‚ê‚Ü‚·B‚»‚̐æ‚É‚à‚€ˆê“x/‚Í‚ ‚è‚Ü‚·‚©H
+‚ ‚Á‚œ‚Æ‚±‚ë‚ŁA•Ê‚̃Gƒ‰[‚ª”­¶‚·‚é‚Å‚µ‚å‚€B
+Substitution replacement not terminated
+u’uŠ·‘€ì‚Ì’uŠ·•¶Žš—ñ‚ªI—¹‚µ‚È‚¢v
+’uŠ·‰‰ŽZŽq‚Í s/PATTERN/REPLACEMENT/‚ÌŒ`Ž®‚ð‚Æ‚ç‚˂΂Ȃè‚Ü‚¹‚ñB‚µ‚©‚µ s/•\/— /; ‚Ì‚æ‚€‚ɁA‘æ“ñƒoƒCƒg‚ª \ ‚Å‚ ‚镶Žš‚ÅPATTERN•”•ª‚ðI‚í‚点‚æ‚€‚Æ‚µ‚œ‚Æ‚«‚É‚±‚̃Gƒ‰[‚ª‹N‚±‚è‚Ü‚·Bƒ}ƒbƒ`‰‰ŽZŽq‚̏I’[•¶Žš / ‚ðƒGƒXƒP[ƒv‚µ‚Ä‚µ‚Ü‚€‚̂ŁAPATTERN‚ª‚³‚ç‚ɐæ‚É‘±‚­‚æ‚€‚ɉðŽß‚³‚ê‚Ü‚·B‚»‚Ì‚œ‚ßperl‚́APATTERN‚Í •\/—  ‚Ì•”•ª‚Å‚ ‚é‚ƍl‚ŠA‚R”Ô–Ú‚Ì/‚̐æ‚ÉREPLACEMENT•”•ª‚ª‚ ‚é‚ɈႢ‚È‚¢‚ÆŽv‚€‚Ì‚Å‚·‚ªA‚»‚̐æ‚É‚à‚€ˆê“x/‚Í‚ ‚è‚Ü‚·‚©H
+‚ ‚Á‚œ‚Æ‚±‚ë‚ŁA•Ê‚̃Gƒ‰[‚ª”­¶‚·‚é‚Å‚µ‚å‚€B
+unmatched [ ] in regexp
+u³‹K•\Œ»‚Ƀ}ƒbƒ`‚µ‚È‚¢ [ ] ‚ª‚ ‚év
+—á‚Š‚΁A/ƒv[ƒ‹/ ‚ł̓Gƒ‰[‚ª‹N‚±‚è‚Ü‚·B‚»‚ê‚Í '[' ‚Ì‘æ“ñƒoƒCƒg‚ª [ ‚Ȃ̂ŁA/ƒv[ƒ‹/ ‚Í /ƒv\x81[\x83\x8B/ ‚Æ‚Ý‚È‚³‚êAperl‚Í•¶ŽšƒNƒ‰ƒX‚ª‚ ‚é‚Ì‚Å‚Í‚È‚¢‚©‚ÆŽv‚¢‚Ü‚·B‚µ‚©‚µ•¶ŽšƒNƒ‰ƒX‚̏I—¹‚ðŽŠ‚· ] ‚ªŒ©‚‚©‚ç‚È‚¢‚̂ŃGƒ‰[‚É‚È‚è‚Ü‚·B
+ƒGƒ‰[‚É‚Í‚È‚ç‚È‚¢‚¯‚Ç•¶Žš‰»‚¯‚·‚éi‚Tj
+—á‚Š‚΁Alc('ƒAƒCƒEƒGƒI')‚́A'ƒaƒcƒeƒgƒi'‚ð•Ô‚µ‚Ü‚·BShift-JIS‚Ì‚QƒoƒCƒg•¶Žš‚Ì’†‚ɂ́A‘æ‚QƒoƒCƒg‚ªASCII‚ʼnpŽš‚É“–‚œ‚é‚à‚Ì‚ª‚ ‚è‚Ü‚·BÚ‚µ‚­‚̓Aƒ‹ƒtƒ@ƒxƒbƒg‚̑啶Žš‚Ə¬•¶Žš‚ð‚²——‰º‚³‚¢B
+ƒGƒ‰[‚âŠÔˆá‚¢‚ð–h‚®‘΍ô
+ˆÈã‚Ì‚æ‚€‚ȃGƒ‰[‚ð–h‚®‚É‚Í‚³‚Ü‚Ž‚Ü‚È•û–@‚ªl‚Š‚ç‚ê‚Ü‚·B—á‚Š‚΁A"•\\ŽŠ" ‚Ə‘‚¯‚΂¢‚¢‚È‚Ç‚Æ‚¢‚€’ñˆÄ‚ª‚ ‚è‚Ü‚·B‚à‚¿‚ë‚ñ‚»‚ê‚Å‚à‚©‚Ü‚¢‚Ü‚¹‚ñB‚µ‚©‚µ‚»‚Ì‚œ‚ß‚É‚Í‚Ç‚Ì•¶Žš‚ÌŒã‚É \ ‚ð“ü‚ê‚ê‚΂¢‚¢‚©‚ð’m‚é•K—v‚ª‚ ‚è‚Ü‚·B‚»‚ê‚Í•¶ŽšƒR[ƒh•\‚ðŒ©‚ê‚Έꔭ‚Å–Ÿ‚ç‚©‚Å‚·B
+c‚È‚Ç‚Æ‚¢‚€–Ê“|‚È‚±‚Æ‚ª‹ê‚É‚È‚ç‚È‚¢lA•¶ŽšƒR[ƒh•\‚È‚ñ‚©i­‚È‚­‚Æ‚à–â‘è‚É‚È‚é‚æ‚€‚È•¶Žš‚­‚ç‚¢‚́jˆÃ‹L‚µ‚Ä‚µ‚Ü‚Š‚΂¢‚¢‚Æ‚¢‚€‚æ‚€‚Ȑl‚É‚Æ‚Á‚ẮAŠm‚©‚É‚»‚ê‚Å‰ðŒˆ‚É‚È‚é‚ÆŽv‚¢‚Ü‚·B‚µ‚©‚µA‚»‚Ì‚æ‚€‚Ȑl‚ɂ́A‚±‚ñ‚ȃy[ƒW‚ðŒ©‚É‚­‚é•K—v‚àƒqƒ}‚à‚È‚¢‚Å‚µ‚å‚€B
+‚»‚±‚ŁA‚±‚Ì‚æ‚€‚ȃy[ƒW‚ð‚í‚Ž‚í‚ŽŒ©‚É‚­‚é‚æ‚€‚Ȑl‚́A•¶ŽšƒR[ƒh•\‚ð‚¢‚¿‚¢‚¿’²‚ׂœ‚­‚È‚¢‚ЂƂŸ‚ƉŒ’肵‚Ü‚·B•Ê‚É‚»‚€‚Ÿ‚©‚ç‚Æ‚¢‚Á‚Ä”ñ“‚ê‚邱‚Æ‚Í‚ ‚è‚Ü‚¹‚ñB‚µ‚©‚µAŽèŠÔ‚ðÉ‚µ‚Þ‚ ‚Ü‚èŠÔˆá‚Á‚œƒvƒƒOƒ‰ƒ€‚𕜋C‚ōì‚Á‚Ä‚¢‚ẮAŠç‚ɃNƒŠ[ƒ€ƒpƒC‚ð‚Ԃ‚¯‚ç‚ê‚Ä‚àŽd•û‚ ‚è‚Ü‚¹‚ñB
+•¶Žš—ñƒŠƒeƒ‰ƒ‹‚̍ì‚è•û
+‚æ‚­’m‚Á‚Ä‚š‚©‚˂΂Ȃç‚È‚¢‚±‚Ƃ́A\ ‚Æ‚¢‚€ƒGƒXƒP[ƒv—p‚Ì•¶Žš‚́A•Ï”“WŠJ‚⃁ƒ^•¶Žš‚̉ðŽß‚æ‚è‚ž‚Á‚Æ‘O‚Ì’iŠK‚Å‚³‚Ü‚Ž‚܂ȉe‹¿‚ð‹y‚Ú‚·‚Æ‚¢‚€‚±‚Æ‚Å‚·B‚»‚Ì‚œ‚߁A‚Ç‚€‚µ‚œ‚çƒf[ƒ^‚ðŠmŽÀ‚ɕϐ”‚Ì’†‚ÉŽû‚ß‚ç‚ê‚é‚©‚ðl‚Š‚é•K—v‚ª‚ ‚è‚Ü‚·B•Ï”‚Ì“à•”‚ÉŽû‚ß‚Ä‚µ‚Ü‚Š‚΁APerl‚ªƒf[ƒ^‚ð“KØ‚ÉŠÇ—‚µ‚Ä‚­‚ê‚Ü‚·B‚æ‚­’m‚ç‚ê‚Ä‚¢‚é $str = "•\ŽŠ" ‚Ì•¶Žš‰»‚¯‚àA•Ï”$str‚É‘ã“ü‚·‚éˆÈ‘OAƒ_ƒuƒ‹ƒNƒH[ƒg‚ň͂ñ‚ŸŽž“_‚Å‚·‚Å‚É•¶Žš‰»‚¯‚µ‚Ä‚¢‚é‚ƍl‚Š‚é‚ׂ«‚Å‚·B‚·‚Å‚É•¶Žš‰»‚¯‚µ‚œƒf[ƒ^‚ð‘ã“ü‚µ‚āAD‚¢Œ‹‰Ê‚ª“Ÿ‚ç‚ê‚é‚Í‚ž‚ª‚ ‚è‚Ü‚¹‚ñB
+ƒqƒAƒhƒLƒ…ƒƒ“ƒg‚͈À‘S«‚̍‚‚¢‰ðŒˆ–@‚Å‚·B‚œ‚Ÿ‚µAI’[•¶Žš—ñ‚ðƒVƒ“ƒOƒ‹ƒNƒH[ƒg‚ň͂ñ‚Å‚â‚ç‚È‚­‚Ä‚Í‚È‚è‚Ü‚¹‚ñBƒ_ƒuƒ‹ƒNƒH[ƒg‚ň͂ñ‚Ÿ‚èAƒNƒH[ƒg‚ð•t‚¯‚È‚©‚Á‚œ‚è‚ł́A—\Šú‚¹‚ʕϐ”“WŠJ‚⃁ƒ^•¶Žš‚̉ðŽß‚ð–h‚®‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñB
+ƒVƒ“ƒOƒ‹ƒNƒH[ƒg‚ŏI’[•¶Žš—ñ‚ðˆÍ‚ñ‚ŸƒqƒAƒhƒLƒ…ƒƒ“ƒg‚ł́A•Ï”“WŠJ‚⃁ƒ^•¶Žš‚̉ðŽß‚͉œ‚à‹N‚±‚è‚Ü‚¹‚ñB‚œ‚ŸAI’[•¶Žš—ñi‚±‚̏ꍇ‚Í "\nEOF\n"j‚ð’T‚·‚±‚Æ‚Ÿ‚¯‚ðs‚¢‚Ü‚·BƒqƒAƒhƒLƒ…ƒƒ“ƒg‚ðŽg‚€‚Æ•¶Žš—ñ‚ɉüs•¶Žš‚ª‚‚«‚Ü‚·‚ªAchomp‚ŏœ‚­‚Æ‚¢‚¢‚Å‚µ‚å‚€B
+ŽŸ‚Ì—á‚Í $str = '‚±‚±‚ɃeƒLƒXƒg‚ð‘‚­' ‚Æ“¯‚¶‚æ‚€‚É“­‚«‚Ü‚·‚ªA•¶Žš—ñ‚Ì“à—e‚É‚æ‚Á‚Ä–â‘肪‹N‚±‚è‚Ü‚¹‚ñB‘‚¢‚œ‚Æ‚š‚è‚ɃŠƒeƒ‰ƒ‹‚ð‘ã“ü‚Å‚«‚é‚ÆŠú‘Ò‚Å‚«‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+chomp($str = << 'EOF');
+‚±‚±‚ɃeƒLƒXƒg‚ð‘‚­
+EOF
+
+$src = << 'EOF';
+ $path = "C:\\path\\file";
+ open FH, $path;
+EOF
+
+‘œ‚­‚Ì•¶Žš—ñ‚ðˆê“x‚ɍì‚è‚œ‚¯‚ê‚΁Asplit‚Å•ªŠ„‚·‚é‚Æ—eˆÕ‚ɍì‚ê‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+($name, $career, $age, $memo) = split "\n", << 'EOF';
+“c’†ˆê˜Y
+ƒvƒƒOƒ‰ƒ}
+ŽO\ŒÜ
+‘å•Ÿ‚ªD•š‚Å‚ ‚éB Žð‚Í‚ ‚Ü‚è“Û‚Ü‚È‚¢B
+EOF
+
+‚à‚€­‚µŠÈŒ‰‚ɏ‘‚«‚œ‚¯‚ê‚΁A‹ó”’•¶ŽšA\i‚QƒoƒCƒg•¶Žš‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚é‚͍̂\‚í‚È‚¢jA‚š‚æ‚уJƒbƒR‚ðŠÜ‚Ü‚È‚¢‚Æ‚¢‚€ðŒ‚ŁAqw() ‚ðŽg‚€‚±‚Æ‚ª‚Å‚«‚Ü‚·B—á‚Š‚΁A@str = qw(•\ŽŠ ‘Ήž•\ );‚Ì‚æ‚€‚É‹ó”’‚ð“ü‚ê‚ăJƒbƒR‚̃GƒXƒP[ƒv‚ð–h‚¬‚Ü‚·B@str = qw(•\ŽŠ ‘Ήž•\);‚Ì‚æ‚€‚É‹ó”’‚ð“ü‚ê‚È‚¢‚ƃGƒ‰[‚ÌŒ³‚Å‚·B
+‚P‚‚̕¶Žš—ñ‚ðì‚鎞‚Å‚àA¶•Ó‚ðŠÛƒJƒbƒR‚ň͂ñ‚ŃŠƒXƒgƒRƒ“ƒeƒLƒXƒg‚ðŽŠ‚·‚©A‰E•Ó‚ðƒXƒ‰ƒCƒX‚É‚·‚é‚©‚µ‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB‚±‚ê‚́AiŒ»ó‚ł́jqw// ‚Í split(' ', q//) ‚Ì—ª‹L‚Æ‚µ‚ÄŽÀ‘•‚µ‚Ä‚¢‚é‚©‚ç‚Å‚·B‚È‚šAPerl 5.6‚ł̓ŠƒXƒg‚Æ“™‰¿‚É‚È‚Á‚Ä‚¢‚é‚æ‚€‚Å‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+($str) = qw(•SŽO\ );
+ $str = (qw/•SŽO\ /)[0];
+ $str = qw/•SŽO\ /; # Perl 5.6
+
+³‹K•\Œ»‚ƃ}ƒbƒ`
+³‹K•\Œ»‚̃ƒ^•¶Žš‚Í‘œ‚¢‚̂ŁA³‹K•\Œ»‚Ì’†‚ÉShift-JIS‚Ì•¶Žš—ñ‚ð–„‚ß‚±‚Þ‚Ì‚Í“Ÿô‚Å‚Í‚ ‚è‚Ü‚¹‚ñB—á‚Š‚΁A/\Q‘Ήž•\/ ‚ł̓Gƒ‰[‚É‚È‚è‚Ü‚·B‚±‚ê‚́A/ / ‚͈̔͂̌ˆ’肪^‚Áæ‚ɍs‚í‚êA‚»‚ÌŽž“_‚ŃGƒ‰[‚ª”­¶‚·‚é‚̂ŁA\Q ‚ÌŒø‰Ê‚ð‹y‚Ú‚·‚±‚Æ‚ª‚Å‚«‚È‚¢‚©‚ç‚Å‚·B‚Ü‚œA/\Q‘Ήž•\\E/ ‚͍I‚­s‚«‚Ü‚¹‚ñB‚±‚ê‚́A‘Ήž•\\E ‚Æ‚¢‚€•¶Žš—ñ‚ðŠÜ‚Þ‚à‚Ì‚É‚µ‚©ƒ}ƒbƒ`‚µ‚Ü‚¹‚ñB‚±‚ê‚́A\\ ‚Æ‚¢‚€˜A‘±‚ª‚ ‚é‚œ‚߁A\E ‚ª”FŽ¯‚³‚ê‚È‚¢‚©‚ç‚Å‚µ‚å‚€i‚œ‚Ô‚ñjB
+‚»‚Ì‚œ‚߁A•Ï”‚É“ü‚ê‚āAƒ}ƒbƒ`‰‰ŽZŽq‚â’uŠ·‰‰ŽZŽq‚Ì’†‚Å“WŠJ‚³‚¹‚é‚Æ‚æ‚낵‚¢‚Å‚·B‚±‚Ì‚Æ‚«“ú–{Œê•¶Žš—ñ‚Í—\‚ßquotemeta ŠÖ”‚ŏˆ—‚µ‚Ä‚š‚«‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$pat = quotemeta +(qw/ •\ /)[0];
+$str =~ /$pat\d+/; # •\1, •\2, ..‚ȂǂɃ}ƒbƒ`
+ # ‚µ‚©‚µ $str = 'Œ•\\1' ‚Å‚àƒ}ƒbƒ`‚·‚éi‚±‚Ì–â‘è‚ÍŒãqj
+
+ã‚Ì‚æ‚€‚ȏ‘‚«•û‚ÍŠm‚©‚ɏX‚¢‚Å‚·‚ˁBƒNƒI[ƒg‚Ì’†‚Å \Q \E ‚ðŽg‚€Žž‚́A³‚µ‚¢•¶Žš—ñ‚ª“ü‚Á‚Ä‚¢‚é•Ï”‚ƈꏏ‚É‚È‚ç–â‘肪‹N‚±‚è‚Ü‚¹‚ñB‚±‚€‚·‚邱‚ƂŁA\Q \E ‚͈̔͂ª–ŸŠm‚É‚È‚é‚©‚ç‚Å‚·B³‚µ‚¢•¶Žš—ñ‚̍ì‚è•û‚́A‘Oq‚̃Šƒeƒ‰ƒ‹‚̍ì‚è‚©‚œ‚ðŽQl‚É‚µ‚ĉº‚³‚¢B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$pat = "(?:\Q$str1\E|\Q$str2\E)*";
+$str =~ /$pat/;
+
+# ŽÀ‚͏ã‚Ì•¶‚ÍŽŸ‚Ì•¶‚Æ“™‰¿B
+# $pat = "(?:" . quotemeta($str1) . "|" . quotemeta($str2) . ")*";
+
+ƒŠƒeƒ‰ƒ‹‚ðƒNƒH[ƒg‚Ì’†‚É’ŒÚ–„‚ß‚±‚Þ‚Æ‚€‚Ü‚­s‚©‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚·B‚»‚ê‚́Aperl‚ª \E ‚Æ‚¢‚€ƒƒ^•¶Žš‚ð”­Œ©‚µ‚æ‚€‚Æ‚¢‚€‚Ì‚ðAShift-JIS•¶Žš‚ª–W‚°‚é‚œ‚ß‚Å‚·B
+"\Q•\\E"‚ł́A•\E‚Ƀ}ƒbƒ`‚·‚鐳‹K•\Œ»‚É‚È‚è‚Ü‚·B•\‚Ì‘æ“ñƒoƒCƒg‚Ì \ ‚ÆŽŸ‚Ì \‚ª‡‚킳‚é‚̂ŁAperl‚É‚Í\Q \x95 \\ E‚Ì‘g‚ݍ‡‚킹‚Å‚ ‚é‚æ‚€‚ÉŽv‚í‚ê‚Ü‚·B \Q‚̍ì—p‚ÌŒ‹‰Ê‚Í\\x95\\x5cE‚É‚È‚è‚Ü‚·B‚»‚Ì‚œ‚߁A•\E‚Ƀ}ƒbƒ`‚µ‚Ü‚·B
+"\Q•\"‚Í‚Ç‚€‚Å‚µ‚å‚€B‚±‚̏ꍇ‚́A" " ‚Ì”ÍˆÍ‚ðŒˆ‚ß‚é‚Æ‚«‚ɁA•\‚Ì‘æ“ñƒoƒCƒg‚ªŒã‚̃NƒH[ƒg‚ðƒGƒXƒP[ƒv‚µ‚Ä‚µ‚Ü‚€‚̂ŁA•¶Žš—ñ‚͈̔͂ªŠú‘Ò‚µ‚œ‚æ‚€‚É‚Í’è‚Ü‚ç‚žAƒGƒ‰[‚É‚È‚è‚Ü‚·B‚±‚̃Gƒ‰[‚Í\Q‚ÌŒø‰Ê‚ðl—¶‚·‚é‘O‚É”­¶‚·‚é‚̂ŁA–h‚¬‚æ‚€‚ª‚ ‚è‚Ü‚¹‚ñB
+"\Q•\\\E"‚Í‚Ç‚€‚Å‚µ‚å‚€BŠm‚©‚ÉShift-JIS‚Å‚Í–â‘è‚ ‚è‚Ü‚¹‚ñB‚µ‚©‚µ“¯‚¶ƒXƒNƒŠƒvƒg‚ðEUC-JP‚âUTF-8‚É•ÏŠ·‚µ‚œ‚Æ‚«‚É‚Í–â‘肪‚ ‚è‚Ü‚·B•\\E‚Æ—]•ª‚È‚Q•¶Žš‚ª‚ ‚镶Žš—ñ‚Å‚È‚¢‚ƃ}ƒbƒ`‚µ‚Ü‚¹‚ñB‚Ç‚¿‚ç‚É‚µ‚ëA\‚ð‚Ç‚±‚É“Y‚Š‚é‚©‚ðl‚Š‚é•K—v‚ª‚ ‚é‚̂ŁA‚±‚±‚ÌŽïŽ|‚ɍ‡‚¢‚Ü‚¹‚ñB
+³‹K•\Œ»‚Í—á‚Š‚΁AŽŸ‚Ì‚æ‚€‚É‚µ‚Ü‚·B‚à‚¿‚ë‚ñ‚±‚ê‚ÍShift-JIS‚Ì‚Ý‚É—LŒø‚Å‚·B
+ $digit = '(?:[0-9]|\x82[\x4F-\x58])'; # ”Žši”ŒŠp‚Æ‘SŠpj
+ $upper = '(?:[A-Z]|\x82[\x60-\x79])'; # ƒAƒ‹ƒtƒ@ƒxƒbƒg‘啶Žši”ŒŠp‚Æ‘SŠpj
+ $lower = '(?:[a-z]|\x82[\x81-\x9A])'; # ƒAƒ‹ƒtƒ@ƒxƒbƒg¬•¶Žši”ŒŠp‚Æ‘SŠpj
+ $space = '(?:[\ \n\r\t\f]|\x81\x40)'; # ‹ó”’•¶Žši”ŒŠp‚Æ‘SŠpj
+ $ascii = '[\x00-\x7F]'; # ASCII•¶Žš
+
+ # ‘SŠp•œ‰Œ–Œi‘÷“_E”Œ‘÷“_E—x‚莚‚ðŠÜ‚ށj
+ $hiraZ = '(?:\x82[\x9F-\xF1]|\x81[\x4A\x4B\x54\x55])';
+
+ # ‘SŠp•Ð‰Œ–Œi’·‰¹•„E‘÷“_E”Œ‘÷“_E—x‚莚‚ðŠÜ‚ށj
+ $kataZ = '(?:\x83[\x40-\x7E\x80-\x96]|\x81[\x5B\x4A\x4B\x52\x53])';
+
+ # ”ŒŠp•Ð‰Œ–Œi”ŒŠp’·‰¹•„E‹å“Ç“_‚ðŠÜ‚ށj
+ $kataH = '[\xA1-\xDF]';
+
+ $onebyte = '[\x00-\x7F\xA1-\xDF]';
+ $twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+ $char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+ # JIS•¶Žš
+ $all_JIS = '(?:[\x00-\x7f\xa1-\xdf]|'.
+ . '\x81[\x40-\x7e\x80-\xac\xb8-\xbf\xc8-\xce\xda-\xe8\xf0-\xf7\xfc]|'
+ . '\x82[\x4f-\x58\x60-\x79\x81-\x9a\x9f-\xf1]|'
+ . '\x83[\x40-\x7e\x80-\x96\x9f-\xb6\xbf-\xd6]|'
+ . '\x84[\x40-\x60\x70-\x7e\x80-\x91\x9f-\xbe]|'
+ . '\x88[\x9f-\xfc]|\x98[\x40-\x72\x9f-\xfc]|\xea[\x40-\x7e\x80-\xa4]|'
+ . '[\x89-\x97\x99-\x9f\xe0-\xe9][\x40-\x7e\x80-\xfc])';
+
+ # ƒxƒ“ƒ_’è‹`•¶Žš
+
+ # NEC“ÁŽê•¶Žš
+ $NEC_special = '(?:\x87[\x40-\x5d\x5f-\x75\x7e\x80-\x9c])';
+
+ # NEC‘I’èIBMŠg’£•¶Žš
+ $NEC_IBM_ext = '(?:\xed[\x40-\x7e\x80-\xfc]|\xee[\x40-\x7e\x80-\xec\xef-\xfc])';
+
+ # IBMŠg’£•¶Žš
+ $IBM_ext = '(?:[\xfa-\xfb][\x40-\x7e\x80-\xfc]|\xfc[\x40-\x4b])';
+
+
+Shift-JIS‚Ń}ƒbƒ`‚ðs‚€Žž‚ɂ́A‚Q‚‚̖â‘肪‚ ‚è‚Ü‚·B
+‘æ“ñƒoƒCƒg‚ªASCII‚̗̈æ‚É“ü‚镶Žš‚ª‚ ‚é‚̂ŁAASCII‚ðŠÜ‚Þƒpƒ^[ƒ“‚Ƀ}ƒbƒ`‚·‚é‰Â”\«‚ª‚ ‚éB
+‚ ‚镶Žš‚Ì‘æ“ñƒoƒCƒg‚ÆŽŸ‚Ì•¶Žš‚Ì‘æˆêƒoƒCƒg‚ª‚P•¶Žš‚Å‚ ‚é‚©‚Ì‚æ‚€‚Ƀ}ƒbƒ`‚µ‚Ä‚µ‚Ü‚€B
+ŒãŽÒ‚ÍEUC-JP‚Å‚à‹N‚±‚è‚€‚é–â‘è‚Å‚·iUTF-8‚È‚ç‹N‚±‚ç‚È‚¢‚ªA¡‚Í‚»‚ꂪ–â‘è‚È‚Ì‚Å‚Í‚È‚¢jB‚µ‚©‚µ‘OŽÒ‚ÍEUC-JP‚Å‚Í‹N‚±‚ç‚È‚¢‚ªAShift-JIS‚Å‚Í‹N‚±‚è‚€‚é–â‘è‚Å‚·B‚±‚ê‚ç‚ð–h‚®•û–@‚́AŒ‹‹Ç“¯‚¶‚±‚Æ‚Å‚·‚ªA³‹K•\Œ»‚Ì’†‚ɁAí‚ɐ擪‚ðŠÜ‚Ü‚¹‚邱‚Æ‚Å‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+# æ“ª‚©‚çƒ}ƒbƒ`
+$str =~ /^$char*?(?:$pat)/;
+
+––”ö‚©‚ç‚̃}ƒbƒ`‚Å‚Í‚€‚Ü‚­s‚©‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚·B"‰E" =~ /E$/‚ðl‚Š‚ê‚Ώ\•ª‚Å‚µ‚å‚€B‚Ü‚œA"\x8E" x 30 . "E"‚Í$str = "ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽE"‚Å‚ ‚邪A"\x8E" x 31 . "E"‚Í$str = "ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽE"‚Å‚ ‚è‚Ü‚·‚©‚çAShift-JIS•¶Žš—ñ‚ðŒã‚ë‚©‚çØ‚蕪‚¯‚é“KØ‚È•û–@‚Í‚È‚¢‚ƍl‚Š‚ç‚ê‚Ü‚·B
+­‚È‚­‚Æ‚àA‚QƒoƒCƒg•¶Žš‚ð\¬‚µ‚È‚¢ƒoƒCƒg [\x00-\x3F\x7F] ‚ªŒ©‚‚©‚鏊‚܂ŁA‹É’[‚ȏꍇ‚Í•¶Žš—ñ‚̍ŏ‰‚܂ŃXƒLƒƒƒ“‚µ‚È‚¢‚Æ‚í‚©‚ç‚žA‚µ‚©‚àŒã“Ç‚Ý lookbehind ‚̐³‹K•\Œ» (?<=PATTERN)‚͍¡‚̏ŠA•s’è’·‚É‚Å‚«‚Ü‚¹‚ñi(?<=(?:\A|[\x00-\x3F\x7F])$char*) ‚Æ‚Í‚Å‚«‚È‚¢j‚̂ŁAæ“ª‚©‚當Žš’PˆÊ‚ł΂炵‚Ä‚©‚珈—‚·‚é‚Ì‚ªAŒ‹‹Ç‚ÍŠÈ•Ö‚È‚Ì‚©‚à‚µ‚ê‚Ü‚¹‚ñB
+ƒOƒ[ƒoƒ‹ƒ}ƒbƒ`
+ƒOƒ[ƒoƒ‹ƒ}ƒbƒ` /g ‚̏ꍇ‚́A\G‚ðŽg‚¢‚Ü‚µ‚å‚€B\G‚Í‘O‰ñƒ}ƒbƒ`‚µ‚œ•”•ª‚Ì––”ö‚ðŽw‚µ‚Ü‚·B
+ŽŸ‚Ì—á‚ł́A’uŠ·‚³‚ê‚È‚¢‚Ì‚ª–]‚Ü‚µ‚¢‚Ì‚Å‚·‚ªA\G‚ª‚È‚¢‚̂ŁAæ“ª‚©‚çŠJŽn‚µ‚Ä•¶Žš—ñ‘S‘̂܂ʼn„‚тă}ƒbƒ`‚µ‚È‚©‚Á‚œ‚ ‚ƁA‰ü‚߂Đ擪‚©‚ç‚PƒoƒCƒgi‚ñ‚ŸˆÊ’u‚©‚çƒXƒLƒƒƒ“‚ðÄŠJ‚·‚é‚̂ŁA‚ž‚ê‚œˆÊ’u‚Ȃ̂Ƀ}ƒbƒ`‚µ‚œ‚ƍl‚Š‚Ä‚µ‚Ü‚¢‚Ü‚·B\G‚ðŽg‚í‚È‚¢‚ƁAŠÔˆá‚Á‚œˆÊ’u‚Ƀ}ƒbƒ`‚·‚é‚©‚à‚µ‚ê‚È‚¢‚€‚Š‚ɁA—]Œv‚ȍČŸž‚ð‚·‚é‚̂ŁAŽžŠÔ‚à‚©‚©‚è‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+ $str = 'ŽŽŽŽŽŽŽŽEŽŽŽŽŽŽŽŽE';
+ $pat = 'ŽE';
+ $str =~ s/\G($char*?)($pat)/${1}E/og;
+ # 'ŽŽŽŽŽŽŽŽEŽŽŽŽŽŽŽŽE' ‚̂܂܁i³‚µ‚¢jB
+
+\G‚ð•t‚¯‚È‚¢ê‡
+
+ $str = 'ŽŽŽŽŽŽŽŽEŽŽŽŽŽŽŽŽE';
+ $pat = 'ŽE';
+ $str =~ s/($char*?)($pat)/${1}E/og; # 'ŽE' ‚ª‚ ‚ê‚Î 'E' ‚É’uŠ·
+ print $str;
+ # 'ŽŽŽŽŽŽŽEŽŽŽŽŽŽŽE' ‚É‚È‚Á‚Ä‚µ‚Ü‚€i‚š‚©‚µ‚¢jB
+
+@@@@ŽŽŽŽŽŽŽŽEŽŽŽŽŽŽŽŽE
+‚P‰ñ–ځ@šššš/šššš/ iƒ}ƒbƒ`‚µ‚È‚¢j
+‚Q‰ñ–ځ@|šššË||||||||| iƒ}ƒbƒ`‚µ‚œ‚Ì‚Å’uŠ·j
+‚R‰ñ–ځ@|||||||||šššš/ iƒ}ƒbƒ`‚µ‚È‚¢j
+‚S‰ñ–ځ@||||||||||šššË iƒ}ƒbƒ`‚µ‚œ‚Ì‚Å’uŠ·j
+
+@–}—áF š@$char‚ª‚QƒoƒCƒg•¶Žš‚Ƀ}ƒbƒ`
+@@@@@/@$char‚ª‚PƒoƒCƒg•¶Žš‚Ƀ}ƒbƒ`
+@@@@ Ë@$pat‚ªƒ}ƒbƒ`
+@@@@@|@ƒXƒLƒƒƒ“‚͈̔͊O
+
+‚œ‚Ÿ‚µAƒpƒ^[ƒ“‚ªƒ[ƒ•¶Žš•‚Ƀ}ƒbƒ`‚·‚éê‡‚ɂ́A’ˆÓ‚ª•K—v‚Å‚·BŽŸ‚Ì—á‚́AuƒAv‚Ì‘O‚É 'Z' ‚ð“ü‚ê‚é‚à‚Ì‚Å‚·B‘æ‚P—á‚Í•¶Žš‚Ì‚ž‚êi'ƒA' : 0x8341‚ɑ΂µ‚Ä'‹ƒA' : 0x8B8341‚ª‚ž‚ê‚ă}ƒbƒ`‚·‚éj‚ð–h‚¢‚Å‚¢‚Ü‚¹‚ñB‘æ‚Q—á‚́Aã‚Ì•û–@‚Łu‚ž‚êv‚ð–h‚²‚€‚Æ‚µ‚œ‚Ì‚Å‚·‚ªAZ ‚Ö‚Ì’uŠ·‚ª˜A‘±‚µ‚Ä‹N‚±‚Á‚Ä‚¢‚Ü‚·B
+‚±‚ê‚Í‘æ‚R—á‚Ì‚æ‚€‚É‚·‚é•K—v‚ª‚ ‚è‚Ü‚·B‚±‚ê‚́A‘æ‚Q—á‚ł́u‚È‚ºHv‚ɏ‘‚¢‚œ‚æ‚€‚ɁA’uŠ·‚³‚ê‚é‚©‚ç‚ƍl‚Š‚ç‚ê‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$str = "ƒAƒCƒEƒGƒAƒAƒCƒEƒA‹ƒA";
+
+print +($temp = $str) =~ s/(?=ƒA)/Z/g, $temp;
+
+print +($temp = $str) =~ s/\G($char*?)(?=ƒA)/${1}Z/g, $temp;
+
+print +($temp = $str) =~ s/\G(\A|$char+?)(?=ƒA)/${1}Z/g, $temp;
+
+Œ‹‰Ê
+5 ZƒAƒCƒEƒGZƒAZƒAƒCƒEZƒA‹ZƒA
+7 ZƒAƒCƒEƒGZZƒAZZƒAƒCƒEZZƒA‹ƒA
+4 ZƒAƒCƒEƒGZƒAZƒAƒCƒEZƒA‹ƒA
+
+‚È‚ºH
+ ƒA ƒC ƒE ƒG ƒA ƒA ƒC ƒE ƒA ‹ƒ A
+1 \G Z
+2 \G$char$char$char$char Z
+3 \G Z
+4 \G$char Z
+5 ˆÈ‰ºAÈ—ª
+
+‚‚܂èAƒOƒ[ƒoƒ‹ƒ}ƒbƒ`‚ł́Aƒ}ƒbƒ`‚ªƒ[ƒ•¶Žš•‚Å‚È‚¢ƒpƒ^[ƒ“‚Ì‘O‚É‚Í\G($char*?)‚ðAƒ[ƒ•¶Žš•‚Å‚ ‚éƒpƒ^[ƒ“‚Ì‘O‚É‚Í\G(\A|$char+?)‚ð“ü‚ê‚é•K—v‚ª‚ ‚è‚Ü‚·B
+‚œ‚Ÿ‚µA‚±‚ê‚Å‚à³‚µ‚­iHjƒ}ƒbƒ`‚³‚¹‚ç‚ê‚È‚¢ê‡‚ª‚ ‚è‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$str = "0123000123";
+
+print +($temp = $str) =~ s/0*/Z/g, $temp;
+
+print +($temp = $str) =~ s/\G($char*?)0*/${1}Z/g, $temp;
+
+print +($temp = $str) =~ s/\G(\A|$char+?)0*/${1}Z/g, $temp;
+__END__
+ 9 ZZ1Z2Z3ZZ1Z2Z3Z
+14 ZZ1ZZ2ZZ3ZZ1ZZ2ZZ3ZZ
+ 7 Z1Z2Z3Z1Z2Z3Z
+
+‚±‚ê‚́Aƒpƒ^[ƒ“‚ªƒ[ƒ•¶Žš•‚Ƀ}ƒbƒ`‚·‚é‚à‚Ì‚Å‚ ‚é‚ƁA/g‚ª‚»‚̏ê‚Å–³ŒÀ‚É‘«“¥‚Ý‚µ‚ďI—¹‚µ‚È‚­‚È‚é‚Ì‚ð–h‚®‚œ‚߁Aperl‚́Aƒ}ƒbƒ`‚ð‹­§“I‚ɐi‚ß‚Ä‚¢‚é‚Ì‚Å‚·‚ªicf. perlre, Repeated patterns matching zero-length substringjA‚±‚̐i‚ß•û‚̐^Ž—i‚µ‚©‚àƒoƒCƒg’PˆÊ‚Å‚Í‚È‚­A•¶Žš’PˆÊ‚Ői‚Þ‚à‚́j‚ªA\G($char*?)‚â\G(\A|$char+?)‚ł́A‚€‚Ü‚­‚Å‚«‚È‚¢‚©‚ç‚Å‚·B‚à‚Á‚Æ‚à‚±‚€‚¢‚€ƒ}ƒbƒ`‚ð‚·‚é‚±‚Ƃ́A‚Ù‚Æ‚ñ‚Ç‚È‚¢‚ƍl‚Š‚ç‚ê‚Ü‚·‚̂ŁA‹C‚É‚·‚é•K—v‚Í‚È‚¢‚Ì‚©‚à’m‚ê‚Ü‚¹‚ñiƒ•‰‚¯É‚µ‚݁jB
+ƒAƒ‹ƒtƒ@ƒxƒbƒg‚̑啶Žš‚Ə¬•¶Žš
+Shift-JIS‚Ì‚QƒoƒCƒg•¶Žš‚Ì’†‚ɂ́A‘æ‚QƒoƒCƒg‚ªASCII‚ʼnpŽš‚É“–‚œ‚é‚à‚Ì‚ª‚ ‚è‚Ü‚·B‚»‚Ì‚œ‚߁AŠÖ” uc, lc ‚âAƒƒ^•¶Žš \U, \L‚ª‚QƒoƒCƒg•¶Žš‚̈ꕔ‚ð•ÏŠ·‚µ‚Ä‚µ‚Ü‚Á‚œ‚èi‚µ‚©‚µŠÖ” ucfirst, lcfirst ‚â ƒƒ^•¶Žš \u, \l ‚Í–â‘è‚Æ‚È‚ç‚È‚¢jAm//i ‚â s///i‚È‚Ç‚Ì /iCüŽq‚É‚æ‚Á‚Ĉႀ•¶Žš‚Ȃ̂Ƀ}ƒbƒ`‚µ‚Ä‚µ‚Ü‚Á‚œ‚è‚·‚邱‚Æ‚ª‚ ‚è‚Ü‚·B
+Shift-JIS•¶Žš—ñ‚ÉŠÜ‚Ü‚ê‚éASCII‚̉pŽš‚ð‘啶Žš‚Ü‚œ‚͏¬•¶Žš‚É‘µ‚Š‚œ‚¢‚È‚çA—á‚Š‚΁AŽŸ‚Ì‚æ‚€‚ȃTƒuƒ‹[ƒ`ƒ“‚ðì‚ê‚ÎŽÀŒ»‚Å‚«‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+lc("PERLƒvƒƒOƒ‰ƒ~ƒ“ƒO"); # 'perlƒvƒƒoƒ‰ƒ~ƒ“ƒo'
+tolower("PERLƒvƒƒOƒ‰ƒ~ƒ“ƒO"); # 'perlƒvƒƒOƒ‰ƒ~ƒ“ƒO'
+
+sub tolower {
+ my $str = $_[0];
+ $str =~ s/\G($char*?)([A-Z]+)/$1\L$2/g;
+ $str;
+}
+
+sub toupper {
+ my $str = $_[0];
+ $str =~ s/\G($char*?)([a-z]+)/$1\U$2/g;
+ $str;
+}
+
+ƒP[ƒX–³Ž‹‚̃}ƒbƒ` /i ‚̏ꍇ‚́A—á‚Š‚Î 'ƒG'‚Ì‘æ“ñƒoƒCƒg‚Í 'G' ‚Å‚ ‚èA'ƒg'‚Ì‘æ“ñƒoƒCƒg‚Í 'g' ‚Å‚ ‚邱‚Æ‚©‚çA'ƒG' =~ /ƒg/i‚̓}ƒbƒ`‚µ‚Ü‚·B‚Å‚·‚©‚çAShift-JIS‚Ő³Šm‚ȃ}ƒbƒ`‚ð‚µ‚œ‚¯‚ê‚΁A/iCüŽq‚ÍŽg‚€‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñB
+‚©‚í‚è‚ɁA•¶Žš—ñ‚ÉŠÜ‚Ü‚ê‚éƒAƒ‹ƒtƒ@ƒxƒbƒgi“ñƒoƒCƒg•¶Žš‚Ì‘æ‚QƒoƒCƒg‚É‚ ‚é‚à‚Ì‚ðœ‚­j‚ð¬•¶Žši‚Ü‚œ‚͑啶ŽšA‚Ç‚¿‚ç‚©j‚É“ˆê‚µ‚ă}ƒbƒ`‚³‚¹‚Ü‚·Btolower‚Ì’è‹`‚͏ã‚ð‚²——‰º‚³‚¢B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+$lcstr = tolower($str);
+$lckey = tolower(quotemeta $key);
+
+if ($lcstr =~ /^$char*?$lckey/) {
+ print "matched";
+}
+else {
+ print "not matched";
+}
+
+‚Ü‚œ‚Í–„‚ߍž‚ݏCüŽq (?ismx-ismx) ‚ð—p‚¢‚Ä‚àD‚¢Œ‹‰Ê‚ð“Ÿ‚ç‚ê‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+"‘æ‚P‰ñPerluk‚Ì‚²ˆÄ“à" =~ /^$char*?PERLuK/i # ƒ}ƒbƒ`‚·‚éi¢‚éj
+"‘æ‚Q‰ñPerluk‚Ì‚²ˆÄ“à" =~ /^$char*?((?i)PERL)uK/ # ƒ}ƒbƒ`‚µ‚È‚¢i—Ç‚µj
+"‘æ‚R‰ñPerluK‚Ì‚²ˆÄ“à" =~ /^$char*?((?i)PERL)uK/ # ƒ}ƒbƒ`‚·‚éi—Ç‚µj
+
+‘SŠp‚QƒoƒCƒgƒAƒ‹ƒtƒ@ƒxƒbƒg‚̃P[ƒX–³Ž‹‚́A‘I‘ð‚É‚æ‚èŽÀŒ»‚Å‚«‚Ü‚·i‚ªA‚â‚Á‚Ï‚è•ÏjB'‚`'‚Ì‘æ‚QƒoƒCƒg‚ª '`' ‚È‚Ì‚àA‚¿‚å‚Á‚Æ’ˆÓ‚Å‚·im`` ‚È‚Ç‚Ì‚Æ‚«’v–œ“IƒGƒ‰[‚É‚È‚éB‚œ‚Ÿ‚µƒoƒbƒNƒNƒH[ƒg‚ðŽg‚€ˆÓ–¡‚Í“Á‚É‚È‚¢jBŒŽ‘¥“I‚ɂ̓Šƒeƒ‰ƒ‹‚ðƒ}ƒbƒ`‰‰ŽZŽq‚â’uŠ·‰‰ŽZŽq‚É’ŒÚ–„‚ߍž‚Þ‚Ì‚Í”ð‚¯‚œ‚¢Š‚Å‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+/(?:‚o|‚)(?:‚d|‚…)(?:‚q|‚’)(?:‚k|‚Œ)/;
+
+‚»‚Ì‘ã‚í‚è‚É‚±‚ñ‚ȃTƒuƒ‹[ƒ`ƒ“‚ðì‚Á‚Ä‚Ý‚Ä‚à‚æ‚¢‚©‚à‚µ‚ê‚Ü‚¹‚ñB
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+$pat = make_regexp_ignorecase("‚o‚d‚q‚kuK");
+print "‘æ‚T‰ñ‚o‚…‚’‚ŒuK‰ï" =~ /^$char*?$pat/ ? "OK": "NOT";
+
+sub make_regexp_ignorecase {
+ my $str = $_[0];
+ $str =~ s/\G([A-Za-z]+|$CharRE)/
+ my $c = ord $1;
+ if($c == 0x82) {
+ my $v = vec($1,1,8);
+ 0x81 <= $v && $v <= 0x9A ? sprintf('\\x82[\\x%2x\\x%2x]', $v, $v-33) :
+ 0x60 <= $v && $v <= 0x79 ? sprintf('\\x82[\\x%2x\\x%2x]', $v, $v+33) :
+ quotemeta($1);
+ }
+ elsif(0x41 <= $c && $c <= 0x5A || 0x61 <= $c && $c <= 0x7A) {"(?:(?i)$1)"}
+ else {quotemeta($1)}
+ /geo;
+ $str;
+}
+
+’·‚¢•¶Žš—ñ‚ɑ΂·‚鐳‹K•\Œ»ŒŸõ
+³‹K•\Œ»‚́APerl ‚É‚Æ‚Á‚ÄŒ‡‚©‚¹‚È‚¢‘¶Ý‚Æ‚¢‚Š‚Ü‚·B‚µ‚©‚µ³‹K•\Œ»‚̐§ŒÀ‚Æ‚µ‚āA*, +, {min,max} ‚È‚Ç‚Ì—ÊŽw’èŽq‚ªƒ}ƒbƒ`‚ðŒJ‚è•Ô‚¹‚é‰ñ”‚̏ãŒÀ‚Æ‚¢‚€–â‘肪‚ ‚è‚Ü‚·B(Ú×‚Í perlre ŽQÆ‚Ì‚±‚Æ)B‚»‚Ì‚œ‚߁A$char*? ‚Æ‚¢‚€³‹K•\Œ»‚ɂ́AŠëŒ¯«‚ª‚ ‚è‚Ü‚·B
+—á‚Š‚΁AŽŸ‚Ì‚æ‚€‚ȃ}ƒbƒ`ƒ“ƒO‚ðl‚Š‚ÄŒ©‚Ü‚µ‚å‚€B$str‚́Au‚ v‚ª10–œŽš˜A‘±‚µ‚œ‚ ‚ƂɁAuƒAƒCABCv‚ª˜AŒ‹‚³‚ê‚œ•¶Žš—ñ‚Å‚·B‚±‚Ì‚æ‚€‚È•¶Žš—ñi‚œ‚Ÿ‚µAuw‚ x‚ª10–œŽš˜A‘±v‚Æ‚¢‚€‚±‚Æ‚Í•ª‚©‚ç‚žA”CˆÓ‚Ì Shift-JIS ƒeƒLƒXƒg‚Å‚ ‚ë‚€‚Æ‚¢‚€‚±‚Æ‚É‚µ‚Ü‚·j‚©‚çA”ŒŠpƒAƒ‹ƒtƒ@ƒxƒbƒg‚ª˜A‘±‚µ‚œ•”•ª‚ðŒ©‚Â‚¯‚œ‚¢‚Æ‚µ‚Ü‚µ‚å‚€B‚·‚é‚ƁA¡‚܂ł̍l‚Š•û‚©‚ç‚·‚é‚ƁAŽŸ‚Ì‚æ‚€‚É‚·‚ê‚΂悢‚ÆŽv‚í‚ê‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+my $char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+my $str = ('‚ ' x 100000) . 'ƒAƒCABC';
+$str =~ /^$char*?([A-Z]+)/o;
+print $1;
+
+‚µ‚©‚µA‚±‚ê‚́AŠÂ‹«‚É‚æ‚Á‚ẮA‘å‚«‚ȃGƒ‰[‚ðˆø‚«‹N‚±‚µ‚Ü‚·B—á‚Š‚΁AWindows 98ã‚Å Active Perl 522 ‚ð—p‚¢‚œê‡AError: Runtime exception ‚Æ‚¢‚€ Perl ‚̃Gƒ‰[‚É‚È‚è‚Ü‚µ‚œB‚Ü‚œAWindows 98ã‚ÅVC++ 6.0‚ŃRƒ“ƒpƒCƒ‹‚³‚ê‚œ Perl 5.6.1 ‚Ÿ‚ƁAu‚±‚̃vƒƒOƒ‰ƒ€‚Í•s³‚ȏˆ—‚ðs‚Á‚œ‚Ì‚Å‹­§I—¹‚³‚ê‚Ü‚·B`v‚È‚Ç‚Æ‚¢‚Á‚œƒGƒ‰[‚É‚È‚è‚Ü‚µ‚œB
+‚±‚Ì‚æ‚€‚È–â‘è‚ð‚Å‚«‚é‚Ÿ‚¯–h‚®‚œ‚߂ɂ́AŽŸ‚Ì‚æ‚€‚É‚µ‚Ü‚·B‚‚܂èA•¶Žš—ñ‚̐擪‚©‚ç’²‚ׂĂ¢‚­ê‡A“ñƒoƒCƒg•¶Žš‚Ì•¶Žš‹«ŠE‚ðŠÔˆá‚Š‚é‚̂́A“ñƒoƒCƒg•¶Žš‚Ì‘æˆêƒoƒCƒg‚Ì’ŒŒã‚𕶎š‹«ŠE‚ÆŒë”FŽ¯‚µ‚œŽž‚Ÿ‚¯‚Å‚·BShift-JIS‚ł́A“ñƒoƒCƒg•¶Žš‚Ì‘æˆêƒoƒCƒg‚́A[\x81-\x9F\xE0-\xFC] ‚Ÿ‚¯‚Å‚·B‚ ‚é‚¢‚́AEUC-JP ‚É•ÏŠ·‰Â”\‚ȗ̈悟‚¯‚ðl—¶‚·‚ê‚΁A[\x81-\x9F\xE0-\xEF] ‚Ÿ‚¯‚Æ‚¢‚€‚±‚Æ‚ª‚Å‚«‚Ü‚·B‚»‚êˆÈŠO‚̃oƒCƒg‚Ì’ŒŒã‚́A—á‚Š‚΁A0x41 ‚Ì’ŒŒã‚́A'A' ‚Ì’ŒŒã‚©A'ƒA' ‚Ì’ŒŒã‚©‚Í•ª‚©‚è‚Ü‚¹‚ñ‚ªAŠm‚©‚É•¶Žš‹«ŠE‚É‚È‚è‚Ü‚·B]‚Á‚āA[\x81-\x9F\xE0-\xFC]+ i‚Ü‚œ‚Í [\x81-\x9F\xE0-\xEF]+ j‚̃oƒCƒgi“ñƒoƒCƒg•¶Žšj‚ª˜A‘±‚·‚é‚Æ‚±‚ë‚Ÿ‚¯‚É’ˆÓ‚·‚ê‚΂悢‚±‚Æ‚É‚È‚è‚Ü‚·B
+‚±‚Ì‚œ‚߁AˆÈ‰º‚Ì‚æ‚€‚ɁA^$char*? ‚Ì‘ã‚í‚è‚É $Apad ‚ðŽg‚¢A\G$char*? ‚Ì‘ã‚í‚è‚É $Gpad ‚ð—p‚¢‚ê‚΁AˆêƒoƒCƒg•¶Žš‚©A“ñƒoƒCƒg•¶Žš‚Ì‚€‚¿‘æ“ñƒoƒCƒg‚ª [\x40-\x7E\x80\xA0-\xDF] ‚ŏI‚í‚é‚à‚Ì‚ªA­‚È‚­‚Æ‚à“K“–‚ÈŠÔŠu‚ŁiãŒÀ‚É’B‚µ‚È‚¢‚€‚¿‚ɁjoŒ»‚·‚ê‚΁AƒGƒ‰[‚É‚È‚ç‚ž‚ɏˆ—‚·‚邱‚Æ‚ª‚Å‚«‚Ü‚·BiŠm—Š“I‚È–â‘è‚Å‚·‚̂ŁAŠ®‘S‚Å‚Í‚ ‚è‚Ü‚¹‚ñBj
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+# ˆê‰ñ‚Ÿ‚¯ƒ}ƒbƒ`
+my $Apad = '(?:(?:\A|[\x00-\x80\xA0-\xDF])(?:[\x81-\x9F\xE0-\xFC]{2})*?)';
+my $str1 = ('‚ ' x 100000) . 'ƒAƒCABC';
+$str1 =~ /$Apad([A-Z]+)/o;
+print "$1\n"; # "ABC" ‚Æ•\ŽŠ‚³‚ê‚éB
+
+# ƒOƒ[ƒoƒ‹ƒ}ƒbƒ`
+my $Gpad = '(?:(?:\G|[\x00-\x80\xA0-\xDF])(?:[\x81-\x9F\xE0-\xFC]{2})*?)';
+
+my $str2 = '‚ ' x 100000 . 'ƒAƒCABC'. '‚š' x 100000 . 'XYZ';
+my @array = $str2 =~ /$Gpad([A-Z]+)/go;
+print "@array\n"; # "ABC XYZ" ‚Æ•\ŽŠ‚³‚ê‚éB
+
+ŠOŽš‚Ì•ÏŠ·
+ƒxƒ“ƒ_’è‹`•¶Žš‚⃆[ƒU’è‹`•¶Žš‚ðŠÜ‚Þ•¶Žš—ñ‚𑌂̊‹«‚Å‚à—˜—p‚Å‚«‚é‚æ‚€‚É‚·‚é‚ɂ́A“KØ‚È•ÏŠ·‚ª•K—v‚Å‚·i–³˜_A‚Ü‚Á‚œ‚­“¯‚¶Žš‘Ì‚Ì—˜—p‚Í‚Ù‚Æ‚ñ‚Ç–]‚ß‚žA‚š‚»‚ç‚­‚Í—ÞŽ—‚µ‚œ•¶Žš‚╶Žš—ñ‚É•ÏŠ·‚·‚邱‚Æ‚É‚È‚é‚Å‚µ‚å‚€jB‚±‚ê‚ÍPerl‚Å‚Í’uŠ·‰‰ŽZŽq s/// ‚ðŽg‚Š‚ΔäŠr“I—eˆÕ‚ÉŽÀŒ»‚Å‚«‚Ü‚·B
+‚ ‚ç‚©‚¶‚߁A‚Ç‚ÌŠOŽš‚ð‚Ç‚€•ÏŠ·‚·‚é‚©‚ð’è‹`‚·‚é•ÏŠ·ƒe[ƒuƒ‹‚ð—pˆÓ‚µ‚È‚­‚Ä‚Í‚È‚è‚Ü‚¹‚ñB‚±‚ê‚ÍPerl‚ł̓nƒbƒVƒ…‚É‚µ‚Ä‚š‚­‚Æ‚»‚ÌŒã‚̏ˆ—‚ªŠy‚É‚È‚è‚Ü‚·B‚±‚±‚ł́A'w932_gai.txt'‚Å’è‹`‚·‚éAWindows codepage-932ƒR[ƒh‚ÉŠî‚¢‚œ‹@ŽíˆË‘¶•¶Žš‚́i•”•ª“Ij•ÏŠ·ƒe[ƒuƒ‹‚ðŽg‚€‚±‚Æ‚É‚µ‚Ü‚·B
+ŽŸ‚̃R[ƒh‚ł́A‚P•¶Žš‚ƒ}ƒbƒ`‚³‚¹A‚»‚Ì•¶Žš‚ª•ÏŠ·ƒnƒbƒVƒ…‚̃L[‚É‚ ‚ê‚ΑΉž‚·‚é’l‚Ì•¶Žš—ñ‚É’uŠ·‚µA‚»‚€‚Å‚È‚¯‚ê‚΂»‚Ì‚Ü‚ÜŽc‚µ‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+require 'w932_gai.txt'; # %table‚Ì’è‹`i•sŠ®‘SIj
+
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+$str =~ s/($char)/exists $table{$1} ? $table{$1} : $1/geo;
+
+“¯—l‚ȏˆ—‚́A‚‚¬‚Ì‚æ‚€‚ȏ‘‚«•û‚Å‚à‚Å‚«‚Ü‚·‚ªAŠOŽš‚Ƀ}ƒbƒ`‚·‚鐳‹K•\Œ» $gaiji‚ð—pˆÓ‚·‚é•K—v‚ª‚ ‚è‚Ü‚·B‚ž‚ê‚œƒ}ƒbƒ`‚ð‚µ‚È‚¢‚œ‚߂ɁA‚±‚¿‚ç‚̐³‹K•\Œ»‚É‚Í \G ‚ª•K—v‚Å‚·B—á‚Š‚΁A$str = '‡@';‚ÌŒã‚ë‚QƒoƒCƒg‚Í "\x87\x40" ‚Å‚·‚ªA‚±‚€‚·‚ê‚΃}ƒbƒ`‚ª‚ž‚ê‚éS”z‚ª‚ ‚è‚Ü‚¹‚ñB‚Ü‚œA”ñ—~’£‚èƒ}ƒbƒ` ($char*?)‚ðŽg‚Š‚Î $char ‚ªŠOŽš‚Ƀ}ƒbƒ`‚µ‚È‚¢‚æ‚€•ÏX‚·‚é•K—v‚Í‚ ‚è‚Ü‚¹‚ñB
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+require 'w932_gai.txt'; # %table‚Ì’è‹`i•sŠ®‘SIj
+
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+$gaiji = '(?:[\x87][\x40-\x9c])';
+
+$str =~ s/\G($char*?)($gaiji)/$1$table{$2}/g;
+
+CP932d•¡’è‹`•¶Žš‚Ì•ÏŠ·
+Microsoft Windows “ú–{Œê”łňê”Ê“I‚ÉŽg—p‚³‚ê‚Ä‚¢‚éƒR[ƒhƒy[ƒW 932 (CP932) ‚ł́AŠô‚‚©‚Ì•¶Žš‚ªd•¡‚µ‚Ä’è‹`‚³‚ê‚œó‘Ô‚É‚È‚Á‚Ä‚¢‚Ü‚·B‚±‚±‚ŁA•¶Žš‚ªd•¡’è‹`‚³‚ê‚Ä‚¢‚é‚Ƃ́AUnicode‚Ì“¯‚¶•„†ˆÊ’u‚ɑΉž•t‚¯‚ç‚ê‚Ä‚¢‚邱‚Æ‚Æ‚µ‚Ü‚·B
+—á‚Š‚΁ACP932 -> Unicode -> CP932 ‚̏‡‚Å•ÏŠ·‚³‚ê‚é‚ƁAd•¡’è‹`•¶Žš‚́A‚Ç‚ê‚©ˆê‚‚ɑµ‚Š‚ç‚ê‚Ü‚·B‚±‚Ì—Dæ‡ˆÊ‚Í JIS X 0208, NEC“ÁŽê•¶Žš (13‹æ)AIBMŠg’£•¶Žš (115`119‹æ)ANEC‘I’èIBMŠg’£•¶Žš (89`92‹æ) ‚̏‡‚Å‚·Bˆê—á‚Æ‚µ‚āA'æ' ‚̏ꍇANEC“ÁŽê•¶Žš‚Ì "\x87\x9A" ‚â IBMŠg’£•¶Žš‚Ì "\xFA\x5B" ‚́AJIS X 0208 ‚Ì "\x81\xE6" ‚É‚È‚è‚Ü‚·B
+‚µ‚©‚µACP-932 ‚̃eƒLƒXƒg’†Ad•¡’è‹`•¶Žš‚ª‚Ç‚ê‚©‚É‘µ‚Á‚Ä‚¢‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚·B—á‚Š‚Î "\x87\x9A" ‚â "\xFA\x5B" ‚ªŠÜ‚Ü‚ê‚Ä‚¢‚é‚ƁAƒeƒLƒXƒg‚ð–Ú‚ÅŒ©‚é‚ƈႢ‚ª‚È‚¢‚̂ɁA"\x81\xE6" ‚ÅŒŸõ‚µ‚Ä‚àŒ©‚‚¯‚ç‚ê‚È‚¢‚±‚Æ‚É‚È‚è‚Ü‚·B
+d•¡’è‹`•¶Žš‚𑵂Š‚郂ƒWƒ…[ƒ‹‚Æ‚µ‚āAShiftJIS/CP932/Correct.pm ‚ª‚ ‚è‚Ü‚·B“üŽè‚ÆŽg‚¢•û‚ÍPerl‚̃y[ƒW‚É–ß‚ê‚ÎŒ©‚‚©‚è‚Ü‚·B
+‚Ü‚œAShiftJIS/String.pm ‚Ì strtr() ‚Ü‚œ‚Í trclosure() ‚ðŽg‚€•û–@‚à‚ ‚è‚Ü‚·B“üŽè‚ÆŽg‚¢•û‚ÍPerl‚̃y[ƒW‚É–ß‚ê‚ÎŒ©‚‚©‚è‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+
+# (1) $necJIS -> $jisNEC (9‘Î)
+ $necJIS = "\x87\x90\x87\x91\x87\x92\x87\x95\x87\x96\x87\x97\x87\x9A\x87\x9B\x87\x9C";
+ # NEC“ÁŽê•¶Žš‚Ì‚€‚¿AJIS•¶Žš‚É•ÏŠ·‚³‚ê‚é‚ׂ«”ñŠ¿Žš
+ $jisNEC = "\x81\xE0\x81\xDF\x81\xE7\x81\xE3\x81\xDB\x81\xDA\x81\xE6\x81\xBF\x81\xBE";
+ # JIS•¶Žš‚Ì‚€‚¿ANEC“ÁŽê•¶Žš‚ɏd•¡’è‹`‚³‚ê‚Ä‚¢‚é”ñŠ¿Žš
+
+# (2) $necibmJIS -> $jisNECIBM (1‘Î)
+ $necibmJIS = "\xEE\xF9";
+ # NEC‘I’èIBMŠg’£•¶Žš‚Ì‚€‚¿AJIS•¶Žš‚É•ÏŠ·‚³‚ê‚é‚ׂ«”ñŠ¿Žš
+ $jisNECIBM = "\x81\xCA";
+ # JIS•¶Žš‚Ì‚€‚¿ANEC‘I’èIBMŠg’£•¶Žš‚ɏd•¡’è‹`‚³‚ê‚Ä‚¢‚é”ñŠ¿Žš
+
+# (3) $ibmJIS -> $jisIBM (2‘Î)
+ $ibmJIS = "\xFA\x54\xFA\x5B";
+ # IBMŠg’£•¶Žš‚Ì‚€‚¿AJIS•¶Žš‚É•ÏŠ·‚³‚ê‚é‚ׂ«”ñŠ¿Žš
+ $jisIBM = "\x81\xCA\x81\xE6";
+ # JIS•¶Žš‚Ì‚€‚¿AIBMŠg’£•¶Žš‚ɏd•¡’è‹`‚³‚ê‚Ä‚¢‚é”ñŠ¿Žš
+
+# (4) $ibmNEC -> $necIBM (13‘Î)
+ $ibmNEC = "\xFA\x4A-\xFA\x53\xFA\x58\xFA\x59\xFA\x5A";
+ # IBMŠg’£•¶Žš‚Ì‚€‚¿ANEC“ÁŽê•¶Žš‚É•ÏŠ·‚³‚ê‚é‚ׂ«”ñŠ¿Žš
+ $necIBM = "\x87\x54-\x87\x5D\x87\x8A\x87\x82\x87\x84";
+ # NEC“ÁŽê•¶Žš‚Ì‚€‚¿AIBMŠg’£•¶Žš‚ɏd•¡’è‹`‚³‚ê‚Ä‚¢‚é”ñŠ¿Žš
+
+# (5) $necibmIBM -> $ibmNECIBM (13‘Î)
+ $necibmIBM = "\xEE\xEF-\xEE\xF8\xEE\xFA\xEE\xFB\xEE\xFC";
+ # NEC‘I’èIBMŠg’£•¶Žš‚Ì‚€‚¿AIBMŠg’£•¶Žš‚É•ÏŠ·‚³‚ê‚é‚ׂ«”ñŠ¿Žš
+ $ibmNECIBM = "\xFA\x40-\xFA\x49\xFA\x55\xFA\x56\xFA\x57";
+ # IBMŠg’£•¶Žš‚Ì‚€‚¿ANEC‘I’èIBMŠg’£•¶Žš‚ɏd•¡’è‹`‚³‚ê‚Ä‚¢‚é”ñŠ¿Žš
+
+# (6) $necibmCJK -> $ibmCJK (360‘Î)
+ $necibmCJK = "\xED\x40-\xEE\xEC";
+ # NEC‘I’èIBMŠg’£•¶Žš’†‚ÌŠ¿Žš
+ $ibmCJK = "\xFA\x5C-\xFC\x4B";
+ # IBMŠg’£•¶Žš’†‚ÌŠ¿Žš
+
+use ShiftJIS::String qw(trclosure);
+
+# •ÏŠ·—pƒNƒ[ƒWƒƒ‚̐¶¬
+$correctCP932 = trclosure(
+ $necJIS.$necibmJIS.$ibmJIS.$ibmNEC.$necibmIBM.$necibmCJK, # from
+ $jisNEC.$jisNECIBM.$jisIBM.$necIBM.$ibmNECIBM.$ibmCJK # to
+);
+
+$result = $correctCP932->($source); # $source ‚ð•ÏŠ·‚µ‚Ä $result ‚ð“Ÿ‚é
+
+•¶Žš”‚𐔂Š‚é
+Shift-JIS•¶Žš—ñ‚Ì•¶Žš”‚𐔂Š‚é‚ɂ́Aƒ}ƒbƒ`‰‰ŽZŽq‚ð—˜—p‚·‚é‚È‚çƒXƒJƒ‰[ƒRƒ“ƒeƒLƒXƒg‚Ő”‚Š‚œ•û‚ªŽáŠ±‘¬‚©‚Á‚œ‚Å‚·B‚»‚ê‚æ‚èA’uŠ·‰‰ŽZŽq‚ð—˜—p‚µ‚œ‚Ù‚€‚ª‘¬‚­‘‚¯‚é‚Æ‚í‚©‚è‚Ü‚µ‚œB
+‚à‚Á‚Æ‚àXS‚ŏ‘‚¢‚œ‚Ù‚€‚ª‚ž‚Á‚Æ‘¬‚©‚Á‚œ‚Å‚·B‚Ü‚ AXSUB‚Í–³—‚É—˜—p‚µ‚È‚­‚Ä‚à‚æ‚¢‚Å‚µ‚å‚€B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+use Benchmark;
+
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+$s = "Š¿Žš‚ \0A±CƒeƒXƒg -";
+
+timethese (100000, {
+ le => q{
+ ($str = $s) =~ s/$char/0/go;
+ $le = length $str;
+ },
+ sg => q{
+ $sg = ($str = $s) =~ s/$char//go;
+ },
+ ab => q{
+ $ab = 0;
+ $ab++ while $s =~ /[^\x81-\x9F\xE0-\xFC]|../g;
+ },
+ ar => q{
+ $ar = @{[ $s =~ /$char/go ]};
+ },
+ gr => q{
+ $gr = grep defined, $s =~ /$char/go;
+ },
+ wh => q{
+ $wh = 0;
+ $wh++ while $s =~ /$char/go;
+ },
+ sj => q{
+ $sj = sjslen($s);
+ },
+ xs => q{
+ $xs = sjlength($s);
+ },
+});
+
+sub sjslen {
+ my($str,$len,$i,$c,$blen);
+ $str = shift;
+ $blen = length $str;
+ while ($i < $blen) {
+ $c = vec($str, $i, 8);
+ if (0x81 <= $c && $c <= 0x9F || 0xE0 <= $c && $c <= 0xFC){ $i++ }
+ $i++,$len++;
+ }
+ $len;
+}
+
+Œ‹‰Ê
+Benchmark: timing 100000 iterations of ab, ar, gr, le, sg, sj, wh, xs...
+ ab: 4 wallclock secs ( 3.46 usr + 0.00 sys = 3.46 CPU) @ 28901.73/s
+ ar: 6 wallclock secs ( 5.98 usr + 0.00 sys = 5.98 CPU) @ 16722.41/s
+ gr: 6 wallclock secs ( 5.50 usr + 0.00 sys = 5.50 CPU) @ 18181.82/s
+ le: 3 wallclock secs ( 2.09 usr + 0.00 sys = 2.09 CPU) @ 47846.89/s
+ sg: 2 wallclock secs ( 1.92 usr + 0.00 sys = 1.92 CPU) @ 52083.33/s
+ sj: 9 wallclock secs ( 8.57 usr + 0.00 sys = 8.57 CPU) @ 11668.61/s
+ wh: 5 wallclock secs ( 4.78 usr + 0.00 sys = 4.78 CPU) @ 20920.50/s
+ xs: 1 wallclock secs ( 0.38 usr + 0.00 sys = 0.38 CPU) @ 263157.89/s
+ (warning: too few iterations for a reliable count)
+
+XSUB
+int
+sjlength(arg)
+ SV* arg
+ PROTOTYPE: $
+ PREINIT:
+ unsigned char *str, *p, *e;
+ STRLEN byte, len = 0;
+ CODE:
+ p = str = (unsigned char *)SvPV(arg, byte);
+ e = str + byte;
+ while (p < e) {
+ if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC)
+ ++p;
+ ++p, ++len;
+ }
+ RETVAL = len;
+ OUTPUT:
+ RETVAL
+
+•¶Žš’PˆÊ‚É•ª‚¯‚é
+Shift-JIS•¶Žš—ñ‚𕶎š’PˆÊ‚É•ªŠ„‚µ‚Ü‚µ‚å‚€B‚±‚̏ꍇ‚́AXS‚ð—˜—p‚µ‚Ä‚à‚ ‚܂葬‚­‚È‚è‚Ü‚¹‚ñ‚Å‚µ‚œB•Ô‚è’l‚̃ŠƒXƒg‚ð—pˆÓ‚·‚é‚Ì‚ÉŽžŠÔ‚ªŽæ‚ç‚ê‚é‚Ì‚©A‚â‚Í‚èPerl‚̐³‹K•\Œ»‚̏ˆ—‚Í‚©‚Ȃ葬‚¢‚à‚Ì‚Ÿ‚Æ‚¢‚€‚±‚Æ‚Å‚µ‚å‚€B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+use Benchmark;
+
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+$s = "“ú–{ŒêÆÎݺÞ\0ABC" x 100;
+
+timethese (1000, {
+ re => q{
+ @re = $s =~ /$char/go;
+ },
+ xs => q{
+ @xs = sjsplit($s);
+ },
+});
+
+Œ‹‰Ê
+Benchmark: timing 1000 iterations of re, xs...
+ re: 7 wallclock secs ( 6.65 usr + 0.00 sys = 6.65 CPU) @ 150.38/s
+ xs: 6 wallclock secs ( 5.33 usr + 0.00 sys = 5.33 CPU) @ 187.62/s
+
+XSUB
+void
+sjsplit(arg)
+ SV* arg
+ PROTOTYPE: $
+ PREINIT:
+ unsigned char *str, *p, *e;
+ STRLEN ch, byte, len = 0;
+ PPCODE:
+ str = (unsigned char *)SvPV(arg,byte);
+ e = str + byte;
+ for (p = str; p < e; p++) {
+ if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC) ++p;
+ ++len;
+ }
+ EXTEND(SP,len);
+ for (p = str; p < e; p += ch) {
+ ch = (0x81 <= *p && *p <= 0x9F || 0xE0 < *p && *p <= 0xFC) ? 2 : 1;
+ PUSHs(sv_2mortal(newSVpv(p,ch)));
+ }
+
+FX‚È•ªŠ„
+•¶Žš‚Å•ªŠ„‚Å‚Ý‚œ‚æ‚€‚ɁA•¶Žš—ñ‚𕪊„‚·‚é‚ɂ́Am//g‚ª•Ö—˜‚Å‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$onebyte = '[\x00-\x7F\xA1-\xDF]';
+$twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+#‚PƒoƒCƒg•¶Žš‚̉ò‚Æ‚QƒoƒCƒg•¶Žš‚̉ò‚É•ª‚¯‚éB
+ while ($str =~ /\G($onebyte*)($twobyte*)/g) {
+ push @one, $1 if $1 ne '';
+ push @two, $2 if $2 ne '';
+ }
+
+#‹å“_‚ªÅŒã‚Ì•¶Žš‚Æ‚È‚é‚æ‚€‚É•ªŠ„‚·‚éB
+# 'B' ‚Å‚Í‚¢‚¢‚ªA•¶Žš‚É‚æ‚Á‚Ä‚Í’ˆÓ‚ª•K—vB
+ @sentences = $str =~ /\G$char*?(?:B|D|$)/g;
+
+“Á’è‚Ì’·‚³‚Ő؂肻‚ë‚Š‚é
+’·‚¢•¶Žš—ñ‚ð“Á’è‚Ì’·‚³iƒoƒCƒg’·j‚Ő؂肻‚ë‚Š‚é‚È‚çAŽŸ‚Ì‚æ‚€‚É‚µ‚Ä‚Å‚«‚Ü‚·B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+$str = '‚í‚Ž‚í‚ŽEUC-JP‚É•ÏŠ·‚µ‚È‚¢‚ŁAShift-JIS‚̂܂܏ˆ—'.
+ '‚Å‚«‚œ‚ç‚¢‚¢‚ñ‚Ÿ‚¯‚ǁA‚È‚©‚È‚©–Ê“|‚Ÿ‚Ë‚ŠB';
+
+print join "\n", bytebreak($str,15);
+
+sub bytebreak{
+ my($byte,$bmax,$ch,@lines);
+ my $str = shift;
+ $byte = $bmax = shift;
+ foreach $ch ($str =~ /$char/go) {
+ $byte += length $ch; # ŽŸ‚Ì•¶Žš‚ðŒp‚¬‘«‚µ‚œ’·‚³
+ if ($byte <= $bmax) {
+ $lines[-1] .= $ch; # ’·‚·‚¬‚È‚¯‚ê‚ÎŒp‚¬‘«‚·
+ } else {
+ $byte = length $ch;
+ push @lines, $ch; # ‚³‚à‚È‚¯‚ê‚ÎŽŸ‚̍s‚Ö
+ }
+ }
+ return @lines;
+ # ’·‚³‚ª‘«‚ç‚È‚¢ê‡‚ɁA‰E‚ðƒXƒy[ƒX‚Å–„‚ß‚œ‚¯‚ê‚΁B
+ # return map {$_ .= ' ' x ($bmax - length)} @lines;
+}
+
+‹Ö‘¥ˆ—‚́A—á‚Š‚ÎŽŸ‚Ì‚æ‚€‚É‚µ‚čs‚¢‚Ü‚·B’Pƒ‚ȍl‚Š•û‚ł́A‹Ö‘¥ˆ—‚́A(i) s“ª‹Ö‘¥•¶Žš‚Ì’Œ‘O‚ʼnüs‚µ‚È‚¢G(ii) s––‹Ö‘¥•¶Žš‚Ì’ŒŒã‚ʼnüs‚µ‚È‚¢G‚Æ‚¢‚€‚±‚Æ‚É‚È‚è‚Ü‚·B‚Ü‚œA"(a)"‚Ì‚æ‚€‚ɁAs––‹Ö‘¥•¶Žš‚ƍs“ª‹Ö‘¥•¶Žš‚ÌŠÔ‚É‚P•¶Žš‚µ‚©‚È‚¢˜A‘±‚µ‚œ•”•ª‚́A‚»‚Ì•”•ª‚Ì‘S‘Ì‚ª–³‰üs‚É‚È‚é“_‚É‚à”z—¶‚µ‚Ü‚·B
+‚±‚Ì—á‚Å‚Í•¶Žš—ñ‚Ì’·‚³‚ðƒoƒCƒg’· length ‚Å‹K’肵‚Ä‚¢‚Ü‚·‚ªA•¶Žš•‚ƃoƒCƒg”‚Í•K‚ž‚µ‚à”ä—Ⴕ‚Ü‚¹‚ñ‚̂ŁAê‡‚É‚æ‚Á‚ẮiƒMƒŠƒVƒA•¶Žš‚Í”ŒŠp•‚É‚µ‚œ‚¢‚Æ‚©A‚Ü‚œ‚̓vƒƒ|[ƒVƒ‡ƒiƒ‹‚̏ꍇ‚Æ‚©AUTF-8‚̏ꍇ‚Æ‚©j•¶Žš•‚ð•Ô‚· width ‚Ì‚æ‚€‚Ȋ֐”‚ð’è‹`‚·‚é•K—v‚ª‚ ‚é‚Å‚µ‚å‚€B
+‚Ü‚œA‚±‚Ì—á‚Ì‚â‚è•û‚ł́A‹Ö‘¥‚É‚æ‚é–³‰üs•”•ª‚Ÿ‚¯‚ňês‚æ‚è’·‚­‚È‚éê‡‚́A‚Í‚Ý‚Ÿ‚µ‚ð–h‚°‚Ü‚¹‚ñB‚»‚ꂪ¢‚é‚È‚çA‹Ö‘¥‚Ì—áŠO‚Æ‚µ‚čs‚𕪂¯‚éi—á‚Š‚Î$next‚Ì’·‚³‚ª$bmax‚ð’Ž‚Š‚È‚¢‚æ‚€‚É‚·‚éjˆ’u‚ª•K—v‚Å‚µ‚å‚€B
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
+
+# s“ª‹Ö‘¥•¶Žšiˆê•”•ªj
+$NotAtBegin = q/)]}fhvxjnp!,.:;?ABXJKICDFGH/;
+# s––‹Ö‘¥•¶Žšiˆê•”•ªj
+$NotAtEnd = q/([{eguwimo/;
+
+# ƒnƒbƒVƒ…‚ðì‚é
+@NotAtBegin{$NotAtBegin =~ m/$CharRE/g} = ();
+@NotAtEnd{ $NotAtEnd =~ m/$CharRE/g} = ();
+
+$Str = '‚í‚Ž‚í‚ŽEUC-JP‚É•ÏŠ·‚µ‚È‚¢‚ŁAShift-JIS‚̂܂܏ˆ—'.
+ '‚Å‚«‚œ‚ç‚¢‚¢‚ñ‚Ÿ‚¯‚ǁA‚È‚©‚È‚©–Ê“|‚Ÿ‚Ë‚ŠB';
+
+print join "\n", linebreak($Str,16);
+
+sub linebreak{
+ my($byte,$i,@chars,$next,@lines);
+ my($str, $bmax, $pad) = @_;
+
+ # $byte‚ÍŽŸ‚Ì•¶Žš‚ðŒp‚¬‘«‚µ‚œ‚Æ‚«‚Ì’·‚³
+ $byte = $bmax; # ‚·‚®‰üs‚Å‚«‚é‚œ‚߂̏‰Šú’lB
+
+ # •¶Žš’PˆÊ‚ɂ΂炷
+ @chars = $str =~ /$CharRE/go;
+
+ for ($i=0; $i<@chars; $i++) {
+ $next .= $chars[$i]; # ŽŸ‚Ì•¶Žš
+ $byte += length $chars[$i]; # ŽŸ‚Ì•¶Žš‚ðŒp‚¬‘«‚µ‚œ’·‚³
+
+ # ŽŸ‚Ì•¶Žš‚ªs––‹Ö‘¥‚Ì‚Æ‚«
+ next if $i+1 < @chars && exists $NotAtEnd{ $chars[$i] };
+ # ŽŸ‚Ì•¶Žš‚ÌŽŸ‚ªs“ª‹Ö‘¥‚Ì‚Æ‚«
+ next if $i+1 < @chars && exists $NotAtBegin{ $chars[$i+1] };
+
+ # s‚̐U‚蕪‚¯
+ # ’·‚·‚¬‚È‚¯‚ê‚ÎŒp‚¬‘«‚·
+ if ($byte <= $bmax) {
+ $lines[-1] .= $next;
+ }
+ # ‚³‚à‚È‚¯‚ê‚ÎŽŸ‚̍s‚Ö
+ else {
+ push @lines, $next;
+ $byte = length $next;# V‚µ‚¢s‚Ì’·‚³
+ }
+ $next = '';
+ }
+ return defined $pad && 1 == length $pad # ‹l‚ß•š
+ ? map {$_ .= $pad x ($bmax - length)} @lines
+ : @lines;
+}
+
+‚Ԃ牺‚ª‚è‹Ö‘¥‚̏ꍇi$bmin ‚©‚ç $bmax‚Ì”ÍˆÍ‚ð‹–‚·jB
+ $bmin = $bmax - 2; # —á‚Š‚΁B
+
+ # s‚̐U‚蕪‚¯
+ # ’·‚·‚¬‚È‚¯‚ê‚ÎŒp‚¬‘«‚·
+ if ($byte <= $bmax && @lines && length $lines[-1] < $bmin){
+ $lines[-1] .= $next;
+ }
+ # ‚³‚à‚È‚¯‚ê‚ÎŽŸ‚̍s‚Ö
+ else {
+ push @lines, $next;
+ $byte = length $next;# V‚µ‚¢s‚Ì’·‚³
+ }
+
+“ú–{Œê•¶Žš—ñ‚ð•À‚Ñ‘Ö‚Š‚é
+‰Œ–Œ•¶Žš—ñ‚ðŒÜ\‰¹‡‚Ƀ\[ƒg‚·‚郂ƒWƒ…[ƒ‹‚Æ‚µ‚āAShiftJIS/Collate.pm ‚ª‚ ‚è‚Ü‚·B“üŽè‚ÆŽg‚¢•û‚ÍPerl‚̃y[ƒW‚É–ß‚ê‚ÎŒ©‚‚©‚è‚Ü‚·B
+u“ǂ݁E•\‹LÆ‡v‚ÍŽŸ‚Ì‚æ‚€‚É‚µ‚čs‚¢‚Ü‚·BsortYomiƒƒ\ƒbƒh‚̎󂯎æ‚郊ƒXƒg‚ÌŠe—v‘f‚́A[ •\‹L—ñ, “Ç‚Ý—ñ ]‚Æ‚¢‚€”z—ñƒŠƒtƒ@ƒŒƒ“ƒX‚Å‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+use ShiftJIS::Collate;
+
+my @data = (
+ [qw/ ¬ŽR ‚±‚â‚Ü /],
+ [qw/ ’·“c ‚È‚ª‚œ /],
+ [qw/ “c’† ‚œ‚È‚© /],
+ [qw/ —é–Ø ‚·‚ž‚« /],
+ [qw/ ¬“ˆ ‚±‚¶‚Ü /],
+ [qw/ Ž™“‡ ‚±‚¶‚Ü /],
+ [qw/ ¬ŽR ‚š‚â‚Ü /],
+ [qw/ ¬“‡ ‚±‚¶‚Ü /],
+ [qw/ ¬“‡ ‚±‚¶‚Ü /],
+ [qw/ ŽR“c ‚â‚Ü‚Ÿ /],
+ [qw/ ‰i“c ‚È‚ª‚œ /],
+);
+
+@sort = ShiftJIS::Collate->new()->sortYomi(@data);
+
+uŠÈˆÕ‘ã•\“ǂݏƍ‡v‚ÍŽŸ‚Ì‚æ‚€‚É‚µ‚čs‚¢‚Ü‚·BsortDaihyoƒƒ\ƒbƒh‚̎󂯎æ‚郊ƒXƒg‚ÌŠe—v‘f‚́A[ •\‹L—ñ, “Ç‚Ý—ñ ]‚Æ‚¢‚€”z—ñƒŠƒtƒ@ƒŒƒ“ƒX‚Å‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB
+ƒTƒ“ƒvƒ‹ƒR[ƒh
+
+#!perl
+use ShiftJIS::Collate;
+
+my @data = (
+ [qw/ ƒÉŒvŽZ ‚ç‚Þ‚Ÿ‚¯‚¢‚³‚ñ /],
+ [qw/ JIS”ԍ† ‚¶‚·‚΂ñ‚²‚€ /],
+ [qw/ ˆÀ’B ‚ ‚Ÿ‚¿ /],
+ [qw/ ˆÀ“¡ ‚ ‚ñ‚Ç‚€ /],
+ [qw/ ‰ÍŒ ‚©‚³‚¢ /],
+ [qw/ ‰Í“à ‚©‚í‚¿ /],
+ [qw/ Šp“c ‚©‚­‚œ /],
+ [qw/ Šp“c ‚©‚Ç‚œ /],
+ [qw/ ”@ŒŽ ‚«‚³‚炬 /],
+ [qw/ ‰Í“à ‚±‚€‚¿ /],
+ [qw/ KŽR ‚±‚€‚â‚Ü /],
+ [qw/ KŽR ‚³‚«‚â‚Ü /],
+ [qw/ ²“¡ ‚³‚Æ‚€ /],
+ [qw/ ²˜a“c ‚³‚í‚Ÿ /],
+ [qw/ ‘ò“‡ ‚³‚킵‚Ü /],
+ [qw/ ‘ò“c ‚³‚í‚Ÿ /],
+ [qw/ àV“c ‚³‚í‚Ÿ /],
+ [qw/ Šp“c ‚‚̂Ÿ /],
+ [qw/ ’Æˆä ‚Â‚¿‚¢ /],
+ [qw/ “yˆä ‚‚¿‚¢ /],
+ [qw/ “y‹ ‚‚¿‚¢ /],
+ [qw/ ŒËˆä ‚Æ‚¢ /],
+ [qw/ ŒË“c ‚Æ‚Ÿ /],
+ [qw/ “yˆä ‚Ç‚¢ /],
+ [qw/ “y‹ ‚Ç‚¢ /],
+ [qw/ “yŠò ‚Æ‚« /],
+ [qw/ ˆÀ“c ‚â‚·‚Ÿ /],
+);
+
+@sort = ShiftJIS::Collate->new()->sortDaihyo(@data);
+
+
+Shift-JIS‚ÌŠ¿Žš‚ðŠÜ‚Þƒtƒ@ƒCƒ‹–Œ/ƒpƒX–Œ
+–{€–ڂ́A‘Œ‚̍€–Ú‚É‘‚µ‚āAŒŸ“¢•s[•ª‚Ì‚Ü‚Ü‹Lq‚µ‚Ä‚¢‚Ü‚·‚̂ŁA‚à‚µ‰œ‚©ŽQl‚É‚µ‚æ‚€‚ÆŽv‚Á‚œê‡A\•ª‚É’ˆÓ‚̏ãA”[“Ÿ‚Å‚«‚é‚Ü‚Å‚²Ž©•ª‚̍ì‹ÆŠÂ‹«‚ŃeƒXƒg‚µ‚Ä‚­‚Ÿ‚³‚¢B
+Windows (95/98/NT/2000‚È‚Ç) ‚ŁAƒtƒ@ƒCƒ‹–Œ‚âƒpƒX–Œ‚ªŠ¿Žši‚±‚±‚Å‚Í“ñƒoƒCƒg•¶Žš‚̈Ӗ¡‚ÅŽg‚Á‚Ä‚¢‚Ü‚·‚̂ŁA•œ‰Œ–Œ‚â‹L†‚È‚Ç‚àŠÜ‚Ý‚Ü‚·Bj‚ðŠÜ‚ޏꍇAPerl‚ňµ‚€Û‚É–â‘肪¶‚¶‚é‰Â”\«‚ª‚ ‚è‚Ü‚·B
+––”öƒoƒCƒg‚ª "\x5C" ‚ÌŠ¿Žš‚ð‚à‚ƒtƒ@ƒCƒ‹–Œ/ƒpƒX–Œ
+ƒfƒBƒŒƒNƒgƒŠ‘€ìŠÖ”imkdir, rmdir, opendir, -d ‚ȂǁjAƒtƒ@ƒCƒ‹‘€ìŠÖ”iopen, unlink, -f ‚Ȃǁj‚ŁAƒAƒNƒZƒX‚Å‚«‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚·B
+ƒtƒ@ƒCƒ‹‚̏ꍇ‚́A––”ö‚É”ŒŠpƒXƒy[ƒX‚ð“Y‚Š‚é‚ƃAƒNƒZƒX‚Å‚«‚éê‡‚ª‚ ‚è‚Ü‚·i—á‚Š‚΁A-f '•\ ' ‚Ü‚œ‚Í -f "\x95\x5C\x20" ‚ȂǁjB
+ƒfƒBƒŒƒNƒgƒŠ‚̏ꍇ‚́A––”ö‚É / ‚© \ ‚ð“Y‚Š‚é‚ƃAƒNƒZƒX‚Å‚«‚éê‡‚ª‚ ‚è‚Ü‚·i—á‚Š‚΁A-d '•\/' ‚Ü‚œ‚Í -d "\x95\x5C/" ‚ȂǁjB––”ö‚É“Y‚Š‚镶Žš‚𔌊pƒXƒy[ƒX‚Æ‚µ‚Ä‚àA‚€‚Ü‚­ƒAƒNƒZƒX‚Å‚«‚éê‡‚ª‚ ‚è‚Ü‚·B“Y‚Š‚镶Žš‚ÌŒó•â‚Æ‚µ‚āAŽOŽí—Þ‚Ì•¶ŽšiƒXƒ‰ƒbƒVƒ…A‰~‹L†A‹ó”’j‚ð‹“‚°‚Ü‚µ‚œ‚ªA‚Ç‚Ì•¶Žš‚ª‚æ‚¢‚©‚́AŠÖ”‚É‚æ‚Á‚ĈقȂéê‡‚ª‚ ‚é‚æ‚€‚Å‚·BŽg—p‚·‚é‘O‚ɏ\•ª‚ɃeƒXƒg‚µ‚Ä‚­‚Ÿ‚³‚¢B
+‚È‚šAƒfƒBƒŒƒNƒgƒŠ–Œ‚Ì––”ö‚É / ‚© \ ‚ð“Y‚Š‚éê‡A‚à‚Æ‚à‚Æ––”ö‚É / ‚© \ ‚ª•t‚¢‚Ä‚¢‚éê‡‚ɂ́A“ñd‚É•t‚¯‚é‚Æ‚€‚Ü‚­s‚©‚È‚¢‚š‚»‚ꂪ‚ ‚è‚Ü‚·‚̂ŁA•¶Žš—ñ˜AŒ‹‚Ì‘O‚ÉŒŸž‚µ‚œ‚Ù‚€‚ª‚æ‚¢‚Å‚µ‚å‚€B
+‚Ç‚€‚µ‚Ä‚à‹““®‚ª•s–Ÿ‚ŐM—Š‚Å‚«‚È‚¢ê‡‚́A`` ‚Ü‚œ‚Í qx// ‚â system()ŠÖ”‚È‚Ç‚ð’Ê‚¶‚ÄWindows‚̃Rƒ}ƒ“ƒh‚ðŒÄ‚Ô‚Ì‚ª—Ç‚¢‚ÆŽv‚¢‚Ü‚·B
+‚š‚Ü‚¯
+ Shift-JIS ‚ŏ‘‚©‚ê‚œ POD ‚ð Perl 5.8.1, 5.8.2 ‚Ì Pod::Html ‚Å HTML ‚É•ÏŠ·‚µ‚œê‡AƒAƒ“ƒJ[‚Ì–Œ‘O‚́A ‰p”Žš‚ƉŒ–Œ•¶Žš [0xA6..0xDF] ‚ðœ‚«A ‘Œ‚ÌŠeƒoƒCƒg‚͉ºüi'_'j‚É•ÏŠ·‚³‚ê‚é‚æ‚€‚Å‚·B ‹ï‘Ì“I‚ɂ́Ause locale; ‰º‚ŁAlc ‚Æ s/\W/_/g ‚ðŽÀs‚µ‚œŒ‹‰Ê (cf. Pod::Html::anchorify) ‚É‚È‚è‚Ü‚·B
+[2003-11-18]
+Perl‚̃y[ƒW
diff --git a/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp
new file mode 100644
index 0000000000..6d51f84fa1
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication a(argc, argv);
+ QTextStream qin(stdin);
+ if (!qin.atEnd()) {
+ int a, b, c;
+ qin >> a >> b >> c;
+ qDebug("%d %d %d", a, b, c);
+ }
+ return 0;
+}
diff --git a/tests/auto/corelib/io/qtextstream/stdinProcess/stdinProcess.pro b/tests/auto/corelib/io/qtextstream/stdinProcess/stdinProcess.pro
new file mode 100644
index 0000000000..9cf4d19387
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/stdinProcess/stdinProcess.pro
@@ -0,0 +1,7 @@
+SOURCES += main.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+DESTDIR = ./
+
+
diff --git a/tests/auto/corelib/io/qtextstream/task113817.txt b/tests/auto/corelib/io/qtextstream/task113817.txt
new file mode 100644
index 0000000000..281ae8c9f2
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/task113817.txt
@@ -0,0 +1,1095 @@
+1 13 -14
+2 13 14
+3 40 -3
+4 16383 4
+5 16383 5
+6 16383 6
+7 16383 7
+8 16383 8
+9 16383 9
+10 16383 10
+11 16383 -1
+12 16383 -1
+13 16383 -1
+14 16383 -1
+15 16383 -1
+16 16383 -1
+17 16383 -1
+18 16383 -1
+19 16383 -1
+20 16383 -1
+21 16383 -1
+22 16383 -1
+23 16383 -1
+24 16383 -1
+25 16383 -1
+26 16383 -1
+27 16383 -1
+28 16383 -1
+29 16383 -1
+30 16383 -1
+31 16383 -1
+32 16383 -1
+33 16383 -1
+34 16383 -1
+35 16383 -1
+36 16383 -1
+37 16383 -1
+38 16383 -1
+39 16383 -1
+40 16383 -1
+41 16383 -1
+42 16383 -1
+43 16383 -1
+44 16383 -1
+45 16383 -1
+46 16383 -1
+47 16383 -1
+48 16383 -1
+49 16383 -1
+50 16383 -1
+51 16383 -1
+52 16383 -1
+53 16383 -1
+54 16383 -1
+55 16383 -1
+56 16383 -1
+57 16383 -1
+58 16383 -1
+59 16383 -1
+60 16383 -1
+61 16383 -1
+62 16383 -1
+63 16383 -1
+64 16383 -1
+65 16383 -1
+66 16383 -1
+67 16383 -1
+68 16383 -1
+69 16383 -1
+70 16383 -1
+71 16383 -1
+72 16383 -1
+73 16383 -1
+74 16383 -1
+75 16383 -1
+76 16383 -1
+77 16383 -1
+78 16383 -1
+79 16383 -1
+80 16383 -1
+81 16383 -1
+82 16383 -1
+83 16383 -1
+84 16383 -1
+85 16383 -1
+86 16383 -1
+87 16383 -1
+88 16383 -1
+89 16383 -1
+90 16383 -1
+91 16383 -1
+92 16383 -1
+93 16383 -1
+94 16383 -1
+95 16383 -1
+96 16383 -1
+97 16383 -1
+98 16383 -1
+99 16383 -1
+100 16383 -1
+101 16383 -1
+102 16383 -1
+103 16383 -1
+104 16383 -1
+105 16383 -1
+106 16383 -1
+107 16383 -1
+108 16383 -1
+109 16383 -1
+110 16383 -1
+111 16383 -1
+112 16383 -1
+113 16383 -1
+114 16383 -1
+115 16383 -1
+116 16383 -1
+117 16383 -1
+118 16383 -1
+119 16383 -1
+120 16383 -1
+121 16383 -1
+122 16383 -1
+123 16383 -1
+124 16383 -1
+125 16383 -1
+126 16383 -1
+127 16383 -1
+128 16383 -1
+129 16383 -1
+130 16383 -1
+131 16383 -1
+132 16383 -1
+133 16383 -1
+134 16383 -1
+135 16383 -1
+136 16383 -1
+137 16383 -1
+138 16383 -1
+139 16383 -1
+140 16383 -1
+141 16383 -1
+142 16383 -1
+143 16383 -1
+144 16383 -1
+145 16383 -1
+146 16383 -1
+147 16383 -1
+148 16383 -1
+149 16383 -1
+150 16383 -1
+151 16383 -1
+152 16383 -1
+153 16383 -1
+154 16383 -1
+155 16383 -1
+156 16383 -1
+157 16383 -1
+158 16383 -1
+159 16383 -1
+160 16383 -1
+161 16383 -1
+162 16383 -1
+163 16383 -1
+164 16383 -1
+165 16383 -1
+166 16383 -1
+167 16383 -1
+168 16383 -1
+169 16383 -1
+170 16383 -1
+171 16383 -1
+172 16383 -1
+173 16383 -1
+174 16383 -1
+175 16383 -1
+176 16383 -1
+177 16383 -1
+178 16383 -1
+179 16383 -1
+180 16383 -1
+181 16383 -1
+182 16383 -1
+183 16383 -1
+184 16383 -1
+185 16383 -1
+186 16383 -1
+187 16383 -1
+188 16383 -1
+189 16383 -1
+190 16383 -1
+191 16383 -1
+192 16383 -1
+193 16383 -1
+194 16383 -1
+195 16383 -1
+196 16383 -1
+197 16383 -1
+198 16383 -1
+199 16383 -1
+200 16383 -1
+201 16383 -1
+202 16383 -1
+203 16383 -1
+204 16383 -1
+205 16383 -1
+206 16383 -1
+207 16383 -1
+208 16383 -1
+209 16383 -1
+210 16383 -1
+211 16383 -1
+212 16383 -1
+213 16383 -1
+214 16383 -1
+215 16383 -1
+216 16383 -1
+217 16383 -1
+218 16383 -1
+219 16383 -1
+220 16383 -1
+221 16383 -1
+222 16383 -1
+223 16383 -1
+224 16383 -1
+225 16383 -1
+226 16383 -1
+227 16383 -1
+228 16383 -1
+229 16383 -1
+230 16383 -1
+231 16383 -1
+232 16383 -1
+233 16383 -1
+234 16383 -1
+235 16383 -1
+236 16383 -1
+237 16383 -1
+238 16383 -1
+239 16383 -1
+240 16383 -1
+241 16383 -1
+242 16383 -1
+243 16383 -1
+244 16383 -1
+245 16383 -1
+246 16383 -1
+247 16383 -1
+248 16383 -1
+249 16383 -1
+250 16383 -1
+251 16383 -1
+252 16383 -1
+253 16383 -1
+254 16383 -1
+255 16383 -1
+256 16383 -1
+257 16383 -1
+258 16383 -1
+259 16383 -1
+260 16383 -1
+261 16383 -1
+262 16383 -1
+263 16383 -1
+264 16383 -1
+265 16383 -1
+266 16383 -1
+267 16383 -1
+268 16383 -1
+269 16383 -1
+270 16383 -1
+271 16383 -1
+272 16383 -1
+273 16383 -1
+274 16383 -1
+275 16383 -1
+276 16383 -1
+277 16383 -1
+278 16383 -1
+279 16383 -1
+280 16383 -1
+281 16383 -1
+282 16383 -1
+283 16383 -1
+284 16383 -1
+285 16383 -1
+286 16383 -1
+287 16383 -1
+288 16383 -1
+289 16383 -1
+290 16383 -1
+291 16383 -1
+292 16383 -1
+293 16383 -1
+294 16383 -1
+295 16383 -1
+296 16383 -1
+297 16383 -1
+298 16383 -1
+299 16383 -1
+300 16383 -1
+301 16383 -1
+302 16383 -1
+303 16383 -1
+304 16383 -1
+305 16383 -1
+306 16383 -1
+307 16383 -1
+308 16383 -1
+309 16383 -1
+310 16383 -1
+311 16383 -1
+312 16383 -1
+313 16383 -1
+314 16383 -1
+315 16383 -1
+316 16383 -1
+317 16383 -1
+318 16383 -1
+319 16383 -1
+320 16383 -1
+321 16383 -1
+322 16383 -1
+323 16383 -1
+324 16383 -1
+325 16383 -1
+326 16383 -1
+327 16383 -1
+328 16383 -1
+329 16383 -1
+330 16383 -1
+331 16383 -1
+332 16383 -1
+333 16383 -1
+334 16383 -1
+335 16383 -1
+336 16383 -1
+337 16383 -1
+338 16383 -1
+339 16383 -1
+340 16383 -1
+341 16383 -1
+342 16383 -1
+343 16383 -1
+344 16383 -1
+345 16383 -1
+346 16383 -1
+347 16383 -1
+348 16383 -1
+349 16383 -1
+350 16383 -1
+351 16383 -1
+352 16383 -1
+353 16383 -1
+354 16383 -1
+355 16383 -1
+356 16383 -1
+357 16383 -1
+358 16383 -1
+359 16383 -1
+360 16383 -1
+361 16383 -1
+362 16383 -1
+363 16383 -1
+364 16383 -1
+365 16383 -1
+366 16383 -1
+367 16383 -1
+368 16383 -1
+369 16383 -1
+370 16383 -1
+371 16383 -1
+372 16383 -1
+373 16383 -1
+374 16383 -1
+375 16383 -1
+376 16383 -1
+377 16383 -1
+378 16383 -1
+379 16383 -1
+380 16383 -1
+381 16383 -1
+382 16383 -1
+383 16383 -1
+384 16383 -1
+385 16383 -1
+386 16383 -1
+387 16383 -1
+388 16383 -1
+389 16383 -1
+390 16383 -1
+391 16383 -1
+392 16383 -1
+393 16383 -1
+394 16383 -1
+395 16383 -1
+396 16383 -1
+397 16383 -1
+398 16383 -1
+399 16383 -1
+400 16383 -1
+401 16383 -1
+402 16383 -1
+403 16383 -1
+404 16383 -1
+405 16383 -1
+406 16383 -1
+407 16383 -1
+408 16383 -1
+409 16383 -1
+410 16383 -1
+411 16383 -1
+412 16383 -1
+413 16383 -1
+414 16383 -1
+415 16383 -1
+416 16383 -1
+417 16383 -1
+418 16383 -1
+419 16383 -1
+420 16383 -1
+421 16383 -1
+422 16383 -1
+423 16383 -1
+424 16383 -1
+425 16383 -1
+426 16383 -1
+427 16383 -1
+428 16383 -1
+429 16383 -1
+430 16383 -1
+431 16383 -1
+432 16383 -1
+433 16383 -1
+434 16383 -1
+435 16383 -1
+436 16383 -1
+437 16383 -1
+438 16383 -1
+439 16383 -1
+440 16383 -1
+441 16383 -1
+442 16383 -1
+443 16383 -1
+444 16383 -1
+445 16383 -1
+446 16383 -1
+447 16383 -1
+448 16383 -1
+449 16383 -1
+450 16383 -1
+451 16383 -1
+452 16383 -1
+453 16383 -1
+454 16383 -1
+455 16383 -1
+456 16383 -1
+457 16383 -1
+458 16383 -1
+459 16383 -1
+460 16383 -1
+461 16383 -1
+462 16383 -1
+463 16383 -1
+464 16383 -1
+465 16383 -1
+466 16383 -1
+467 16383 -1
+468 16383 -1
+469 16383 -1
+470 16383 -1
+471 16383 -1
+472 16383 -1
+473 16383 -1
+474 16383 -1
+475 16383 -1
+476 16383 -1
+477 16383 -1
+478 16383 -1
+479 16383 -1
+480 16383 -1
+481 16383 -1
+482 16383 -1
+483 16383 -1
+484 16383 -1
+485 16383 -1
+486 16383 -1
+487 16383 -1
+488 16383 -1
+489 16383 -1
+490 16383 -1
+491 16383 -1
+492 16383 -1
+493 16383 -1
+494 16383 -1
+495 16383 -1
+496 16383 -1
+497 16383 -1
+498 16383 -1
+499 16383 -1
+500 16383 -1
+501 16383 -1
+502 16383 -1
+503 16383 -1
+504 16383 -1
+505 16383 -1
+506 16383 -1
+507 16383 -1
+508 16383 -1
+509 16383 -1
+510 16383 -1
+511 16383 -1
+512 16383 -1
+513 16383 -1
+514 16383 -1
+515 16383 -1
+516 16383 -1
+517 16383 -1
+518 16383 -1
+519 16383 -1
+520 16383 -1
+521 16383 -1
+522 16383 -1
+523 16383 -1
+524 16383 -1
+525 16383 -1
+526 16383 -1
+527 16383 -1
+528 16383 -1
+529 16383 -1
+530 16383 -1
+531 16383 -1
+532 16383 -1
+533 16383 -1
+534 16383 -1
+535 16383 -1
+536 16383 -1
+537 16383 -1
+538 16383 -1
+539 16383 -1
+540 16383 -1
+541 16383 -1
+542 16383 -1
+543 16383 -1
+544 16383 -1
+545 16383 -1
+546 16383 -1
+547 16383 -1
+548 16383 -1
+549 16383 -1
+550 16383 -1
+551 16383 -1
+552 16383 -1
+553 16383 -1
+554 16383 -1
+555 16383 -1
+556 16383 -1
+557 16383 -1
+558 16383 -1
+559 16383 -1
+560 16383 -1
+561 16383 -1
+562 16383 -1
+563 16383 -1
+564 16383 -1
+565 16383 -1
+566 16383 -1
+567 16383 -1
+568 16383 -1
+569 16383 -1
+570 16383 -1
+571 16383 -1
+572 16383 -1
+573 16383 -1
+574 16383 -1
+575 16383 -1
+576 16383 -1
+577 16383 -1
+578 16383 -1
+579 16383 -1
+580 16383 -1
+581 16383 -1
+582 16383 -1
+583 16383 -1
+584 16383 -1
+585 16383 -1
+586 16383 -1
+587 16383 -1
+588 16383 -1
+589 16383 -1
+590 16383 -1
+591 16383 -1
+592 16383 -1
+593 16383 -1
+594 16383 -1
+595 16383 -1
+596 16383 -1
+597 16383 -1
+598 16383 -1
+599 16383 -1
+600 16383 -1
+601 16383 -1
+602 16383 -1
+603 16383 -1
+604 16383 -1
+605 16383 -1
+606 16383 -1
+607 16383 -1
+608 16383 -1
+609 16383 -1
+610 16383 -1
+611 16383 -1
+612 16383 -1
+613 16383 -1
+614 16383 -1
+615 16383 -1
+616 16383 -1
+617 16383 -1
+618 16383 -1
+619 16383 -1
+620 16383 -1
+621 16383 -1
+622 16383 -1
+623 16383 -1
+624 16383 -1
+625 16383 -1
+626 16383 -1
+627 16383 -1
+628 16383 -1
+629 16383 -1
+630 16383 -1
+631 16383 -1
+632 16383 -1
+633 16383 -1
+634 16383 -1
+635 16383 -1
+636 16383 -1
+637 16383 -1
+638 16383 -1
+639 16383 -1
+640 16383 -1
+641 16383 -1
+642 16383 -1
+643 16383 -1
+644 16383 -1
+645 16383 -1
+646 16383 -1
+647 16383 -1
+648 16383 -1
+649 16383 -1
+650 16383 -1
+651 16383 -1
+652 16383 -1
+653 16383 -1
+654 16383 -1
+655 16383 -1
+656 16383 -1
+657 16383 -1
+658 16383 -1
+659 16383 -1
+660 16383 -1
+661 16383 -1
+662 16383 -1
+663 16383 -1
+664 16383 -1
+665 16383 -1
+666 16383 -1
+667 16383 -1
+668 16383 -1
+669 16383 -1
+670 16383 -1
+671 16383 -1
+672 16383 -1
+673 16383 -1
+674 16383 -1
+675 16383 -1
+676 16383 -1
+677 16383 -1
+678 16383 -1
+679 16383 -1
+680 16383 -1
+681 16383 -1
+682 16383 -1
+683 16383 -1
+684 16383 -1
+685 16383 -1
+686 16383 -1
+687 16383 -1
+688 16383 -1
+689 16383 -1
+690 16383 -1
+691 16383 -1
+692 16383 -1
+693 16383 -1
+694 16383 -1
+695 16383 -1
+696 16383 -1
+697 16383 -1
+698 16383 -1
+699 16383 -1
+700 16383 -1
+701 16383 -1
+702 16383 -1
+703 16383 -1
+704 16383 -1
+705 16383 -1
+706 16383 -1
+707 16383 -1
+708 16383 -1
+709 16383 -1
+710 16383 -1
+711 16383 -1
+712 16383 -1
+713 16383 -1
+714 16383 -1
+715 16383 -1
+716 16383 -1
+717 16383 -1
+718 16383 -1
+719 16383 -1
+720 16383 -1
+721 16383 -1
+722 16383 -1
+723 16383 -1
+724 16383 -1
+725 16383 -1
+726 16383 -1
+727 16383 -1
+728 16383 -1
+729 16383 -1
+730 16383 -1
+731 16383 -1
+732 16383 -1
+733 16383 -1
+734 16383 -1
+735 16383 -1
+736 16383 -1
+737 16383 -1
+738 16383 -1
+739 16383 -1
+740 16383 -1
+741 16383 -1
+742 16383 -1
+743 16383 -1
+744 16383 -1
+745 16383 -1
+746 16383 -1
+747 16383 -1
+748 16383 -1
+749 16383 -1
+750 16383 -1
+751 16383 -1
+752 16383 -1
+753 16383 -1
+754 16383 -1
+755 16383 -1
+756 16383 -1
+757 16383 -1
+758 16383 -1
+759 16383 -1
+760 16383 -1
+761 16383 -1
+762 16383 -1
+763 16383 -1
+764 16383 -1
+765 16383 -1
+766 16383 -1
+767 16383 -1
+768 16383 -1
+769 16383 -1
+770 16383 -1
+771 16383 -1
+772 16383 -1
+773 16383 -1
+774 16383 -1
+775 16383 -1
+776 16383 -1
+777 16383 -1
+778 16383 -1
+779 16383 -1
+780 16383 -1
+781 16383 -1
+782 16383 -1
+783 16383 -1
+784 16383 -1
+785 16383 -1
+786 16383 -1
+787 16383 -1
+788 16383 -1
+789 16383 -1
+790 16383 -1
+791 16383 -1
+792 16383 -1
+793 16383 -1
+794 16383 -1
+795 16383 -1
+796 16383 -1
+797 16383 -1
+798 16383 -1
+799 16383 -1
+800 16383 -1
+801 16383 -1
+802 16383 -1
+803 16383 -1
+804 16383 -1
+805 16383 -1
+806 16383 -1
+807 16383 -1
+808 16383 -1
+809 16383 -1
+810 16383 -1
+811 16383 -1
+812 16383 -1
+813 16383 -1
+814 16383 -1
+815 16383 -1
+816 16383 -1
+817 16383 -1
+818 16383 -1
+819 16383 -1
+820 16383 -1
+821 16383 -1
+822 16383 -1
+823 16383 -1
+824 16383 -1
+825 16383 -1
+826 16383 -1
+827 16383 -1
+828 16383 -1
+829 16383 -1
+830 16383 -1
+831 16383 -1
+832 16383 -1
+833 16383 -1
+834 16383 -1
+835 16383 -1
+836 16383 -1
+837 16383 -1
+838 16383 -1
+839 16383 -1
+840 16383 -1
+841 16383 -1
+842 16383 -1
+843 16383 -1
+844 16383 -1
+845 16383 -1
+846 16383 -1
+847 16383 -1
+848 16383 -1
+849 16383 -1
+850 16383 -1
+851 16383 -1
+852 16383 -1
+853 16383 -1
+854 16383 -1
+855 16383 -1
+856 16383 -1
+857 16383 -1
+858 16383 -1
+859 16383 -1
+860 16383 -1
+861 16383 -1
+862 16383 -1
+863 16383 -1
+864 16383 -1
+865 16383 -1
+866 16383 -1
+867 16383 -1
+868 16383 -1
+869 16383 -1
+870 16383 -1
+871 16383 -1
+872 16383 -1
+873 16383 -1
+874 16383 -1
+875 16383 -1
+876 16383 -1
+877 16383 -1
+878 16383 -1
+879 16383 -1
+880 16383 -1
+881 16383 -1
+882 16383 -1
+883 16383 -1
+884 16383 -1
+885 16383 -1
+886 16383 -1
+887 16383 -1
+888 16383 -1
+889 16383 -1
+890 16383 -1
+891 16383 -1
+892 16383 -1
+893 16383 -1
+894 16383 -1
+895 16383 -1
+896 16383 -1
+897 16383 -1
+898 16383 -1
+899 16383 -1
+900 16383 -1
+901 16383 -1
+902 16383 -1
+903 16383 -1
+904 16383 -1
+905 16383 -1
+906 16383 -1
+907 16383 -1
+908 16383 -1
+909 16383 -1
+910 16383 -1
+911 16383 -1
+912 16383 -1
+913 16383 -1
+914 16383 -1
+915 16383 -1
+916 16383 -1
+917 16383 -1
+918 16383 -1
+919 16383 -1
+920 16383 -1
+921 16383 -1
+922 16383 -1
+923 16383 -1
+924 16383 -1
+925 16383 -1
+926 16383 -1
+927 16383 -1
+928 16383 -1
+929 16383 -1
+930 16383 -1
+931 16383 -1
+932 16383 -1
+933 16383 -1
+934 16383 -1
+935 16383 -1
+936 16383 -1
+937 16383 -1
+938 16383 -1
+939 16383 -1
+940 16383 -1
+941 16383 -1
+942 16383 -1
+943 16383 -1
+944 16383 -1
+945 16383 -1
+946 16383 -1
+947 16383 -1
+948 16383 -1
+949 16383 -1
+950 16383 -1
+951 16383 -1
+952 16383 -1
+953 16383 -1
+954 16383 -1
+955 16383 -1
+956 16383 -1
+957 16383 -1
+958 16383 -1
+959 16383 -1
+960 16383 -1
+961 16383 -1
+962 16383 -1
+963 16383 -1
+964 16383 -1
+965 16383 -1
+966 16383 -1
+967 16383 -1
+968 16383 -1
+969 16383 -1
+970 16383 -1
+971 16383 -1
+972 16383 -1
+973 16383 -1
+974 16383 -1
+975 16383 -1
+976 16383 -1
+977 16383 -1
+978 16383 -1
+979 16383 -1
+980 16383 -1
+981 16383 -1
+982 16383 -1
+983 16383 -1
+984 16383 -1
+985 16383 -1
+986 16383 -1
+987 16383 -1
+988 16383 -1
+989 16383 -1
+990 16383 -1
+991 16383 -1
+992 16383 -1
+993 16383 -1
+994 16383 -1
+995 16383 -1
+996 16383 -1
+997 16383 -1
+998 16383 -1
+999 16383 -1
+1000 16383 -1
+1001 16383 -1
+1002 16383 -1
+1003 16383 -1
+1004 16383 -1
+1005 16383 -1
+1006 16383 -1
+1007 16383 -1
+1008 16383 -1
+1009 16383 -1
+1010 16383 -1
+1011 16383 -1
+1012 16383 -1
+1013 16383 -1
+1014 16383 -1
+1015 16383 -1
+1016 16383 -1
+1017 16383 -1
+1018 16383 -1
+1019 16383 -1
+1020 16383 -1
+1021 16383 -1
+1022 16383 -1
+1023 16383 -1
+1024 16383 -1
+1025 16383 -1
+1026 16383 -1
+1027 16383 -1
+1028 16383 -1
+1029 16383 -1
+1030 16383 -1
+1031 16383 -1
+1032 16383 -1
+1033 16383 -1
+1034 16383 -1
+1035 16383 -1
+1036 16383 -1
+1037 16383 -1
+1038 16383 -1
+1039 16383 -1
+1040 16383 -1
+1041 16383 -1
+1042 16383 -1
+1043 16383 -1
+1044 16383 -1
+1045 16383 -1
+1046 16383 -1
+1047 16383 -1
+1048 16383 -1
+1049 16383 -1
+1050 16383 -1
+1051 16383 -1
+1052 16383 -1
+1053 16383 -1
+1054 16383 -1
+1055 16383 -1
+1056 16383 -1
+1057 16383 -1
+1058 16383 -1
+1059 16383 -1
+1060 16383 -1
+1061 16383 -1
+1062 16383 -1
+1063 16383 -1
+1064 16383 -1
+1065 16383 -1
+1066 16383 -1
+1067 16383 -1
+1068 16383 -1
+1069 16383 -1
+1070 16383 -1
+1071 16383 -1
+1072 16383 -1
+1073 16383 -1
+1074 16383 -1
+1075 16383 -1
+1076 16383 -1
+1077 16383 -1
+1078 16383 -1
+1079 16383 -1
+1080 16383 -1
+1081 16383 -1
+1082 16383 -1
+1083 16383 -1
+1084 16383 -1
+1085 16383 -1
+1086 16383 -1
+1087 16383 -1
+1088 16383 -1
+1089 16383 -1
+1090 16383 -1
+1091 16383 -1
+1092 16383 -1
+1093 16383 -1
+1094 16383 -1
+1095 16383 -1
diff --git a/tests/auto/corelib/io/qtextstream/test/test.pro b/tests/auto/corelib/io/qtextstream/test/test.pro
new file mode 100644
index 0000000000..e0eb4ef193
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/test/test.pro
@@ -0,0 +1,40 @@
+load(qttest_p4)
+SOURCES += ../tst_qtextstream.cpp
+
+TARGET = ../tst_qtextstream
+
+win32 {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qtextstream
+} else {
+ TARGET = ../../release/tst_qtextstream
+ }
+}
+
+RESOURCES += ../qtextstream.qrc
+
+QT = core network
+
+
+wince*|symbian: {
+ addFiles.files = ../rfc3261.txt ../shift-jis.txt ../task113817.txt ../qtextstream.qrc ../tst_qtextstream.cpp
+ addFiles.path = .
+ res.files = ../resources
+ res.path = .
+ DEPLOYMENT += addFiles
+}
+
+wince*: {
+ DEFINES += SRCDIR=\\\"\\\"
+}else:symbian {
+ # Symbian can't define SRCDIR meaningfully here
+ qt_not_deployed {
+ codecs_plugins.files = qcncodecs.dll qjpcodecs.dll qtwcodecs.dll qkrcodecs.dll
+ codecs_plugins.path = $$QT_PLUGINS_BASE_DIR/codecs
+ DEPLOYMENT += codecs_plugins
+ }
+}else {
+ DEFINES += SRCDIR=\\\"$$PWD/../\\\"
+}
+
+
diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
new file mode 100644
index 0000000000..848f813d1e
--- /dev/null
+++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
@@ -0,0 +1,2919 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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$
+**
+****************************************************************************/
+
+
+/*-*-encoding:latin1-*-*/
+//#include <iostream>
+//using namespace std;
+
+#include <QtTest/QtTest>
+
+#ifdef Q_OS_UNIX
+#include <locale.h>
+#endif
+
+#include <QBuffer>
+#include <QByteArray>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QFile>
+#include <QTcpSocket>
+#include <QTextStream>
+#include <QTextCodec>
+#include <QProcess>
+
+#include "../../../network-settings.h"
+
+static const char *TestFileName = "testfile";
+
+Q_DECLARE_METATYPE(qlonglong)
+Q_DECLARE_METATYPE(qulonglong)
+Q_DECLARE_METATYPE(QList<int>)
+
+QT_BEGIN_NAMESPACE
+template<> struct QMetaTypeId<QIODevice::OpenModeFlag>
+{ enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
+QT_END_NAMESPACE
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#ifdef Q_OS_SYMBIAN
+#define SRCDIR ""
+#endif
+
+class tst_QTextStream : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QTextStream();
+ virtual ~tst_QTextStream();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void construction();
+
+ // lines
+ void readLineFromDevice_data();
+ void readLineFromDevice();
+ void readLineFromString_data();
+ void readLineFromString();
+ void readLineFromTextDevice_data();
+ void readLineFromTextDevice();
+ void readLineUntilNull();
+ void readLineMaxlen_data();
+ void readLineMaxlen();
+ void readLinesFromBufferCRCR();
+
+ // all
+ void readAllFromDevice_data();
+ void readAllFromDevice();
+ void readAllFromString_data();
+ void readAllFromString();
+ void readLineFromStringThenChangeString();
+
+ // device tests
+ void setDevice();
+
+ // char operators
+ void QChar_operators_FromDevice_data();
+ void QChar_operators_FromDevice();
+ void char_operators_FromDevice_data();
+ void char_operators_FromDevice();
+
+ // natural number read operator
+ void signedShort_read_operator_FromDevice_data();
+ void signedShort_read_operator_FromDevice();
+ void unsignedShort_read_operator_FromDevice_data();
+ void unsignedShort_read_operator_FromDevice();
+ void signedInt_read_operator_FromDevice_data();
+ void signedInt_read_operator_FromDevice();
+ void unsignedInt_read_operator_FromDevice_data();
+ void unsignedInt_read_operator_FromDevice();
+ void qlonglong_read_operator_FromDevice_data();
+ void qlonglong_read_operator_FromDevice();
+ void qulonglong_read_operator_FromDevice_data();
+ void qulonglong_read_operator_FromDevice();
+
+ // natural number write operator
+ void signedShort_write_operator_ToDevice_data();
+ void signedShort_write_operator_ToDevice();
+ void unsignedShort_write_operator_ToDevice_data();
+ void unsignedShort_write_operator_ToDevice();
+ void signedInt_write_operator_ToDevice_data();
+ void signedInt_write_operator_ToDevice();
+ void unsignedInt_write_operator_ToDevice_data();
+ void unsignedInt_write_operator_ToDevice();
+ void qlonglong_write_operator_ToDevice_data();
+ void qlonglong_write_operator_ToDevice();
+ void qulonglong_write_operator_ToDevice_data();
+ void qulonglong_write_operator_ToDevice();
+
+ void int_read_with_locale_data();
+ void int_read_with_locale();
+
+ void int_write_with_locale_data();
+ void int_write_with_locale();
+
+ // real number read operator
+ void float_read_operator_FromDevice_data();
+ void float_read_operator_FromDevice();
+ void double_read_operator_FromDevice_data();
+ void double_read_operator_FromDevice();
+
+ // real number write operator
+ void float_write_operator_ToDevice_data();
+ void float_write_operator_ToDevice();
+ void double_write_operator_ToDevice_data();
+ void double_write_operator_ToDevice();
+
+ void double_write_with_flags_data();
+ void double_write_with_flags();
+
+ void double_write_with_precision_data();
+ void double_write_with_precision();
+
+ // text read operators
+ void charPtr_read_operator_FromDevice_data();
+ void charPtr_read_operator_FromDevice();
+ void stringRef_read_operator_FromDevice_data();
+ void stringRef_read_operator_FromDevice();
+ void byteArray_read_operator_FromDevice_data();
+ void byteArray_read_operator_FromDevice();
+
+ // text write operators
+ void string_write_operator_ToDevice_data();
+ void string_write_operator_ToDevice();
+
+ // other
+ void skipWhiteSpace_data();
+ void skipWhiteSpace();
+ void lineCount_data();
+ void lineCount();
+ void performance();
+ void hexTest_data();
+ void hexTest();
+ void binTest_data();
+ void binTest();
+ void octTest_data();
+ void octTest();
+ void zeroTermination();
+ void ws_manipulator();
+ void stillOpenWhenAtEnd();
+ void readNewlines_data();
+ void readNewlines();
+ void seek();
+ void pos();
+ void pos2();
+ void pos3LargeFile();
+ void readStdin();
+ void readAllFromStdin();
+ void readLineFromStdin();
+ void read();
+ void qbool();
+ void forcePoint();
+ void forceSign();
+ void read0d0d0a();
+ void numeralCase_data();
+ void numeralCase();
+ void nanInf();
+ void utf8IncompleteAtBufferBoundary_data();
+ void utf8IncompleteAtBufferBoundary();
+ void writeSeekWriteNoBOM();
+
+ // status
+ void status_real_read_data();
+ void status_real_read();
+ void status_integer_read();
+ void status_word_read();
+ void status_write_error();
+
+ // use case tests
+ void useCase1();
+ void useCase2();
+
+ // manipulators
+ void manipulators_data();
+ void manipulators();
+
+ // UTF-16 BOM (Byte Order Mark)
+ void generateBOM();
+ void readBomSeekBackReadBomAgain();
+
+ // task-specific tests
+ void task180679_alignAccountingStyle();
+ void task178772_setCodec();
+
+private:
+ void generateLineData(bool for_QString);
+ void generateAllData(bool for_QString);
+ void generateOperatorCharData(bool for_QString);
+ void generateNaturalNumbersData(bool for_QString);
+ void generateRealNumbersData(bool for_QString);
+ void generateStringData(bool for_QString);
+ void generateRealNumbersDataWrite();
+};
+
+// Testing get/set functions
+void tst_QTextStream::getSetCheck()
+{
+ // Initialize codecs
+ int argc = 0;
+ char **argv = 0;
+ QCoreApplication app(argc, argv);
+
+ QTextStream obj1;
+ // QTextCodec * QTextStream::codec()
+ // void QTextStream::setCodec(QTextCodec *)
+ QTextCodec *var1 = QTextCodec::codecForName("en");
+ obj1.setCodec(var1);
+ QCOMPARE(var1, obj1.codec());
+ obj1.setCodec((QTextCodec *)0);
+ QCOMPARE((QTextCodec *)0, obj1.codec());
+
+ // bool QTextStream::autoDetectUnicode()
+ // void QTextStream::setAutoDetectUnicode(bool)
+ obj1.setAutoDetectUnicode(false);
+ QCOMPARE(false, obj1.autoDetectUnicode());
+ obj1.setAutoDetectUnicode(true);
+ QCOMPARE(true, obj1.autoDetectUnicode());
+
+ // bool QTextStream::generateByteOrderMark()
+ // void QTextStream::setGenerateByteOrderMark(bool)
+ obj1.setGenerateByteOrderMark(false);
+ QCOMPARE(false, obj1.generateByteOrderMark());
+ obj1.setGenerateByteOrderMark(true);
+ QCOMPARE(true, obj1.generateByteOrderMark());
+
+ // QIODevice * QTextStream::device()
+ // void QTextStream::setDevice(QIODevice *)
+ QFile *var4 = new QFile;
+ obj1.setDevice(var4);
+ QCOMPARE(static_cast<QIODevice *>(var4), obj1.device());
+ obj1.setDevice((QIODevice *)0);
+ QCOMPARE((QIODevice *)0, obj1.device());
+ delete var4;
+
+ // Status QTextStream::status()
+ // void QTextStream::setStatus(Status)
+ obj1.setStatus(QTextStream::Status(QTextStream::Ok));
+ QCOMPARE(QTextStream::Status(QTextStream::Ok), obj1.status());
+ obj1.setStatus(QTextStream::Status(QTextStream::ReadPastEnd));
+ QCOMPARE(QTextStream::Status(QTextStream::ReadPastEnd), obj1.status());
+ obj1.resetStatus();
+ obj1.setStatus(QTextStream::Status(QTextStream::ReadCorruptData));
+ QCOMPARE(QTextStream::Status(QTextStream::ReadCorruptData), obj1.status());
+
+ // FieldAlignment QTextStream::fieldAlignment()
+ // void QTextStream::setFieldAlignment(FieldAlignment)
+ obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignLeft));
+ QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignLeft), obj1.fieldAlignment());
+ obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignRight));
+ QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignRight), obj1.fieldAlignment());
+ obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignCenter));
+ QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignCenter), obj1.fieldAlignment());
+ obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignAccountingStyle));
+ QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignAccountingStyle), obj1.fieldAlignment());
+
+ // QChar QTextStream::padChar()
+ // void QTextStream::setPadChar(QChar)
+ QChar var7 = 'Q';
+ obj1.setPadChar(var7);
+ QCOMPARE(var7, obj1.padChar());
+ obj1.setPadChar(QChar());
+ QCOMPARE(QChar(), obj1.padChar());
+
+ // int QTextStream::fieldWidth()
+ // void QTextStream::setFieldWidth(int)
+ obj1.setFieldWidth(0);
+ QCOMPARE(0, obj1.fieldWidth());
+ obj1.setFieldWidth(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.fieldWidth());
+ obj1.setFieldWidth(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.fieldWidth());
+
+ // NumberFlags QTextStream::numberFlags()
+ // void QTextStream::setNumberFlags(NumberFlags)
+ obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ShowBase));
+ QCOMPARE(QTextStream::NumberFlags(QTextStream::ShowBase), obj1.numberFlags());
+ obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ForcePoint));
+ QCOMPARE(QTextStream::NumberFlags(QTextStream::ForcePoint), obj1.numberFlags());
+ obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ForceSign));
+ QCOMPARE(QTextStream::NumberFlags(QTextStream::ForceSign), obj1.numberFlags());
+ obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::UppercaseBase));
+ QCOMPARE(QTextStream::NumberFlags(QTextStream::UppercaseBase), obj1.numberFlags());
+ obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::UppercaseDigits));
+ QCOMPARE(QTextStream::NumberFlags(QTextStream::UppercaseDigits), obj1.numberFlags());
+
+ // int QTextStream::integerBase()
+ // void QTextStream::setIntegerBase(int)
+ obj1.setIntegerBase(0);
+ QCOMPARE(0, obj1.integerBase());
+ obj1.setIntegerBase(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.integerBase());
+ obj1.setIntegerBase(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.integerBase());
+
+ // RealNumberNotation QTextStream::realNumberNotation()
+ // void QTextStream::setRealNumberNotation(RealNumberNotation)
+ obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::SmartNotation));
+ QCOMPARE(QTextStream::RealNumberNotation(QTextStream::SmartNotation), obj1.realNumberNotation());
+ obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::FixedNotation));
+ QCOMPARE(QTextStream::RealNumberNotation(QTextStream::FixedNotation), obj1.realNumberNotation());
+ obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::ScientificNotation));
+ QCOMPARE(QTextStream::RealNumberNotation(QTextStream::ScientificNotation), obj1.realNumberNotation());
+
+ // int QTextStream::realNumberPrecision()
+ // void QTextStream::setRealNumberPrecision(int)
+ obj1.setRealNumberPrecision(0);
+ QCOMPARE(0, obj1.realNumberPrecision());
+ obj1.setRealNumberPrecision(INT_MIN);
+ QCOMPARE(6, obj1.realNumberPrecision()); // Setting a negative precision reverts it to the default value (6).
+ obj1.setRealNumberPrecision(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.realNumberPrecision());
+}
+
+tst_QTextStream::tst_QTextStream()
+{
+ Q_SET_DEFAULT_IAP
+}
+
+tst_QTextStream::~tst_QTextStream()
+{
+}
+
+void tst_QTextStream::init()
+{
+}
+
+void tst_QTextStream::cleanup()
+{
+ QCoreApplication::instance()->processEvents();
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::construction()
+{
+ QTextStream stream;
+ QCOMPARE(stream.codec(), QTextCodec::codecForLocale());
+ QCOMPARE(stream.device(), static_cast<QIODevice *>(0));
+ QCOMPARE(stream.string(), static_cast<QString *>(0));
+
+ QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
+ QVERIFY(stream.atEnd());
+
+ QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
+ QCOMPARE(stream.readAll(), QString());
+
+}
+
+void tst_QTextStream::generateLineData(bool for_QString)
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QStringList>("lines");
+
+ // latin-1
+ QTest::newRow("emptyer") << QByteArray() << QStringList();
+ QTest::newRow("lf") << QByteArray("\n") << (QStringList() << "");
+ QTest::newRow("crlf") << QByteArray("\r\n") << (QStringList() << "");
+ QTest::newRow("oneline/nothing") << QByteArray("ole") << (QStringList() << "ole");
+ QTest::newRow("oneline/lf") << QByteArray("ole\n") << (QStringList() << "ole");
+ QTest::newRow("oneline/crlf") << QByteArray("ole\r\n") << (QStringList() << "ole");
+ QTest::newRow("twolines/lf/lf") << QByteArray("ole\ndole\n") << (QStringList() << "ole" << "dole");
+ QTest::newRow("twolines/crlf/crlf") << QByteArray("ole\r\ndole\r\n") << (QStringList() << "ole" << "dole");
+ QTest::newRow("twolines/lf/crlf") << QByteArray("ole\ndole\r\n") << (QStringList() << "ole" << "dole");
+ QTest::newRow("twolines/lf/nothing") << QByteArray("ole\ndole") << (QStringList() << "ole" << "dole");
+ QTest::newRow("twolines/crlf/nothing") << QByteArray("ole\r\ndole") << (QStringList() << "ole" << "dole");
+ QTest::newRow("threelines/lf/lf/lf") << QByteArray("ole\ndole\ndoffen\n") << (QStringList() << "ole" << "dole" << "doffen");
+ QTest::newRow("threelines/crlf/crlf/crlf") << QByteArray("ole\r\ndole\r\ndoffen\r\n") << (QStringList() << "ole" << "dole" << "doffen");
+ QTest::newRow("threelines/crlf/crlf/nothing") << QByteArray("ole\r\ndole\r\ndoffen") << (QStringList() << "ole" << "dole" << "doffen");
+
+ if (!for_QString) {
+ // utf-8
+ QTest::newRow("utf8/twolines")
+ << QByteArray("\xef\xbb\xbf"
+ "\x66\x67\x65\x0a"
+ "\x66\x67\x65\x0a", 11)
+ << (QStringList() << "fge" << "fge");
+
+ // utf-16
+ // one line
+ QTest::newRow("utf16-BE/nothing")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65", 8) << (QStringList() << "\345ge");
+ QTest::newRow("utf16-LE/nothing")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00", 8) << (QStringList() << "\345ge");
+ QTest::newRow("utf16-BE/lf")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a", 10) << (QStringList() << "\345ge");
+ QTest::newRow("utf16-LE/lf")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00", 10) << (QStringList() << "\345ge");
+
+ // two lines
+ QTest::newRow("utf16-BE/twolines")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a", 18)
+ << (QStringList() << "\345ge" << "\345ge");
+ QTest::newRow("utf16-LE/twolines")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00", 18)
+ << (QStringList() << "\345ge" << "\345ge");
+
+ // three lines
+ QTest::newRow("utf16-BE/threelines")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a", 26)
+ << (QStringList() << "\345ge" << "\345ge" << "\345ge");
+ QTest::newRow("utf16-LE/threelines")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00", 26)
+ << (QStringList() << "\345ge" << "\345ge" << "\345ge");
+
+ // utf-32
+ QTest::newRow("utf32-BE/twolines")
+ << QByteArray("\x00\x00\xfe\xff"
+ "\x00\x00\x00\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a"
+ "\x00\x00\x00\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a", 36)
+ << (QStringList() << "\345ge" << "\345ge");
+ QTest::newRow("utf32-LE/twolines")
+ << QByteArray("\xff\xfe\x00\x00"
+ "\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a\x00\x00\x00"
+ "\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a\x00\x00\x00", 36)
+ << (QStringList() << "\345ge" << "\345ge");
+ }
+
+ // partials
+ QTest::newRow("cr") << QByteArray("\r") << (QStringList() << "");
+ QTest::newRow("oneline/cr") << QByteArray("ole\r") << (QStringList() << "ole");
+ if (!for_QString)
+ QTest::newRow("utf16-BE/cr") << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65\x00\x0d", 10) << (QStringList() << "\345ge");
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromDevice_data()
+{
+ generateLineData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromDevice()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QStringList, lines);
+
+ QFile::remove(TestFileName);
+ QFile file(TestFileName);
+ QVERIFY(file.open(QFile::ReadWrite));
+ QCOMPARE(file.write(data), qlonglong(data.size()));
+ QVERIFY(file.flush());
+ file.seek(0);
+
+ QTextStream stream(&file);
+ QStringList list;
+ while (!stream.atEnd())
+ list << stream.readLine();
+
+ QCOMPARE(list, lines);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineMaxlen_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QStringList>("lines");
+
+ QTest::newRow("Hey")
+ << QString("Hey")
+ << (QStringList() << QString("Hey") << QString(""));
+ QTest::newRow("Hey\\n")
+ << QString("Hey\n")
+ << (QStringList() << QString("Hey") << QString(""));
+ QTest::newRow("HelloWorld")
+ << QString("HelloWorld")
+ << (QStringList() << QString("Hello") << QString("World"));
+ QTest::newRow("Helo\\nWorlds")
+ << QString("Helo\nWorlds")
+ << (QStringList() << QString("Helo") << QString("World"));
+ QTest::newRow("AAAAA etc.")
+ << QString(16385, QLatin1Char('A'))
+ << (QStringList() << QString("AAAAA") << QString("AAAAA"));
+ QTest::newRow("multibyte string")
+ << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242\341\233\232\341\232\240\n")
+ << (QStringList() << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242")
+ << QString::fromUtf8("\341\233\232\341\232\240"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineMaxlen()
+{
+ QFETCH(QString, input);
+ QFETCH(QStringList, lines);
+ for (int i = 0; i < 2; ++i) {
+ bool useDevice = (i == 1);
+ QTextStream stream;
+ QFile::remove("testfile");
+ QFile file("testfile");
+ if (useDevice) {
+ file.open(QIODevice::ReadWrite);
+ file.write(input.toUtf8());
+ file.seek(0);
+ stream.setDevice(&file);
+ stream.setCodec("utf-8");
+ } else {
+ stream.setString(&input);
+ }
+
+ QStringList list;
+ list << stream.readLine(5);
+ list << stream.readLine(5);
+
+ QCOMPARE(list, lines);
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLinesFromBufferCRCR()
+{
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QByteArray data("0123456789\r\r\n");
+
+ for (int i = 0; i < 10000; ++i)
+ buffer.write(data);
+
+ buffer.close();
+ if (buffer.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ QTextStream stream(&buffer);
+ while (!stream.atEnd())
+ QCOMPARE(stream.readLine(), QString("0123456789"));
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromString_data()
+{
+ generateLineData(true);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromString()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QStringList, lines);
+
+ QString dataString = data;
+
+ QTextStream stream(&dataString, QIODevice::ReadOnly);
+ QStringList list;
+ while (!stream.atEnd())
+ list << stream.readLine();
+
+ QCOMPARE(list, lines);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromStringThenChangeString()
+{
+ QString first = "First string";
+ QString second = "Second string";
+
+ QTextStream stream(&first, QIODevice::ReadOnly);
+ QString result = stream.readLine();
+ QCOMPARE(first, result);
+
+ stream.setString(&second, QIODevice::ReadOnly);
+ result = stream.readLine();
+ QCOMPARE(second, result);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::setDevice()
+{
+ // Check that the read buffer is reset after setting a new device
+ QByteArray data1("Hello World");
+ QByteArray data2("How are you");
+
+ QBuffer bufferOld(&data1);
+ bufferOld.open(QIODevice::ReadOnly);
+
+ QBuffer bufferNew(&data2);
+ bufferNew.open(QIODevice::ReadOnly);
+
+ QString text;
+ QTextStream stream(&bufferOld);
+ stream >> text;
+ QCOMPARE(text, QString("Hello"));
+
+ stream.setDevice(&bufferNew);
+ stream >> text;
+ QCOMPARE(text, QString("How"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromTextDevice_data()
+{
+ generateLineData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromTextDevice()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QStringList, lines);
+
+ for (int i = 0; i < 8; ++i) {
+ QBuffer buffer(&data);
+ if (i < 4)
+ QVERIFY(buffer.open(QIODevice::ReadOnly | QIODevice::Text));
+ else
+ QVERIFY(buffer.open(QIODevice::ReadOnly));
+
+ QTextStream stream(&buffer);
+ QStringList list;
+ while (!stream.atEnd()) {
+ stream.pos(); // <- triggers side effects
+ QString line;
+
+ if (i & 1) {
+ QChar c;
+ while (!stream.atEnd()) {
+ stream >> c;
+ if (stream.status() == QTextStream::Ok) {
+ if (c != QLatin1Char('\n') && c != QLatin1Char('\r'))
+ line += c;
+ if (c == QLatin1Char('\n'))
+ break;
+ }
+ }
+ } else {
+ line = stream.readLine();
+ }
+
+ if ((i & 3) == 3 && !QString(QTest::currentDataTag()).contains("utf16"))
+ stream.seek(stream.pos());
+ list << line;
+ }
+ QCOMPARE(list, lines);
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::generateAllData(bool for_QString)
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QString>("output");
+
+ // latin-1
+ QTest::newRow("empty") << QByteArray() << QString();
+ QTest::newRow("latin1-a") << QByteArray("a") << QString("a");
+ QTest::newRow("latin1-a\\r") << QByteArray("a\r") << QString("a\r");
+ QTest::newRow("latin1-a\\r\\n") << QByteArray("a\r\n") << QString("a\r\n");
+ QTest::newRow("latin1-a\\n") << QByteArray("a\n") << QString("a\n");
+
+ // utf-16
+ if (!for_QString) {
+ // one line
+ QTest::newRow("utf16-BE/nothing")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65", 8) << QString("\345ge");
+ QTest::newRow("utf16-LE/nothing")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00", 8) << QString("\345ge");
+ QTest::newRow("utf16-BE/lf")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a", 10) << QString("\345ge\n");
+ QTest::newRow("utf16-LE/lf")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00", 10) << QString("\345ge\n");
+ QTest::newRow("utf16-BE/crlf")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0d\x00\x0a", 12) << QString("\345ge\r\n");
+ QTest::newRow("utf16-LE/crlf")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0d\x00\x0a\x00", 12) << QString("\345ge\r\n");
+
+ // two lines
+ QTest::newRow("utf16-BE/twolines")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a", 18)
+ << QString("\345ge\n\345ge\n");
+ QTest::newRow("utf16-LE/twolines")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00", 18)
+ << QString("\345ge\n\345ge\n");
+
+ // three lines
+ QTest::newRow("utf16-BE/threelines")
+ << QByteArray("\xfe\xff"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a"
+ "\x00\xe5\x00\x67\x00\x65\x00\x0a", 26)
+ << QString("\345ge\n\345ge\n\345ge\n");
+ QTest::newRow("utf16-LE/threelines")
+ << QByteArray("\xff\xfe"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00"
+ "\xe5\x00\x67\x00\x65\x00\x0a\x00", 26)
+ << QString("\345ge\n\345ge\n\345ge\n");
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineUntilNull()
+{
+ QFile file(SRCDIR "rfc3261.txt");
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ QTextStream stream(&file);
+ for (int i = 0; i < 15066; ++i) {
+ QString line = stream.readLine();
+ QVERIFY(!line.isNull());
+ QVERIFY(!line.isNull());
+ }
+ QVERIFY(!stream.readLine().isNull());
+ QVERIFY(stream.readLine().isNull());
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readAllFromDevice_data()
+{
+ generateAllData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readAllFromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QString, output);
+
+ QBuffer buffer(&input);
+ buffer.open(QBuffer::ReadOnly);
+
+ QTextStream stream(&buffer);
+ QCOMPARE(stream.readAll(), output);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readAllFromString_data()
+{
+ generateAllData(true);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readAllFromString()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QString, output);
+
+ QString str = input;
+
+ QTextStream stream(&str);
+ QCOMPARE(stream.readAll(), output);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::skipWhiteSpace_data()
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QChar>("output");
+
+ // latin1
+ QTest::newRow("empty") << QByteArray() << QChar('\0');
+ QTest::newRow(" one") << QByteArray(" one") << QChar('o');
+ QTest::newRow("\\none") << QByteArray("\none") << QChar('o');
+ QTest::newRow("\\n one") << QByteArray("\n one") << QChar('o');
+ QTest::newRow(" \\r\\n one") << QByteArray(" \r\n one") << QChar('o');
+
+ // utf-16
+ QTest::newRow("utf16-BE (empty)") << QByteArray("\xfe\xff", 2) << QChar('\0');
+ QTest::newRow("utf16-BE ( one)") << QByteArray("\xfe\xff\x00 \x00o\x00n\x00e", 10) << QChar('o');
+ QTest::newRow("utf16-BE (\\none)") << QByteArray("\xfe\xff\x00\n\x00o\x00n\x00e", 10) << QChar('o');
+ QTest::newRow("utf16-BE (\\n one)") << QByteArray("\xfe\xff\x00\n\x00 \x00o\x00n\x00e", 12) << QChar('o');
+ QTest::newRow("utf16-BE ( \\r\\n one)") << QByteArray("\xfe\xff\x00 \x00\r\x00\n\x00 \x00o\x00n\x00e", 20) << QChar('o');
+
+ QTest::newRow("utf16-LE (empty)") << QByteArray("\xff\xfe", 2) << QChar('\0');
+ QTest::newRow("utf16-LE ( one)") << QByteArray("\xff\xfe \x00o\x00n\x00e\x00", 10) << QChar('o');
+ QTest::newRow("utf16-LE (\\none)") << QByteArray("\xff\xfe\n\x00o\x00n\x00e\x00", 10) << QChar('o');
+ QTest::newRow("utf16-LE (\\n one)") << QByteArray("\xff\xfe\n\x00 \x00o\x00n\x00e\x00", 12) << QChar('o');
+ QTest::newRow("utf16-LE ( \\r\\n one)") << QByteArray("\xff\xfe \x00\r\x00\n\x00 \x00o\x00n\x00e\x00", 20) << QChar('o');
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::skipWhiteSpace()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QChar, output);
+
+ QBuffer buffer(&input);
+ buffer.open(QBuffer::ReadOnly);
+
+ QTextStream stream(&buffer);
+ stream.skipWhiteSpace();
+
+ QChar tmp;
+ stream >> tmp;
+
+ QCOMPARE(tmp, output);
+
+ QString str = input;
+ QTextStream stream2(&input);
+ stream2.skipWhiteSpace();
+
+ stream2 >> tmp;
+
+ QCOMPARE(tmp, output);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::lineCount_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("lineCount");
+
+ QTest::newRow("empty") << QByteArray() << 0;
+ QTest::newRow("oneline") << QByteArray("a\n") << 1;
+ QTest::newRow("twolines") << QByteArray("a\nb\n") << 2;
+ QTest::newRow("oneemptyline") << QByteArray("\n") << 1;
+ QTest::newRow("twoemptylines") << QByteArray("\n\n") << 2;
+ QTest::newRow("buffersize-1 line") << QByteArray(16382, '\n') << 16382;
+ QTest::newRow("buffersize line") << QByteArray(16383, '\n') << 16383;
+ QTest::newRow("buffersize+1 line") << QByteArray(16384, '\n') << 16384;
+ QTest::newRow("buffersize+2 line") << QByteArray(16385, '\n') << 16385;
+
+ QFile file(SRCDIR "rfc3261.txt"); file.open(QFile::ReadOnly);
+ QTest::newRow("rfc3261") << file.readAll() << 15067;
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::lineCount()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, lineCount);
+
+ QFile out("out.txt");
+ out.open(QFile::WriteOnly);
+
+ QTextStream lineReader(data);
+ int lines = 0;
+ while (!lineReader.atEnd()) {
+ QString line = lineReader.readLine();
+ out.write(line.toLatin1() + "\n");
+ ++lines;
+ }
+
+ out.close();
+ QCOMPARE(lines, lineCount);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::performance()
+{
+ // Phase #1 - test speed of reading a huge text file with QFile.
+ QTime stopWatch;
+
+ int elapsed1 = 0;
+ int elapsed2 = 0;
+
+ stopWatch.restart();
+ int nlines1 = 0;
+ QFile file(SRCDIR "rfc3261.txt");
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ while (!file.atEnd()) {
+ ++nlines1;
+ file.readLine();
+ }
+
+ elapsed1 += stopWatch.elapsed();
+ stopWatch.restart();
+
+ int nlines2 = 0;
+ QFile file2(SRCDIR "rfc3261.txt");
+ QVERIFY(file2.open(QFile::ReadOnly));
+
+ QTextStream stream(&file2);
+ while (!stream.atEnd()) {
+ ++nlines2;
+ stream.readLine();
+ }
+
+ elapsed2 += stopWatch.elapsed();
+ QCOMPARE(nlines1, nlines2);
+
+ qDebug("QFile used %.2f seconds to read the file",
+ elapsed1 / 1000.0);
+
+ qDebug("QTextStream used %.2f seconds to read the file",
+ elapsed2 / 1000.0);
+ if (elapsed2 > elapsed1) {
+ qDebug("QFile is %.2fx faster than QTextStream",
+ double(elapsed2) / double(elapsed1));
+ } else {
+ qDebug("QTextStream is %.2fx faster than QFile",
+ double(elapsed1) / double(elapsed2));
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::hexTest_data()
+{
+ QTest::addColumn<qlonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_INT64_C(0) << QByteArray("0x0");
+ QTest::newRow("1") << Q_INT64_C(1) << QByteArray("0x1");
+ QTest::newRow("2") << Q_INT64_C(2) << QByteArray("0x2");
+ QTest::newRow("3") << Q_INT64_C(3) << QByteArray("0x3");
+ QTest::newRow("4") << Q_INT64_C(4) << QByteArray("0x4");
+ QTest::newRow("5") << Q_INT64_C(5) << QByteArray("0x5");
+ QTest::newRow("6") << Q_INT64_C(6) << QByteArray("0x6");
+ QTest::newRow("7") << Q_INT64_C(7) << QByteArray("0x7");
+ QTest::newRow("8") << Q_INT64_C(8) << QByteArray("0x8");
+ QTest::newRow("9") << Q_INT64_C(9) << QByteArray("0x9");
+ QTest::newRow("a") << Q_INT64_C(0xa) << QByteArray("0xa");
+ QTest::newRow("b") << Q_INT64_C(0xb) << QByteArray("0xb");
+ QTest::newRow("c") << Q_INT64_C(0xc) << QByteArray("0xc");
+ QTest::newRow("d") << Q_INT64_C(0xd) << QByteArray("0xd");
+ QTest::newRow("e") << Q_INT64_C(0xe) << QByteArray("0xe");
+ QTest::newRow("f") << Q_INT64_C(0xf) << QByteArray("0xf");
+ QTest::newRow("-1") << Q_INT64_C(-1) << QByteArray("-0x1");
+ QTest::newRow("0xffffffff") << Q_INT64_C(0xffffffff) << QByteArray("0xffffffff");
+ QTest::newRow("0xfffffffffffffffe") << Q_INT64_C(0xfffffffffffffffe) << QByteArray("-0x2");
+ QTest::newRow("0xffffffffffffffff") << Q_INT64_C(0xffffffffffffffff) << QByteArray("-0x1");
+ QTest::newRow("0x7fffffffffffffff") << Q_INT64_C(0x7fffffffffffffff) << QByteArray("0x7fffffffffffffff");
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::hexTest()
+{
+ QFETCH(qlonglong, number);
+ QFETCH(QByteArray, data);
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << showbase << hex << number;
+ stream.flush();
+ QCOMPARE(array, data);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::binTest_data()
+{
+ QTest::addColumn<int>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << 0 << QByteArray("0b0");
+ QTest::newRow("1") << 1 << QByteArray("0b1");
+ QTest::newRow("2") << 2 << QByteArray("0b10");
+ QTest::newRow("5") << 5 << QByteArray("0b101");
+ QTest::newRow("-1") << -1 << QByteArray("-0b1");
+ QTest::newRow("11111111") << 0xff << QByteArray("0b11111111");
+ QTest::newRow("1111111111111111") << 0xffff << QByteArray("0b1111111111111111");
+ QTest::newRow("1111111011111110") << 0xfefe << QByteArray("0b1111111011111110");
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::binTest()
+{
+ QFETCH(int, number);
+ QFETCH(QByteArray, data);
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << showbase << bin << number;
+ stream.flush();
+ QCOMPARE(array.constData(), data.constData());
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::octTest_data()
+{
+ QTest::addColumn<int>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << 0 << QByteArray("00");
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::octTest()
+{
+ QFETCH(int, number);
+ QFETCH(QByteArray, data);
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << showbase << oct << number;
+ stream.flush();
+ QCOMPARE(array, data);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::zeroTermination()
+{
+ QTextStream stream;
+ char c = '@';
+
+ QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
+ stream >> c;
+ QCOMPARE(c, '\0');
+
+ c = '@';
+
+ QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
+ stream >> &c;
+ QCOMPARE(c, '\0');
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::ws_manipulator()
+{
+ {
+ QString string = "a b c d";
+ QTextStream stream(&string);
+
+ char a, b, c, d;
+ stream >> a >> b >> c >> d;
+ QCOMPARE(a, 'a');
+ QCOMPARE(b, ' ');
+ QCOMPARE(c, 'b');
+ QCOMPARE(d, ' ');
+ }
+ {
+ QString string = "a b c d";
+ QTextStream stream(&string);
+
+ char a, b, c, d;
+ stream >> a >> ws >> b >> ws >> c >> ws >> d;
+ QCOMPARE(a, 'a');
+ QCOMPARE(b, 'b');
+ QCOMPARE(c, 'c');
+ QCOMPARE(d, 'd');
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::stillOpenWhenAtEnd()
+{
+ int argc = 0;
+ char **argv = 0;
+ QCoreApplication app(argc, argv);
+
+ QFile file(SRCDIR "tst_qtextstream.cpp");
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ QTextStream stream(&file);
+ while (!stream.readLine().isNull()) {}
+ QVERIFY(file.isOpen());
+
+#ifdef Q_OS_WINCE
+ QSKIP("Qt/CE: Cannot test network on emulator", SkipAll);
+#endif
+ QTcpSocket socket;
+ socket.connectToHost(QtNetworkSettings::serverName(), 143);
+#if defined(Q_OS_SYMBIAN)
+ // This number is determined in an arbitrary way; whatever it takes
+ // to make the test pass.
+ QVERIFY(socket.waitForReadyRead(30000));
+#else
+ QVERIFY(socket.waitForReadyRead(5000));
+#endif
+
+ QTextStream stream2(&socket);
+ while (!stream2.readLine().isNull()) {}
+ QVERIFY(socket.isOpen());
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readNewlines_data()
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QString>("output");
+
+ QTest::newRow("empty") << QByteArray() << QString();
+ QTest::newRow("\\r\\n") << QByteArray("\r\n") << QString("\n");
+ QTest::newRow("\\r\\r\\n") << QByteArray("\r\r\n") << QString("\n");
+ QTest::newRow("\\r\\n\\r\\n") << QByteArray("\r\n\r\n") << QString("\n\n");
+ QTest::newRow("\\n") << QByteArray("\n") << QString("\n");
+ QTest::newRow("\\n\\n") << QByteArray("\n\n") << QString("\n\n");
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readNewlines()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QString, output);
+
+ QBuffer buffer(&input);
+ buffer.open(QBuffer::ReadOnly | QBuffer::Text);
+ QTextStream stream(&buffer);
+ QCOMPARE(stream.readAll(), output);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::seek()
+{
+ QFile file(SRCDIR "rfc3261.txt");
+ QVERIFY(file.open(QFile::ReadOnly));
+
+ QTextStream stream(&file);
+ QString tmp;
+ stream >> tmp;
+ QCOMPARE(tmp, QString::fromLatin1("Network"));
+
+ // QTextStream::seek(0) should both clear its internal read/write buffers
+ // and seek the device.
+ for (int i = 0; i < 4; ++i) {
+ stream.seek(12 + i);
+ stream >> tmp;
+ QCOMPARE(tmp, QString("Network").mid(i));
+ }
+ for (int i = 0; i < 4; ++i) {
+ stream.seek(16 - i);
+ stream >> tmp;
+ QCOMPARE(tmp, QString("Network").mid(4 - i));
+ }
+ stream.seek(139181);
+ stream >> tmp;
+ QCOMPARE(tmp, QString("information"));
+ stream.seek(388683);
+ stream >> tmp;
+ QCOMPARE(tmp, QString("telephone"));
+
+ // Also test this with a string
+ QString words = QLatin1String("thisisa");
+ QTextStream stream2(&words, QIODevice::ReadOnly);
+ stream2 >> tmp;
+ QCOMPARE(tmp, QString::fromLatin1("thisisa"));
+
+ for (int i = 0; i < 4; ++i) {
+ stream2.seek(i);
+ stream2 >> tmp;
+ QCOMPARE(tmp, QString("thisisa").mid(i));
+ }
+ for (int i = 0; i < 4; ++i) {
+ stream2.seek(4 - i);
+ stream2 >> tmp;
+ QCOMPARE(tmp, QString("thisisa").mid(4 - i));
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::pos()
+{
+ int argc = 1;
+ QCoreApplication app(argc, 0);
+ {
+ // Strings
+ QString str("this is a test");
+ QTextStream stream(&str, QIODevice::ReadWrite);
+
+ QCOMPARE(stream.pos(), qint64(0));
+ for (int i = 0; i <= str.size(); ++i) {
+ QVERIFY(stream.seek(i));
+ QCOMPARE(stream.pos(), qint64(i));
+ }
+ for (int j = str.size(); j >= 0; --j) {
+ QVERIFY(stream.seek(j));
+ QCOMPARE(stream.pos(), qint64(j));
+ }
+
+ QVERIFY(stream.seek(0));
+
+ QChar ch;
+ stream >> ch;
+ QCOMPARE(ch, QChar('t'));
+
+ QCOMPARE(stream.pos(), qint64(1));
+ QVERIFY(stream.seek(1));
+ QCOMPARE(stream.pos(), qint64(1));
+ QVERIFY(stream.seek(0));
+
+ QString strtmp;
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString("this"));
+
+ QCOMPARE(stream.pos(), qint64(4));
+ stream.seek(0);
+ stream.seek(4);
+
+ stream >> ch;
+ QCOMPARE(ch, QChar(' '));
+ QCOMPARE(stream.pos(), qint64(5));
+
+ stream.seek(10);
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString("test"));
+ QCOMPARE(stream.pos(), qint64(14));
+ }
+ {
+ // Latin1 device
+ QFile file(SRCDIR "rfc3261.txt");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+
+ QTextStream stream(&file);
+
+ QCOMPARE(stream.pos(), qint64(0));
+
+ for (int i = 0; i <= file.size(); i += 7) {
+ QVERIFY(stream.seek(i));
+ QCOMPARE(stream.pos(), qint64(i));
+ }
+ for (int j = file.size(); j >= 0; j -= 7) {
+ QVERIFY(stream.seek(j));
+ QCOMPARE(stream.pos(), qint64(j));
+ }
+
+ stream.seek(0);
+
+ QString strtmp;
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString("Network"));
+ QCOMPARE(stream.pos(), qint64(19));
+
+ stream.seek(2598);
+ QCOMPARE(stream.pos(), qint64(2598));
+ stream >> strtmp;
+ QCOMPARE(stream.pos(), qint64(2607));
+ QCOMPARE(strtmp, QString("locations"));
+ }
+ {
+ // Shift-JIS device
+ for (int i = 0; i < 2; ++i) {
+ QFile file(SRCDIR "shift-jis.txt");
+ if (i == 0)
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ else
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+
+ QTextStream stream(&file);
+ stream.setCodec("Shift-JIS");
+ QVERIFY(stream.codec());
+
+ QCOMPARE(stream.pos(), qint64(0));
+ for (int i = 0; i <= file.size(); i += 7) {
+ QVERIFY(stream.seek(i));
+ QCOMPARE(stream.pos(), qint64(i));
+ }
+ for (int j = file.size(); j >= 0; j -= 7) {
+ QVERIFY(stream.seek(j));
+ QCOMPARE(stream.pos(), qint64(j));
+ }
+
+ stream.seek(2089);
+ QString strtmp;
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString("AUnicode"));
+ QCOMPARE(stream.pos(), qint64(2097));
+
+ stream.seek(43325);
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString("Shift-JIS"));
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString::fromUtf8("\343\201\247\346\233\270\343\201\213\343\202\214\343\201\237"));
+ QCOMPARE(stream.pos(), qint64(43345));
+ stream >> strtmp;
+ QCOMPARE(strtmp, QString("POD"));
+ QCOMPARE(stream.pos(), qint64(43349));
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::pos2()
+{
+ QByteArray data("abcdef\r\nghijkl\r\n");
+ QBuffer buffer(&data);
+ QVERIFY(buffer.open(QIODevice::ReadOnly | QIODevice::Text));
+
+ QTextStream stream(&buffer);
+
+ QChar ch;
+
+ QCOMPARE(stream.pos(), qint64(0));
+ stream >> ch;
+ QCOMPARE(ch, QChar('a'));
+ QCOMPARE(stream.pos(), qint64(1));
+
+ QString str;
+ stream >> str;
+ QCOMPARE(str, QString("bcdef"));
+ QCOMPARE(stream.pos(), qint64(6));
+
+ stream >> str;
+ QCOMPARE(str, QString("ghijkl"));
+ QCOMPARE(stream.pos(), qint64(14));
+
+ // Seek back and try again
+ stream.seek(1);
+ QCOMPARE(stream.pos(), qint64(1));
+ stream >> str;
+ QCOMPARE(str, QString("bcdef"));
+ QCOMPARE(stream.pos(), qint64(6));
+
+ stream.seek(6);
+ stream >> str;
+ QCOMPARE(str, QString("ghijkl"));
+ QCOMPARE(stream.pos(), qint64(14));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::pos3LargeFile()
+{
+ {
+ QFile file(TestFileName);
+ file.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out( &file );
+ // NOTE: The unusual spacing is to ensure non-1-character whitespace.
+ QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n";
+ // Approximate 50kb text file
+ const int NbLines = (50*1024) / lineString.length() + 1;
+ for (int line = 0; line < NbLines; ++line)
+ out << lineString;
+ // File is automatically flushed and closed on destruction.
+ }
+ QFile file(TestFileName);
+ file.open(QIODevice::ReadOnly | QIODevice::Text);
+ QTextStream in( &file );
+ const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ int value;
+ while (true) {
+ in.pos();
+ for ( int i = 0; i < 10; ++i ) {
+ in >> value;
+ if (in.status() != QTextStream::Ok) {
+ // End case, i == 0 && eof reached.
+ QCOMPARE(i, 0);
+ QCOMPARE(in.status(), QTextStream::ReadPastEnd);
+ return;
+ }
+ QCOMPARE(value, testValues[i]);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readStdin()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("Qt/CE and Symbian have no stdin/out support for processes", SkipAll);
+#endif
+ QProcess stdinProcess;
+ stdinProcess.start("stdinProcess/stdinProcess");
+ stdinProcess.setReadChannel(QProcess::StandardError);
+
+ QTextStream stream(&stdinProcess);
+ stream << "1" << endl;
+ stream << "2" << endl;
+ stream << "3" << endl;
+
+ stdinProcess.closeWriteChannel();
+
+ QVERIFY(stdinProcess.waitForFinished(5000));
+
+ int a, b, c;
+ stream >> a >> b >> c;
+ QCOMPARE(a, 1);
+ QCOMPARE(b, 2);
+ QCOMPARE(c, 3);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readAllFromStdin()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("Qt/CE and Symbian have no stdin/out support for processes", SkipAll);
+#endif
+ QProcess stdinProcess;
+ stdinProcess.start("readAllStdinProcess/readAllStdinProcess", QIODevice::ReadWrite | QIODevice::Text);
+ stdinProcess.setReadChannel(QProcess::StandardError);
+
+ QTextStream stream(&stdinProcess);
+ stream.setCodec("ISO-8859-1");
+ stream << "hello world" << flush;
+
+ stdinProcess.closeWriteChannel();
+
+ QVERIFY(stdinProcess.waitForFinished(5000));
+ QChar quoteChar('"');
+ QCOMPARE(stream.readAll(), QString::fromLatin1("%1hello world%2 \n").arg(quoteChar).arg(quoteChar));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::readLineFromStdin()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+ QSKIP("Qt/CE and Symbian have no stdin/out support for processes", SkipAll);
+#endif
+ QProcess stdinProcess;
+ stdinProcess.start("readLineStdinProcess/readLineStdinProcess", QIODevice::ReadWrite | QIODevice::Text);
+ stdinProcess.setReadChannel(QProcess::StandardError);
+
+ stdinProcess.write("abc\n");
+ QVERIFY(stdinProcess.waitForReadyRead(5000));
+ QCOMPARE(stdinProcess.readAll().data(), QByteArray("abc").data());
+
+ stdinProcess.write("def\n");
+ QVERIFY(stdinProcess.waitForReadyRead(5000));
+ QCOMPARE(stdinProcess.readAll(), QByteArray("def"));
+
+ stdinProcess.closeWriteChannel();
+
+ QVERIFY(stdinProcess.waitForFinished(5000));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::read()
+{
+ {
+ QFile::remove("testfile");
+ QFile file("testfile");
+ file.open(QFile::WriteOnly);
+ file.write("4.15 abc ole");
+ file.close();
+
+ QVERIFY(file.open(QFile::ReadOnly));
+ QTextStream stream(&file);
+ QCOMPARE(stream.read(0), QString(""));
+ QCOMPARE(stream.read(4), QString("4.15"));
+ QCOMPARE(stream.read(4), QString(" abc"));
+ stream.seek(1);
+ QCOMPARE(stream.read(4), QString(".15 "));
+ stream.seek(1);
+ QCOMPARE(stream.read(4), QString(".15 "));
+ stream.seek(2);
+ QCOMPARE(stream.read(4), QString("15 a"));
+ // ### add tests for reading \r\n etc..
+ }
+
+ {
+ // File larger than QTEXTSTREAM_BUFFERSIZE
+ QFile::remove("testfile");
+ QFile file("testfile");
+ file.open(QFile::WriteOnly);
+ for (int i = 0; i < 16384 / 8; ++i)
+ file.write("01234567");
+ file.write("0");
+ file.close();
+
+ QVERIFY(file.open(QFile::ReadOnly));
+ QTextStream stream(&file);
+ QCOMPARE(stream.read(10), QString("0123456701"));
+ QCOMPARE(stream.read(10), QString("2345670123"));
+ QCOMPARE(stream.readAll().size(), 16385-20);
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::qbool()
+{
+ QString s;
+ QTextStream stream(&s);
+ stream << s.contains(QString("hei"));
+ QCOMPARE(s, QString("0"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::forcePoint()
+{
+ QString str;
+ QTextStream stream(&str);
+ stream << fixed << forcepoint << 1.0 << " " << 1 << " " << 0 << " " << -1.0 << " " << -1;
+ QCOMPARE(str, QString("1.000000 1 0 -1.000000 -1"));
+
+ str.clear();
+ stream.seek(0);
+ stream << scientific << forcepoint << 1.0 << " " << 1 << " " << 0 << " " << -1.0 << " " << -1;
+ QCOMPARE(str, QString("1.000000e+00 1 0 -1.000000e+00 -1"));
+
+ str.clear();
+ stream.seek(0);
+ stream.setRealNumberNotation(QTextStream::SmartNotation);
+ stream << forcepoint << 1.0 << " " << 1 << " " << 0 << " " << -1.0 << " " << -1;
+ QCOMPARE(str, QString("1.00000 1 0 -1.00000 -1"));
+
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::forceSign()
+{
+ QString str;
+ QTextStream stream(&str);
+ stream << forcesign << 1.2 << " " << -1.2 << " " << 0;
+ QCOMPARE(str, QString("+1.2 -1.2 +0"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::read0d0d0a()
+{
+ QFile file("task113817.txt");
+ file.open(QIODevice::ReadOnly | QIODevice::Text);
+
+ QTextStream stream(&file);
+ while (!stream.atEnd())
+ stream.readLine();
+}
+
+// ------------------------------------------------------------------------------
+
+Q_DECLARE_METATYPE(QTextStreamFunction);
+
+QTextStream &noop(QTextStream &s) { return s; }
+
+void tst_QTextStream::numeralCase_data()
+{
+ QTextStreamFunction noop_ = noop;
+ QTextStreamFunction bin_ = bin;
+ QTextStreamFunction oct_ = oct;
+ QTextStreamFunction hex_ = hex;
+ QTextStreamFunction base = showbase;
+ QTextStreamFunction ucb = uppercasebase;
+ QTextStreamFunction lcb = lowercasebase;
+ QTextStreamFunction ucd = uppercasedigits;
+ QTextStreamFunction lcd = lowercasedigits;
+
+ QTest::addColumn<QTextStreamFunction>("func1");
+ QTest::addColumn<QTextStreamFunction>("func2");
+ QTest::addColumn<QTextStreamFunction>("func3");
+ QTest::addColumn<QTextStreamFunction>("func4");
+ QTest::addColumn<int>("value");
+ QTest::addColumn<QString>("expected");
+ QTest::newRow("dec 1") << noop_ << noop_ << noop_ << noop_ << 31 << "31";
+ QTest::newRow("dec 2") << noop_ << base << noop_ << noop_ << 31 << "31";
+
+ QTest::newRow("hex 1") << hex_ << noop_ << noop_ << noop_ << 31 << "1f";
+ QTest::newRow("hex 2") << hex_ << noop_ << noop_ << lcd << 31 << "1f";
+ QTest::newRow("hex 3") << hex_ << noop_ << ucb << noop_ << 31 << "1f";
+ QTest::newRow("hex 4") << hex_ << noop_ << noop_ << ucd << 31 << "1F";
+ QTest::newRow("hex 5") << hex_ << noop_ << lcb << ucd << 31 << "1F";
+ QTest::newRow("hex 6") << hex_ << noop_ << ucb << ucd << 31 << "1F";
+ QTest::newRow("hex 7") << hex_ << base << noop_ << noop_ << 31 << "0x1f";
+ QTest::newRow("hex 8") << hex_ << base << lcb << lcd << 31 << "0x1f";
+ QTest::newRow("hex 9") << hex_ << base << ucb << noop_ << 31 << "0X1f";
+ QTest::newRow("hex 10") << hex_ << base << ucb << lcd << 31 << "0X1f";
+ QTest::newRow("hex 11") << hex_ << base << noop_ << ucd << 31 << "0x1F";
+ QTest::newRow("hex 12") << hex_ << base << lcb << ucd << 31 << "0x1F";
+ QTest::newRow("hex 13") << hex_ << base << ucb << ucd << 31 << "0X1F";
+
+ QTest::newRow("bin 1") << bin_ << noop_ << noop_ << noop_ << 31 << "11111";
+ QTest::newRow("bin 2") << bin_ << base << noop_ << noop_ << 31 << "0b11111";
+ QTest::newRow("bin 3") << bin_ << base << lcb << noop_ << 31 << "0b11111";
+ QTest::newRow("bin 4") << bin_ << base << ucb << noop_ << 31 << "0B11111";
+ QTest::newRow("bin 5") << bin_ << base << noop_ << ucd << 31 << "0b11111";
+ QTest::newRow("bin 6") << bin_ << base << lcb << ucd << 31 << "0b11111";
+ QTest::newRow("bin 7") << bin_ << base << ucb << ucd << 31 << "0B11111";
+
+ QTest::newRow("oct 1") << oct_ << noop_ << noop_ << noop_ << 31 << "37";
+ QTest::newRow("oct 2") << oct_ << base << noop_ << noop_ << 31 << "037";
+}
+
+// From Task 125496
+void tst_QTextStream::numeralCase()
+{
+ QFETCH(QTextStreamFunction, func1);
+ QFETCH(QTextStreamFunction, func2);
+ QFETCH(QTextStreamFunction, func3);
+ QFETCH(QTextStreamFunction, func4);
+ QFETCH(int, value);
+ QFETCH(QString, expected);
+
+ QString str;
+ QTextStream stream(&str);
+ stream << func1 << func2 << func3 << func4 << value;
+ QCOMPARE(str, expected);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::nanInf()
+{
+ // Cannot use test data in this function, as comparing nans and infs isn't
+ // well defined.
+ QString str("nan NAN nAn +nan +NAN +nAn -nan -NAN -nAn"
+ " inf INF iNf +inf +INF +iNf -inf -INF -iNf");
+
+ QTextStream stream(&str);
+
+ double tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0;
+ stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0;
+
+ stream.seek(0);
+
+ float tmpF = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0;
+ stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0);
+
+ QString s;
+ QTextStream out(&s);
+ out << qInf() << " " << -qInf() << " " << qQNaN()
+ << uppercasedigits << " "
+ << qInf() << " " << -qInf() << " " << qQNaN()
+ << flush;
+
+ QCOMPARE(s, QString("inf -inf nan INF -INF NAN"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::utf8IncompleteAtBufferBoundary_data()
+{
+ QTest::addColumn<bool>("useLocale");
+
+ QTest::newRow("utf8") << false;
+
+ // is this locale UTF-8?
+ if (QString(QChar::ReplacementCharacter).toLocal8Bit() == "\xef\xbf\xbd")
+ QTest::newRow("locale") << true;
+}
+
+void tst_QTextStream::utf8IncompleteAtBufferBoundary()
+{
+ QFile::remove(TestFileName);
+ QFile data(TestFileName);
+
+ QTextCodec *utf8Codec = QTextCodec::codecForMib(106);
+ QString lineContents = QString::fromUtf8("\342\200\223" // U+2013 EN DASH
+ "\342\200\223"
+ "\342\200\223"
+ "\342\200\223"
+ "\342\200\223"
+ "\342\200\223");
+
+ data.open(QFile::WriteOnly | QFile::Truncate);
+ {
+ QTextStream out(&data);
+ out.setCodec(utf8Codec);
+ out.setFieldWidth(3);
+
+ for (int i = 0; i < 1000; ++i) {
+ out << i << lineContents << endl;
+ }
+ }
+ data.close();
+
+ data.open(QFile::ReadOnly);
+ QTextStream in(&data);
+
+ QFETCH(bool, useLocale);
+ if (!useLocale)
+ in.setCodec(utf8Codec); // QUtf8Codec
+ else
+ in.setCodec(QTextCodec::codecForLocale());
+
+ int i = 0;
+ do {
+ QString line = in.readLine().trimmed();
+ ++i;
+ QVERIFY2(line.endsWith(lineContents), QString("Line %1: %2").arg(i).arg(line).toLocal8Bit());
+ } while (!in.atEnd());
+}
+
+// ------------------------------------------------------------------------------
+
+// Make sure we don't write a BOM after seek()ing
+
+void tst_QTextStream::writeSeekWriteNoBOM()
+{
+
+ //First with the default codec (normally either latin-1 or UTF-8)
+
+ QBuffer out;
+ out.open(QIODevice::WriteOnly);
+ QTextStream stream(&out);
+
+ int number = 0;
+ QString sizeStr = QLatin1String("Size=")
+ + QString::number(number).rightJustified(10, QLatin1Char('0'));
+ stream << sizeStr << endl;
+ stream << "Version=" << QString::number(14) << endl;
+ stream << "blah blah blah" << endl;
+ stream.flush();
+
+ QCOMPARE(out.buffer().constData(), "Size=0000000000\nVersion=14\nblah blah blah\n");
+
+ // Now overwrite the size header item
+ number = 42;
+ stream.seek(0);
+ sizeStr = QLatin1String("Size=")
+ + QString::number(number).rightJustified(10, QLatin1Char('0'));
+ stream << sizeStr << endl;
+ stream.flush();
+
+ // Check buffer is still OK
+ QCOMPARE(out.buffer().constData(), "Size=0000000042\nVersion=14\nblah blah blah\n");
+
+
+ //Then UTF-16
+
+ QBuffer out16;
+ out16.open(QIODevice::WriteOnly);
+ QTextStream stream16(&out16);
+ stream16.setCodec("UTF-16");
+
+ stream16 << "one" << "two" << QLatin1String("three");
+ stream16.flush();
+
+ // save that output
+ QByteArray first = out16.buffer();
+
+ stream16.seek(0);
+ stream16 << "one";
+ stream16.flush();
+
+ QCOMPARE(out16.buffer(), first);
+}
+
+
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::generateOperatorCharData(bool for_QString)
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QChar>("qchar_output");
+ QTest::addColumn<char>("char_output");
+ QTest::addColumn<QByteArray>("write_output");
+
+ QTest::newRow("empty") << QByteArray() << QChar('\0') << '\0' << QByteArray("\0", 1);
+ QTest::newRow("a") << QByteArray("a") << QChar('a') << 'a' << QByteArray("a");
+ QTest::newRow("\\na") << QByteArray("\na") << QChar('\n') << '\n' << QByteArray("\n");
+ QTest::newRow("\\0") << QByteArray("\0") << QChar('\0') << '\0' << QByteArray("\0", 1);
+ QTest::newRow("\\xff") << QByteArray("\xff") << QChar('\xff') << '\xff' << QByteArray("\xff");
+ QTest::newRow("\\xfe") << QByteArray("\xfe") << QChar('\xfe') << '\xfe' << QByteArray("\xfe");
+
+ if (!for_QString) {
+ QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QChar('\0') << '\0' << QByteArray("\0", 1);
+ QTest::newRow("utf16-BE (a)") << QByteArray("\xff\xfe\x61\x00", 4) << QChar('a') << 'a' << QByteArray("a");
+ QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QChar('\0') << '\0' << QByteArray("\0", 1);
+ QTest::newRow("utf16-LE (a)") << QByteArray("\xfe\xff\x00\x61", 4) << QChar('a') << 'a' << QByteArray("a");
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::QChar_operators_FromDevice_data()
+{
+ generateOperatorCharData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::QChar_operators_FromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QChar, qchar_output);
+ QFETCH(QByteArray, write_output);
+
+ QBuffer buf(&input);
+ buf.open(QBuffer::ReadOnly);
+ QTextStream stream(&buf);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ QChar tmp;
+ stream >> tmp;
+ QCOMPARE(tmp, qchar_output);
+
+ QBuffer writeBuf;
+ writeBuf.open(QBuffer::WriteOnly);
+
+ QTextStream writeStream(&writeBuf);
+ writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ writeStream << qchar_output;
+ writeStream.flush();
+
+ QCOMPARE(writeBuf.buffer().size(), write_output.size());
+ QCOMPARE(writeBuf.buffer().constData(), write_output.constData());
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::char_operators_FromDevice_data()
+{
+ generateOperatorCharData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::char_operators_FromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(char, char_output);
+ QFETCH(QByteArray, write_output);
+
+ QBuffer buf(&input);
+ buf.open(QBuffer::ReadOnly);
+ QTextStream stream(&buf);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ char tmp;
+ stream >> tmp;
+ QCOMPARE(tmp, char_output);
+
+ QBuffer writeBuf;
+ writeBuf.open(QBuffer::WriteOnly);
+
+ QTextStream writeStream(&writeBuf);
+ writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ writeStream << char_output;
+ writeStream.flush();
+
+ QCOMPARE(writeBuf.buffer().size(), write_output.size());
+ QCOMPARE(writeBuf.buffer().constData(), write_output.constData());
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::generateNaturalNumbersData(bool for_QString)
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<qulonglong>("output");
+
+ QTest::newRow("empty") << QByteArray() << qulonglong(0);
+ QTest::newRow("a") << QByteArray("a") << qulonglong(0);
+ QTest::newRow(" ") << QByteArray(" ") << qulonglong(0);
+ QTest::newRow("0") << QByteArray("0") << qulonglong(0);
+ QTest::newRow("1") << QByteArray("1") << qulonglong(1);
+ QTest::newRow("12") << QByteArray("12") << qulonglong(12);
+ QTest::newRow("-12") << QByteArray("-12") << qulonglong(-12);
+ QTest::newRow("-0") << QByteArray("-0") << qulonglong(0);
+ QTest::newRow(" 1") << QByteArray(" 1") << qulonglong(1);
+ QTest::newRow(" \\r\\n\\r\\n123") << QByteArray(" \r\n\r\n123") << qulonglong(123);
+
+ // bit boundary tests
+ QTest::newRow("127") << QByteArray("127") << qulonglong(127);
+ QTest::newRow("128") << QByteArray("128") << qulonglong(128);
+ QTest::newRow("129") << QByteArray("129") << qulonglong(129);
+ QTest::newRow("-127") << QByteArray("-127") << qulonglong(-127);
+ QTest::newRow("-128") << QByteArray("-128") << qulonglong(-128);
+ QTest::newRow("-129") << QByteArray("-129") << qulonglong(-129);
+ QTest::newRow("32767") << QByteArray("32767") << qulonglong(32767);
+ QTest::newRow("32768") << QByteArray("32768") << qulonglong(32768);
+ QTest::newRow("32769") << QByteArray("32769") << qulonglong(32769);
+ QTest::newRow("-32767") << QByteArray("-32767") << qulonglong(-32767);
+ QTest::newRow("-32768") << QByteArray("-32768") << qulonglong(-32768);
+ QTest::newRow("-32769") << QByteArray("-32769") << qulonglong(-32769);
+ QTest::newRow("65537") << QByteArray("65537") << qulonglong(65537);
+ QTest::newRow("65536") << QByteArray("65536") << qulonglong(65536);
+ QTest::newRow("65535") << QByteArray("65535") << qulonglong(65535);
+ QTest::newRow("-65537") << QByteArray("-65537") << qulonglong(-65537);
+ QTest::newRow("-65536") << QByteArray("-65536") << qulonglong(-65536);
+ QTest::newRow("-65535") << QByteArray("-65535") << qulonglong(-65535);
+ QTest::newRow("2147483646") << QByteArray("2147483646") << qulonglong(2147483646);
+ QTest::newRow("2147483647") << QByteArray("2147483647") << qulonglong(2147483647);
+ QTest::newRow("2147483648") << QByteArray("2147483648") << Q_UINT64_C(2147483648);
+ QTest::newRow("-2147483646") << QByteArray("-2147483646") << qulonglong(-2147483646);
+ QTest::newRow("-2147483647") << QByteArray("-2147483647") << qulonglong(-2147483647);
+ QTest::newRow("-2147483648") << QByteArray("-2147483648") << Q_UINT64_C(-2147483648);
+ QTest::newRow("4294967296") << QByteArray("4294967296") << Q_UINT64_C(4294967296);
+ QTest::newRow("4294967297") << QByteArray("4294967297") << Q_UINT64_C(4294967297);
+ QTest::newRow("4294967298") << QByteArray("4294967298") << Q_UINT64_C(4294967298);
+ QTest::newRow("-4294967296") << QByteArray("-4294967296") << Q_UINT64_C(-4294967296);
+ QTest::newRow("-4294967297") << QByteArray("-4294967297") << Q_UINT64_C(-4294967297);
+ QTest::newRow("-4294967298") << QByteArray("-4294967298") << Q_UINT64_C(-4294967298);
+ QTest::newRow("9223372036854775807") << QByteArray("9223372036854775807") << Q_UINT64_C(9223372036854775807);
+ QTest::newRow("9223372036854775808") << QByteArray("9223372036854775808") << Q_UINT64_C(9223372036854775808);
+ QTest::newRow("9223372036854775809") << QByteArray("9223372036854775809") << Q_UINT64_C(9223372036854775809);
+ QTest::newRow("18446744073709551615") << QByteArray("18446744073709551615") << Q_UINT64_C(18446744073709551615);
+ QTest::newRow("18446744073709551616") << QByteArray("18446744073709551616") << Q_UINT64_C(0);
+ QTest::newRow("18446744073709551617") << QByteArray("18446744073709551617") << Q_UINT64_C(1);
+ // 18446744073709551617 bytes should be enough for anyone.... ;-)
+
+ // hex tests
+ QTest::newRow("0x0") << QByteArray("0x0") << qulonglong(0);
+ QTest::newRow("0x") << QByteArray("0x") << qulonglong(0);
+ QTest::newRow("0x1") << QByteArray("0x1") << qulonglong(1);
+ QTest::newRow("0xf") << QByteArray("0xf") << qulonglong(15);
+ QTest::newRow("0xdeadbeef") << QByteArray("0xdeadbeef") << Q_UINT64_C(3735928559);
+ QTest::newRow("0XDEADBEEF") << QByteArray("0XDEADBEEF") << Q_UINT64_C(3735928559);
+ QTest::newRow("0xdeadbeefZzzzz") << QByteArray("0xdeadbeefZzzzz") << Q_UINT64_C(3735928559);
+ QTest::newRow(" 0xdeadbeefZzzzz") << QByteArray(" 0xdeadbeefZzzzz") << Q_UINT64_C(3735928559);
+
+ // oct tests
+ QTest::newRow("00") << QByteArray("00") << qulonglong(0);
+ QTest::newRow("0141") << QByteArray("0141") << qulonglong(97);
+ QTest::newRow("01419999") << QByteArray("01419999") << qulonglong(97);
+ QTest::newRow(" 01419999") << QByteArray(" 01419999") << qulonglong(97);
+
+ // bin tests
+ QTest::newRow("0b0") << QByteArray("0b0") << qulonglong(0);
+ QTest::newRow("0b1") << QByteArray("0b1") << qulonglong(1);
+ QTest::newRow("0b10") << QByteArray("0b10") << qulonglong(2);
+ QTest::newRow("0B10") << QByteArray("0B10") << qulonglong(2);
+ QTest::newRow("0b101010") << QByteArray("0b101010") << qulonglong(42);
+ QTest::newRow("0b1010102345") << QByteArray("0b1010102345") << qulonglong(42);
+ QTest::newRow(" 0b1010102345") << QByteArray(" 0b1010102345") << qulonglong(42);
+
+ // utf-16 tests
+ if (!for_QString) {
+ QTest::newRow("utf16-BE (empty)") << QByteArray("\xfe\xff", 2) << qulonglong(0);
+ QTest::newRow("utf16-BE (0xdeadbeef)")
+ << QByteArray("\xfe\xff"
+ "\x00\x30\x00\x78\x00\x64\x00\x65\x00\x61\x00\x64\x00\x62\x00\x65\x00\x65\x00\x66", 22)
+ << Q_UINT64_C(3735928559);
+ QTest::newRow("utf16-LE (empty)") << QByteArray("\xff\xfe", 2) << Q_UINT64_C(0);
+ QTest::newRow("utf16-LE (0xdeadbeef)")
+ << QByteArray("\xff\xfe"
+ "\x30\x00\x78\x00\x64\x00\x65\x00\x61\x00\x64\x00\x62\x00\x65\x00\x65\x00\x66\x00", 22)
+ << Q_UINT64_C(3735928559);
+ }
+}
+
+// ------------------------------------------------------------------------------
+#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(texttype, type) \
+ void tst_QTextStream:: texttype##_read_operator_FromDevice_data() \
+ { generateNaturalNumbersData(false); } \
+ void tst_QTextStream:: texttype##_read_operator_FromDevice() \
+ { \
+ QFETCH(QByteArray, input); \
+ QFETCH(qulonglong, output); \
+ type sh; \
+ QTextStream stream(&input); \
+ stream >> sh; \
+ QCOMPARE(sh, (type)output); \
+ }
+IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedShort, signed short)
+IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedShort, unsigned short)
+IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedInt, signed int)
+IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedInt, unsigned int)
+IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qlonglong, qlonglong)
+IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qulonglong, qulonglong)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::generateRealNumbersData(bool for_QString)
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<double>("output");
+
+ QTest::newRow("empty") << QByteArray() << 0.0;
+ QTest::newRow("a") << QByteArray("a") << 0.0;
+ QTest::newRow("1.0") << QByteArray("1.0") << 1.0;
+ QTest::newRow(" 1") << QByteArray(" 1") << 1.0;
+ QTest::newRow(" \\r\\n1.2") << QByteArray(" \r\n1.2") << 1.2;
+ QTest::newRow("3.14") << QByteArray("3.14") << 3.14;
+ QTest::newRow("-3.14") << QByteArray("-3.14") << -3.14;
+ QTest::newRow(" -3.14") << QByteArray(" -3.14") << -3.14;
+ QTest::newRow("314e-02") << QByteArray("314e-02") << 3.14;
+ QTest::newRow("314E-02") << QByteArray("314E-02") << 3.14;
+ QTest::newRow("314e+02") << QByteArray("314e+02") << 31400.;
+ QTest::newRow("314E+02") << QByteArray("314E+02") << 31400.;
+
+ // ### add numbers with exponents
+
+ if (!for_QString) {
+ QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << 0.0;
+ QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << 0.0;
+ }
+}
+
+// ------------------------------------------------------------------------------
+#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(texttype, type) \
+ void tst_QTextStream:: texttype##_read_operator_FromDevice_data() \
+ { generateRealNumbersData(false); } \
+ void tst_QTextStream:: texttype##_read_operator_FromDevice() \
+ { \
+ QFETCH(QByteArray, input); \
+ QFETCH(double, output); \
+ type sh; \
+ QTextStream stream(&input); \
+ stream >> sh; \
+ QCOMPARE(sh, (type)output); \
+ }
+IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(float, float)
+IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(double, double)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::generateStringData(bool for_QString)
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QByteArray>("array_output");
+ QTest::addColumn<QString>("string_output");
+
+ QTest::newRow("empty") << QByteArray() << QByteArray() << QString();
+ QTest::newRow("a") << QByteArray("a") << QByteArray("a") << QString("a");
+ QTest::newRow("a b") << QByteArray("a b") << QByteArray("a") << QString("a");
+ QTest::newRow(" a b") << QByteArray(" a b") << QByteArray("a") << QString("a");
+ QTest::newRow("a1") << QByteArray("a1") << QByteArray("a1") << QString("a1");
+ QTest::newRow("a1 b1") << QByteArray("a1 b1") << QByteArray("a1") << QString("a1");
+ QTest::newRow(" a1 b1") << QByteArray(" a1 b1") << QByteArray("a1") << QString("a1");
+ QTest::newRow("\\n\\n\\nole i dole\\n") << QByteArray("\n\n\nole i dole\n") << QByteArray("ole") << QString("ole");
+
+ if (!for_QString) {
+ QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QByteArray() << QString();
+ QTest::newRow("utf16-BE (corrupt)") << QByteArray("\xff", 1) << QByteArray("\xff") << QString("\xff");
+ QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QByteArray() << QString();
+ QTest::newRow("utf16-LE (corrupt)") << QByteArray("\xfe", 1) << QByteArray("\xfe") << QString("\xfe");
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::charPtr_read_operator_FromDevice_data()
+{
+ generateStringData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::charPtr_read_operator_FromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QByteArray, array_output);
+
+ QBuffer buffer(&input);
+ buffer.open(QBuffer::ReadOnly);
+ QTextStream stream(&buffer);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ char buf[1024];
+ stream >> buf;
+
+ QCOMPARE((const char *)buf, array_output.constData());
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::stringRef_read_operator_FromDevice_data()
+{
+ generateStringData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::stringRef_read_operator_FromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QString, string_output);
+
+ QBuffer buffer(&input);
+ buffer.open(QBuffer::ReadOnly);
+ QTextStream stream(&buffer);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ QString tmp;
+ stream >> tmp;
+
+ QCOMPARE(tmp, string_output);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::byteArray_read_operator_FromDevice_data()
+{
+ generateStringData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::byteArray_read_operator_FromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QByteArray, array_output);
+
+ QBuffer buffer(&input);
+ buffer.open(QBuffer::ReadOnly);
+ QTextStream stream(&buffer);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ QByteArray array;
+ stream >> array;
+
+ QCOMPARE(array, array_output);
+}
+
+// ------------------------------------------------------------------------------
+#define IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(texttype, type) \
+ void tst_QTextStream:: texttype##_write_operator_ToDevice() \
+ { \
+ QFETCH(qulonglong, number); \
+ QFETCH(QByteArray, data); \
+ \
+ QBuffer buffer; \
+ buffer.open(QBuffer::WriteOnly); \
+ QTextStream stream(&buffer); \
+ stream << (type)number; \
+ stream.flush(); \
+ \
+ QCOMPARE(buffer.data().constData(), data.constData()); \
+ }
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::signedShort_write_operator_ToDevice_data()
+{
+ QTest::addColumn<qulonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
+ QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
+ QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("-1");
+ QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
+ QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("-32768");
+ QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("-32767");
+ QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("-1");
+ QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("0");
+ QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("1");
+}
+IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedShort, signed short)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::unsignedShort_write_operator_ToDevice_data()
+{
+ QTest::addColumn<qulonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
+ QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
+ QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("65535");
+ QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
+ QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
+ QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
+ QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
+ QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("0");
+ QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("1");
+}
+IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedShort, unsigned short)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::signedInt_write_operator_ToDevice_data()
+{
+ QTest::addColumn<qulonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
+ QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
+ QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("-1");
+ QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
+ QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
+ QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
+ QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
+ QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
+ QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
+ QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
+ QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("-2147483648");
+ QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("-2147483647");
+ QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("-1");
+ QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("0");
+ QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("1");
+}
+IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedInt, signed int)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::unsignedInt_write_operator_ToDevice_data()
+{
+ QTest::addColumn<qulonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
+ QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
+ QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("4294967295");
+ QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
+ QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
+ QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
+ QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
+ QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
+ QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
+ QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
+ QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("2147483648");
+ QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("2147483649");
+ QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("4294967295");
+ QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("0");
+ QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("1");
+}
+IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedInt, unsigned int)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::qlonglong_write_operator_ToDevice_data()
+{
+ QTest::addColumn<qulonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
+ QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
+ QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("-1");
+ QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
+ QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
+ QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
+ QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
+ QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
+ QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
+ QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
+ QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("2147483648");
+ QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("2147483649");
+ QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("4294967295");
+ QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("4294967296");
+ QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("4294967297");
+ QTest::newRow("9223372036854775807") << Q_UINT64_C(9223372036854775807) << QByteArray("9223372036854775807");
+ QTest::newRow("9223372036854775808") << Q_UINT64_C(9223372036854775808) << QByteArray("-9223372036854775808");
+ QTest::newRow("9223372036854775809") << Q_UINT64_C(9223372036854775809) << QByteArray("-9223372036854775807");
+ QTest::newRow("18446744073709551615") << Q_UINT64_C(18446744073709551615) << QByteArray("-1");
+}
+IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qlonglong, qlonglong)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::qulonglong_write_operator_ToDevice_data()
+{
+ QTest::addColumn<qulonglong>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
+ QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
+ QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("18446744073709551615");
+ QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
+ QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
+ QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
+ QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
+ QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
+ QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
+ QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
+ QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("2147483648");
+ QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("2147483649");
+ QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("4294967295");
+ QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("4294967296");
+ QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("4294967297");
+ QTest::newRow("9223372036854775807") << Q_UINT64_C(9223372036854775807) << QByteArray("9223372036854775807");
+ QTest::newRow("9223372036854775808") << Q_UINT64_C(9223372036854775808) << QByteArray("9223372036854775808");
+ QTest::newRow("9223372036854775809") << Q_UINT64_C(9223372036854775809) << QByteArray("9223372036854775809");
+ QTest::newRow("18446744073709551615") << Q_UINT64_C(18446744073709551615) << QByteArray("18446744073709551615");
+}
+IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qulonglong, qulonglong)
+ ;
+
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::generateRealNumbersDataWrite()
+{
+ QTest::addColumn<double>("number");
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("0") << 0.0 << QByteArray("0");
+ QTest::newRow("3.14") << 3.14 << QByteArray("3.14");
+ QTest::newRow("-3.14") << -3.14 << QByteArray("-3.14");
+ QTest::newRow("1.2e+10") << 1.2e+10 << QByteArray("1.2e+10");
+ QTest::newRow("-1.2e+10") << -1.2e+10 << QByteArray("-1.2e+10");
+}
+
+// ------------------------------------------------------------------------------
+#define IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(texttype, type) \
+ void tst_QTextStream:: texttype##_write_operator_ToDevice_data() \
+ { generateRealNumbersDataWrite(); } \
+ void tst_QTextStream:: texttype##_write_operator_ToDevice() \
+ { \
+ QFETCH(double, number); \
+ QFETCH(QByteArray, data); \
+ \
+ QBuffer buffer; \
+ buffer.open(QBuffer::WriteOnly); \
+ QTextStream stream(&buffer); \
+ float f = (float)number; \
+ stream << f; \
+ stream.flush(); \
+ QCOMPARE(buffer.data().constData(), data.constData()); \
+ }
+IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(float, float)
+IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(double, float)
+ ;
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::string_write_operator_ToDevice_data()
+{
+ QTest::addColumn<QByteArray>("bytedata");
+ QTest::addColumn<QString>("stringdata");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::newRow("empty") << QByteArray("", 1) << QString(1, '\0') << QByteArray("", 1);
+ QTest::newRow("a") << QByteArray("a") << QString("a") << QByteArray("a");
+ QTest::newRow("a cow jumped over the moon")
+ << QByteArray("a cow jumped over the moon")
+ << QString("a cow jumped over the moon")
+ << QByteArray("a cow jumped over the moon");
+
+ // ### get the utf16-be test on its legs.
+ /*
+ QTest::newRow("utf16-BE (a cow jumped over the moon)")
+ << QByteArray("\xff\xfe\x00\x61\x00\x20\x00\x63\x00\x6f\x00\x77\x00\x20\x00\x6a\x00\x75\x00\x6d\x00\x70\x00\x65\x00\x64\x00\x20\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x6d\x00\x6f\x00\x6f\x00\x6e\x00\x0a", 56)
+ << QString("a cow jumped over the moon")
+ << QByteArray("a cow jumped over the moon");
+ */
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::string_write_operator_ToDevice()
+{
+ QFETCH(QByteArray, bytedata);
+ QFETCH(QString, stringdata);
+ QFETCH(QByteArray, result);
+
+ {
+ // char*
+ QBuffer buf;
+ buf.open(QBuffer::WriteOnly);
+ QTextStream stream(&buf);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ stream << bytedata.constData();
+ stream.flush();
+ QCOMPARE(buf.buffer().constData(), result.constData());
+ }
+ {
+ // QByteArray
+ QBuffer buf;
+ buf.open(QBuffer::WriteOnly);
+ QTextStream stream(&buf);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ stream << bytedata;
+ stream.flush();
+ QCOMPARE(buf.buffer().constData(), result.constData());
+ }
+ {
+ // QString
+ QBuffer buf;
+ buf.open(QBuffer::WriteOnly);
+ QTextStream stream(&buf);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ stream << stringdata;
+ stream.flush();
+ QCOMPARE(buf.buffer().constData(), result.constData());
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::useCase1()
+{
+ QFile::remove("testfile");
+ QFile file("testfile");
+ QVERIFY(file.open(QFile::ReadWrite));
+
+ {
+ QTextStream stream(&file);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ stream << 4.15 << " " << QByteArray("abc") << " " << QString("ole");
+ }
+
+ file.seek(0);
+ QCOMPARE(file.readAll(), QByteArray("4.15 abc ole"));
+ file.seek(0);
+
+ {
+ double d;
+ QByteArray a;
+ QString s;
+ QTextStream stream(&file);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ stream >> d;
+ stream >> a;
+ stream >> s;
+
+ QCOMPARE(d, 4.15);
+ QCOMPARE(a, QByteArray("abc"));
+ QCOMPARE(s, QString("ole"));
+ }
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::useCase2()
+{
+ QFile::remove("testfile");
+ QFile file("testfile");
+ QVERIFY(file.open(QFile::ReadWrite));
+
+ QTextStream stream(&file);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+ stream << 4.15 << " " << QByteArray("abc") << " " << QString("ole");
+
+ file.close();
+ QVERIFY(file.open(QFile::ReadWrite));
+
+ QCOMPARE(file.readAll(), QByteArray("4.15 abc ole"));
+
+ file.close();
+ QVERIFY(file.open(QFile::ReadWrite));
+
+ double d;
+ QByteArray a;
+ QString s;
+ QTextStream stream2(&file);
+ stream2.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream2.setAutoDetectUnicode(true);
+
+ stream2 >> d;
+ stream2 >> a;
+ stream2 >> s;
+
+ QCOMPARE(d, 4.15);
+ QCOMPARE(a, QByteArray("abc"));
+ QCOMPARE(s, QString("ole"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::manipulators_data()
+{
+ QTest::addColumn<int>("flags");
+ QTest::addColumn<int>("width");
+ QTest::addColumn<double>("realNumber");
+ QTest::addColumn<int>("intNumber");
+ QTest::addColumn<QString>("textData");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::newRow("no flags") << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
+ QTest::newRow("rightadjust") << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
+
+ // ### FIX
+// QTest::newRow("leftadjust") << int(QTextStream::left) << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
+// QTest::newRow("showpos") << int(QTextStream::showpos) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
+// QTest::newRow("showpos2") << int(QTextStream::showpos) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
+// QTest::newRow("hex") << int(QTextStream::hex | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
+// QTest::newRow("hex uppercase") << int(QTextStream::hex | QTextStream::uppercase | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::manipulators()
+{
+// QFETCH(int, flags);
+ QFETCH(int, width);
+ QFETCH(double, realNumber);
+ QFETCH(int, intNumber);
+ QFETCH(QString, textData);
+ QFETCH(QByteArray, result);
+
+ QBuffer buffer;
+ buffer.open(QBuffer::WriteOnly);
+
+ QTextStream stream(&buffer);
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setAutoDetectUnicode(true);
+
+// stream.setFlags(flags);
+ stream.setFieldWidth(width);
+ stream << realNumber;
+ stream << intNumber;
+ stream << textData;
+ stream.flush();
+
+ QCOMPARE(buffer.data().constData(), result.constData());
+}
+
+void tst_QTextStream::generateBOM()
+{
+ QFile::remove("bom.txt");
+ {
+ QFile file("bom.txt");
+ QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate));
+
+ QTextStream stream(&file);
+ stream.setCodec(QTextCodec::codecForName("UTF-16LE"));
+ stream << "Hello" << endl;
+
+ file.close();
+ QVERIFY(file.open(QFile::ReadOnly));
+ QCOMPARE(file.readAll(), QByteArray("\x48\x00\x65\00\x6c\00\x6c\00\x6f\x00\x0a\x00", 12));
+ }
+
+ QFile::remove("bom.txt");
+ {
+ QFile file("bom.txt");
+ QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate));
+
+ QTextStream stream(&file);
+ stream.setCodec(QTextCodec::codecForName("UTF-16LE"));
+ stream << bom << "Hello" << endl;
+
+ file.close();
+ QVERIFY(file.open(QFile::ReadOnly));
+ QCOMPARE(file.readAll(), QByteArray("\xff\xfe\x48\x00\x65\00\x6c\00\x6c\00\x6f\x00\x0a\x00", 14));
+ }
+}
+
+void tst_QTextStream::readBomSeekBackReadBomAgain()
+{
+ QFile::remove("utf8bom");
+ QFile file("utf8bom");
+ QVERIFY(file.open(QFile::ReadWrite));
+ file.write("\xef\xbb\xbf" "Andreas");
+ file.seek(0);
+ QCOMPARE(file.pos(), qint64(0));
+
+ QTextStream stream(&file);
+ stream.setCodec("UTF-8");
+ QString Andreas;
+ stream >> Andreas;
+ QCOMPARE(Andreas, QString("Andreas"));
+ stream.seek(0);
+ stream >> Andreas;
+ QCOMPARE(Andreas, QString("Andreas"));
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::status_real_read_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<double>("expected_f");
+ QTest::addColumn<QString>("expected_w");
+ QTest::addColumn<QList<int> >("results");
+
+ QTest::newRow("1.23 abc ") << QString("1.23 abc ") << 1.23 << QString("abc")
+ << (QList<int>()
+ << (int)QTextStream::Ok
+ << (int)QTextStream::ReadCorruptData
+ << (int)QTextStream::Ok
+ << (int)QTextStream::Ok
+ << (int)QTextStream::ReadPastEnd);
+}
+
+void tst_QTextStream::status_real_read()
+{
+ QFETCH(QString, input);
+ QFETCH(double, expected_f);
+ QFETCH(QString, expected_w);
+ QFETCH(QList<int>, results);
+
+ QTextStream s(&input);
+ double f = 0.0;
+ QString w;
+ s >> f;
+ QCOMPARE((int)s.status(), results.at(0));
+ QCOMPARE(f, expected_f);
+ s >> f;
+ QCOMPARE((int)s.status(), results.at(1));
+ s.resetStatus();
+ QCOMPARE((int)s.status(), results.at(2));
+ s >> w;
+ QCOMPARE((int)s.status(), results.at(3));
+ QCOMPARE(w, expected_w);
+ s >> f;
+ QCOMPARE((int)s.status(), results.at(4));
+}
+
+void tst_QTextStream::status_integer_read()
+{
+#ifdef Q_OS_WINCE
+ QString text = QLatin1String("123 abc ");
+ QTextStream s(&text);
+#else
+ QTextStream s("123 abc ");
+#endif
+ int i;
+ QString w;
+ s >> i;
+ QCOMPARE(s.status(), QTextStream::Ok);
+ s >> i;
+ QCOMPARE(s.status(), QTextStream::ReadCorruptData);
+ s.resetStatus();
+ QCOMPARE(s.status(), QTextStream::Ok);
+ s >> w;
+ QCOMPARE(s.status(), QTextStream::Ok);
+ QCOMPARE(w, QString("abc"));
+ s >> i;
+ QCOMPARE(s.status(), QTextStream::ReadPastEnd);
+}
+
+void tst_QTextStream::status_word_read()
+{
+#ifdef Q_OS_WINCE
+ QString text = QLatin1String("abc ");
+ QTextStream s(&text);
+#else
+ QTextStream s("abc ");
+#endif
+ QString w;
+ s >> w;
+ QCOMPARE(s.status(), QTextStream::Ok);
+ s >> w;
+ QCOMPARE(s.status(), QTextStream::ReadPastEnd);
+}
+
+class FakeBuffer : public QBuffer
+{
+protected:
+ qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); }
+public:
+ FakeBuffer(bool locked = false) : m_lock(locked) {}
+ void setLocked(bool locked) { m_lock = locked; }
+private:
+ bool m_lock;
+};
+
+void tst_QTextStream::status_write_error()
+{
+ FakeBuffer fb(false);
+ QVERIFY(fb.open(QBuffer::ReadWrite));
+ QTextStream fs(&fb);
+ fs.setCodec(QTextCodec::codecForName("latin1"));
+ /* first write some initial content */
+ fs << "hello";
+ fs.flush();
+ QCOMPARE(fs.status(), QTextStream::Ok);
+ QCOMPARE(fb.data(), QByteArray("hello"));
+ /* then test that writing can cause an error */
+ fb.setLocked(true);
+ fs << "error";
+ fs.flush();
+ QCOMPARE(fs.status(), QTextStream::WriteFailed);
+ QCOMPARE(fb.data(), QByteArray("hello"));
+ /* finally test that writing after an error doesn't change the stream any more */
+ fb.setLocked(false);
+ fs << "can't do that";
+ fs.flush();
+ QCOMPARE(fs.status(), QTextStream::WriteFailed);
+ QCOMPARE(fb.data(), QByteArray("hello"));
+}
+
+void tst_QTextStream::task180679_alignAccountingStyle()
+{
+ {
+ QString result;
+ QTextStream out(&result);
+ out.setFieldAlignment(QTextStream::AlignAccountingStyle);
+ out.setFieldWidth(4);
+ out.setPadChar('0');
+ out << -1;
+ QCOMPARE(result, QLatin1String("-001"));
+ }
+
+ {
+ QString result;
+ QTextStream out(&result);
+ out.setFieldAlignment(QTextStream::AlignAccountingStyle);
+ out.setFieldWidth(4);
+ out.setPadChar('0');
+ out << "-1";
+ QCOMPARE(result, QLatin1String("00-1"));
+ }
+
+ {
+ QString result;
+ QTextStream out(&result);
+ out.setFieldAlignment(QTextStream::AlignAccountingStyle);
+ out.setFieldWidth(6);
+ out.setPadChar('0');
+ out << -1.2;
+ QCOMPARE(result, QLatin1String("-001.2"));
+ }
+
+ {
+ QString result;
+ QTextStream out(&result);
+ out.setFieldAlignment(QTextStream::AlignAccountingStyle);
+ out.setFieldWidth(6);
+ out.setPadChar('0');
+ out << "-1.2";
+ QCOMPARE(result, QLatin1String("00-1.2"));
+ }
+}
+
+void tst_QTextStream::task178772_setCodec()
+{
+ QByteArray ba("\xe5 v\xe6r\n\xc3\xa5 v\xc3\xa6r\n");
+ QString res = QLatin1String("\xe5 v\xe6r");
+
+ QTextStream stream(ba);
+ stream.setCodec("ISO 8859-1");
+ QCOMPARE(stream.readLine(),res);
+ stream.setCodec("UTF-8");
+ QCOMPARE(stream.readLine(),res);
+}
+
+void tst_QTextStream::double_write_with_flags_data()
+{
+ QTest::addColumn<double>("number");
+ QTest::addColumn<QString>("output");
+ QTest::addColumn<int>("numberFlags");
+ QTest::addColumn<int>("realNumberNotation");
+
+ QTest::newRow("-ForceSign") << -1.23 << QString("-1.23") << (int)QTextStream::ForceSign << 0;
+ QTest::newRow("+ForceSign") << 1.23 << QString("+1.23") << (int)QTextStream::ForceSign << 0;
+ QTest::newRow("inf") << qInf() << QString("inf") << 0 << 0;
+ QTest::newRow("-inf") << -qInf() << QString("-inf") << 0 << 0;
+ QTest::newRow("inf uppercase") << qInf() << QString("INF") << (int)QTextStream::UppercaseDigits << 0;
+ QTest::newRow("-inf uppercase") << -qInf() << QString("-INF") << (int)QTextStream::UppercaseDigits << 0;
+ QTest::newRow("nan") << qQNaN() << QString("nan") << 0 << 0;
+ QTest::newRow("nan") << qQNaN() << QString("NAN") << (int)QTextStream::UppercaseDigits << 0;
+ QTest::newRow("scientific") << 1.234567e+02 << QString("1.234567e+02") << 0 << (int)QTextStream::ScientificNotation;
+ QTest::newRow("scientific2") << 1.234567e+02 << QString("1.234567e+02") << (int)QTextStream::UppercaseBase << (int)QTextStream::ScientificNotation;
+ QTest::newRow("scientific uppercase") << 1.234567e+02 << QString("1.234567E+02") << (int)QTextStream::UppercaseDigits << (int)QTextStream::ScientificNotation;
+}
+
+void tst_QTextStream::double_write_with_flags()
+{
+ QFETCH(double, number);
+ QFETCH(QString, output);
+ QFETCH(int, numberFlags);
+ QFETCH(int, realNumberNotation);
+
+ QString buf;
+ QTextStream stream(&buf);
+ if (numberFlags)
+ stream.setNumberFlags(QTextStream::NumberFlag(numberFlags));
+ if (realNumberNotation)
+ stream.setRealNumberNotation(QTextStream::RealNumberNotation(realNumberNotation));
+ stream << number;
+ QCOMPARE(buf, output);
+}
+
+void tst_QTextStream::double_write_with_precision_data()
+{
+ QTest::addColumn<int>("precision");
+ QTest::addColumn<double>("value");
+ QTest::addColumn<QString>("result");
+
+ QTest::ignoreMessage(QtWarningMsg, "QTextStream::setRealNumberPrecision: Invalid precision (-1)");
+ QTest::newRow("-1") << -1 << 3.14159 << QString("3.14159");
+ QTest::newRow("0") << 0 << 3.14159 << QString("3");
+ QTest::newRow("1") << 1 << 3.14159 << QString("3");
+ QTest::newRow("2") << 2 << 3.14159 << QString("3.1");
+ QTest::newRow("3") << 3 << 3.14159 << QString("3.14");
+ QTest::newRow("5") << 5 << 3.14159 << QString("3.1416");
+ QTest::newRow("6") << 6 << 3.14159 << QString("3.14159");
+ QTest::newRow("7") << 7 << 3.14159 << QString("3.14159");
+ QTest::newRow("10") << 10 << 3.14159 << QString("3.14159");
+}
+
+void tst_QTextStream::double_write_with_precision()
+{
+ QFETCH(int, precision);
+ QFETCH(double, value);
+ QFETCH(QString, result);
+
+ QString buf;
+ QTextStream stream(&buf);
+ stream.setRealNumberPrecision(precision);
+ stream << value;
+ QCOMPARE(buf, result);
+}
+
+void tst_QTextStream::int_read_with_locale_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<int>("output");
+
+ QTest::newRow("C -123") << QString("C") << QString("-123") << -123;
+ QTest::newRow("C +123") << QString("C") << QString("+123") << 123;
+ QTest::newRow("C 12345") << QString("C") << QString("12345") << 12345;
+ QTest::newRow("C 12,345") << QString("C") << QString("12,345") << 12;
+ QTest::newRow("C 12.345") << QString("C") << QString("12.345") << 12;
+
+ QTest::newRow("de_DE -123") << QString("de_DE") << QString("-123") << -123;
+ QTest::newRow("de_DE +123") << QString("de_DE") << QString("+123") << 123;
+ QTest::newRow("de_DE 12345") << QString("de_DE") << QString("12345") << 12345;
+ QTest::newRow("de_DE 12.345") << QString("de_DE") << QString("12.345") << 12345;
+ QTest::newRow("de_DE .12345") << QString("de_DE") << QString(".12345") << 0;
+}
+
+void tst_QTextStream::int_read_with_locale()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, input);
+ QFETCH(int, output);
+
+ QTextStream stream(&input);
+ stream.setLocale(locale);
+ int result;
+ stream >> result;
+ QCOMPARE(result, output);
+}
+
+void tst_QTextStream::int_write_with_locale_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<int>("numberFlags");
+ QTest::addColumn<int>("input");
+ QTest::addColumn<QString>("output");
+
+ QTest::newRow("C -123") << QString("C") << 0 << -123 << QString("-123");
+ QTest::newRow("C +123") << QString("C") << (int)QTextStream::ForceSign << 123 << QString("+123");
+ QTest::newRow("C 12345") << QString("C") << 0 << 12345 << QString("12345");
+
+ QTest::newRow("de_DE -123") << QString("de_DE") << 0 << -123 << QString("-123");
+ QTest::newRow("de_DE +123") << QString("de_DE") << (int)QTextStream::ForceSign << 123 << QString("+123");
+ QTest::newRow("de_DE 12345") << QString("de_DE") << 0 << 12345 << QString("12.345");
+}
+
+void tst_QTextStream::int_write_with_locale()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, numberFlags);
+ QFETCH(int, input);
+ QFETCH(QString, output);
+
+ QString result;
+ QTextStream stream(&result);
+ stream.setLocale(locale);
+ if (numberFlags)
+ stream.setNumberFlags(QTextStream::NumberFlags(numberFlags));
+ stream << input;
+ QCOMPARE(result, output);
+}
+
+// ------------------------------------------------------------------------------
+
+// like QTEST_APPLESS_MAIN, but initialising the locale on Unix
+#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)
+QT_BEGIN_NAMESPACE
+extern bool qt_locale_initialized;
+QT_END_NAMESPACE
+#endif
+
+int main(int argc, char *argv[])
+{
+#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)
+ ::setlocale(LC_ALL, "");
+ qt_locale_initialized = true;
+#endif
+ tst_QTextStream tc;
+ return QTest::qExec(&tc, argc, argv);
+}
+
+#include "tst_qtextstream.moc"
+
diff --git a/tests/auto/corelib/io/qurl/.gitignore b/tests/auto/corelib/io/qurl/.gitignore
new file mode 100644
index 0000000000..c2da731ecd
--- /dev/null
+++ b/tests/auto/corelib/io/qurl/.gitignore
@@ -0,0 +1 @@
+tst_qurl
diff --git a/tests/auto/corelib/io/qurl/idna-test.c b/tests/auto/corelib/io/qurl/idna-test.c
new file mode 100644
index 0000000000..7effd03168
--- /dev/null
+++ b/tests/auto/corelib/io/qurl/idna-test.c
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation 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$
+**
+****************************************************************************/
+
+struct idna
+{
+ char *name;
+ size_t inlen;
+ unsigned long in[100];
+ char *out;
+ int allowunassigned;
+ int usestd3asciirules;
+ int toasciirc;
+ int tounicoderc;
+} idnalist[] =
+{
+ {
+ "Arabic (Egyptian)", 17,
+ {
+ 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643,
+ 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A,
+ 0x061F},
+ IDNA_ACE_PREFIX "egbpdaj6bu4bxfgehfvwxn", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Chinese (simplified)", 9,
+ {
+ 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587},
+ IDNA_ACE_PREFIX "ihqwcrb4cv8a8dqg056pqjye", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Chinese (traditional)", 9,
+ {
+ 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587},
+ IDNA_ACE_PREFIX "ihqwctvzc91f659drss3x8bo0yb", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Czech", 22,
+ {
+ 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073,
+ 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076,
+ 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079},
+ IDNA_ACE_PREFIX "Proprostnemluvesky-uyb24dma41a", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Hebrew", 22,
+ {
+ 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5,
+ 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9,
+ 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA},
+ IDNA_ACE_PREFIX "4dbcagdahymbxekheh6e0a7fei0b", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Hindi (Devanagari)", 30,
+ {
+ 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928,
+ 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902,
+ 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938,
+ 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902},
+ IDNA_ACE_PREFIX "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd", 0, 0,
+ IDNA_SUCCESS
+ }, {
+ "Japanese (kanji and hiragana)", 18,
+ {
+ 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E,
+ 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044,
+ 0x306E, 0x304B},
+ IDNA_ACE_PREFIX "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa", 0, 0,
+ IDNA_SUCCESS
+ }, {
+ "Russian (Cyrillic)", 28,
+ {
+ 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435,
+ 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432,
+ 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443,
+ 0x0441, 0x0441, 0x043A, 0x0438},
+ IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l", 0, 0,
+ IDNA_SUCCESS, IDNA_SUCCESS
+ }, {
+ "Spanish", 40,
+ {
+ 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F,
+ 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069,
+ 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074,
+ 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065,
+ 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C},
+ IDNA_ACE_PREFIX "PorqunopuedensimplementehablarenEspaol-fmd56a", 0, 0,
+ IDNA_SUCCESS
+ }, {
+ "Vietnamese", 31,
+ {
+ 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD,
+ 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3,
+ 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069,
+ 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074},
+ IDNA_ACE_PREFIX "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g", 0, 0,
+ IDNA_SUCCESS
+ }, {
+ "Japanese", 8,
+ {
+ 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F},
+ IDNA_ACE_PREFIX "3B-ww4c5e180e575a65lsy2b", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Japanese", 24,
+ {
+ 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069,
+ 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052,
+ 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053},
+ IDNA_ACE_PREFIX "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n", 0, 0,
+ IDNA_SUCCESS
+ }, {
+ "Japanese", 25,
+ {
+ 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E,
+ 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061,
+ 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834,
+ 0x6240},
+ IDNA_ACE_PREFIX "Hello-Another-Way--fc4qua05auwb3674vfr0b", 0, 0,
+ IDNA_SUCCESS
+ }, {
+ "Japanese", 8,
+ {
+ 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032},
+ IDNA_ACE_PREFIX "2-u9tlzr9756bt3uc0v", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Japanese", 13,
+ {
+ 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069,
+ 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D},
+ IDNA_ACE_PREFIX "MajiKoi5-783gue6qz075azm5e", 0, 0, IDNA_SUCCESS,
+ IDNA_SUCCESS
+ }, {
+ "Japanese", 9,
+ {
+ 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0},
+ IDNA_ACE_PREFIX "de-jg4avhby1noc0d", 0, 0, IDNA_SUCCESS, IDNA_SUCCESS
+ }, {
+ "Japanese", 7,
+ {
+ 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067},
+ IDNA_ACE_PREFIX "d9juau41awczczp", 0, 0, IDNA_SUCCESS, IDNA_SUCCESS
+ }, {
+ "Greek", 8,
+ {0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac},
+ IDNA_ACE_PREFIX "hxargifdar", 0, 0, IDNA_SUCCESS, IDNA_SUCCESS
+ }, {
+ "Maltese (Malti)", 10,
+ {0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
+ 0x0127, 0x0061},
+ IDNA_ACE_PREFIX "bonusaa-5bb1da", 0, 0, IDNA_SUCCESS, IDNA_SUCCESS
+ }, {
+ "Russian (Cyrillic)", 28,
+ {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
+ 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
+ 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
+ 0x0441, 0x0441, 0x043a, 0x0438},
+ IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l", 0, 0,
+ IDNA_SUCCESS, IDNA_SUCCESS
+ }
+};
diff --git a/tests/auto/corelib/io/qurl/qurl.pro b/tests/auto/corelib/io/qurl/qurl.pro
new file mode 100644
index 0000000000..a43a57e002
--- /dev/null
+++ b/tests/auto/corelib/io/qurl/qurl.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES += tst_qurl.cpp
+QT = core core-private
+symbian: TARGET.CAPABILITY = NetworkServices
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
new file mode 100644
index 0000000000..d7f7742d46
--- /dev/null
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -0,0 +1,4049 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 <QtTest/QtTest>
+#include <QtCore/QDebug>
+
+#include <qcoreapplication.h>
+
+#include <qfileinfo.h>
+#include <qurl.h>
+#include <qtextcodec.h>
+#include <qmap.h>
+#include "private/qtldurl_p.h"
+
+// For testsuites
+#define IDNA_ACE_PREFIX "xn--"
+#define IDNA_SUCCESS 1
+#define STRINGPREP_NO_UNASSIGNED 1
+#define STRINGPREP_CONTAINS_UNASSIGNED 2
+#define STRINGPREP_CONTAINS_PROHIBITED 3
+#define STRINGPREP_BIDI_BOTH_L_AND_RAL 4
+#define STRINGPREP_BIDI_LEADTRAIL_NOT_RAL 5
+
+struct ushortarray {
+ ushortarray(unsigned short *array = 0)
+ {
+ if (array)
+ memcpy(points, array, sizeof(points));
+ }
+
+ unsigned short points[100];
+};
+
+Q_DECLARE_METATYPE(ushortarray)
+Q_DECLARE_METATYPE(QUrl::FormattingOptions)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QUrl : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QUrl();
+ virtual ~tst_QUrl();
+
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void effectiveTLDs_data();
+ void effectiveTLDs();
+ void getSetCheck();
+ void constructing();
+ void assignment();
+ void comparison();
+ void copying();
+ void setUrl();
+ void i18n_data();
+ void i18n();
+ void punycode_data();
+ void punycode();
+ void resolving_data();
+ void resolving();
+ void toString_data();
+ void toString();
+ void toString_constructed_data();
+ void toString_constructed();
+ void isParentOf_data();
+ void isParentOf();
+ void toLocalFile_data();
+ void toLocalFile();
+ void fromLocalFile_data();
+ void fromLocalFile();
+ void relative();
+ void compat_legacy();
+ void compat_constructor_01_data();
+ void compat_constructor_01();
+ void compat_constructor_02_data();
+ void compat_constructor_02();
+ void compat_constructor_03_data();
+ void compat_constructor_03();
+ void compat_isValid_01_data();
+ void compat_isValid_01();
+ void compat_isValid_02_data();
+ void compat_isValid_02();
+ void compat_path_data();
+ void compat_path();
+ void compat_fileName_data();
+ void compat_fileName();
+ void compat_decode_data();
+ void compat_decode();
+ void compat_encode_data();
+ void compat_encode();
+ void percentEncoding_data();
+ void percentEncoding();
+ void swap();
+ void symmetry();
+ void ipv6_data();
+ void ipv6();
+ void ipv6_2_data();
+ void ipv6_2();
+ void moreIpv6();
+ void toPercentEncoding_data();
+ void toPercentEncoding();
+ void isRelative_data();
+ void isRelative();
+ void queryItems();
+ void hasQuery_data();
+ void hasQuery();
+ void hasQueryItem_data();
+ void hasQueryItem();
+ void nameprep();
+ void isValid();
+ void schemeValidator_data();
+ void schemeValidator();
+ void invalidSchemeValidator();
+ void tolerantParser();
+ void correctEncodedMistakes_data();
+ void correctEncodedMistakes();
+ void correctDecodedMistakes_data();
+ void correctDecodedMistakes();
+ void idna_testsuite_data();
+ void idna_testsuite();
+ void nameprep_testsuite_data();
+ void nameprep_testsuite();
+ void nameprep_highcodes_data();
+ void nameprep_highcodes();
+ void ace_testsuite_data();
+ void ace_testsuite();
+ void std3violations_data();
+ void std3violations();
+ void std3deviations_data();
+ void std3deviations();
+ void tldRestrictions_data();
+ void tldRestrictions();
+ void emptyQueryOrFragment();
+ void hasFragment_data();
+ void hasFragment();
+ void setEncodedFragment_data();
+ void setEncodedFragment();
+ void fromEncoded();
+ void stripTrailingSlash();
+ void hosts_data();
+ void hosts();
+ void setPort();
+ void toEncoded_data();
+ void toEncoded();
+ void setAuthority_data();
+ void setAuthority();
+ void errorString();
+ void clear();
+ void resolvedWithAbsoluteSchemes() const;
+ void resolvedWithAbsoluteSchemes_data() const;
+ void binaryData_data();
+ void binaryData();
+ void fromUserInput_data();
+ void fromUserInput();
+ void task_199967();
+ void task_240612();
+ void taskQTBUG_6962();
+ void taskQTBUG_8701();
+ void removeAllEncodedQueryItems_data();
+ void removeAllEncodedQueryItems();
+};
+
+// Testing get/set functions
+void tst_QUrl::getSetCheck()
+{
+ QUrl obj1;
+ // int QUrl::port()
+ // void QUrl::setPort(int)
+ obj1.setPort(0);
+ QCOMPARE(0, obj1.port());
+
+ QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range");
+ obj1.setPort(INT_MIN);
+ QCOMPARE(-1, obj1.port()); // Out of range, -1
+
+ QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range");
+ obj1.setPort(INT_MAX);
+ QCOMPARE(-1, obj1.port()); // Out of range, -1
+
+ obj1.setPort(1234);
+ QCOMPARE(1234, obj1.port());
+
+ // static QStringList QUrl::idnWhitelist()
+ // static void QUrl::setIdnWhitelist(QStringList)
+ QStringList original = QUrl::idnWhitelist(); // save for later
+
+ QUrl::setIdnWhitelist(QStringList());
+ QCOMPARE(QUrl::idnWhitelist(), QStringList());
+
+ QStringList norway; norway << "no";
+ QUrl::setIdnWhitelist(norway);
+ QCOMPARE(QUrl::idnWhitelist(), norway);
+
+ QStringList modified = original;
+ modified << "foo";
+ QUrl::setIdnWhitelist(modified);
+ QCOMPARE(QUrl::idnWhitelist(), modified);
+
+ // reset to the original
+ QUrl::setIdnWhitelist(original);
+ QCOMPARE(QUrl::idnWhitelist(), original);
+}
+
+tst_QUrl::tst_QUrl()
+{
+}
+
+tst_QUrl::~tst_QUrl()
+{
+
+}
+
+void tst_QUrl::init()
+{
+}
+
+void tst_QUrl::cleanup()
+{
+}
+
+void tst_QUrl::constructing()
+{
+ QUrl url;
+ QVERIFY(!url.isValid());
+ QVERIFY(url.isEmpty());
+ QCOMPARE(url.port(), -1);
+ QCOMPARE(url.toString(), QString());
+
+ QList<QPair<QString, QString> > query;
+ query += qMakePair(QString("type"), QString("login"));
+ query += qMakePair(QString("name"), QString("åge nissemannsen"));
+ query += qMakePair(QString("ole&du"), QString("anne+jørgen=sant"));
+ query += qMakePair(QString("prosent"), QString("%"));
+ url.setQueryItems(query);
+ QVERIFY(!url.isEmpty());
+
+ QCOMPARE(url.encodedQuery().constData(),
+ QByteArray("type=login&name=%C3%A5ge%20nissemannsen&ole%26du="
+ "anne+j%C3%B8rgen%3Dsant&prosent=%25").constData());
+
+ url.setQueryDelimiters('>', '/');
+ url.setQueryItems(query);
+
+ QCOMPARE(url.encodedQuery(),
+ QByteArray("type>login/name>%C3%A5ge%20nissemannsen/ole&du>"
+ "anne+j%C3%B8rgen=sant/prosent>%25"));
+
+ url.setFragment(QString::fromLatin1("top"));
+ QCOMPARE(url.fragment(), QString::fromLatin1("top"));
+
+ url.setScheme("http");
+ url.setHost("qt.nokia.com");
+
+ QCOMPARE(url.toString(),
+ QString::fromLatin1("http://qt.nokia.com?type>login/name>åge nissemannsen"
+ "/ole&du>anne+jørgen=sant/prosent>%#top"));
+
+ QUrl justHost("qt.nokia.com");
+ QVERIFY(!justHost.isEmpty());
+ QVERIFY(justHost.host().isEmpty());
+ QCOMPARE(justHost.path(), QString::fromLatin1("qt.nokia.com"));
+
+ QUrl hostWithSlashes("//qt.nokia.com");
+ QVERIFY(hostWithSlashes.path().isEmpty());
+ QCOMPARE(hostWithSlashes.host(), QString::fromLatin1("qt.nokia.com"));
+
+
+ QUrl withHashInPath;
+ withHashInPath.setPath(QString::fromLatin1("hi#mum.txt"));
+ QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt"));
+ QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt"));
+ QUrl fromHashInPath = QUrl::fromEncoded(withHashInPath.toEncoded());
+ QVERIFY(withHashInPath == fromHashInPath);
+
+
+ QUrl buildUNC;
+ buildUNC.setScheme(QString::fromLatin1("file"));
+ buildUNC.setHost(QString::fromLatin1("somehost"));
+ buildUNC.setPath(QString::fromLatin1("somepath"));
+ QCOMPARE(buildUNC.toLocalFile(), QString::fromLatin1("//somehost/somepath"));
+ buildUNC.toEncoded();
+ QVERIFY(!buildUNC.isEmpty());
+}
+
+void tst_QUrl::assignment()
+{
+ QUrl url("http://qt.nokia.com/");
+ QVERIFY(url.isValid());
+
+ QUrl copy;
+ copy = url;
+
+ QVERIFY(url == copy);
+}
+
+void tst_QUrl::comparison()
+{
+ QUrl url1("http://qt.nokia.com/");
+ QVERIFY(url1.isValid());
+
+ QUrl url2("http://qt.nokia.com/");
+ QVERIFY(url2.isValid());
+
+ QVERIFY(url1 == url2);
+
+ // 6.2.2 Syntax-based Normalization
+ QUrl url3 = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D");
+ QUrl url4 = QUrl::fromEncoded("eXAMPLE://a/./b/../b/%63/%7bfoo%7d");
+ QVERIFY(url3 == url4);
+
+ // 6.2.2.1 Make sure hexdecimal characters in percent encoding are
+ // treated case-insensitively
+ QUrl url5;
+ url5.setEncodedQuery("a=%2a");
+ QUrl url6;
+ url6.setEncodedQuery("a=%2A");
+ QVERIFY(url5 == url6);
+
+ // ensure that encoded characters in the query do not match
+ QUrl url7;
+ url7.setEncodedQuery("a=%63");
+ QUrl url8;
+ url8.setEncodedQuery("a=c");
+ QVERIFY(url7 != url8);
+}
+
+void tst_QUrl::copying()
+{
+ QUrl url("http://qt.nokia.com/");
+ QVERIFY(url.isValid());
+
+ QUrl copy(url);
+
+ QVERIFY(url == copy);
+}
+
+void tst_QUrl::setUrl()
+{
+ {
+ QUrl url("http://0.foo.com");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString::fromLatin1("http"));
+ QCOMPARE(url.path(), QString());
+ QCOMPARE(url.host(), QString::fromLatin1("0.foo.com"));
+ }
+
+ {
+ QUrl url("file:/");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString::fromLatin1("file"));
+ QCOMPARE(url.path(), QString::fromLatin1("/"));
+ QVERIFY(url.encodedQuery().isEmpty());
+ QVERIFY(url.userInfo().isEmpty());
+ QVERIFY(url.authority().isEmpty());
+ QVERIFY(url.fragment().isEmpty());
+ QCOMPARE(url.port(), -1);
+ }
+
+ {
+ QUrl url("hTTp://www.foo.bar:80");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString::fromLatin1("hTTp"));
+ QCOMPARE(url.path(), QString());
+ QVERIFY(url.encodedQuery().isEmpty());
+ QVERIFY(url.userInfo().isEmpty());
+ QVERIFY(url.fragment().isEmpty());
+ QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar"));
+ QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80"));
+ QCOMPARE(url.port(), 80);
+
+ QUrl url2("//www1.foo.bar");
+ QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("hTTp://www1.foo.bar"));
+ }
+
+ {
+ QUrl url("http://user:pass@[56::56:56:56:127.0.0.1]:99");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString::fromLatin1("http"));
+ QCOMPARE(url.path(), QString());
+ QVERIFY(url.encodedQuery().isEmpty());
+ QCOMPARE(url.userInfo(), QString::fromLatin1("user:pass"));
+ QVERIFY(url.fragment().isEmpty());
+ QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:127.0.0.1"));
+ QCOMPARE(url.authority(), QString::fromLatin1("user:pass@[56::56:56:56:127.0.0.1]:99"));
+ QCOMPARE(url.port(), 99);
+ }
+
+ {
+ QUrl url("http://www.foo.bar");
+ QVERIFY(url.isValid());
+
+ QUrl url2("/top//test/../test1/file.html");
+ QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www.foo.bar/top//test1/file.html"));
+ }
+
+ {
+ QUrl url("http://www.foo.bar");
+ QVERIFY(url.isValid());
+
+ QUrl url2("/top//test/../test1/file.html");
+ QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www.foo.bar/top//test1/file.html"));
+ }
+
+ {
+ QUrl url("http://www.foo.bar/top//test2/file2.html");
+ QVERIFY(url.isValid());
+
+ QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar/top//test2/file2.html"));
+ }
+
+ {
+ QUrl url("http://www.foo.bar/top//test2/file2.html");
+ QVERIFY(url.isValid());
+
+ QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar/top//test2/file2.html"));
+ }
+
+ {
+ QUrl url("file:/usr/local/src/kde2/////kdelibs/kio");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toString(), QString::fromLatin1("file:///usr/local/src/kde2/////kdelibs/kio"));
+ }
+
+ {
+ QUrl url("http://www.foo.bar");
+ QVERIFY(url.isValid());
+
+ QUrl url2("mailto:bastian@kde.org");
+ QVERIFY(url2.isValid());
+ QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("mailto:bastian@kde.org"));
+ }
+
+ {
+ QUrl url("mailto:bastian@kde.org?subject=hello");
+ QCOMPARE(url.toString(), QString::fromLatin1("mailto:bastian@kde.org?subject=hello"));
+ }
+
+ {
+ QUrl url("file:/usr/local/src/kde2/kdelibs/kio/");
+ QVERIFY(url.isValid());
+
+ QUrl url2("../../////kdebase/konqueror");
+ QCOMPARE(url.resolved(url2).toString(),
+ QString::fromLatin1("file:///usr/local/src/kde2/////kdebase/konqueror"));
+ }
+
+ {
+ QString u1 = "file:/home/dfaure/my#myref";
+ QUrl url = u1;
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref"));
+ QCOMPARE(url.fragment(), QString::fromLatin1("myref"));
+ }
+
+ {
+ QString u1 = "file:/home/dfaure/my#myref";
+ QUrl url = u1;
+ QVERIFY(url.isValid());
+
+ QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref"));
+ QCOMPARE(url.fragment(), QString::fromLatin1("myref"));
+ }
+
+ {
+ QUrl url("gg:www.kde.org");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString::fromLatin1("gg"));
+ QVERIFY(url.host().isEmpty());
+ QCOMPARE(url.path(), QString::fromLatin1("www.kde.org"));
+ }
+
+ {
+ QUrl url("KDE");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.path(), QString::fromLatin1("KDE"));
+ QVERIFY(url.scheme().isEmpty());
+ }
+
+ {
+ QUrl url("$HOME/.kde/share/config");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.path(), QString::fromLatin1("$HOME/.kde/share/config"));
+ QVERIFY(url.scheme().isEmpty());
+ }
+
+ {
+ QUrl url("file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.fragment(), QString::fromLatin1("QObject::connect"));
+ }
+
+ {
+ QUrl url("file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.fragment(), QString::fromLatin1("QObject:connect"));
+ }
+
+ {
+ // suburls
+ QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/#myref");
+ QVERIFY(url.isValid());
+
+ // or simply 'myref?'
+ QCOMPARE(url.fragment(), QString::fromLatin1("gzip:/#tar:/#myref"));
+ }
+
+ {
+ QUrl url("error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.fragment(), QString::fromLatin1("http://asdfu.adgi.sdfgoi"));
+ }
+
+ {
+ // suburls
+ QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/");
+ QVERIFY(url.isValid());
+ }
+
+ {
+ QUrl url("file:/home/dfaure/cdrdao-1.1.5/dao/#CdrDriver.cc#");
+ QVERIFY(url.isValid());
+ }
+
+ {
+ QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my tar file.tgz#gzip:/#tar:/README"));
+ }
+
+ {
+ QUrl notPretty;
+ notPretty.setEncodedUrl("http://ferret.lmh.ox.ac.uk/%7Ekdecvs/");
+ QVERIFY(notPretty.isValid());
+ QCOMPARE(notPretty.toString(), QString::fromLatin1("http://ferret.lmh.ox.ac.uk/~kdecvs/"));
+
+ QUrl notPretty2;
+ notPretty2.setEncodedUrl("file:/home/test/directory%20with%20spaces");
+ QVERIFY(notPretty2.isValid());
+ QCOMPARE(notPretty2.toString(), QString::fromLatin1("file:///home/test/directory with spaces"));
+
+ QUrl notPretty3("fish://foo/%23README%23");
+ QVERIFY(notPretty3.isValid());
+ QCOMPARE(notPretty3.toString(), QString::fromLatin1("fish://foo/%23README%23"));
+
+ QUrl url15581;
+ url15581.setUrl("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html");
+ QCOMPARE(url15581.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html"));
+ QCOMPARE(url15581.toEncoded().constData(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/spaces%20in%20url.html").constData());
+
+ QUrl url15582("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html");
+ QCOMPARE(url15582.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html"));
+ QCOMPARE(url15582.toEncoded(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html"));
+ }
+
+ {
+ QUrl carsten;
+ carsten.setPath("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18");
+ QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18"));
+
+ QUrl charles;
+ charles.setPath("/home/charles/foo%20moo");
+ QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo%20moo"));
+
+ QUrl charles2;
+ charles2.setEncodedUrl("file:/home/charles/foo%20moo");
+ QCOMPARE(charles2.path(), QString::fromLatin1("/home/charles/foo moo"));
+ }
+
+ {
+ QUrl udir;
+ QCOMPARE(udir.toEncoded(), QByteArray());
+ QVERIFY(!udir.isValid());
+
+ udir = QUrl::fromLocalFile("/home/dfaure/file.txt");
+ QCOMPARE(udir.path(), QString::fromLatin1("/home/dfaure/file.txt"));
+ QCOMPARE(udir.toEncoded(), QByteArray("file:///home/dfaure/file.txt"));
+ }
+
+ {
+ QUrl url;
+ url.setUrl("hello.com#?");
+ QVERIFY(url.isValid());
+ url.setUrl("hello.com");
+ QVERIFY(!url.toString().contains(QLatin1Char('#')));
+ QVERIFY(!url.toString().contains(QLatin1Char('?')));
+ }
+
+ {
+ QUrl url;
+ url.setUrl("http://1.2.3.4.example.com");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString("http"));
+ QCOMPARE(url.host(), QString("1.2.3.4.example.com"));
+ }
+
+ {
+ QUrl url;
+ url.setUrl("http://1.2.3.4");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString("http"));
+ QCOMPARE(url.host(), QString("1.2.3.4"));
+ }
+ {
+ QUrl url;
+ url.setUrl("http://1.2.3.4/");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString("http"));
+ QCOMPARE(url.host(), QString("1.2.3.4"));
+ QCOMPARE(url.path(), QString("/"));
+ }
+ {
+ QUrl url;
+ url.setUrl("http://1.2.3.4?foo");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString("http"));
+ QCOMPARE(url.host(), QString("1.2.3.4"));
+ QCOMPARE(url.encodedQuery(), QByteArray("foo"));
+ }
+ {
+ QUrl url;
+ url.setUrl("http://1.2.3.4#bar");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString("http"));
+ QCOMPARE(url.host(), QString("1.2.3.4"));
+ QCOMPARE(url.fragment(), QString("bar"));
+ }
+
+ {
+ QUrl url;
+ url.setEncodedUrl("data:text/javascript,d5%20%3D%20'five\\u0027s'%3B");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.scheme(), QString("data"));
+ QCOMPARE(url.host(), QString());
+ QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';"));
+ QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B");
+ }
+
+ { //check it calls detach
+ QUrl u1("http://aaa.com");
+ QUrl u2 = u1;
+ u2.setUrl("http://bbb.com");
+ QCOMPARE(u1.host(), QString::fromLatin1("aaa.com"));
+ QCOMPARE(u2.host(), QString::fromLatin1("bbb.com"));
+ }
+
+/*
+ The tests below are copied from kdelibs/kdecore/tests/kurltest.cpp (an old version of)
+
+ Copyright (c) 1999-2005 Waldo Bastian <bastian@kde.org>
+ Copyright (c) 2000-2005 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+/*
+ ### File / directory specifics
+
+ KURL u2( QCString("/home/dfaure/") );
+ printf("\n* URL is %s\n",u2.url().ascii());
+// not ignoring trailing slash
+ check("KURL::directory(false,false)", u2.directory(false,false), "/home/dfaure/");
+ check("KURL::directory(true,false)", u2.directory(true,false), "/home/dfaure");
+// ignoring trailing slash
+ check("KURL::directory(false,true)", u2.directory(false,true), "/home/");
+ check("KURL::directory(true,true)", u2.directory(true,true), "/home");
+ u2.cd("..");
+ check("KURL::cd(\"..\")", u2.url(), "file:/home");
+ u2.cd("thomas");
+ check("KURL::cd(\"thomas\")", u2.url(), "file:/home/thomas");
+ u2.cd("/opt/kde/bin/");
+ check("KURL::cd(\"/opt/kde/bin/\")", u2.url(), "file:/opt/kde/bin/");
+ u2 = "ftp://ftp.kde.org/";
+ printf("\n* URL is %s\n",u2.url().ascii());
+ u2.cd("pub");
+ check("KURL::cd(\"pub\")", u2.url(), "ftp://ftp.kde.org/pub");
+ u2 = u2.upURL();
+ check("KURL::upURL()", u2.url(), "ftp://ftp.kde.org/");
+ u2 = u1;
+ printf("\n* URL is %s\n",u2.url().ascii());
+// setFileName
+ u2.setFileName( "myfile.txt" );
+ check("KURL::setFileName()", u2.url(), "file:/home/dfaure/myfile.txt");
+ u2.setFileName( "myotherfile.txt" );
+ check("KURL::setFileName()", u2.url(), "file:/home/dfaure/myotherfile.txt");
+// more tricky, renaming a directory (kpropsdlg.cc, line ~ 238)
+ QString tmpurl = "file:/home/dfaure/myolddir/";
+ if ( tmpurl.at(tmpurl.length() - 1) == '/')
+// It's a directory, so strip the trailing slash first
+ tmpurl.truncate( tmpurl.length() - 1);
+ KURL newUrl = tmpurl;
+ newUrl.setFileName( "mynewdir" );
+ check("KURL::setFileName() special", newUrl.url(), "file:/home/dfaure/mynewdir");
+// addPath tests
+ newUrl.addPath( "subdir" );
+ check("KURL::addPath(\"subdir\")", newUrl.url(), "file:/home/dfaure/mynewdir/subdir");
+ newUrl.addPath( "/foo/" );
+ check("KURL::addPath(\"/foo/\")", newUrl.url(), "file:/home/dfaure/mynewdir/subdir/foo/");
+ u2 = "http://www.kde.org"; // no path
+ u2.addPath( "subdir" );
+ check("KURL::addPath(\"subdir\")", u2.url(), "http://www.kde.org/subdir");
+ u2.addPath( "" );
+ check("KURL::addPath(\"subdir\")", u2.url(), "http://www.kde.org/subdir"); // unchanged
+
+// even more tricky
+ u2 = "print:/specials/Print%20To%20File%20(PDF%2FAcrobat)";
+ printf("\n* URL is %s\n",u2.url().ascii());
+ check("KURL::path()", u2.path(), "/specials/Print To File (PDF/Acrobat)");
+ check("KURL::fileName()", u2.fileName(), "Print To File (PDF/Acrobat)");
+ u2.setFileName( "" );
+ check("KURL::setFileName()", u2.url(), "print:/specials/");
+
+ u2 = "file:/specials/Print";
+ printf("\n* URL is %s\n",u2.url().ascii());
+ check("KURL::path()", u2.path(), "/specials/Print");
+ check("KURL::fileName()", u2.fileName(), "Print");
+ u2.setFileName( "" );
+ check("KURL::setFileName()", u2.url(), "file:/specials/");
+
+ const char * u3 = "ftp://host/dir1/dir2/myfile.txt";
+ printf("\n* URL is %s\n",u3);
+ check("KURL::hasSubURL()", KURL(u3).hasSubURL() ? "yes" : "no", "no");
+ lst.clear();
+ lst = KURL::split( KURL(u3) );
+ check("KURL::split()", lst.count()==1 ? "1" : "error", "1");
+ check("KURL::split()", lst.first().url(), "ftp://host/dir1/dir2/myfile.txt");
+// cdUp code
+ KURL lastUrl = lst.last();
+ QString dir = lastUrl.directory( true, true );
+ check( "KURL::directory(true,true)", dir, "/dir1/dir2");
+*/
+
+ {
+ // !!! FAILS
+// QString ucmp1 = "ftp://ftp.de.kde.org/dir";
+// QString ucmp2 = "ftp://ftp.de.kde.org/dir/";
+// QVERIFY(QUrl(ucmp1) == QUrl(ucmp2));
+ }
+
+
+ /*
+/// Comparisons
+ QString ucmp1 = "ftp://ftp.de.kde.org/dir";
+ QString ucmp2 = "ftp://ftp.de.kde.org/dir/";
+ check("urlcmp(only slash difference)", urlcmp(ucmp1,ucmp2)?"ko":"ok","ok");
+ check("urlcmp(only slash difference, ignore_trailing)", urlcmp(ucmp1,ucmp2,true,false)?"ok":"ko","ok");
+ QString ucmp3 = "ftp://ftp.de.kde.org/dir/#";
+ check("urlcmp(only hash difference)", urlcmp(ucmp2,ucmp3)?"ko":"ok","ok");
+ check("urlcmp(only hash difference, ignore_ref)", urlcmp(ucmp2,ucmp3,false,true)?"ok":"ko","ok");
+ check("urlcmp(slash and hash difference, ignore_trailing, ignore_ref)", urlcmp(ucmp2,ucmp3,true,true)?"ok":"ko","ok");
+ check("urlcmp(empty, empty)", urlcmp("","",false,true)?"ok":"ko","ok");
+ check("urlcmp(empty, empty)", urlcmp("","")?"ok":"ko","ok");
+ check("urlcmp(empty, not empty)", urlcmp("",ucmp1)?"ok":"ko","ko");
+ check("urlcmp(empty, not empty)", urlcmp("",ucmp1,false,true)?"ok":"ko","ko");
+ check("urlcmp(malformed, not empty)", urlcmp("file",ucmp1)?"ok":"ko","ko");
+ check("urlcmp(malformed, not empty)", urlcmp("file",ucmp1,false,true)?"ok":"ko","ko");
+
+ KURL ftpUrl ( "ftp://ftp.de.kde.org" );
+ printf("\n* URL is %s\n",ftpUrl.url().latin1());
+ check("KURL::path()", ftpUrl.path(), QString());
+ ftpUrl = "ftp://ftp.de.kde.org/";
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp.de.kde.org/host/subdir/") ? "yes" : "no", "yes");
+ ftpUrl = "ftp://ftp/host/subdir/";
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir/") ? "yes" : "no", "yes");
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir") ? "yes" : "no", "yes");
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdi") ? "yes" : "no", "no");
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir/blah/") ? "yes" : "no", "yes");
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/blah/subdir") ? "yes" : "no", "no");
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "file://ftp/host/subdir/") ? "yes" : "no", "no");
+ check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir/subsub") ? "yes" : "no", "yes");
+
+// WABA: The following tests are to test the handling of relative URLs as
+// found on web-pages.
+
+ KURL waba1( "http://www.website.com/directory/?hello#ref" );
+ {
+ KURL waba2( waba1, "relative.html");
+ check("http: Relative URL, single file", waba2.url(), "http://www.website.com/directory/relative.html");
+ }
+ {
+ KURL waba2( waba1, "../relative.html");
+ check("http: Relative URL, single file, directory up", waba2.url(), "http://www.website.com/relative.html");
+ }
+ {
+ KURL waba2( waba1, "down/relative.html");
+ check("http: Relative URL, single file, directory down", waba2.url(), "http://www.website.com/directory/down/relative.html");
+ }
+ {
+ KURL waba2( waba1, "/down/relative.html");
+ check("http: Relative URL, full path", waba2.url(), "http://www.website.com/down/relative.html");
+ }
+ {
+ KURL waba2( waba1, "//www.kde.org/relative.html");
+ check("http: Relative URL, with host", waba2.url(), "http://www.kde.org/relative.html");
+ }
+ {
+ KURL waba2( waba1, "relative.html?query=test&name=harry");
+ check("http: Relative URL, with query", waba2.url(), "http://www.website.com/directory/relative.html?query=test&name=harry");
+ waba2.removeQueryItem("query");
+ check("http: Removing query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry");
+ waba2.addQueryItem("age", "18");
+ check("http: Adding query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry&age=18");
+ waba2.addQueryItem("age", "21");
+ check("http: Adding query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry&age=18&age=21");
+ waba2.addQueryItem("fullname", "Harry Potter");
+ check("http: Adding query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry&age=18&age=21&fullname=Harry%20Potter");
+ }
+ {
+ KURL waba2( waba1, "?query=test&name=harry");
+ check("http: Relative URL, with query and no filename", waba2.url(), "http://www.website.com/directory/?query=test&name=harry");
+ }
+ {
+ KURL waba2( waba1, "relative.html#with_reference");
+ check("http: Relative URL, with reference", waba2.url(), "http://www.website.com/directory/relative.html#with_reference");
+ }
+ {
+ KURL waba2( waba1, "#");
+ check("http: Relative URL, with empty reference", waba2.url(), "http://www.website.com/directory/?hello#");
+ }
+ {
+ KURL waba2( waba1, "");
+ check("http: Empty relative URL", waba2.url(), "http://www.website.com/directory/?hello#ref");
+ }
+ {
+ KURL base( "http://faure@www.kde.org" ); // no path
+ KURL waba2( base, "filename.html");
+ check("http: Relative URL, orig URL had no path", waba2.url(), "http://faure@www.kde.org/filename.html");
+ }
+ {
+ KURL base( "http://faure:pass@www.kde.org:81?query" );
+ KURL rel1( base, "http://www.kde.org/bleh/"); // same host
+ check("http: Relative URL, orig URL had username", rel1.url(), "http://faure:pass@www.kde.org/bleh/");
+ KURL rel2( base, "http://www.yahoo.org"); // different host
+ check("http: Relative URL, orig URL had username", rel2.url(), "http://www.yahoo.org");
+ }
+
+ waba1 = "http://www.website.com/directory/filename?bla#blub";
+ {
+ KURL waba2( waba1, "relative.html");
+ check("http: Relative URL, single file", waba2.url(), "http://www.website.com/directory/relative.html");
+ }
+ {
+ KURL waba2( waba1, "../relative.html");
+ check("http: Relative URL, single file, directory up", waba2.url(), "http://www.website.com/relative.html");
+ }
+ {
+ KURL waba2( waba1, "down/relative.html");
+ check("http: Relative URL, single file, directory down", waba2.url(), "http://www.website.com/directory/down/relative.html");
+ }
+ {
+ KURL waba2( waba1, "/down/relative.html");
+ check("http: Relative URL, full path", waba2.url(), "http://www.website.com/down/relative.html");
+ }
+ {
+ KURL waba2( waba1, "relative.html?query=test&name=harry");
+ check("http: Relative URL, with query", waba2.url(), "http://www.website.com/directory/relative.html?query=test&name=harry");
+ }
+ {
+ KURL waba2( waba1, "?query=test&name=harry");
+ check("http: Relative URL, with query and no filename", waba2.url(), "http://www.website.com/directory/filename?query=test&name=harry");
+ }
+ {
+ KURL waba2( waba1, "relative.html#with_reference");
+ check("http: Relative URL, with reference", waba2.url(), "http://www.website.com/directory/relative.html#with_reference");
+ }
+ {
+ KURL waba2( waba1, "http:/relative.html"); // "rfc 1606 loophole"
+ check("http: Strange relative URL", waba2.url(), "http://www.website.com/relative.html");
+ }
+ waba1.setUser("waldo");
+ check("http: Set user", waba1.url(), "http://waldo@www.website.com/directory/filename?bla#blub");
+ waba1.setUser("waldo/bastian");
+ check("http: Set user with slash in it", waba1.url(), "http://waldo%2Fbastian@www.website.com/directory/filename?bla#blub");
+ waba1.setRef( QString() );
+ waba1.setPass( "pass" );
+ waba1.setDirectory( "/foo" );
+ waba1.setProtocol( "https" );
+ waba1.setHost( "web.com" );
+ waba1.setPort( 881 );
+ check("http: setRef/setPass/setDirectory/setHost/setPort", waba1.url(), "https://waldo%2Fbastian:pass@web.com:881/foo/?bla");
+ waba1.setDirectory( "/foo/" );
+ check("http: setDirectory #2", waba1.url(), "https://waldo%2Fbastian:pass@web.com:881/foo/?bla");
+
+// Empty queries should be preserved!
+ waba1 = "http://www.kde.org/cgi/test.cgi?";
+ check("http: URL with empty query string", waba1.url(),
+ "http://www.kde.org/cgi/test.cgi?");
+
+// Empty references should be preserved
+ waba1 = "http://www.kde.org/cgi/test.cgi#";
+ check("http: URL with empty reference string", waba1.url(),
+ "http://www.kde.org/cgi/test.cgi#");
+ check("hasRef()", waba1.hasRef()?"true":"false","true");
+ check("hasHTMLRef()", waba1.hasHTMLRef()?"true":"false","true");
+ check("encodedHtmlRef()", waba1.encodedHtmlRef(),QString());
+
+// URLs who forgot to encode spaces in the query.
+ waba1 = "http://www.kde.org/cgi/test.cgi?hello=My Value";
+ check("http: URL with incorrect encoded query", waba1.url(),
+ "http://www.kde.org/cgi/test.cgi?hello=My%20Value");
+
+// URL with ':' in query (':' should NOT be encoded!)
+ waba1.setQuery("hello:My Value");
+ check("http: URL with ':' in query", waba1.url(),
+ "http://www.kde.org/cgi/test.cgi?hello:My%20Value");
+ check("upURL() removes query", waba1.upURL().url(),
+ "http://www.kde.org/cgi/test.cgi");
+
+// URLs who forgot to encode spaces in the query.
+ waba1 = "http://www.kde.org/cgi/test.cgi?hello=My Value+20";
+ check("http: URL with incorrect encoded query", waba1.url(),
+ "http://www.kde.org/cgi/test.cgi?hello=My%20Value+20");
+
+// Urls without path (BR21387)
+ waba1 = "http://meine.db24.de?link=home_c_login_login";
+ check("http: URL with empty path string", waba1.url(),
+ "http://meine.db24.de?link=home_c_login_login");
+ check("http: URL with empty path string path", waba1.path(),
+ "");
+ check("http: URL with empty path string query", waba1.query(),
+ "?link=home_c_login_login");
+
+ waba1 = "http://a:389?b=c";
+ check( "http: URL with port, query, and empty path; url", waba1.url(), "http://a:389?b=c" );
+ check( "http: URL with port, query, and empty path; host", waba1.host(), "a" );
+ check( "http: URL with port, query, and empty path; port", QString::number( waba1.port() ), "389" );
+ check( "http: URL with port, query, and empty path; path", waba1.path(), "" );
+ check( "http: URL with port, query, and empty path; query", waba1.query(), "?b=c" );
+
+// Urls without path (BR21387)
+ waba1 = "http://meine.db24.de#link=home_c_login_login";
+ check("http: URL with empty path string", waba1.url(),
+ "http://meine.db24.de#link=home_c_login_login");
+ check("http: URL with empty path string path", waba1.path(),
+ "");
+
+ waba1 = "http://a:389#b=c";
+ check( "http: URL with port, ref, and empty path; url", waba1.url(), "http://a:389#b=c" );
+ check( "http: URL with port, ref, and empty path; host", waba1.host(), "a" );
+ check( "http: URL with port, ref, and empty path; port", QString::number( waba1.port() ), "389" );
+ check( "http: URL with port, ref, and empty path; path", waba1.path(), "" );
+ check( "http: URL with port, ref, and empty path; ref", waba1.ref(), "b=c" );
+ check( "http: URL with port, ref, and empty path; query", waba1.query(), "" );
+
+// IPV6
+ waba1 = "http://[::FFFF:129.144.52.38]:81/index.html";
+ check("http: IPV6 host", waba1.host(),
+ "::ffff:129.144.52.38");
+ check("http: IPV6 port", QString("%1").arg(waba1.port()),
+ "81");
+
+// IPV6
+ waba1 = "http://waba:pass@[::FFFF:129.144.52.38]:81/index.html";
+ check("http: IPV6 host", waba1.host(),
+ "::ffff:129.144.52.38");
+ check("http: IPV6 host", waba1.user(),
+ "waba");
+ check("http: IPV6 host", waba1.pass(),
+ "pass");
+ check("http: IPV6 port", QString("%1").arg(waba1.port()),
+ "81");
+
+// IPV6
+ waba1 = "http://www.kde.org/cgi/test.cgi";
+ waba1.setHost("::ffff:129.144.52.38");
+ check("http: IPV6 host", waba1.url(),
+ "http://[::ffff:129.144.52.38]/cgi/test.cgi");
+ waba1 = "http://[::ffff:129.144.52.38]/cgi/test.cgi";
+ assert( waba1.isValid() );
+
+// IPV6 without path
+ waba1 = "http://[::ffff:129.144.52.38]?query";
+ assert( waba1.isValid() );
+ check("http: IPV6 without path", waba1.url(),
+ "http://[::ffff:129.144.52.38]?query");
+ check("http: IPV6 without path; query", waba1.query(),
+ "?query");
+ waba1 = "http://[::ffff:129.144.52.38]#ref";
+ assert( waba1.isValid() );
+ check("http: IPV6 without path", waba1.url(),
+ "http://[::ffff:129.144.52.38]#ref");
+ check("http: IPV6 without path; ref", waba1.ref(),
+ "ref");
+// IPV6 without path but with a port
+ waba1 = "http://[::ffff:129.144.52.38]:81?query";
+ assert( waba1.isValid() );
+ check("http: IPV6 without path", waba1.url(),
+ "http://[::ffff:129.144.52.38]:81?query");
+ check("http: IPV6 without path; port", QString::number( waba1.port() ), "81" );
+ check("http: IPV6 without path; query", waba1.query(), "?query");
+ waba1 = "http://[::ffff:129.144.52.38]:81#ref";
+ assert( waba1.isValid() );
+ check("http: IPV6 without path", waba1.url(),
+ "http://[::ffff:129.144.52.38]:81#ref");
+ check("http: IPV6 without path; port", QString::number( waba1.port() ), "81" );
+ check("http: IPV6 without path; ref", waba1.ref(), "ref");
+
+// Streaming operators
+ KURL origURL( "http://www.website.com/directory/?#ref" );
+ waba1 = "http://[::ffff:129.144.52.38]:81?query";
+ QByteArray buffer;
+ {
+ QDataStream stream( buffer, QIODevice::WriteOnly );
+ stream << origURL
+ << KURL( "file:" ) // an invalid one
+ << waba1; // the IPv6 one
+ }
+ {
+ QDataStream stream( buffer, QIODevice::ReadOnly );
+ KURL restoredURL;
+ stream >> restoredURL;
+ check( "Streaming valid URL", origURL.url(), restoredURL.url() );
+ stream >> restoredURL;
+ check( "Streaming invalid URL", restoredURL.isValid()?"valid":"malformed", "malformed" );
+ check( "Streaming invalid URL", restoredURL.url(), "file:" );
+ stream >> restoredURL;
+ check( "Streaming ipv6 URL with query", restoredURL.url(), waba1.url() );
+ }
+
+// Broken stuff
+ waba1 = "file:a";
+ check("Broken stuff #1 path", waba1.path(), "a");
+ check("Broken stuff #1 fileName(false)", waba1.fileName(false), "a");
+ check("Broken stuff #1 fileName(true)", waba1.fileName(true), "a");
+ check("Broken stuff #1 directory(false, false)", waba1.directory(false, false), "");
+ check("Broken stuff #1 directory(true, false)", waba1.directory(true, false), "");
+ check("Broken stuff #1 directory(false, true)", waba1.directory(true, true), "");
+
+ waba1 = "file:a/";
+ check("Broken stuff #2 path", waba1.path(), "a/");
+ check("Broken stuff #2 fileName(false)", waba1.fileName(false), "");
+ check("Broken stuff #2 fileName(true)", waba1.fileName(true), "a");
+ check("Broken stuff #2 directory(false, false)", waba1.directory(false, false), "a/");
+ check("Broken stuff #2 directory(true, false)", waba1.directory(true, false), "a");
+ check("Broken stuff #2 directory(false, true)", waba1.directory(true, true), "");
+
+ waba1 = "file:";
+ check("Broken stuff #3 empty", waba1.isEmpty()?"EMPTY":"NOT", "NOT");
+ check("Broken stuff #3 valid", waba1.isValid()?"VALID":"MALFORMED", "MALFORMED");
+ check("Broken stuff #3 path", waba1.path(), "");
+ check("Broken stuff #3 fileName(false)", waba1.fileName(false), "");
+ check("Broken stuff #3 fileName(true)", waba1.fileName(true), "");
+ check("Broken stuff #3 directory(false, false)", waba1.directory(false, false), "");
+ check("Broken stuff #3 directory(true, false)", waba1.directory(true, false), "");
+ check("Broken stuff #3 directory(false, true)", waba1.directory(true, true), "");
+ KURL broken;
+ broken.setPath( QString() );
+ check("Broken stuff #4 empty", broken.isEmpty()?"EMPTY":"NOT", "NOT");
+// It's valid: because isValid refers to parsing, not to what happens afterwards.
+ check("Broken stuff #4 valid", broken.isValid()?"VALID":"MALFORMED", "VALID");
+ check("Broken stuff #4 path", broken.path(), "");
+ broken = "file://"; // just because coolo wondered
+ check("Broken stuff #5 empty", broken.isEmpty()?"EMPTY":"NOT", "NOT");
+ check("Broken stuff #5 valid", broken.isValid()?"VALID":"MALFORMED", "MALFORMED");
+ check("Broken stuff #5 path", broken.path(), "");
+ broken = "file";
+ check("Broken stuff #6 valid", broken.isValid()?"VALID":"MALFORMED", "MALFORMED");
+
+#if 0 // BROKEN?
+// UNC like names
+ KURL unc1("FILE://localhost/home/root");
+ check("UNC, with localhost", unc1.path(), "/home/root");
+ check("UNC, with localhost", unc1.url(), "file:/home/root");
+#endif
+ KURL unc2("file:///home/root");
+ check("UNC, with empty host", unc2.path(), "/home/root");
+ check("UNC, with empty host", unc2.url(), "file:/home/root");
+
+ {
+ KURL unc3("FILE://remotehost/home/root");
+#if 0 // BROKEN?
+ check("UNC, with remote host", unc3.path(), "//remotehost/home/root");
+#endif
+ check("UNC, with remote host", unc3.url(), "file://remotehost/home/root");
+ KURL url2("file://atlas/dfaure");
+ check("KURL::host()", url2.host(), "atlas");
+ check("KURL::path()", url2.path(), "/dfaure");
+ //check("KURL::path()", url3.path(), "//atlas/dfaure"); // says Waba
+ //KURL url3("file:////atlas/dfaure");
+ //check("KURL::path()", url3.path(), "//atlas/dfaure"); // says Waba
+ }
+
+ KURL umail1 ( "mailto:faure@kde.org" );
+ check("mailto: URL, general form", umail1.protocol(), "mailto");
+ check("mailto: URL, general form", umail1.path(), "faure@kde.org");
+ check("mailto: URL, is relative", KURL::isRelativeURL("mailto:faure@kde.org") ? "true" : "false", "false");
+ KURL umail2 ( "mailto:Faure David <faure@kde.org>" );
+ check("mailto: URL, general form", umail2.protocol(), "mailto");
+ check("mailto: URL, general form", umail2.path(), "Faure David <faure@kde.org>");
+ check("isRelativeURL(\"mailto:faure@kde.org\")", KURL::isRelativeURL("mailto:faure@kde.org") ? "yes" : "no", "no");
+ KURL umail3 ( "mailto:" );
+ check("mailto: invalid URL", umail3.isValid()?"valid":"malformed", "malformed");
+
+ check("man: URL, is relative", KURL::isRelativeURL("man:mmap") ? "true" : "false", "false");
+ check("javascript: URL, is relative", KURL::isRelativeURL("javascript:doSomething()") ? "true" : "false", "false");
+// more isRelative
+ check("file: URL, is relative", KURL::isRelativeURL("file:/blah") ? "true" : "false", "false");
+ check("/path, is relative", KURL::isRelativeURL("/path") ? "true" : "false", "true"); // arguable
+ check("something, is relative", KURL::isRelativeURL("something") ? "true" : "false", "true");
+ KURL about("about:konqueror");
+ check("about:",about.path(),"konqueror");
+
+ KURL ulong("https://swww.gad.de:443/servlet/CookieAccepted?MAIL=s@gad.de&VER=25901");
+ check("host",ulong.host(),"swww.gad.de");
+ check("path",ulong.path(),"/servlet/CookieAccepted");
+
+ QTextCodec::setCodecForLocale( KGlobal::charsets()->codecForName( "iso-8859-1" ) );
+// UTF8 tests
+ KURL uloc("/home/dfaure/konqtests/Matériel");
+ check("locale8bit",uloc.url().latin1(),"file:/home/dfaure/konqtests/Mat%E9riel"); // escaping the letter would be correct too
+ check("pretty",uloc.prettyURL(),"file:/home/dfaure/konqtests/Matériel"); // escaping the letter would be correct too
+// 106 is MIB for UTF-8
+ check("UTF8",uloc.url(0, 106),"file:/home/dfaure/konqtests/Mat%C3%A9riel");
+ uloc = KURL("file:/home/dfaure/konqtests/Mat%C3%A9riel", 106);
+ check("UTF8 path", uloc.path(), "/home/dfaure/konqtests/Matériel");
+
+// fromPathOrURL tests
+ uloc = KURL::fromPathOrURL( "/home/dfaure/konqtests/Mat%E9riel" );
+ check("fromPathOrURL path", uloc.path(), "/home/dfaure/konqtests/Mat%E9riel");
+ uloc = KURL::fromPathOrURL( "http://www.kde.org" );
+ check("fromPathOrURL url", uloc.url(), "http://www.kde.org");
+ uloc = KURL::fromPathOrURL( "www.kde.org" );
+ check("fromPathOrURL url", uloc.isValid()?"valid":"malformed", "malformed");
+ uloc = KURL::fromPathOrURL( "index.html" );
+ check("fromPathOrURL url", uloc.isValid()?"valid":"malformed", "malformed");
+ uloc = KURL::fromPathOrURL( "" );
+ check("fromPathOrURL url", uloc.isValid()?"valid":"malformed", "malformed");
+
+ QTextCodec::setCodecForLocale( KGlobal::charsets()->codecForName( "koi8-r" ) );
+ baseURL = "file:/home/coolo";
+ KURL russian = baseURL.directory(false, true) + QString::fromLocal8Bit( "ÆÇÎ7" );
+ check( "russian", russian.url(), "file:/home/%C6%C7%CE7" );
+
+ KURL tobi1("http://some.host.net/path/to/file#fragmentPrecedes?theQuery");
+ check("wrong order of query and hypertext reference #1", tobi1.ref(), "fragmentPrecedes");
+ check("wrong order of query and hypertext reference #2", tobi1.query(), "?theQuery");
+
+ tobi1 = "http://host.net/path/?#http://brokenäadsfküpoij31ü029muß2890zupycÜ*!*'OŽ+ß0i";
+ check("zero-length query",tobi1.query(),"?");
+
+ tobi1 = "http://host.net/path/#no-query";
+ check("no query", tobi1.query(),"");
+
+ tobi1 = "http://host.net/path?myfirstquery#andsomeReference";
+ tobi1.setEncodedPathAndQuery("another/path/?another&query");
+ check("setEncodedPathAndQuery test#1", tobi1.query(), "?another&query");
+ check("setEncodedPathAndQuery test#2", tobi1.path(), "another/path/");
+ tobi1.setEncodedPathAndQuery("another/path?another&query");
+ check("setEncodedPathAndQuery test#1", tobi1.query(), "?another&query");
+ check("setEncodedPathAndQuery test#2", tobi1.path(), "another/path");
+
+ KURL theKow = "http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25";
+ check("queryItem (first item)", theKow.queryItem("q"), "frerich");
+ check("queryItem (middle item)", theKow.queryItem("hl"), "de");
+ check("queryItem (last item)", theKow.queryItem("lr"), "lang de");
+ check("queryItem (invalid item)", theKow.queryItem("InterstellarCounselor"), QString());
+ check("queryItem (empty item)", theKow.queryItem("empty"), "");
+ check("queryItem (item with encoded chars)", theKow.queryItem("test"), "+ :%");
+
+// checks for queryItems(), which returns a QMap<QString,QString>:
+ KURL queryUrl( "mailto:Marc%20Mutz%20%3cmutz@kde.org%3E?"
+ "Subject=subscribe+me&"
+ "body=subscribe+mutz%40kde.org&"
+ "Cc=majordomo%40lists.kde.org" );
+ check("queryItems (c.s. keys)",
+ QStringList(queryUrl.queryItems().keys()).join(", "),
+ "Cc, Subject, body" );
+ check("queryItems (c.i.s. keys)",
+ QStringList(queryUrl.queryItems(KURL::CaseInsensitiveKeys).keys()).join(", "),
+ "body, cc, subject" );
+ check("queryItems (values; c.s. keys)",
+ QStringList(queryUrl.queryItems().values()).join(", "),
+ "majordomo@lists.kde.org, subscribe me, subscribe mutz@kde.org" );
+ check("queryItems (values; c.i.s. keys)",
+ QStringList(queryUrl.queryItems(KURL::CaseInsensitiveKeys).values()).join(", "),
+ "subscribe mutz@kde.org, majordomo@lists.kde.org, subscribe me" );
+
+ KURL umlaut1("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
+ check("umlaut1.url()", umlaut1.url(), "http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
+
+ KURL umlaut2("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel", 106);
+ check("umlaut2.url()", umlaut2.url(), "http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
+
+// Needed for #49616
+ check( "encode_string('C++')", KURL::encode_string( "C++" ), "C%2B%2B" );
+ check( "decode_string('C%2B%2B')", KURL::decode_string( "C%2B%2B" ), "C++" );
+ check( "decode_string('C%00A')", KURL::decode_string( "C%00%A" ), "C" ); // we stop at %00
+
+ check( "encode_string('%')", KURL::encode_string( "%" ), "%25" );
+ check( "encode_string(':')", KURL::encode_string( ":" ), "%3A" );
+
+ KURL amantia( "http://%E1.foo" );
+ check("amantia.isValid()", amantia.isValid() ? "true" : "false", "true");
+#ifdef HAVE_IDNA_H
+ check("amantia.url()", amantia.url(), "http://xn--80a.foo"); // Non-ascii is allowed in IDN domain names.
+#else
+ check("amantia.url()", amantia.url(), "http://?.foo"); // why not
+#endif
+
+ KURL smb("smb://domain;username:password@server/share");
+ check("smb.isValid()", smb.isValid() ? "true" : "false", "true");
+ check("smb.user()", smb.user(), "domain;username");
+ smb = "smb:/";
+ check("smb:/", smb.isValid()?"VALID":"MALFORMED", "VALID");
+ smb = "smb://"; // kurl.cpp rev 1.106
+ check("smb://", smb.isValid()?"VALID":"MALFORMED", "MALFORMED");
+ smb = "smb://host";
+ check("smb://host", smb.isValid()?"VALID":"MALFORMED", "VALID");
+ smb = "smb:///";
+ check("smb:///", smb.isValid()?"VALID":"MALFORMED", "VALID");
+
+ KURL weird;
+ weird = "http://strange<hostname>/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
+
+ weird = "http://strange<username>@strange<hostname>/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
+
+ weird = "http://strange<username>@ok_hostname/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
+ check("weird.host()", weird.host(), "ok_hostname");
+
+ weird = "http://strange;hostname/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
+
+ weird = "http://strange;username@strange;hostname/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
+
+ weird = "http://strange;username@ok_hostname/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
+ check("weird.host()", weird.host(), "ok_hostname");
+
+ weird = "http://strange;username:password@strange;hostname/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
+
+ weird = "http://strange;username:password@ok_hostname/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
+ check("weird.host()", weird.host(), "ok_hostname");
+
+ weird = "http://[strange;hostname]/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
+
+ weird = "http://[::fff:1:23]/";
+ check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
+ check("weird.host()", weird.host(), "::fff:1:23");
+
+ KURL com1("http://server.com/dir/", ".");
+ check("com1.url()", com1.url(), "http://server.com/dir/");
+
+ KURL com2("http://server.com/dir/blubb/", "blah/");
+ check("com2.url()", com2.url(), "http://server.com/dir/blubb/blah/");
+
+ KURL utf8_1("audiocd:/By%20Name/15%20Geantra%C3%AE.wav", 106);
+ check("utf8_1.fileName()", utf8_1.fileName(), QString::fromLatin1("15 Geantraî.wav"));
+
+ KURL utf8_2("audiocd:/By%20Name/15%2fGeantra%C3%AE.wav", 106);
+ check("utf8_2.fileName()", utf8_2.fileName(), QString::fromLatin1("15/Geantraî.wav"));
+
+ KURL url_newline_1("http://www.foo.bar/foo/bar\ngnork");
+ check("url_newline_1.url()", url_newline_1.url(), QString::fromLatin1("http://www.foo.bar/foo/bar%0Agnork"));
+
+ KURL url_newline_2("http://www.foo.bar/foo?bar\ngnork");
+ check("url_newline_2.url()", url_newline_2.url(), QString::fromLatin1("http://www.foo.bar/foo?bar%0Agnork"));
+
+ KURL local_file_1("file://localhost/my/file");
+ check("local_file_1.isLocalFile()", local_file_1.isLocalFile() ? "true" : "false", "true");
+
+ KURL local_file_2("file://www.kde.org/my/file");
+ check("local_file_2.isLocalFile()", local_file_2.isLocalFile() ? "true" : "false", "false");
+
+ KURL local_file_3;
+ local_file_3.setHost(getenv("HOSTNAME"));
+ local_file_3.setPath("/my/file");
+ printf("\nURL=%s\n", local_file_3.url().latin1());
+ check("local_file_3.isLocalFile()", local_file_3.isLocalFile() ? "true" : "false", "true");
+
+ KURL local_file_4("file:///my/file");
+ check("local_file_4.isLocalFile()", local_file_4.isLocalFile() ? "true" : "false", "true");
+
+ KURL local_file_5;
+ local_file_5.setPath("/foo?bar");
+ check("local_file_5.url()", local_file_5.url(), "file:/foo%3Fbar");
+
+ QString basePath = "/home/bastian";
+
+ check("relativePath(\"/home/bastian\", \"/home/bastian\")", KURL::relativePath(basePath, "/home/bastian"), "./");
+ bool b;
+ check("relativePath(\"/home/bastian\", \"/home/bastian/src/plugins\")", KURL::relativePath(basePath, "/home/bastian/src/plugins", &b), "./src/plugins");
+ check("Is a subdirectory?", b ? "true" : "false", "true");
+ check("relativePath(\"/home/bastian\", \"./src/plugins\")", KURL::relativePath(basePath, "./src/plugins"), "./src/plugins");
+ check("relativePath(\"/home/bastian\", \"/home/waba/src/plugins\")", KURL::relativePath(basePath, "/home/waba/src/plugins", &b), "../waba/src/plugins");
+ check("Is a subdirectory?", b ? "true" : "false", "false");
+ check("relativePath(\"/home/bastian\", \"/\")", KURL::relativePath(basePath, "/"), "../../");
+
+ check("relativePath(\"/\", \"/\")", KURL::relativePath("/", "/"), "./");
+ check("relativePath(\"/\", \"/home/bastian\")", KURL::relativePath("/", "/home/bastian"), "./home/bastian");
+ check("relativePath(\"\", \"/home/bastian\")", KURL::relativePath("", "/home/bastian"), "/home/bastian");
+
+ baseURL = "http://www.kde.org/index.html";
+ check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/index.html#help\")", KURL::relativeURL(baseURL, "http://www.kde.org/index.html#help"), "#help");
+ check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/index.html?help=true\")", KURL::relativeURL(baseURL, "http://www.kde.org/index.html?help=true"), "index.html?help=true");
+ check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/contact.html\")", KURL::relativeURL(baseURL, "http://www.kde.org/contact.html"), "contact.html");
+ check("relativeURL(\"http://www.kde.org/index.html\", \"ftp://ftp.kde.org/pub/kde\")", KURL::relativeURL(baseURL, "ftp://ftp.kde.org/pub/kde"), "ftp://ftp.kde.org/pub/kde");
+ check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/index.html\")", KURL::relativeURL(baseURL, "http://www.kde.org/index.html"), "./");
+
+ baseURL = "http://www.kde.org/info/index.html";
+ check("relativeURL(\"http://www.kde.org/info/index.html\", \"http://www.kde.org/bugs/contact.html\")", KURL::relativeURL(baseURL, "http://www.kde.org/bugs/contact.html"), "../bugs/contact.html");
+
+ baseURL = "ptal://mlc:usb:PC_970";
+ check("isValid()?", baseURL.isValid() ? "true" : "false", "false");
+ check("url()", baseURL.url(), "ptal://mlc:usb:PC_970");
+
+ baseURL = "http://mlc:80/";
+ check("isValid()?", baseURL.isValid() ? "true" : "false", "true");
+ check("port()?", QString::number(baseURL.port()), "80");
+ check("path()?", baseURL.path(), "/");
+
+ baseURL = "ptal://mlc:usb@PC_970"; // User=mlc, password=usb, host=PC_970
+ check("isValid()?", baseURL.isValid() ? "true" : "false", "true");
+ check("host()?", baseURL.host(), "pc_970");
+ check("user()?", baseURL.user(), "mlc");
+ check("pass()?", baseURL.pass(), "usb");
+
+ weird = "ftp://user%40host.com@ftp.host.com/var/www/";
+ check("user()?", weird.user(), "user@host.com" );
+ check("host()?", weird.host(), "ftp.host.com" );
+ KURL up = weird.upURL();
+ check("KURL::upURL()", up.url(), "ftp://user%40host.com@ftp.host.com/var/");
+ up = up.upURL();
+ check("KURL::upURL()", up.url(), "ftp://user%40host.com@ftp.host.com/");
+ up = up.upURL();
+ check("KURL::upURL()", up.url(), "ftp://user%40host.com@ftp.host.com/"); // unchanged
+
+ KURL ldap = "ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)";
+ check("host()?", ldap.host(), "host.com");
+ check("port()?", QString("%1").arg(ldap.port()), "6666");
+ check("path()?", ldap.path(), "/o=University of Michigan,c=US");
+ check("query()?", ldap.query(), "??sub?(cn=Babs%20Jensen)");
+ check("url()?", ldap.url(), "ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)");
+ ldap.setQuery("??sub?(cn=Karl%20Marx)");
+ check("query()?", ldap.query(), "??sub?(cn=Karl%20Marx)");
+ check("url()?", ldap.url(), "ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Karl%20Marx)");
+
+ KURL leo = "data:text/html,http://www.invalid/";
+ check("data URL: isValid", leo.isValid()?"valid":"malformed", "valid" );
+ check("data URL: protocol", leo.protocol(), "data" );
+ check("data URL: url", leo.url(), "data:text/html,http://www.invalid/" );
+ check("data URL: path", leo.path(), "text/html,http://www.invalid/" );
+
+// URI Mode tests
+ url1 = "http://www.foobar.com/";
+ check("KURL(\"http://www.foobar.com/\").uriMode()", QString::number(url1.uriMode()), QString::number(KURL::URL));
+ url1 = "mailto:user@host.com";
+ check("KURL(\"mailto:user@host.com\").uriMode()", QString::number(url1.uriMode()), QString::number(KURL::Mailto));
+ check("KURL(\"mailto:user@host.com\").url()", url1.url(), "mailto:user@host.com");
+ check("KURL(\"mailto:user@host.com\").url(0, 106)", url1.url(0, 106), "mailto:user@host.com");
+ url1 = "data:text/plain,foobar?gazonk=flarp";
+ check("KURL(\"data:text/plain,foobar?gazonk=flarp\").uriMode()", QString::number(url1.uriMode()), QString::number(KURL::RawURI));
+ check("KURL(\"data:text/plain,foobar?gazonk=flarp\").path()", url1.path(), "text/plain,foobar?gazonk=flarp");
+ url1 = "mailto:User@Host.COM?subject=Hello";
+ check("KURL(\"mailto:User@Host.COM?subject=Hello\").path()", url1.path(), "User@host.com");
+
+ printf("\nTest OK !\n");
+ */
+
+
+ }
+
+void tst_QUrl::i18n_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QByteArray>("punyOutput");
+
+ QTest::newRow("øl") << QString::fromLatin1("http://ole:passord@www.øl.no/index.html?ole=æsemann&ilder gud=hei#top")
+ << QByteArray("http://ole:passord@www.xn--l-4ga.no/index.html?ole=%C3%A6semann&ilder%20gud=hei#top");
+ QTest::newRow("räksmörgås") << QString::fromLatin1("http://www.räksmörgås.no/")
+ << QByteArray("http://www.xn--rksmrgs-5wao1o.no/");
+ QTest::newRow("bühler") << QString::fromLatin1("http://www.bühler.no/")
+ << QByteArray("http://www.xn--bhler-kva.no/");
+ QTest::newRow("non-latin1")
+ << QString::fromUtf8("http://www.\316\261\316\270\316\256\316\275\316\261.info")
+ << QByteArray("http://www.xn--jxafb0a0a.info");
+}
+
+void tst_QUrl::i18n()
+{
+ QFETCH(QString, input);
+ QFETCH(QByteArray, punyOutput);
+
+ QUrl url(input);
+ QVERIFY(url.isValid());
+
+ QCOMPARE(url.toEncoded().constData(), punyOutput.constData());
+ QCOMPARE(QUrl::fromEncoded(punyOutput), url);
+ QCOMPARE(QUrl::fromEncoded(punyOutput).toString(), input);
+}
+
+
+void tst_QUrl::resolving_data()
+{
+ QTest::addColumn<QString>("baseUrl");
+ QTest::addColumn<QString>("relativeUrl");
+ QTest::addColumn<QString>("relsolvedUrl");
+
+ // 5.4.1 Normal Examples (http://www.ietf.org/rfc/rfc3986.txt)
+ QTest::newRow("g:h") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g:h") << QString::fromLatin1("g:h");
+ QTest::newRow("g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g") << QString::fromLatin1("http://a/b/c/g");
+ QTest::newRow("./g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./g") << QString::fromLatin1("http://a/b/c/g");
+ QTest::newRow("g/") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g/") << QString::fromLatin1("http://a/b/c/g/");
+ QTest::newRow("/g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("/g") << QString::fromLatin1("http://a/g");
+ QTest::newRow("//g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("//g") << QString::fromLatin1("http://g");
+ QTest::newRow("?y") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("?y") << QString::fromLatin1("http://a/b/c/d;p?y");
+ QTest::newRow("g?y") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y") << QString::fromLatin1("http://a/b/c/g?y");
+ QTest::newRow("#s") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("#s") << QString::fromLatin1("http://a/b/c/d;p?q#s");
+ QTest::newRow("g#s") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g#s") << QString::fromLatin1("http://a/b/c/g#s");
+ QTest::newRow("g?y#s") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y#s") << QString::fromLatin1("http://a/b/c/g?y#s");
+ QTest::newRow(";x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(";x") << QString::fromLatin1("http://a/b/c/;x");
+ QTest::newRow("g;x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x") << QString::fromLatin1("http://a/b/c/g;x");
+ QTest::newRow("g;x?y#s") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x?y#s") << QString::fromLatin1("http://a/b/c/g;x?y#s");
+ QTest::newRow("[empty]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("") << QString::fromLatin1("http://a/b/c/d;p?q");
+ QTest::newRow(".") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(".") << QString::fromLatin1("http://a/b/c/");
+ QTest::newRow("./") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./") << QString::fromLatin1("http://a/b/c/");
+ QTest::newRow("..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..") << QString::fromLatin1("http://a/b/");
+ QTest::newRow("../") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../") << QString::fromLatin1("http://a/b/");
+ QTest::newRow("../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../g") << QString::fromLatin1("http://a/b/g");
+ QTest::newRow("../..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../..") << QString::fromLatin1("http://a/");
+ QTest::newRow("../../") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../") << QString::fromLatin1("http://a/");
+ QTest::newRow("../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../g") << QString::fromLatin1("http://a/g");
+
+ // 5.4.2 Abnormal Examples (http://www.ietf.org/rfc/rfc3986.txt)
+
+ // Parsers must be careful in handling cases where there are more
+ // relative path ".." segments than there are hierarchical levels in the
+ // base URI's path. Note that the ".." syntax cannot be used to change
+ // the authority component of a URI.
+ QTest::newRow("../../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../g") << QString::fromLatin1("http://a/g");
+ QTest::newRow("../../../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../../g") << QString::fromLatin1("http://a/g");
+
+ // Similarly, parsers must remove the dot-segments "." and ".." when
+ // they are complete components of a path, but not when they are only
+ // part of a segment.
+ QTest::newRow("/./g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("/./g") << QString::fromLatin1("http://a/g");
+ QTest::newRow("/../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("/../g") << QString::fromLatin1("http://a/g");
+ QTest::newRow("g.") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g.") << QString::fromLatin1("http://a/b/c/g.");
+ QTest::newRow(".g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(".g") << QString::fromLatin1("http://a/b/c/.g");
+ QTest::newRow("g..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g..") << QString::fromLatin1("http://a/b/c/g..");
+ QTest::newRow("..g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..g") << QString::fromLatin1("http://a/b/c/..g");
+
+ // Less likely are cases where the relative URI reference uses
+ // unnecessary or nonsensical forms of the "." and ".." complete path
+ // segments.
+ QTest::newRow("./../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./../g") << QString::fromLatin1("http://a/b/g");
+ QTest::newRow("./g/.") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./g/.") << QString::fromLatin1("http://a/b/c/g/");
+ QTest::newRow("g/./h") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g/./h") << QString::fromLatin1("http://a/b/c/g/h");
+ QTest::newRow("g/../h") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g/../h") << QString::fromLatin1("http://a/b/c/h");
+ QTest::newRow("g;x=1/./y") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x=1/./y") << QString::fromLatin1("http://a/b/c/g;x=1/y");
+ QTest::newRow("g;x=1/../y") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x=1/../y") << QString::fromLatin1("http://a/b/c/y");
+
+ // Some applications fail to separate the reference's query and/or
+ // fragment components from a relative path before merging it with the
+ // base path and removing dot-segments. This error is rarely noticed,
+ // since typical usage of a fragment never includes the hierarchy ("/")
+ // character, and the query component is not normally used within
+ // relative references.
+ QTest::newRow("g?y/./x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y/./x") << QString::fromLatin1("http://a/b/c/g?y/./x");
+ QTest::newRow("g?y/../x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y/../x") << QString::fromLatin1("http://a/b/c/g?y/../x");
+ QTest::newRow("g#s/./x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g#s/./x") << QString::fromLatin1("http://a/b/c/g#s/./x");
+ QTest::newRow("g#s/../x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g#s/../x") << QString::fromLatin1("http://a/b/c/g#s/../x");
+
+ // Some parsers allow the scheme name to be present in a relative URI
+ // reference if it is the same as the base URI scheme. This is
+ // considered to be a loophole in prior specifications of partial URI
+ // [RFC1630]. Its use should be avoided, but is allowed for backward
+ // compatibility.
+ // For strict parsers :
+// QTest::newRow("http:g [for strict parsers]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http:g");
+ // For backward compatibility :
+ QTest::newRow("http:g [for backward compatibility]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http://a/b/c/g");
+
+ // Resolve relative with relative
+ QTest::newRow("../a (1)") << QString::fromLatin1("b") << QString::fromLatin1("../a") << QString::fromLatin1("a");
+ QTest::newRow("../a (2)") << QString::fromLatin1("b/a") << QString::fromLatin1("../a") << QString::fromLatin1("a");
+ QTest::newRow("../a (3)") << QString::fromLatin1("b/c/a") << QString::fromLatin1("../a") << QString::fromLatin1("b/a");
+ QTest::newRow("../a (4)") << QString::fromLatin1("b") << QString::fromLatin1("/a") << QString::fromLatin1("/a");
+
+ QTest::newRow("../a (5)") << QString::fromLatin1("/b") << QString::fromLatin1("../a") << QString::fromLatin1("/a");
+ QTest::newRow("../a (6)") << QString::fromLatin1("/b/a") << QString::fromLatin1("../a") << QString::fromLatin1("/a");
+ QTest::newRow("../a (7)") << QString::fromLatin1("/b/c/a") << QString::fromLatin1("../a") << QString::fromLatin1("/b/a");
+ QTest::newRow("../a (8)") << QString::fromLatin1("/b") << QString::fromLatin1("/a") << QString::fromLatin1("/a");
+}
+
+void tst_QUrl::resolving()
+{
+ QFETCH(QString, baseUrl);
+ QFETCH(QString, relativeUrl);
+ QFETCH(QString, relsolvedUrl);
+
+ QUrl url(baseUrl);
+ QCOMPARE(url.resolved(relativeUrl).toString(), relsolvedUrl);
+}
+
+
+void tst_QUrl::toString_data()
+{
+ QTest::addColumn<QString>("urlString");
+ QTest::addColumn<uint>("options");
+ QTest::addColumn<QString>("string");
+
+ QTest::newRow("data0") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme)
+ << QString::fromLatin1("//ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data2") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemovePassword)
+ << QString::fromLatin1("http://ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data3") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveUserInfo)
+ << QString::fromLatin1("http://www.troll.no:9090/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data4") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemovePort)
+ << QString::fromLatin1("http://ole:password@www.troll.no/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data5") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveAuthority)
+ << QString::fromLatin1("http:/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data6") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemovePath)
+ << QString::fromLatin1("http://ole:password@www.troll.no:9090?ole=semann&gud=hei#top");
+
+ QTest::newRow("data7") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveQuery)
+ << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html#top");
+
+ QTest::newRow("data8") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveFragment)
+ << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei");
+
+ QTest::newRow("data9") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemovePassword)
+ << QString::fromLatin1("//ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data10") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemoveUserInfo)
+ << QString::fromLatin1("//www.troll.no:9090/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data11") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemovePort)
+ << QString::fromLatin1("//ole:password@www.troll.no/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data12") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemoveAuthority)
+ << QString::fromLatin1("/index.html?ole=semann&gud=hei#top");
+
+ QTest::newRow("data13") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemovePath)
+ << QString::fromLatin1("//ole:password@www.troll.no:9090?ole=semann&gud=hei#top");
+
+ QTest::newRow("data14") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemoveAuthority | QUrl::RemoveFragment)
+ << QString::fromLatin1("/index.html?ole=semann&gud=hei");
+
+ QTest::newRow("data15") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveAuthority | QUrl::RemoveQuery)
+ << QString::fromLatin1("http:/index.html#top");
+
+ QTest::newRow("data16") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemovePassword | QUrl::RemovePort
+ | QUrl::RemovePath | QUrl::RemoveQuery
+ | QUrl::RemoveFragment)
+ << QString::fromLatin1("http://ole@www.troll.no");
+
+ QTest::newRow("data17") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+ << uint(QUrl::RemoveScheme | QUrl::RemovePassword
+ | QUrl::RemovePort | QUrl::RemovePath
+ | QUrl::RemoveQuery | QUrl::RemoveFragment)
+ << QString::fromLatin1("//ole@www.troll.no");
+
+ QTest::newRow("data18") << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged")
+ << uint(QUrl::None)
+ << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged");
+
+ /*
+ QTest::newRow("data19") << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/a/../?my=query&your=query#yougotfragged")
+ << uint(QUrl::None)
+ << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged");
+ */
+
+ QTest::newRow("nopath_task31320") << QString::fromLatin1("host://protocol")
+ << uint(QUrl::None)
+ << QString::fromLatin1("host://protocol");
+
+ QTest::newRow("underscore_QTBUG-7434") << QString::fromLatin1("http://foo_bar.host.com/rss.php")
+ << uint(QUrl::None)
+ << QString::fromLatin1("http://foo_bar.host.com/rss.php");
+}
+
+void tst_QUrl::toString()
+{
+ QFETCH(QString, urlString);
+ QFETCH(uint, options);
+ QFETCH(QString, string);
+
+ QUrl url(urlString);
+ QCOMPARE(url.toString(QUrl::FormattingOptions(options)), string);
+}
+
+//### more tests ... what do we expect ...
+void tst_QUrl::isParentOf_data()
+{
+ QTest::addColumn<QString>("parent");
+ QTest::addColumn<QString>("child");
+ QTest::addColumn<bool>("trueFalse");
+
+ QTest::newRow("data0") << QString::fromLatin1("http://a.b.c/d")
+ << QString::fromLatin1("http://a.b.c/d/e?f") << true;
+ QTest::newRow("data1") << QString::fromLatin1("http://a.b.c/d")
+ << QString::fromLatin1("http://a.b.c/d") << false;
+ QTest::newRow("data2") << QString::fromLatin1("http://a.b.c/d")
+ << QString::fromLatin1("http://a.b.c/de") << false;
+ QTest::newRow("data3") << QString::fromLatin1("http://a.b.c/d/")
+ << QString::fromLatin1("http://a.b.c/de") << false;
+ QTest::newRow("data4") << QString::fromLatin1("http://a.b.c/d/")
+ << QString::fromLatin1("http://a.b.c/d/e") << true;
+
+
+}
+
+void tst_QUrl::toString_constructed_data()
+{
+ QTest::addColumn<QString>("scheme");
+ QTest::addColumn<QString>("userName");
+ QTest::addColumn<QString>("password");
+ QTest::addColumn<QString>("host");
+ QTest::addColumn<int>("port");
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QByteArray>("query");
+ QTest::addColumn<QString>("fragment");
+ QTest::addColumn<QString>("asString");
+ QTest::addColumn<QByteArray>("asEncoded");
+
+ QString n("");
+
+ QTest::newRow("data1") << n << n << n << QString::fromLatin1("qt.nokia.com") << -1 << QString::fromLatin1("index.html")
+ << QByteArray() << n << QString::fromLatin1("//qt.nokia.com/index.html")
+ << QByteArray("//qt.nokia.com/index.html");
+ QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QByteArray()
+ << n << QString::fromLatin1("file:///root") << QByteArray("file:///root");
+ QTest::newRow("userAndPass") << QString::fromLatin1("http") << QString::fromLatin1("dfaure") << QString::fromLatin1("kde")
+ << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
+ << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/");
+ QTest::newRow("PassWithoutUser") << QString::fromLatin1("http") << n << QString::fromLatin1("kde")
+ << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
+ << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/");
+}
+
+void tst_QUrl::toString_constructed()
+{
+ QFETCH(QString, scheme);
+ QFETCH(QString, userName);
+ QFETCH(QString, password);
+ QFETCH(QString, host);
+ QFETCH(int, port);
+ QFETCH(QString, path);
+ QFETCH(QByteArray, query);
+ QFETCH(QString, fragment);
+ QFETCH(QString, asString);
+ QFETCH(QByteArray, asEncoded);
+
+ QUrl url;
+ if (!scheme.isEmpty())
+ url.setScheme(scheme);
+ if (!userName.isEmpty())
+ url.setUserName(userName);
+ if (!password.isEmpty())
+ url.setPassword(password);
+ if (!host.isEmpty())
+ url.setHost(host);
+ if (port != -1)
+ url.setPort(port);
+ if (!path.isEmpty())
+ url.setPath(path);
+ if (!query.isEmpty())
+ url.setEncodedQuery(query);
+ if (!fragment.isEmpty())
+ url.setFragment(fragment);
+
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toString(), asString);
+ QCOMPARE(QString::fromLatin1(url.toEncoded()), QString::fromLatin1(asEncoded)); // readable in case of differences
+ QCOMPARE(url.toEncoded(), asEncoded);
+}
+
+
+void tst_QUrl::isParentOf()
+{
+ QFETCH(QString, parent);
+ QFETCH(QString, child);
+ QFETCH(bool, trueFalse);
+
+ QUrl url(parent);
+ QCOMPARE(url.isParentOf(QUrl(child)), trueFalse);
+}
+
+void tst_QUrl::toLocalFile_data()
+{
+ QTest::addColumn<QString>("theUrl");
+ QTest::addColumn<QString>("theFile");
+
+ QTest::newRow("data0") << QString::fromLatin1("file:/a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("data4") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("data5") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("c:/a.txt");
+ QTest::newRow("data6") << QString::fromLatin1("file://somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
+ QTest::newRow("data7") << QString::fromLatin1("file://somehost/") << QString::fromLatin1("//somehost/");
+ QTest::newRow("data8") << QString::fromLatin1("file://somehost") << QString::fromLatin1("//somehost");
+ QTest::newRow("data9") << QString::fromLatin1("file:////somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
+ QTest::newRow("data10") << QString::fromLatin1("FILE:/a.txt") << QString::fromLatin1("/a.txt");
+
+ // and some that result in empty (i.e., not local)
+ QTest::newRow("xdata0") << QString::fromLatin1("/a.txt") << QString();
+ QTest::newRow("xdata1") << QString::fromLatin1("//a.txt") << QString();
+ QTest::newRow("xdata2") << QString::fromLatin1("///a.txt") << QString();
+ QTest::newRow("xdata3") << QString::fromLatin1("foo:/a.txt") << QString();
+ QTest::newRow("xdata4") << QString::fromLatin1("foo://a.txt") << QString();
+ QTest::newRow("xdata5") << QString::fromLatin1("foo:///a.txt") << QString();
+}
+
+void tst_QUrl::toLocalFile()
+{
+ QFETCH(QString, theUrl);
+ QFETCH(QString, theFile);
+
+ QUrl url(theUrl);
+ QCOMPARE(url.toLocalFile(), theFile);
+}
+
+void tst_QUrl::fromLocalFile_data()
+{
+ QTest::addColumn<QString>("theFile");
+ QTest::addColumn<QString>("theUrl");
+ QTest::addColumn<QString>("thePath");
+
+ QTest::newRow("data0") << QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("data1") << QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt");
+ QTest::newRow("data2") << QString::fromLatin1("/a/b.txt") << QString::fromLatin1("file:///a/b.txt") << QString::fromLatin1("/a/b.txt");
+ QTest::newRow("data3") << QString::fromLatin1("c:/a.txt") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
+ QTest::newRow("data4") << QString::fromLatin1("//somehost/somedir/somefile") << QString::fromLatin1("file://somehost/somedir/somefile")
+ << QString::fromLatin1("/somedir/somefile");
+ QTest::newRow("data5") << QString::fromLatin1("//somehost") << QString::fromLatin1("file://somehost")
+ << QString::fromLatin1("");
+ QTest::newRow("data6") << QString::fromLatin1("//somehost/") << QString::fromLatin1("file://somehost/")
+ << QString::fromLatin1("/");
+}
+
+void tst_QUrl::fromLocalFile()
+{
+ QFETCH(QString, theFile);
+ QFETCH(QString, theUrl);
+ QFETCH(QString, thePath);
+
+ QUrl url = QUrl::fromLocalFile(theFile);
+
+ QCOMPARE(url.toString(), theUrl);
+ QCOMPARE(url.path(), thePath);
+}
+
+void tst_QUrl::compat_legacy()
+{
+ {
+ QUrl u( "file:bar" );
+ QCOMPARE( u.toString(QUrl::RemoveScheme), QString("bar") );
+ }
+
+ /* others
+ */
+ {
+ QUrl u( "http://qt.nokia.com/images/ban/pgs_front.jpg" );
+ QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg") );
+ }
+ {
+ QUrl tmp( "http://qt.nokia.com/images/ban/" );
+ QUrl u = tmp.resolved(QString("pgs_front.jpg"));
+ QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg") );
+ }
+ {
+ QUrl tmp;
+ QUrl u = tmp.resolved(QString("http://qt.nokia.com/images/ban/pgs_front.jpg"));
+ QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg") );
+ }
+ {
+ QUrl tmp;
+ QUrl u = tmp.resolved(QString("http://qt.nokia.com/images/ban/pgs_front.jpg"));
+ QFileInfo fi(u.path());
+ u.setPath(fi.path());
+ QCOMPARE( u.path(), QString("/images/ban") );
+ }
+}
+
+void tst_QUrl::compat_constructor_01_data()
+{
+ QTest::addColumn<QString>("urlStr");
+ QTest::addColumn<QString>("res");
+
+ //next we fill it with data
+ QTest::newRow( "data0" ) << QString("Makefile") << QString("Makefile"); // nolonger add file by default
+ QTest::newRow( "data1" ) << QString("Makefile") << QString("Makefile");
+ QTest::newRow( "data2" ) << QString("ftp://ftp.qt.nokia.com/qt/INSTALL") << QString("ftp://ftp.qt.nokia.com/qt/INSTALL");
+ QTest::newRow( "data3" ) << QString("ftp://ftp.qt.nokia.com/qt/INSTALL") << QString("ftp://ftp.qt.nokia.com/qt/INSTALL");
+}
+
+void tst_QUrl::compat_constructor_01()
+{
+ /* The following should work as expected:
+ *
+ * QUrlOperator op;
+ * op.copy( QString( "Makefile" ),
+ * QString("ftp://rms:grmpf12@nibbler/home/rms/tmp"),
+ * false );
+ *
+ * as well as the following:
+ *
+ * QUrlOperator op;
+ * op.copy(QString("ftp://ftp.qt.nokia.com/qt/INSTALL"), ".");
+ */
+ QFETCH( QString, urlStr );
+
+ {
+ QUrl empty;
+ QUrl u = empty.resolved(urlStr);
+
+ QTEST( u.toString(), "res" );
+ }
+ {
+ QUrl empty;
+ QUrl u = empty.resolved(urlStr);
+
+ QTEST( u.toString(), "res" );
+ }
+}
+
+void tst_QUrl::compat_constructor_02_data()
+{
+ QTest::addColumn<QString>("urlStr");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("res");
+
+ //next we fill it with data
+ QTest::newRow( "data0" ) << QString("ftp://ftp.qt.nokia.com/qt") << QString("INSTALL") << QString("ftp://ftp.qt.nokia.com/INSTALL");
+ QTest::newRow( "data1" ) << QString("ftp://ftp.qt.nokia.com/qt/") << QString("INSTALL") << QString("ftp://ftp.qt.nokia.com/qt/INSTALL");
+}
+
+void tst_QUrl::compat_constructor_02()
+{
+ /* The following should work as expected:
+ *
+ * QUrlOperator op( "ftp://ftp.qt.nokia.com/qt" );
+ * op.copy(QString("INSTALL"), ".");
+ */
+ QFETCH( QString, urlStr );
+ QFETCH( QString, fileName );
+
+ QUrl tmp( urlStr );
+ QUrl u = tmp.resolved(fileName);
+
+ QTEST( u.toString(), "res" );
+}
+
+void tst_QUrl::compat_constructor_03_data()
+{
+ QTest::addColumn<QString>("urlStr");
+ QTest::addColumn<QString>("res");
+
+ //next we fill it with data
+ QTest::newRow( "protocol00" ) << QString( "http://qt.nokia.com/index.html" ) << QString( "http://qt.nokia.com/index.html" );
+ QTest::newRow( "protocol01" ) << QString( "http://qt.nokia.com" ) << QString( "http://qt.nokia.com" );
+ QTest::newRow( "protocol02" ) << QString( "http://qt.nokia.com/" ) << QString( "http://qt.nokia.com/" );
+ QTest::newRow( "protocol03" ) << QString( "http://qt.nokia.com/foo" ) << QString( "http://qt.nokia.com/foo" );
+ QTest::newRow( "protocol04" ) << QString( "http://qt.nokia.com/foo/" ) << QString( "http://qt.nokia.com/foo/" );
+ QTest::newRow( "protocol05" ) << QString( "ftp://ftp.qt.nokia.com/foo/index.txt" ) << QString( "ftp://ftp.qt.nokia.com/foo/index.txt" );
+
+ QTest::newRow( "local00" ) << QString( "/foo" ) << QString( "/foo" );
+ QTest::newRow( "local01" ) << QString( "/foo/" ) << QString( "/foo/" );
+ QTest::newRow( "local02" ) << QString( "/foo/bar" ) << QString( "/foo/bar" );
+ QTest::newRow( "local03" ) << QString( "/foo/bar/" ) << QString( "/foo/bar/" );
+ QTest::newRow( "local04" ) << QString( "foo" ) << QString( "foo" );
+ QTest::newRow( "local05" ) << QString( "foo/" ) << QString( "foo/" );
+ QTest::newRow( "local06" ) << QString( "foo/bar" ) << QString( "foo/bar" );
+ QTest::newRow( "local07" ) << QString( "foo/bar/" ) << QString( "foo/bar/" );
+ QTest::newRow( "local09" ) << QString( "" ) << QString( "" );
+
+ QTest::newRow( "file00" ) << QString( "file:/foo" ) << QString( "file:///foo" );
+ QTest::newRow( "file01" ) << QString( "file:/foo/" ) << QString( "file:///foo/" );
+ QTest::newRow( "file02" ) << QString( "file:/foo/bar" ) << QString( "file:///foo/bar" );
+ QTest::newRow( "file03" ) << QString( "file:/foo/bar/" ) << QString( "file:///foo/bar/" );
+ QTest::newRow( "relProtocol00" ) << QString( "foo:bar" ) << QString( "foo:bar" );
+ QTest::newRow( "relProtocol01" ) << QString( "foo:/bar" ) << QString( "foo:/bar" );
+
+ QTest::newRow( "windowsDrive00" ) << QString( "c:/" ) << QString( "c:/" );
+ QTest::newRow( "windowsDrive01" ) << QString( "c:" ) << QString( "c:" );
+ QTest::newRow( "windowsDrive02" ) << QString( "c:/WinNT/" ) << QString( "c:/WinNT/" );
+ QTest::newRow( "windowsDrive03" ) << QString( "c:/autoexec.bat" ) << QString( "c:/autoexec.bat" );
+ QTest::newRow( "windowsDrive04" ) << QString( "c:WinNT/" ) << QString( "c:WinNT/" );
+ QTest::newRow( "windowsDrive05" ) << QString( "c:autoexec.bat" ) << QString( "c:autoexec.bat" );
+
+ QTest::newRow("task31280") << QString("protocol://host") << QString("protocol://host");
+}
+
+void tst_QUrl::compat_constructor_03()
+{
+ QFETCH( QString, urlStr );
+
+ QUrl u( urlStr );
+ QTEST( u.toString(), "res" );
+}
+
+void tst_QUrl::compat_isValid_01_data()
+{
+ QTest::addColumn<QString>("urlStr");
+ QTest::addColumn<bool>("res");
+
+ QTest::newRow( "ok_01" ) << QString("ftp://ftp.qt.nokia.com/qt/INSTALL") << (bool)true;
+ QTest::newRow( "ok_02" ) << QString( "file:/foo") << (bool)true;
+ QTest::newRow( "ok_03" ) << QString( "file:foo") << (bool)true;
+
+ QTest::newRow( "err_01" ) << QString("#ftp://ftp.qt.nokia.com/qt/INSTALL") << (bool)true;
+ QTest::newRow( "err_02" ) << QString( "file:/::foo") << (bool)true;
+}
+
+void tst_QUrl::compat_isValid_01()
+{
+ QFETCH( QString, urlStr );
+ QFETCH( bool, res );
+
+ QUrl url( urlStr );
+ QVERIFY( url.isValid() == res );
+}
+
+void tst_QUrl::compat_isValid_02_data()
+{
+ QTest::addColumn<QString>("protocol");
+ QTest::addColumn<QString>("user");
+ QTest::addColumn<QString>("password");
+ QTest::addColumn<QString>("host");
+ QTest::addColumn<int>("port");
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("res");
+
+ QString n = "";
+
+ QTest::newRow( "ok_01" ) << n << n << n << n << -1 << QString("path") << (bool)true;
+ QTest::newRow( "ok_02" ) << QString("ftp") << n << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true;
+ QTest::newRow( "ok_03" ) << QString("ftp") << QString("foo") << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true;
+ QTest::newRow( "ok_04" ) << QString("ftp") << QString("foo") << QString("bar") << QString("ftp.qt.nokia.com") << -1 << n << (bool)true;
+ QTest::newRow( "ok_05" ) << QString("ftp") << n << n << QString("ftp.qt.nokia.com") << -1 << QString("path")<< (bool)true;
+ QTest::newRow( "ok_06" ) << QString("ftp") << QString("foo") << n << QString("ftp.qt.nokia.com") << -1 << QString("path") << (bool)true;
+ QTest::newRow( "ok_07" ) << QString("ftp") << QString("foo") << QString("bar") << QString("ftp.qt.nokia.com") << -1 << QString("path")<< (bool)true;
+
+ QTest::newRow( "err_01" ) << n << n << n << n << -1 << n << (bool)false;
+ QTest::newRow( "err_02" ) << QString("ftp") << n << n << n << -1 << n << (bool)true;
+ QTest::newRow( "err_03" ) << n << QString("foo") << n << n << -1 << n << (bool)true;
+ QTest::newRow( "err_04" ) << n << n << QString("bar") << n << -1 << n << (bool)true;
+ QTest::newRow( "err_05" ) << n << n << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true;
+ QTest::newRow( "err_06" ) << n << n << n << n << 80 << n << (bool)true;
+ QTest::newRow( "err_07" ) << QString("ftp") << QString("foo") << n << n << -1 << n << (bool)true;
+ QTest::newRow( "err_08" ) << QString("ftp") << n << QString("bar") << n << -1 << n << (bool)true;
+ QTest::newRow( "err_09" ) << QString("ftp") << QString("foo") << QString("bar") << n << -1 << n << (bool)true;
+}
+
+void tst_QUrl::compat_isValid_02()
+{
+ QFETCH( QString, protocol );
+ QFETCH( QString, user );
+ QFETCH( QString, password );
+ QFETCH( QString, host );
+ QFETCH( int, port );
+ QFETCH( QString, path );
+ QFETCH( bool, res );
+
+ QUrl url;
+ if ( !protocol.isEmpty() )
+ url.setScheme( protocol );
+ if ( !user.isEmpty() )
+ url.setUserName( user );
+ if ( !password.isEmpty() )
+ url.setPassword( password );
+ if ( !host.isEmpty() )
+ url.setHost( host );
+ if ( port != -1 )
+ url.setPort( port );
+ if ( !path.isEmpty() )
+ url.setPath( path );
+
+ QVERIFY( url.isValid() == res );
+}
+
+void tst_QUrl::compat_path_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<QString>("res");
+
+ QTest::newRow( "protocol00" ) << "http://qt.nokia.com/images/ban/pgs_front.jpg" << "/images/ban/pgs_front.jpg";
+
+#if defined( Q_OS_WIN32 )
+ QTest::newRow( "winShare00" ) << "//Anarki/homes" << "/homes";
+#endif
+}
+
+void tst_QUrl::compat_path()
+{
+ QFETCH( QString, url );
+
+ QUrl u( url );
+ QTEST( u.path(), "res" );
+}
+
+void tst_QUrl::compat_fileName_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<QString>("fileName");
+
+#ifdef Q_OS_WIN32
+ QTest::newRow( "Windows - DrivePathFileName - \\" ) << QString("c:\\windows\\tmp\\filename.txt")<< QString("filename.txt");
+ QTest::newRow( "Windows - DrivePathFileName - /" ) << QString("c:/windows/tmp/filename.txt") << QString("filename.txt");
+ QTest::newRow( "Windows - DrivePathWithSlash - \\" ) << QString("c:\\windows\\tmp\\") << QString();
+ QTest::newRow( "Windows - DrivePathWithSlash - /" ) << QString("c:/windows/tmp/") << QString();
+ QTest::newRow( "Windows - DrivePathWithoutSlash - \\" ) << QString("c:/windows/tmp") << QString("tmp");
+ QTest::newRow( "Windows - DrivePathWithoutSlash - /" ) << QString("c:/windows/tmp") << QString("tmp");
+#endif
+ QTest::newRow( "Path00" ) << QString("/") << QString();
+ QTest::newRow( "Path01" ) << QString("/home/dev/test/") << QString();
+ QTest::newRow( "PathFileName00" ) << QString("/home/dev/test") << QString("test");
+}
+
+void tst_QUrl::compat_fileName()
+{
+ QFETCH( QString, url );
+ QFETCH( QString, fileName );
+ QUrl fileUrl = QUrl::fromLocalFile(url);
+ QFileInfo fi(fileUrl.toLocalFile());
+ QCOMPARE( fi.fileName(), fileName );
+}
+
+void tst_QUrl::compat_decode_data()
+{
+ QTest::addColumn<QByteArray>("encodedString");
+ QTest::addColumn<QString>("decodedString");
+
+ QTest::newRow("NormalString") << QByteArray("filename") << QString("filename");
+ QTest::newRow("NormalStringEncoded") << QByteArray("file%20name") << QString("file name");
+ QTest::newRow("JustEncoded") << QByteArray("%20") << QString(" ");
+ QTest::newRow("HTTPUrl") << QByteArray("http://qt.nokia.com") << QString("http://qt.nokia.com");
+ QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt%20nokia%20com") << QString("http://qt nokia com");
+ QTest::newRow("EmptyString") << QByteArray("") << QString("");
+ QTest::newRow("Task27166") << QByteArray("Fran%C3%A7aise") << QString("Française");
+}
+
+void tst_QUrl::compat_decode()
+{
+ QFETCH(QByteArray, encodedString);
+ QFETCH(QString, decodedString);
+
+ QCOMPARE(QUrl::fromPercentEncoding(encodedString), decodedString);
+}
+
+void tst_QUrl::compat_encode_data()
+{
+ QTest::addColumn<QString>("decodedString");
+ QTest::addColumn<QByteArray>("encodedString");
+
+ QTest::newRow("NormalString") << QString("filename") << QByteArray("filename");
+ QTest::newRow("NormalStringEncoded") << QString("file name") << QByteArray("file%20name");
+ QTest::newRow("JustEncoded") << QString(" ") << QByteArray("%20");
+ QTest::newRow("HTTPUrl") << QString("http://qt.nokia.com") << QByteArray("http%3A//qt.nokia.com");
+ QTest::newRow("HTTPUrlEncoded") << QString("http://qt nokia com") << QByteArray("http%3A//qt%20nokia%20com");
+ QTest::newRow("EmptyString") << QString("") << QByteArray("");
+ QTest::newRow("Task27166") << QString::fromLatin1("Française") << QByteArray("Fran%C3%A7aise");
+}
+
+void tst_QUrl::compat_encode()
+{
+ QFETCH(QString, decodedString);
+ QFETCH(QByteArray, encodedString);
+
+ QCOMPARE(QUrl::toPercentEncoding(decodedString, "/.").constData(), encodedString.constData());
+}
+
+
+void tst_QUrl::relative()
+{
+ QUrl url("../ole");
+ QCOMPARE(url.path(), QString::fromLatin1("../ole"));
+
+ QUrl url2("./");
+ QCOMPARE(url2.path(), QString::fromLatin1("./"));
+
+ QUrl url3("..");
+ QCOMPARE(url3.path(), QString::fromLatin1(".."));
+
+ QUrl url4("../..");
+ QCOMPARE(url4.path(), QString::fromLatin1("../.."));
+}
+
+void tst_QUrl::percentEncoding_data()
+{
+ QTest::addColumn<QString>("original");
+ QTest::addColumn<QByteArray>("encoded");
+
+ QTest::newRow("test_01") << QString::fromLatin1("sdfsdf") << QByteArray("sdfsdf");
+ QTest::newRow("test_02") << QString::fromLatin1("æss") << QByteArray("%C3%A6ss");
+ // not unreserved or reserved
+ QTest::newRow("test_03") << QString::fromLatin1("{}") << QByteArray("%7B%7D");
+}
+
+void tst_QUrl::percentEncoding()
+{
+ QFETCH(QString, original);
+ QFETCH(QByteArray, encoded);
+
+ QCOMPARE(QUrl(original).toEncoded().constData(), encoded.constData());
+ QVERIFY(QUrl::fromEncoded(QUrl(original).toEncoded()) == QUrl(original));
+ QCOMPARE(QUrl::fromEncoded(QUrl(original).toEncoded()).toString(), original);
+ QVERIFY(QUrl::fromEncoded(encoded) == QUrl(original));
+}
+
+void tst_QUrl::toPercentEncoding_data()
+{
+ QTest::addColumn<QString>("original");
+ QTest::addColumn<QByteArray>("encoded");
+ QTest::addColumn<QByteArray>("excludeInEncoding");
+ QTest::addColumn<QByteArray>("includeInEncoding");
+
+ QTest::newRow("test_01") << QString::fromLatin1("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
+ << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
+ << QByteArray("")
+ << QByteArray("");
+ QTest::newRow("test_02") << QString::fromLatin1("{\t\n\r^\"abc}")
+ << QByteArray("%7B%09%0A%0D%5E%22abc%7D")
+ << QByteArray("")
+ << QByteArray("");
+ QTest::newRow("test_03") << QString::fromLatin1("://?#[]@!$&'()*+,;=")
+ << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D")
+ << QByteArray("")
+ << QByteArray("");
+ QTest::newRow("test_04") << QString::fromLatin1("://?#[]@!$&'()*+,;=")
+ << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=")
+ << QByteArray("!$&'()*+,;=")
+ << QByteArray("");
+ QTest::newRow("test_05") << QString::fromLatin1("abcd")
+ << QByteArray("a%62%63d")
+ << QByteArray("")
+ << QByteArray("bc");
+}
+
+void tst_QUrl::toPercentEncoding()
+{
+ QFETCH(QString, original);
+ QFETCH(QByteArray, encoded);
+ QFETCH(QByteArray, excludeInEncoding);
+ QFETCH(QByteArray, includeInEncoding);
+
+ QByteArray encodedUrl = QUrl::toPercentEncoding(original, excludeInEncoding, includeInEncoding);
+ QCOMPARE(encodedUrl.constData(), encoded.constData());
+ QCOMPARE(original, QUrl::fromPercentEncoding(encodedUrl));
+}
+
+void tst_QUrl::swap()
+{
+ QUrl u1(QLatin1String("http://qt.nokia.com")), u2(QLatin1String("http://www.kdab.com"));
+ u1.swap(u2);
+ QCOMPARE(u2.host(),QLatin1String("qt.nokia.com"));
+ QCOMPARE(u1.host(),QLatin1String("www.kdab.com"));
+}
+
+void tst_QUrl::symmetry()
+{
+ QUrl url(QString::fromLatin1("http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl"));
+ QCOMPARE(url.scheme(), QString::fromLatin1("http"));
+ QCOMPARE(url.host(), QString::fromLatin1("www.räksmörgås.se"));
+ QCOMPARE(url.path(), QString::fromLatin1("/pub"));
+ // this will be encoded ...
+ QCOMPARE(url.encodedQuery().constData(), QString::fromLatin1("a=b&a=d%C3%B8&a=f").toLatin1().constData());
+ // unencoded
+ QCOMPARE(url.allQueryItemValues("a").join("").toLatin1().constData(), "bdøf");
+ QCOMPARE(url.fragment(), QString::fromLatin1("vræl"));
+
+ QUrl onlyHost("//qt.nokia.com");
+ QCOMPARE(onlyHost.toString(), QString::fromLatin1("//qt.nokia.com"));
+
+ {
+ QString urlString = QString::fromLatin1("http://desktop:33326/upnp/{32f525a6-6f31-426e-91ca-01c2e6c2c57e}");
+ QUrl urlPreviewList(urlString);
+ QCOMPARE(urlPreviewList.toString(), urlString);
+ QByteArray b = urlPreviewList.toEncoded();
+ QCOMPARE(b.constData(), "http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D");
+ QCOMPARE(QUrl::fromEncoded(b).toString(), urlString);
+
+ }{
+ QString urlString = QString::fromLatin1("http://desktop:53423/deviceDescription?uuid={7977c17b-00bf-4af9-894e-fed28573c3a9}");
+ QUrl urlPreviewList(urlString);
+ QCOMPARE(urlPreviewList.toString(), urlString);
+ QByteArray b = urlPreviewList.toEncoded();
+ QCOMPARE(b.constData(), "http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D");
+ QCOMPARE(QUrl::fromEncoded(b).toString(), urlString);
+ }
+}
+
+
+void tst_QUrl::ipv6_data()
+{
+ QTest::addColumn<QString>("ipv6Auth");
+ QTest::addColumn<bool>("isValid");
+
+ QTest::newRow("case 1") << QString::fromLatin1("//[56:56:56:56:56:56:56:56]") << true;
+ QTest::newRow("case 2") << QString::fromLatin1("//[::56:56:56:56:56:56:56]") << true;
+ QTest::newRow("case 3") << QString::fromLatin1("//[56::56:56:56:56:56:56]") << true;
+ QTest::newRow("case 4") << QString::fromLatin1("//[56:56::56:56:56:56:56]") << true;
+ QTest::newRow("case 5") << QString::fromLatin1("//[56:56:56::56:56:56:56]") << true;
+ QTest::newRow("case 6") << QString::fromLatin1("//[56:56:56:56::56:56:56]") << true;
+ QTest::newRow("case 7") << QString::fromLatin1("//[56:56:56:56:56::56:56]") << true;
+ QTest::newRow("case 8") << QString::fromLatin1("//[56:56:56:56:56:56::56]") << true;
+ QTest::newRow("case 9") << QString::fromLatin1("//[56:56:56:56:56:56:56::]") << true;
+ QTest::newRow("case 4 with one less") << QString::fromLatin1("//[56::56:56:56:56:56]") << true;
+ QTest::newRow("case 4 with less and ip4") << QString::fromLatin1("//[56::56:56:56:127.0.0.1]") << true;
+ QTest::newRow("case 7 with one and ip4") << QString::fromLatin1("//[56::255.0.0.0]") << true;
+ QTest::newRow("case 2 with ip4") << QString::fromLatin1("//[::56:56:56:56:56:0.0.0.255]") << true;
+ QTest::newRow("case 2 with half ip4") << QString::fromLatin1("//[::56:56:56:56:56:56:0.255]") << false;
+ QTest::newRow("case 4 with less and ip4 and port and useinfo") << QString::fromLatin1("//user:pass@[56::56:56:56:127.0.0.1]:99") << true;
+ QTest::newRow("case :,") << QString::fromLatin1("//[:,]") << false;
+ QTest::newRow("case ::bla") << QString::fromLatin1("//[::bla]") << false;
+}
+
+void tst_QUrl::ipv6()
+{
+ QFETCH(QString, ipv6Auth);
+ QFETCH(bool, isValid);
+
+ QUrl url(ipv6Auth);
+
+ QCOMPARE(url.isValid(), isValid);
+ if (url.isValid()) {
+ QCOMPARE(url.toString(), ipv6Auth);
+ url.setHost(url.host());
+ QCOMPARE(url.toString(), ipv6Auth);
+ }
+};
+
+void tst_QUrl::ipv6_2_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+
+ QTest::newRow("[::ffff:129.144.52.38]")
+ << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi")
+ << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi");
+ QTest::newRow("[::FFFF:129.144.52.38]")
+ << QString("http://[::FFFF:129.144.52.38]/cgi/test.cgi")
+ << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi");
+}
+
+void tst_QUrl::ipv6_2()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+
+ QUrl url(input);
+ QCOMPARE(url.toString(), output);
+ url.setHost(url.host());
+ QCOMPARE(url.toString(), output);
+}
+
+void tst_QUrl::moreIpv6()
+{
+ QUrl waba1("http://www.kde.org/cgi/test.cgi");
+ waba1.setHost("::ffff:129.144.52.38");
+ QCOMPARE(QString::fromLatin1(waba1.toEncoded()), QString::fromLatin1("http://[::ffff:129.144.52.38]/cgi/test.cgi"));
+}
+
+void tst_QUrl::punycode_data()
+{
+ QTest::addColumn<QString>("original");
+ QTest::addColumn<QByteArray>("encoded");
+
+ QTest::newRow("øl") << QString::fromLatin1("øl") << QByteArray("xn--l-4ga");
+ QTest::newRow("Bühler") << QString::fromLatin1("Bühler") << QByteArray("xn--Bhler-kva");
+ QTest::newRow("räksmörgås") << QString::fromLatin1("räksmörgås") << QByteArray("xn--rksmrgs-5wao1o");
+}
+
+void tst_QUrl::punycode()
+{
+ QFETCH(QString, original);
+ QFETCH(QByteArray, encoded);
+
+ QCOMPARE(QUrl::fromPunycode(encoded), original);
+ QCOMPARE(QUrl::fromPunycode(QUrl::toPunycode(original)), original);
+ QCOMPARE(QUrl::toPunycode(original).constData(), encoded.constData());
+}
+
+void tst_QUrl::isRelative_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<bool>("trueFalse");
+
+ QTest::newRow("not") << QString::fromLatin1("http://qt.nokia.com") << false;
+ QTest::newRow("55288") << QString::fromLatin1("node64.html#fig:form:ana") << true;
+
+ // kde
+ QTest::newRow("mailto: URL, is relative") << "mailto:faure@kde.org" << false;
+ QTest::newRow("man: URL, is relative") << "man:mmap" << false;
+ QTest::newRow("javascript: URL, is relative") << "javascript:doSomething()" << false;
+ QTest::newRow("file: URL, is relative") << "file:/blah" << false;
+ QTest::newRow("/path, is relative") << "/path" << true;
+ QTest::newRow("something, is relative") << "something" << true;
+ // end kde
+}
+
+void tst_QUrl::isRelative()
+{
+ QFETCH(QString, url);
+ QFETCH(bool, trueFalse);
+
+ QCOMPARE(QUrl(url).isRelative(), trueFalse);
+}
+
+void tst_QUrl::queryItems()
+{
+ QUrl url;
+ QVERIFY(!url.hasQuery());
+
+ QList<QPair<QString, QString> > newItems;
+ newItems += qMakePair(QString("2"), QString("b"));
+ newItems += qMakePair(QString("1"), QString("a"));
+ newItems += qMakePair(QString("3"), QString("c"));
+ newItems += qMakePair(QString("4"), QString("a b"));
+ newItems += qMakePair(QString("5"), QString("&"));
+ newItems += qMakePair(QString("foo bar"), QString("hello world"));
+ newItems += qMakePair(QString("foo+bar"), QString("hello+world"));
+ newItems += qMakePair(QString("tex"), QString("a + b = c"));
+ url.setQueryItems(newItems);
+ QVERIFY(url.hasQuery());
+
+ QList<QPair<QString, QString> > setItems = url.queryItems();
+ QVERIFY(newItems == setItems);
+
+ url.addQueryItem("1", "z");
+
+ QVERIFY(url.hasQueryItem("1"));
+ QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "a");
+
+ url.addQueryItem("1", "zz");
+
+ QStringList expected;
+ expected += "a";
+ expected += "z";
+ expected += "zz";
+ QCOMPARE(expected, url.allQueryItemValues("1"));
+
+ url.removeQueryItem("1");
+ QCOMPARE(url.allQueryItemValues("1").size(), 2);
+ QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "z");
+
+ url.removeAllQueryItems("1");
+ QVERIFY(!url.hasQueryItem("1"));
+
+ QCOMPARE(url.queryItemValue("4").toLatin1().constData(), "a b");
+ QCOMPARE(url.queryItemValue("5").toLatin1().constData(), "&");
+ QCOMPARE(url.queryItemValue("tex").toLatin1().constData(), "a + b = c");
+ QCOMPARE(url.queryItemValue("foo bar").toLatin1().constData(), "hello world");
+ url.setUrl("http://www.google.com/search?q=a+b");
+ QCOMPARE(url.queryItemValue("q"), QString("a+b"));
+ url.setUrl("http://www.google.com/search?q=a=b"); // invalid, but should be tolerated
+ QCOMPARE(url.queryItemValue("q"), QString("a=b"));
+}
+
+void tst_QUrl::hasQuery_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<bool>("trueFalse");
+
+ QTest::newRow("no query items") << "http://www.foo.bar" << false;
+
+ QTest::newRow("empty query") << "http://www.foo.bar?" << true;
+ QTest::newRow("empty query 2") << "http://www.foo.bar/?" << true;
+
+ QTest::newRow("query") << "http://www.foo.bar?query" << true;
+ QTest::newRow("query=") << "http://www.foo.bar?query=" << true;
+ QTest::newRow("query=value") << "http://www.foo.bar?query=value" << true;
+
+ QTest::newRow("%3f") << "http://www.foo.bar/file%3f" << false;
+ QTest::newRow("%3f-query") << "http://www.foo.bar/file%3fquery" << false;
+ QTest::newRow("%3f-query=value") << "http://www.foo.bar/file%3fquery=value" << false;
+}
+
+void tst_QUrl::hasQuery()
+{
+ QFETCH(QString, url);
+ QFETCH(bool, trueFalse);
+
+ QUrl qurl(url);
+ QCOMPARE(qurl.hasQuery(), trueFalse);
+ QCOMPARE(qurl.encodedQuery().isNull(), !trueFalse);
+}
+
+void tst_QUrl::hasQueryItem_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<QString>("item");
+ QTest::addColumn<bool>("trueFalse");
+
+ QTest::newRow("no query items") << "http://www.foo.bar" << "baz" << false;
+ QTest::newRow("query item: hello") << "http://www.foo.bar?hello=world" << "hello" << true;
+ QTest::newRow("no query item: world") << "http://www.foo.bar?hello=world" << "world" << false;
+ QTest::newRow("query item: qt") << "http://www.foo.bar?hello=world&qt=rocks" << "qt" << true;
+}
+
+void tst_QUrl::hasQueryItem()
+{
+ QFETCH(QString, url);
+ QFETCH(QString, item);
+ QFETCH(bool, trueFalse);
+
+ QCOMPARE(QUrl(url).hasQueryItem(item), trueFalse);
+}
+
+void tst_QUrl::nameprep()
+{
+ QUrl url(QString::fromUtf8("http://www.fu""\xc3""\x9f""ball.de/"));
+ QCOMPARE(url.toString(), QString::fromLatin1("http://www.fussball.de/"));
+}
+
+void tst_QUrl::isValid()
+{
+ {
+ QUrl url(QString("A=B"));
+ QVERIFY(url.isValid());
+ QCOMPARE(url.path(), QString("A=B"));
+ }
+ {
+ QUrl url = QUrl::fromEncoded("http://strange<username>@ok-hostname/", QUrl::StrictMode);
+ QVERIFY(!url.isValid());
+ // < and > are not allowed in userinfo in strict mode
+ url.setUserName("normal_username");
+ QVERIFY(url.isValid());
+ }
+ {
+ QUrl url = QUrl::fromEncoded("http://strange<username>@ok-hostname/");
+ QVERIFY(url.isValid());
+ // < and > are allowed in tolerant mode
+ }
+ {
+ QUrl url = QUrl::fromEncoded("http://strange;hostname/here");
+ QVERIFY(!url.isValid());
+ QCOMPARE(url.path(), QString("/here"));
+ url.setAuthority("strange;hostname");
+ QVERIFY(!url.isValid());
+ url.setAuthority("foobar@bar");
+ QVERIFY(url.isValid());
+ url.setAuthority("strange;hostname");
+ QVERIFY(!url.isValid());
+ QVERIFY(url.errorString().contains("invalid hostname"));
+ }
+
+ {
+ QUrl url = QUrl::fromEncoded("foo://stuff;1/g");
+ QVERIFY(!url.isValid());
+ QCOMPARE(url.path(), QString("/g"));
+ url.setHost("stuff;1");
+ QVERIFY(!url.isValid());
+ url.setHost("stuff-1");
+ QVERIFY(url.isValid());
+ url.setHost("stuff;1");
+ QVERIFY(!url.isValid());
+ QVERIFY(url.errorString().contains("invalid hostname"));
+ }
+
+}
+
+void tst_QUrl::schemeValidator_data()
+{
+ QTest::addColumn<QByteArray>("encodedUrl");
+ QTest::addColumn<bool>("result");
+ QTest::addColumn<QString>("toString");
+
+ QTest::newRow("empty") << QByteArray() << false << QString();
+
+ // ftp
+ QTest::newRow("ftp:") << QByteArray("ftp:") << true << QString("ftp:");
+ QTest::newRow("ftp://ftp.qt.nokia.com")
+ << QByteArray("ftp://ftp.qt.nokia.com")
+ << true << QString("ftp://ftp.qt.nokia.com");
+ QTest::newRow("ftp://ftp.qt.nokia.com/")
+ << QByteArray("ftp://ftp.qt.nokia.com/")
+ << true << QString("ftp://ftp.qt.nokia.com/");
+ QTest::newRow("ftp:/index.html")
+ << QByteArray("ftp:/index.html")
+ << false << QString();
+
+ // mailto
+ QTest::newRow("mailto:") << QByteArray("mailto:") << true << QString("mailto:");
+ QTest::newRow("mailto://smtp.trolltech.com/ole@bull.name")
+ << QByteArray("mailto://smtp.trolltech.com/ole@bull.name") << false << QString();
+ QTest::newRow("mailto:") << QByteArray("mailto:") << true << QString("mailto:");
+ QTest::newRow("mailto:ole@bull.name")
+ << QByteArray("mailto:ole@bull.name") << true << QString("mailto:ole@bull.name");
+
+ // file
+ QTest::newRow("file:") << QByteArray("file:/etc/passwd") << true << QString("file:///etc/passwd");
+}
+
+void tst_QUrl::schemeValidator()
+{
+ QFETCH(QByteArray, encodedUrl);
+ QFETCH(bool, result);
+ QFETCH(QString, toString);
+
+ QUrl url = QUrl::fromEncoded(encodedUrl);
+ QCOMPARE(url.isValid(), result);
+}
+
+void tst_QUrl::invalidSchemeValidator()
+{
+ // test that if scheme does not start with an ALPHA, QUrl::isValid() returns false
+ {
+ QUrl url("1http://qt.nokia.com", QUrl::StrictMode);
+ QCOMPARE(url.isValid(), false);
+ }
+ {
+ QUrl url("http://qt.nokia.com");
+ url.setScheme("111http://qt.nokia.com");
+ QCOMPARE(url.isValid(), false);
+ }
+ {
+ QUrl url = QUrl::fromEncoded("1http://qt.nokia.com", QUrl::StrictMode);
+ QCOMPARE(url.isValid(), false);
+ }
+
+ // non-ALPHA character at other positions in the scheme are ok
+ {
+ QUrl url("ht111tp://qt.nokia.com", QUrl::StrictMode);
+ QVERIFY(url.isValid());
+ }
+ {
+ QUrl url("http://qt.nokia.com");
+ url.setScheme("ht123tp://qt.nokia.com");
+ QVERIFY(url.isValid());
+ }
+ {
+ QUrl url = QUrl::fromEncoded("ht321tp://qt.nokia.com", QUrl::StrictMode);
+ QVERIFY(url.isValid());
+ }
+}
+
+void tst_QUrl::tolerantParser()
+{
+ {
+ QUrl url("http://www.example.com/path%20with spaces.html");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.path(), QString("/path with spaces.html"));
+ QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%20with%20spaces.html"));
+ url.setUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode);
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%2520with%20spaces.html"));
+ }
+ {
+ QUrl url = QUrl::fromEncoded("http://www.example.com/path%20with spaces.html");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.path(), QString("/path with spaces.html"));
+ url.setEncodedUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode);
+ QVERIFY(!url.isValid());
+ }
+
+ {
+ QUrl url15581("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.htm>");
+ QVERIFY(url15581.isValid());
+ QCOMPARE(url15581.toEncoded().constData(), "http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.htm%3E");
+ }
+
+ {
+ QUrl webkit22616 =
+ QUrl::fromEncoded("http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%u0442%u0435%u0441%u0442");
+ QVERIFY(webkit22616.isValid());
+ QCOMPARE(webkit22616.toEncoded().constData(),
+ "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%25u0442%25u0435%25u0441%25u0442");
+ }
+
+ {
+ QUrl url;
+ url.setUrl("http://foo.bar/[image][1].jpg");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+
+ url.setUrl("[].jpg");
+ QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg"));
+
+ url.setUrl("/some/[path]/[]");
+ QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D"));
+
+ url.setUrl("//[::56:56:56:56:56:56:56]");
+ QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]"));
+
+ url.setUrl("//[::56:56:56:56:56:56:56]#[]");
+ QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]#%5B%5D"));
+
+ url.setUrl("//[::56:56:56:56:56:56:56]?[]");
+ QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]?%5B%5D"));
+
+ url.setUrl("%hello.com/f%");
+ QCOMPARE(url.toEncoded(), QByteArray("%25hello.com/f%25"));
+
+ url.setEncodedUrl("http://www.host.com/foo.php?P0=[2006-3-8]");
+ QVERIFY(url.isValid());
+
+ url.setEncodedUrl("http://foo.bar/[image][1].jpg");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+
+ url.setEncodedUrl("[].jpg");
+ QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg"));
+
+ url.setEncodedUrl("/some/[path]/[]");
+ QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D"));
+
+ url.setEncodedUrl("//[::56:56:56:56:56:56:56]");
+ QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]"));
+
+ url.setEncodedUrl("//[::56:56:56:56:56:56:56]#[]");
+ QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]#%5B%5D"));
+
+ url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]");
+ QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]?%5B%5D"));
+
+ url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}");
+ QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D"));
+ }
+
+ {
+ // task 243557
+ QByteArray tsdgeos("http://google.com/c?c=Translation+%C2%BB+trunk|");
+ QUrl tsdgeosQUrl;
+ tsdgeosQUrl.setEncodedUrl(tsdgeos, QUrl::TolerantMode);
+ QVERIFY(tsdgeosQUrl.isValid()); // failed in Qt-4.4, works in Qt-4.5
+ QByteArray tsdgeosExpected("http://google.com/c?c=Translation+%C2%BB+trunk%7C");
+ //QCOMPARE(tsdgeosQUrl.toEncoded(), tsdgeosExpected); // unusable output from qtestlib...
+ QCOMPARE(QString(tsdgeosQUrl.toEncoded()), QString(tsdgeosExpected));
+ }
+
+ {
+ QUrl url;
+ url.setUrl("http://strange<username>@hostname/", QUrl::TolerantMode);
+ QVERIFY(url.isValid());
+ QCOMPARE(QString(url.toEncoded()), QString("http://strange%3Cusername%3E@hostname/"));
+ }
+}
+
+void tst_QUrl::correctEncodedMistakes_data()
+{
+ QTest::addColumn<QByteArray>("encodedUrl");
+ QTest::addColumn<bool>("result");
+ QTest::addColumn<QString>("toString");
+ QTest::addColumn<QByteArray>("toEncoded");
+
+ QTest::newRow("%") << QByteArray("%") << true << QString("%") << QByteArray("%25");
+ QTest::newRow("3%") << QByteArray("3%") << true << QString("3%") << QByteArray("3%25");
+ QTest::newRow("13%") << QByteArray("13%") << true << QString("13%") << QByteArray("13%25");
+ QTest::newRow("13%!") << QByteArray("13%!") << true << QString("13%!") << QByteArray("13%25!");
+ QTest::newRow("13%!!") << QByteArray("13%!!") << true << QString("13%!!") << QByteArray("13%25!!");
+ QTest::newRow("13%a") << QByteArray("13%a") << true << QString("13%a") << QByteArray("13%25a");
+ QTest::newRow("13%az") << QByteArray("13%az") << true << QString("13%az") << QByteArray("13%25az");
+ QTest::newRow("13%25") << QByteArray("13%25") << true << QString("13%") << QByteArray("13%25");
+}
+
+void tst_QUrl::correctEncodedMistakes()
+{
+ QFETCH(QByteArray, encodedUrl);
+ QFETCH(bool, result);
+ QFETCH(QString, toString);
+ QFETCH(QByteArray, toEncoded);
+
+ QUrl url = QUrl::fromEncoded(encodedUrl);
+ QCOMPARE(url.isValid(), result);
+ if (url.isValid()) {
+ QCOMPARE(url.toString(), toString);
+ QCOMPARE(url.toEncoded(), toEncoded);
+ }
+}
+
+void tst_QUrl::correctDecodedMistakes_data()
+{
+ QTest::addColumn<QString>("decodedUrl");
+ QTest::addColumn<bool>("result");
+ QTest::addColumn<QString>("toString");
+ QTest::addColumn<QByteArray>("toEncoded");
+
+ QTest::newRow("%") << QString("%") << true << QString("%") << QByteArray("%25");
+ QTest::newRow("3%") << QString("3%") << true << QString("3%") << QByteArray("3%25");
+ QTest::newRow("13%") << QString("13%") << true << QString("13%") << QByteArray("13%25");
+ QTest::newRow("13%!") << QString("13%!") << true << QString("13%!") << QByteArray("13%25!");
+ QTest::newRow("13%!!") << QString("13%!!") << true << QString("13%!!") << QByteArray("13%25!!");
+ QTest::newRow("13%a") << QString("13%a") << true << QString("13%a") << QByteArray("13%25a");
+ QTest::newRow("13%az") << QString("13%az") << true << QString("13%az") << QByteArray("13%25az");
+ QTest::newRow("13%25") << QString("13%25") << true << QString("13%25") << QByteArray("13%2525");
+}
+
+void tst_QUrl::correctDecodedMistakes()
+{
+ QFETCH(QString, decodedUrl);
+ QFETCH(bool, result);
+ QFETCH(QString, toString);
+ QFETCH(QByteArray, toEncoded);
+
+ QUrl url(decodedUrl);
+ QCOMPARE(url.isValid(), result);
+ if (url.isValid()) {
+ QCOMPARE(url.toString(), toString);
+ QCOMPARE(url.toEncoded(), toEncoded);
+ }
+}
+
+void tst_QUrl::idna_testsuite_data()
+{
+ QTest::addColumn<int>("numchars");
+ QTest::addColumn<ushortarray>("unicode");
+ QTest::addColumn<QByteArray>("punycode");
+ QTest::addColumn<int>("allowunassigned");
+ QTest::addColumn<int>("usestd3asciirules");
+ QTest::addColumn<int>("toasciirc");
+ QTest::addColumn<int>("tounicoderc");
+
+ unsigned short d1[] = { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643,
+ 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A,
+ 0x061F };
+ QTest::newRow("Arabic (Egyptian)") << 17 << ushortarray(d1)
+ << QByteArray(IDNA_ACE_PREFIX "egbpdaj6bu4bxfgehfvwxn")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d2[] = { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D,
+ 0x6587 };
+ QTest::newRow("Chinese (simplified)") << 9 << ushortarray(d2)
+ << QByteArray(IDNA_ACE_PREFIX "ihqwcrb4cv8a8dqg056pqjye")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d3[] = { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D,
+ 0x6587 };
+ QTest::newRow("Chinese (traditional)") << 9 << ushortarray(d3)
+ << QByteArray(IDNA_ACE_PREFIX "ihqwctvzc91f659drss3x8bo0yb")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d4[] = { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073,
+ 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076,
+ 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 };
+ QTest::newRow("Czech") << 22 << ushortarray(d4)
+ << QByteArray(IDNA_ACE_PREFIX "Proprostnemluvesky-uyb24dma41a")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d5[] = { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5,
+ 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9,
+ 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA };
+ QTest::newRow("Hebrew") << 22 << ushortarray(d5)
+ << QByteArray(IDNA_ACE_PREFIX "4dbcagdahymbxekheh6e0a7fei0b")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d6[] = { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928,
+ 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902,
+ 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938,
+ 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 };
+ QTest::newRow("Hindi (Devanagari)") << 30 << ushortarray(d6)
+ << QByteArray(IDNA_ACE_PREFIX "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd")
+ << 0 << 0 << IDNA_SUCCESS;
+
+ unsigned short d7[] = { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E,
+ 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044,
+ 0x306E, 0x304B };
+ QTest::newRow("Japanese (kanji and hiragana)") << 18 << ushortarray(d7)
+ << QByteArray(IDNA_ACE_PREFIX "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa")
+ << 0 << 0 << IDNA_SUCCESS;
+
+ unsigned short d8[] = { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435,
+ 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432,
+ 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443,
+ 0x0441, 0x0441, 0x043A, 0x0438 };
+ QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d8)
+ << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d9[] = { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F,
+ 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069,
+ 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074,
+ 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065,
+ 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C };
+ QTest::newRow("Spanish") << 40 << ushortarray(d9)
+ << QByteArray(IDNA_ACE_PREFIX "PorqunopuedensimplementehablarenEspaol-fmd56a")
+ << 0 << 0 << IDNA_SUCCESS;
+
+ unsigned short d10[] = { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD,
+ 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3,
+ 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069,
+ 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 };
+ QTest::newRow("Vietnamese") << 31 << ushortarray(d10)
+ << QByteArray(IDNA_ACE_PREFIX "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g")
+ << 0 << 0 << IDNA_SUCCESS;
+
+ unsigned short d11[] = { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F };
+ QTest::newRow("Japanese") << 8 << ushortarray(d11)
+ << QByteArray(IDNA_ACE_PREFIX "3B-ww4c5e180e575a65lsy2b")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d12[] = { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069,
+ 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052,
+ 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 };
+ QTest::newRow("Japanese2") << 24 << ushortarray(d12)
+ << QByteArray(IDNA_ACE_PREFIX "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n")
+ << 0 << 0 << IDNA_SUCCESS;
+
+ unsigned short d13[] = { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E,
+ 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061,
+ 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834,
+ 0x6240 };
+ QTest::newRow("Japanese3") << 25 << ushortarray(d13)
+ << QByteArray(IDNA_ACE_PREFIX "Hello-Another-Way--fc4qua05auwb3674vfr0b")
+ << 0 << 0 << IDNA_SUCCESS;
+
+ unsigned short d14[] = { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 };
+ QTest::newRow("Japanese4") << 8 << ushortarray(d14)
+ << QByteArray(IDNA_ACE_PREFIX "2-u9tlzr9756bt3uc0v")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d15[] = { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069,
+ 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D };
+ QTest::newRow("Japanese5") << 13 << ushortarray(d15)
+ << QByteArray(IDNA_ACE_PREFIX "MajiKoi5-783gue6qz075azm5e")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d16[] = { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 };
+ QTest::newRow("Japanese6") << 9 << ushortarray(d16)
+ << QByteArray(IDNA_ACE_PREFIX "de-jg4avhby1noc0d")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d17[] = { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 };
+ QTest::newRow("Japanese7") << 7 << ushortarray(d17)
+ << QByteArray(IDNA_ACE_PREFIX "d9juau41awczczp")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d18[] = { 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac };
+ QTest::newRow("Greek") << 8 << ushortarray(d18)
+ << QByteArray(IDNA_ACE_PREFIX "hxargifdar")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d19[] = { 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
+ 0x0127, 0x0061 };
+ QTest::newRow("Maltese (Malti)") << 10 << ushortarray(d19)
+ << QByteArray(IDNA_ACE_PREFIX "bonusaa-5bb1da")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ unsigned short d20[] = {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
+ 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
+ 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
+ 0x0441, 0x0441, 0x043a, 0x0438 };
+ QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d20)
+ << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l")
+ << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+}
+
+void tst_QUrl::idna_testsuite()
+{
+ QFETCH(int, numchars);
+ QFETCH(ushortarray, unicode);
+ QFETCH(QByteArray, punycode);
+
+ QString s = QString::fromUtf16(unicode.points, numchars);
+ QCOMPARE(punycode, QUrl::toPunycode(s));
+}
+
+void tst_QUrl::nameprep_testsuite_data()
+{
+ QTest::addColumn<QString>("in");
+ QTest::addColumn<QString>("out");
+ QTest::addColumn<QString>("profile");
+ QTest::addColumn<int>("flags");
+ QTest::addColumn<int>("rc");
+
+ QTest::newRow("Map to nothing")
+ << QString::fromUtf8("foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B"
+ "bar""\xE2\x80\x8B\xE2\x81\xA0""baz\xEF\xB8\x80\xEF\xB8\x88"
+ "\xEF\xB8\x8F\xEF\xBB\xBF")
+ << QString::fromUtf8("foobarbaz")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Case folding ASCII U+0043 U+0041 U+0046 U+0045")
+ << QString::fromUtf8("CAFE")
+ << QString::fromUtf8("cafe")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Case folding 8bit U+00DF (german sharp s)")
+ << QString::fromUtf8("\xC3\x9F")
+ << QString("ss")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Case folding U+0130 (turkish capital I with dot)")
+ << QString::fromUtf8("\xC4\xB0")
+ << QString::fromUtf8("i\xcc\x87")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Case folding multibyte U+0143 U+037A")
+ << QString::fromUtf8("\xC5\x83\xCD\xBA")
+ << QString::fromUtf8("\xC5\x84 \xCE\xB9")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Case folding U+2121 U+33C6 U+1D7BB")
+ << QString::fromUtf8("\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB")
+ << QString::fromUtf8("telc\xE2\x88\x95""kg\xCF\x83")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Normalization of U+006a U+030c U+00A0 U+00AA")
+ << QString::fromUtf8("\x6A\xCC\x8C\xC2\xA0\xC2\xAA")
+ << QString::fromUtf8("\xC7\xB0 a")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Case folding U+1FB7 and normalization")
+ << QString::fromUtf8("\xE1\xBE\xB7")
+ << QString::fromUtf8("\xE1\xBE\xB6\xCE\xB9")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Self-reverting case folding U+01F0 and normalization")
+// << QString::fromUtf8("\xC7\xF0") ### typo in the original testsuite
+ << QString::fromUtf8("\xC7\xB0")
+ << QString::fromUtf8("\xC7\xB0")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Self-reverting case folding U+0390 and normalization")
+ << QString::fromUtf8("\xCE\x90")
+ << QString::fromUtf8("\xCE\x90")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Self-reverting case folding U+03B0 and normalization")
+ << QString::fromUtf8("\xCE\xB0")
+ << QString::fromUtf8("\xCE\xB0")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Self-reverting case folding U+1E96 and normalization")
+ << QString::fromUtf8("\xE1\xBA\x96")
+ << QString::fromUtf8("\xE1\xBA\x96")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Self-reverting case folding U+1F56 and normalization")
+ << QString::fromUtf8("\xE1\xBD\x96")
+ << QString::fromUtf8("\xE1\xBD\x96")
+ << QString() << 0 << 0;
+
+ QTest::newRow("ASCII space character U+0020")
+ << QString::fromUtf8("\x20")
+ << QString::fromUtf8("\x20")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Non-ASCII 8bit space character U+00A0")
+ << QString::fromUtf8("\xC2\xA0")
+ << QString::fromUtf8("\x20")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Non-ASCII multibyte space character U+1680")
+ << QString::fromUtf8("\xE1\x9A\x80")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Non-ASCII multibyte space character U+2000")
+ << QString::fromUtf8("\xE2\x80\x80")
+ << QString::fromUtf8("\x20")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Zero Width Space U+200b")
+ << QString::fromUtf8("\xE2\x80\x8b")
+ << QString()
+ << QString() << 0 << 0;
+
+ QTest::newRow("Non-ASCII multibyte space character U+3000")
+ << QString::fromUtf8("\xE3\x80\x80")
+ << QString::fromUtf8("\x20")
+ << QString() << 0 << 0;
+
+ QTest::newRow("ASCII control characters U+0010 U+007F")
+ << QString::fromUtf8("\x10\x7F")
+ << QString::fromUtf8("\x10\x7F")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Non-ASCII 8bit control character U+0085")
+ << QString::fromUtf8("\xC2\x85")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Non-ASCII multibyte control character U+180E")
+ << QString::fromUtf8("\xE1\xA0\x8E")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Zero Width No-Break Space U+FEFF")
+ << QString::fromUtf8("\xEF\xBB\xBF")
+ << QString()
+ << QString() << 0 << 0;
+
+ QTest::newRow("Non-ASCII control character U+1D175")
+ << QString::fromUtf8("\xF0\x9D\x85\xB5")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Plane 0 private use character U+F123")
+ << QString::fromUtf8("\xEF\x84\xA3")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Plane 15 private use character U+F1234")
+ << QString::fromUtf8("\xF3\xB1\x88\xB4")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Plane 16 private use character U+10F234")
+ << QString::fromUtf8("\xF4\x8F\x88\xB4")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Non-character code point U+8FFFE")
+ << QString::fromUtf8("\xF2\x8F\xBF\xBE")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Non-character code point U+10FFFF")
+ << QString::fromUtf8("\xF4\x8F\xBF\xBF")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Surrogate code U+DF42")
+ << QString::fromUtf8("\xED\xBD\x82")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Non-plain text character U+FFFD")
+ << QString::fromUtf8("\xEF\xBF\xBD")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Ideographic description character U+2FF5")
+ << QString::fromUtf8("\xE2\xBF\xB5")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Display property character U+0341")
+ << QString::fromUtf8("\xCD\x81")
+ << QString::fromUtf8("\xCC\x81")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Left-to-right mark U+200E")
+ << QString::fromUtf8("\xE2\x80\x8E")
+ << QString::fromUtf8("\xCC\x81")
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Deprecated U+202A")
+ << QString::fromUtf8("\xE2\x80\xAA")
+ << QString::fromUtf8("\xCC\x81")
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Language tagging character U+E0001")
+ << QString::fromUtf8("\xF3\xA0\x80\x81")
+ << QString::fromUtf8("\xCC\x81")
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Language tagging character U+E0042")
+ << QString::fromUtf8("\xF3\xA0\x81\x82")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
+
+ QTest::newRow("Bidi: RandALCat character U+05BE and LCat characters")
+ << QString::fromUtf8("foo\xD6\xBE""bar")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL;
+
+ QTest::newRow("Bidi: RandALCat character U+FD50 and LCat characters")
+ << QString::fromUtf8("foo\xEF\xB5\x90""bar")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL;
+
+ QTest::newRow("Bidi: RandALCat character U+FB38 and LCat characters")
+ << QString::fromUtf8("foo\xEF\xB9\xB6""bar")
+ << QString::fromUtf8("foo \xd9\x8e""bar")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Bidi: RandALCat without trailing RandALCat U+0627 U+0031")
+ << QString::fromUtf8("\xD8\xA7\x31")
+ << QString()
+ << QString("Nameprep") << 0 << STRINGPREP_BIDI_LEADTRAIL_NOT_RAL;
+
+ QTest::newRow("Bidi: RandALCat character U+0627 U+0031 U+0628")
+ << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8")
+ << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8")
+ << QString() << 0 << 0;
+
+ QTest::newRow("Unassigned code point U+E0002")
+ << QString::fromUtf8("\xF3\xA0\x80\x82")
+ << QString()
+ << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED;
+
+ QTest::newRow("Larger test (shrinking)")
+ << QString::fromUtf8("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2"
+ "\xaa\xce\xb0\xe2\x80\x80")
+ << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ")
+ << QString("Nameprep") << 0 << 0;
+
+ QTest::newRow("Larger test (expanding)")
+ << QString::fromUtf8("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80")
+ << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88"
+ "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91"
+ "\xe3\x83\xbc\xe3\x83\x88")
+ << QString() << 0 << 0;
+}
+
+#ifdef QT_BUILD_INTERNAL
+QT_BEGIN_NAMESPACE
+extern void qt_nameprep(QString *source, int from);
+extern bool qt_check_std3rules(const QChar *, int);
+QT_END_NAMESPACE
+#endif
+
+void tst_QUrl::nameprep_testsuite()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QString, in);
+ QFETCH(QString, out);
+ QFETCH(QString, profile);
+
+ QEXPECT_FAIL("Left-to-right mark U+200E",
+ "Investigate further", Continue);
+ QEXPECT_FAIL("Deprecated U+202A",
+ "Investigate further", Continue);
+ QEXPECT_FAIL("Language tagging character U+E0001",
+ "Investigate further", Continue);
+ qt_nameprep(&in, 0);
+ QCOMPARE(in, out);
+#endif
+}
+
+void tst_QUrl::nameprep_highcodes_data()
+{
+ QTest::addColumn<QString>("in");
+ QTest::addColumn<QString>("out");
+ QTest::addColumn<QString>("profile");
+ QTest::addColumn<int>("flags");
+ QTest::addColumn<int>("rc");
+
+ {
+ QChar st[] = { '-', 0xd801, 0xdc1d, 'a' };
+ QChar se[] = { '-', 0xd801, 0xdc45, 'a' };
+ QTest::newRow("highcodes (U+1041D)")
+ << QString(st, sizeof(st)/sizeof(st[0]))
+ << QString(se, sizeof(se)/sizeof(se[0]))
+ << QString() << 0 << 0;
+ }
+ {
+ QChar st[] = { 0x011C, 0xd835, 0xdf6e, 0x0110 };
+ QChar se[] = { 0x011D, 0x03C9, 0x0111 };
+ QTest::newRow("highcodes (U+1D76E)")
+ << QString(st, sizeof(st)/sizeof(st[0]))
+ << QString(se, sizeof(se)/sizeof(se[0]))
+ << QString() << 0 << 0;
+ }
+ {
+ QChar st[] = { 'D', 0xdb40, 0xdc20, 'o', 0xd834, 0xdd7a, '\'', 0x2060, 'h' };
+ QChar se[] = { 'd', 'o', '\'', 'h' };
+ QTest::newRow("highcodes (D, U+E0020, o, U+1D17A, ', U+2060, h)")
+ << QString(st, sizeof(st)/sizeof(st[0]))
+ << QString(se, sizeof(se)/sizeof(se[0]))
+ << QString() << 0 << 0;
+ }
+}
+
+void tst_QUrl::nameprep_highcodes()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QString, in);
+ QFETCH(QString, out);
+ QFETCH(QString, profile);
+
+ qt_nameprep(&in, 0);
+ QCOMPARE(in, out);
+#endif
+}
+
+void tst_QUrl::ace_testsuite_data()
+{
+ QTest::addColumn<QString>("in");
+ QTest::addColumn<QString>("toace");
+ QTest::addColumn<QString>("fromace");
+ QTest::addColumn<QString>("unicode");
+
+ QTest::newRow("ascii-lower") << "fluke" << "fluke" << "fluke" << "fluke";
+ QTest::newRow("ascii-mixed") << "FLuke" << "fluke" << "fluke" << "fluke";
+ QTest::newRow("ascii-upper") << "FLUKE" << "fluke" << "fluke" << "fluke";
+
+ QTest::newRow("asciifolded") << QString::fromLatin1("stra\337e") << "strasse" << "." << "strasse";
+ QTest::newRow("asciifolded-dotcom") << QString::fromLatin1("stra\337e.example.com") << "strasse.example.com" << "." << "strasse.example.com";
+ QTest::newRow("greek-mu") << QString::fromLatin1("\265V")
+ <<"xn--v-lmb"
+ << "."
+ << QString::fromUtf8("\316\274v");
+
+ QTest::newRow("non-ascii-lower") << QString::fromLatin1("alqualond\353")
+ << "xn--alqualond-34a"
+ << "."
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("non-ascii-mixed") << QString::fromLatin1("Alqualond\353")
+ << "xn--alqualond-34a"
+ << "."
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("non-ascii-upper") << QString::fromLatin1("ALQUALOND\313")
+ << "xn--alqualond-34a"
+ << "."
+ << QString::fromLatin1("alqualond\353");
+
+ QTest::newRow("idn-lower") << "xn--alqualond-34a" << "xn--alqualond-34a"
+ << QString::fromLatin1("alqualond\353")
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("idn-mixed") << "Xn--alqualond-34a" << "xn--alqualond-34a"
+ << QString::fromLatin1("alqualond\353")
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("idn-mixed2") << "XN--alqualond-34a" << "xn--alqualond-34a"
+ << QString::fromLatin1("alqualond\353")
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("idn-mixed3") << "xn--ALQUALOND-34a" << "xn--alqualond-34a"
+ << QString::fromLatin1("alqualond\353")
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("idn-mixed4") << "xn--alqualond-34A" << "xn--alqualond-34a"
+ << QString::fromLatin1("alqualond\353")
+ << QString::fromLatin1("alqualond\353");
+ QTest::newRow("idn-upper") << "XN--ALQUALOND-34A" << "xn--alqualond-34a"
+ << QString::fromLatin1("alqualond\353")
+ << QString::fromLatin1("alqualond\353");
+
+ QTest::newRow("separator-3002") << QString::fromUtf8("example\343\200\202com")
+ << "example.com" << "." << "example.com";
+
+ QString egyptianIDN =
+ QString::fromUtf8("\331\210\330\262\330\247\330\261\330\251\055\330\247\331\204\330"
+ "\243\330\252\330\265\330\247\331\204\330\247\330\252.\331\205"
+ "\330\265\330\261");
+ QTest::newRow("egyptian-tld-ace")
+ << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c"
+ << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c"
+ << "."
+ << egyptianIDN;
+ QTest::newRow("egyptian-tld-unicode")
+ << egyptianIDN
+ << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c"
+ << "."
+ << egyptianIDN;
+ QTest::newRow("egyptian-tld-mix1")
+ << QString::fromUtf8("\331\210\330\262\330\247\330\261\330\251\055\330\247\331\204\330"
+ "\243\330\252\330\265\330\247\331\204\330\247\330\252.xn--wgbh1c")
+ << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c"
+ << "."
+ << egyptianIDN;
+ QTest::newRow("egyptian-tld-mix2")
+ << QString::fromUtf8("xn----rmckbbajlc6dj7bxne2c.\331\205\330\265\330\261")
+ << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c"
+ << "."
+ << egyptianIDN;
+}
+
+void tst_QUrl::ace_testsuite()
+{
+ static const char canonsuffix[] = ".troll.no";
+ QFETCH(QString, in);
+ QFETCH(QString, toace);
+ QFETCH(QString, fromace);
+ QFETCH(QString, unicode);
+
+ const char *suffix = canonsuffix;
+ if (toace.contains('.'))
+ suffix = 0;
+
+ QString domain = in + suffix;
+ QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
+ if (fromace != ".")
+ QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
+ QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);
+
+ domain = in + (suffix ? ".troll.No" : "");
+ QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
+ if (fromace != ".")
+ QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
+ QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);
+
+ domain = in + (suffix ? ".troll.NO" : "");
+ QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
+ if (fromace != ".")
+ QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
+ QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);
+}
+
+void tst_QUrl::std3violations_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<bool>("validUrl");
+
+ QTest::newRow("too-long") << "this-domain-is-far-too-long-for-its-own-good-and-should-have-been-limited-to-63-chars" << false;
+ QTest::newRow("dash-begin") << "-x-foo" << false;
+ QTest::newRow("dash-end") << "x-foo-" << false;
+ QTest::newRow("dash-begin-end") << "-foo-" << false;
+
+ QTest::newRow("control") << "\033foo" << false;
+ QTest::newRow("bang") << "foo!" << false;
+ QTest::newRow("plus") << "foo+bar" << false;
+ QTest::newRow("dot") << "foo.bar";
+ QTest::newRow("startingdot") << ".bar" << false;
+ QTest::newRow("startingdot2") << ".example.com" << false;
+ QTest::newRow("slash") << "foo/bar" << true;
+ QTest::newRow("colon") << "foo:80" << true;
+ QTest::newRow("question") << "foo?bar" << true;
+ QTest::newRow("at") << "foo@bar" << true;
+ QTest::newRow("backslash") << "foo\\bar" << false;
+
+ // these characters are transformed by NFKC to non-LDH characters
+ QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false; // U+2024 ONE DOT LEADER
+ QTest::newRow("slash-like") << QString::fromUtf8("foo\357\274\217bar") << false; // U+FF0F FULLWIDTH SOLIDUS
+
+ // The following should be invalid but isn't
+ // the DIVISON SLASH doesn't case-fold to a slash
+ // is this a problem with RFC 3490?
+ //QTest::newRow("slash-like2") << QString::fromUtf8("foo\342\210\225bar") << false; // U+2215 DIVISION SLASH
+}
+
+void tst_QUrl::std3violations()
+{
+ QFETCH(QString, source);
+
+#ifdef QT_BUILD_INTERNAL
+ {
+ QString prepped = source;
+ qt_nameprep(&prepped, 0);
+ QVERIFY(!qt_check_std3rules(prepped.constData(), prepped.length()));
+ }
+#endif
+
+ if (source.contains('.'))
+ return; // this test ends here
+
+ QUrl url;
+ url.setHost(source);
+ QVERIFY(url.host().isEmpty());
+
+ QFETCH(bool, validUrl);
+ if (validUrl)
+ return; // test ends here for these cases
+
+ url = QUrl("http://" + source + "/some/path");
+ QVERIFY(!url.isValid());
+}
+
+void tst_QUrl::std3deviations_data()
+{
+ QTest::addColumn<QString>("source");
+
+ QTest::newRow("ending-dot") << "example.com.";
+ QTest::newRow("ending-dot3002") << QString("example.com") + QChar(0x3002);
+ QTest::newRow("underline") << "foo_bar"; //QTBUG-7434
+}
+
+void tst_QUrl::std3deviations()
+{
+ QFETCH(QString, source);
+ QVERIFY(!QUrl::toAce(source).isEmpty());
+
+ QUrl url;
+ url.setHost(source);
+ QVERIFY(!url.host().isEmpty());
+}
+
+void tst_QUrl::tldRestrictions_data()
+{
+ QTest::addColumn<QString>("tld");
+ QTest::addColumn<bool>("encode");
+
+ // current whitelist
+ QTest::newRow("ac") << QString("ac") << true;
+ QTest::newRow("at") << QString("at") << true;
+ QTest::newRow("br") << QString("br") << true;
+ QTest::newRow("cat") << QString("cat") << true;
+ QTest::newRow("ch") << QString("ch") << true;
+ QTest::newRow("cl") << QString("cl") << true;
+ QTest::newRow("cn") << QString("cn") << true;
+ QTest::newRow("de") << QString("de") << true;
+ QTest::newRow("dk") << QString("dk") << true;
+ QTest::newRow("fi") << QString("fi") << true;
+ QTest::newRow("hu") << QString("hu") << true;
+ QTest::newRow("info") << QString("info") << true;
+ QTest::newRow("io") << QString("io") << true;
+ QTest::newRow("jp") << QString("jp") << true;
+ QTest::newRow("kr") << QString("kr") << true;
+ QTest::newRow("li") << QString("li") << true;
+ QTest::newRow("lt") << QString("lt") << true;
+ QTest::newRow("museum") << QString("museum") << true;
+ QTest::newRow("no") << QString("no") << true;
+ QTest::newRow("se") << QString("se") << true;
+ QTest::newRow("sh") << QString("sh") << true;
+ QTest::newRow("th") << QString("th") << true;
+ QTest::newRow("tm") << QString("tm") << true;
+ QTest::newRow("tw") << QString("tw") << true;
+ QTest::newRow("vn") << QString("vn") << true;
+
+ // known blacklists:
+ QTest::newRow("com") << QString("com") << false;
+ QTest::newRow("foo") << QString("foo") << false;
+}
+
+void tst_QUrl::tldRestrictions()
+{
+ QFETCH(QString, tld);
+
+ // www.brød.tld
+ QByteArray ascii = "www.xn--brd-1na." + tld.toLatin1();
+ QString unicode = QLatin1String("www.br\370d.") + tld;
+ QString encoded = QUrl::fromAce(ascii);
+ QTEST(!encoded.contains(".xn--"), "encode");
+ QTEST(encoded == unicode, "encode");
+
+ QUrl url = QUrl::fromEncoded("http://www.xn--brd-1na." + tld.toLatin1());
+ QTEST(!url.host().contains(".xn--"), "encode");
+ QTEST(url.host() == unicode, "encode");
+
+ url.setUrl(QLatin1String("http://www.xn--brd-1na.") + tld);
+ QTEST(!url.host().contains(".xn--"), "encode");
+ QTEST(url.host() == unicode, "encode");
+
+ url.setUrl(QLatin1String("http://www.br\370d.") + tld);
+ QTEST(!url.host().contains(".xn--"), "encode");
+ QTEST(url.host() == unicode, "encode");
+
+ url = QUrl::fromEncoded("http://www.br%C3%B8d." + tld.toLatin1());
+ QTEST(!url.host().contains(".xn--"), "encode");
+ QTEST(url.host() == unicode, "encode");
+}
+
+void tst_QUrl::emptyQueryOrFragment()
+{
+ QUrl qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi?", QUrl::TolerantMode);
+ QCOMPARE(qurl.toEncoded().constData(), "http://www.kde.org/cgi/test.cgi?"); // Empty refs should be preserved
+ QCOMPARE(qurl.toString(), QString("http://www.kde.org/cgi/test.cgi?"));
+ qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi#", QUrl::TolerantMode);
+ QCOMPARE(qurl.toEncoded().constData(), "http://www.kde.org/cgi/test.cgi#");
+ QCOMPARE(qurl.toString(), QString("http://www.kde.org/cgi/test.cgi#"));
+
+ {
+ // start with an empty one
+ QUrl url("http://www.foo.bar/baz");
+ QVERIFY(!url.hasFragment());
+ QVERIFY(url.fragment().isNull());
+
+ // add fragment
+ url.setFragment(QLatin1String("abc"));
+ QVERIFY(url.hasFragment());
+ QCOMPARE(url.fragment(), QString(QLatin1String("abc")));
+ QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz#abc")));
+
+ // remove fragment
+ url.setFragment(QString());
+ QVERIFY(!url.hasFragment());
+ QVERIFY(url.fragment().isNull());
+ QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz")));
+
+ // add empty fragment
+ url.setFragment(QLatin1String(""));
+ QVERIFY(url.hasFragment());
+ QVERIFY(url.fragment().isEmpty());
+ QVERIFY(!url.fragment().isNull());
+ QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz#")));
+ }
+
+ {
+ // start with an empty one
+ QUrl url("http://www.foo.bar/baz");
+ QVERIFY(!url.hasQuery());
+ QVERIFY(url.encodedQuery().isNull());
+
+ // add encodedQuery
+ url.setEncodedQuery("abc=def");
+ QVERIFY(url.hasQuery());
+ QCOMPARE(QString(url.encodedQuery()), QString(QLatin1String("abc=def")));
+ QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def")));
+
+ // remove encodedQuery
+ url.setEncodedQuery(0);
+ QVERIFY(!url.hasQuery());
+ QVERIFY(url.encodedQuery().isNull());
+ QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz")));
+
+ // add empty encodedQuery
+ url.setEncodedQuery("");
+ QVERIFY(url.hasQuery());
+ QVERIFY(url.encodedQuery().isEmpty());
+ QVERIFY(!url.encodedQuery().isNull());
+ QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?")));
+ }
+}
+
+void tst_QUrl::hasFragment_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<bool>("trueFalse");
+
+ QTest::newRow("no fragment") << "http://www.foo.bar" << false;
+
+ QTest::newRow("empty fragment") << "http://www.foo.bar#" << true;
+ QTest::newRow("empty fragment 2") << "http://www.foo.bar/#" << true;
+
+ QTest::newRow("fragment") << "http://www.foo.bar#baz" << true;
+ QTest::newRow("fragment2") << "http://www.foo.bar/#baz" << true;
+
+ QTest::newRow("%23") << "http://www.foo.bar/%23" << false;
+ QTest::newRow("%23-and-something") << "http://www.foo.bar/%23baz" << false;
+}
+
+void tst_QUrl::hasFragment()
+{
+ QFETCH(QString, url);
+ QFETCH(bool, trueFalse);
+
+ QUrl qurl(url);
+ QCOMPARE(qurl.hasFragment(), trueFalse);
+ QCOMPARE(qurl.fragment().isNull(), !trueFalse);
+}
+
+void tst_QUrl::setEncodedFragment_data()
+{
+ QTest::addColumn<QByteArray>("base");
+ QTest::addColumn<QByteArray>("fragment");
+ QTest::addColumn<QByteArray>("expected");
+
+ typedef QByteArray BA;
+ QTest::newRow("empty") << BA("http://www.kde.org") << BA("") << BA("http://www.kde.org#");
+ QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc");
+ QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new");
+ QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c");
+ QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a#b");
+}
+
+void tst_QUrl::setEncodedFragment()
+{
+ QFETCH(QByteArray, base);
+ QFETCH(QByteArray, fragment);
+ QFETCH(QByteArray, expected);
+ QUrl u;
+ u.setEncodedUrl(base, QUrl::TolerantMode);
+ QVERIFY(u.isValid());
+ u.setEncodedFragment(fragment);
+ QVERIFY(u.isValid());
+ QVERIFY(u.hasFragment());
+ QCOMPARE(QString::fromLatin1(u.toEncoded()), QString::fromLatin1(expected));
+}
+
+void tst_QUrl::fromEncoded()
+{
+ QUrl qurl2 = QUrl::fromEncoded("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)", QUrl::TolerantMode);
+ QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)"));
+ QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)"));
+ QCOMPARE(qurl2.toEncoded().constData(), "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)");
+
+ QUrl qurl = QUrl::fromEncoded("http://\303\244.de");
+ QVERIFY(qurl.isValid());
+ QCOMPARE(qurl.toEncoded().constData(), "http://xn--4ca.de");
+
+ QUrl qurltest(QUrl::fromPercentEncoding("http://\303\244.de"));
+ QVERIFY(qurltest.isValid());
+
+ QUrl qurl_newline_1 = QUrl::fromEncoded("http://www.foo.bar/foo/bar\ngnork", QUrl::TolerantMode);
+ QVERIFY(qurl_newline_1.isValid());
+ QCOMPARE(qurl_newline_1.toEncoded().constData(), "http://www.foo.bar/foo/bar%0Agnork");
+}
+
+void tst_QUrl::stripTrailingSlash()
+{
+ QUrl u1( "ftp://ftp.de.kde.org/dir" );
+ QUrl u2( "ftp://ftp.de.kde.org/dir/" );
+ QUrl::FormattingOptions options = QUrl::None;
+ options |= QUrl::StripTrailingSlash;
+ QString str1 = u1.toString(options);
+ QString str2 = u2.toString(options);
+ QCOMPARE( str1, u1.toString() );
+ QCOMPARE( str2, u1.toString() );
+ bool same = str1 == str2;
+ QVERIFY( same );
+}
+
+void tst_QUrl::hosts_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::addColumn<QString>("host");
+
+ QTest::newRow("empty") << QString("") << QString("");
+ QTest::newRow("empty1") << QString("file:///file") << QString("");
+ QTest::newRow("empty2") << QString("file:/file") << QString("");
+ QTest::newRow("empty3") << QString("http:///file") << QString("");
+ QTest::newRow("empty4") << QString("http:/file") << QString("");
+
+ // numeric hostnames
+ QTest::newRow("http://123/") << QString("http://123/") << QString("123");
+ QTest::newRow("http://456/") << QString("http://456/") << QString("456");
+ QTest::newRow("http://1000/") << QString("http://1000/") << QString("1000");
+
+ // IP literals
+ QTest::newRow("normal-ip-literal") << QString("http://1.2.3.4") << QString("1.2.3.4");
+ QTest::newRow("normal-ip-literal-with-port") << QString("http://1.2.3.4:80")
+ << QString("1.2.3.4");
+ QTest::newRow("ipv6-literal") << QString("http://[::1]") << QString("::1");
+ QTest::newRow("ipv6-literal-with-port") << QString("http://[::1]:80") << QString("::1");
+ QTest::newRow("long-ipv6-literal") << QString("http://[2001:200:0:8002:203:47ff:fea5:3085]")
+ << QString("2001:200:0:8002:203:47ff:fea5:3085");
+ QTest::newRow("long-ipv6-literal-with-port") << QString("http://[2001:200:0:8002:203:47ff:fea5:3085]:80")
+ << QString("2001:200:0:8002:203:47ff:fea5:3085");
+ QTest::newRow("ipv6-literal-v4compat") << QString("http://[::255.254.253.252]")
+ << QString("::255.254.253.252");
+ QTest::newRow("ipv6-literal-v4compat-2") << QString("http://[1000::ffff:127.128.129.1]")
+ << QString("1000::ffff:127.128.129.1");
+ QTest::newRow("long-ipv6-literal-v4compat") << QString("http://[fec0:8000::8002:1000:ffff:200.100.50.250]")
+ << QString("fec0:8000::8002:1000:ffff:200.100.50.250");
+ QTest::newRow("longer-ipv6-literal-v4compat") << QString("http://[fec0:8000:4000:8002:1000:ffff:200.100.50.250]")
+ << QString("fec0:8000:4000:8002:1000:ffff:200.100.50.250");
+
+#if 0
+ // this is actually invalid
+ QTest::newRow("mac-literal") << QString("obex://[00:30:1b:b7:21:fb]")
+ << QString("00:30:1b:b7:21:fb");
+#endif
+
+ // normal hostnames
+ QTest::newRow("normal") << QString("http://intern") << QString("intern");
+ QTest::newRow("normal2") << QString("http://qt.nokia.com") << QString("qt.nokia.com");
+
+ // IDN hostnames
+ QTest::newRow("idn") << QString(QLatin1String("http://\345r.no")) << QString(QLatin1String("\345r.no"));
+ QTest::newRow("idn-ace") << QString("http://xn--r-1fa.no") << QString(QLatin1String("\345r.no"));
+}
+
+void tst_QUrl::hosts()
+{
+ QFETCH(QString, url);
+
+ QTEST(QUrl(url).host(), "host");
+}
+
+void tst_QUrl::setPort()
+{
+ {
+ QUrl url;
+ QVERIFY(url.toString().isEmpty());
+ url.setPort(80);
+ QCOMPARE(url.port(), 80);
+ QCOMPARE(url.toString(), QString::fromLatin1("//:80"));
+ url.setPort(-1);
+ QCOMPARE(url.port(), -1);
+ QVERIFY(url.toString().isEmpty());
+ url.setPort(80);
+ QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range");
+ url.setPort(65536);
+ QCOMPARE(url.port(), -1);
+ }
+}
+
+void tst_QUrl::toEncoded_data()
+{
+ QTest::addColumn<QByteArray>("url");
+ QTest::addColumn<QUrl::FormattingOptions>("options");
+ QTest::addColumn<QByteArray>("encoded");
+ QTest::newRow("file:///dir/") << QByteArray("file:///dir/")
+ << QUrl::FormattingOptions(QUrl::StripTrailingSlash)
+ << QByteArray("file:///dir");
+}
+
+void tst_QUrl::toEncoded()
+{
+ QFETCH(QByteArray, url);
+ QFETCH(QUrl::FormattingOptions, options);
+ QFETCH(QByteArray, encoded);
+
+ QCOMPARE(QUrl::fromEncoded(url).toEncoded(options), encoded);
+}
+
+void tst_QUrl::setAuthority_data()
+{
+ QTest::addColumn<QString>("authority");
+ QTest::addColumn<QString>("url");
+ QTest::newRow("Plain auth") << QString("62.70.27.22:21") << QString("//62.70.27.22:21");
+ QTest::newRow("Yet another plain auth") << QString("192.168.1.1:21") << QString("//192.168.1.1:21");
+ QTest::newRow("Auth without port") << QString("192.168.1.1") << QString("//192.168.1.1");
+ QTest::newRow("Auth w/full hostname without port") << QString("shusaku.troll.no") << QString("//shusaku.troll.no");
+ QTest::newRow("Auth w/hostname without port") << QString("shusaku") << QString("//shusaku");
+ QTest::newRow("Auth w/full hostname that ends with number, without port") << QString("shusaku.troll.no.2") << QString("//shusaku.troll.no.2");
+ QTest::newRow("Auth w/hostname that ends with number, without port") << QString("shusaku2") << QString("//shusaku2");
+ QTest::newRow("Empty auth") << QString() << QString();
+}
+
+void tst_QUrl::setAuthority()
+{
+ QUrl u;
+ QFETCH(QString, authority);
+ QFETCH(QString, url);
+ u.setAuthority(authority);
+ QCOMPARE(u.toString(), url);
+}
+
+void tst_QUrl::errorString()
+{
+ QUrl u = QUrl::fromEncoded("http://strange<username>@bad_hostname/", QUrl::StrictMode);
+ QVERIFY(!u.isValid());
+ QString errorString = "Invalid URL \"http://strange<username>@bad_hostname/\": "
+ "error at position 14: expected end of URL, but found '<'";
+ QCOMPARE(u.errorString(), errorString);
+
+ QUrl v;
+ errorString = "Invalid URL \"\": ";
+ QCOMPARE(v.errorString(), errorString);
+}
+
+void tst_QUrl::clear()
+{
+ QUrl url("a");
+ QUrl url2("a");
+ QCOMPARE(url, url2);
+ url.clear();
+ QVERIFY(url != url2);
+}
+
+void tst_QUrl::binaryData_data()
+{
+ QTest::addColumn<QString>("url");
+ QTest::newRow("username") << "http://%01%0D%0A%7F@foo/";
+ QTest::newRow("username-at") << "http://abc%40_def@foo/";
+ QTest::newRow("username-nul") << "http://abc%00_def@foo/";
+ QTest::newRow("username-colon") << "http://abc%3A_def@foo/";
+ QTest::newRow("username-nonutf8") << "http://abc%E1_def@foo/";
+
+ QTest::newRow("password") << "http://user:%01%0D%0A%7F@foo/";
+ QTest::newRow("password-at") << "http://user:abc%40_def@foo/";
+ QTest::newRow("password-nul") << "http://user:abc%00_def@foo/";
+ QTest::newRow("password-nonutf8") << "http://user:abc%E1_def@foo/";
+
+ QTest::newRow("file") << "http://foo/%01%0D%0A%7F";
+ QTest::newRow("file-nul") << "http://foo/abc%00_def";
+ QTest::newRow("file-hash") << "http://foo/abc%23_def";
+ QTest::newRow("file-question") << "http://foo/abc%3F_def";
+ QTest::newRow("file-nonutf8") << "http://foo/abc%E1_def";
+ QTest::newRow("file-slash") << "http://foo/abc%2f_def";
+
+ QTest::newRow("ref") << "http://foo/file#a%01%0D%0A%7F";
+ QTest::newRow("ref-nul") << "http://foo/file#abc%00_def";
+ QTest::newRow("ref-question") << "http://foo/file#abc?_def";
+ QTest::newRow("ref-nonutf8") << "http://foo/file#abc%E1_def";
+
+ QTest::newRow("query-value") << "http://foo/query?foo=%01%0D%0A%7F";
+ QTest::newRow("query-value-nul") << "http://foo/query?foo=abc%00_def";
+ QTest::newRow("query-value-nonutf8") << "http://foo/query?foo=abc%E1_def";
+
+ QTest::newRow("query-name") << "http://foo/query/a%01%0D%0A%7Fz=foo";
+ QTest::newRow("query-name-nul") << "http://foo/query/abc%00_def=foo";
+ QTest::newRow("query-name-nonutf8") << "http://foo/query/abc%E1_def=foo";
+}
+
+void tst_QUrl::binaryData()
+{
+ QFETCH(QString, url);
+ QUrl u = QUrl::fromEncoded(url.toUtf8());
+
+ QVERIFY(u.isValid());
+ QVERIFY(!u.isEmpty());
+
+ QString url2 = QString::fromUtf8(u.toEncoded());
+ //QCOMPARE(url2.length(), url.length());
+ QCOMPARE(url2, url);
+}
+
+void tst_QUrl::fromUserInput_data()
+{
+ //
+ // most of this test is:
+ // Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ // Distributed under the BSD license.
+ // See qurl.cpp
+ //
+
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QUrl>("guessUrlFromString");
+
+ // Null
+ QTest::newRow("null") << QString() << QUrl();
+
+ // File
+ QDirIterator it(QDir::homePath());
+ int c = 0;
+ while (it.hasNext()) {
+ it.next();
+ QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.filePath() << QUrl::fromLocalFile(it.filePath());
+ }
+
+ // basic latin1
+ QTest::newRow("unicode-0") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xc3\xa5.com/").toUtf8(), QUrl::TolerantMode);
+ QTest::newRow("unicode-0b") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded("http://%C3%A5.com/", QUrl::TolerantMode);
+ QTest::newRow("unicode-0c") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded("http://xn--5ca.com/", QUrl::TolerantMode);
+ // unicode
+ QTest::newRow("unicode-1") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xce\xbb.com/").toUtf8(), QUrl::TolerantMode);
+ QTest::newRow("unicode-1b") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded("http://%CE%BB.com/", QUrl::TolerantMode);
+ QTest::newRow("unicode-1c") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded("http://xn--wxa.com/", QUrl::TolerantMode);
+
+ // no scheme
+ QTest::newRow("add scheme-0") << "example.org" << QUrl("http://example.org");
+ QTest::newRow("add scheme-1") << "www.example.org" << QUrl("http://www.example.org");
+ QTest::newRow("add scheme-2") << "ftp.example.org" << QUrl("ftp://ftp.example.org");
+ QTest::newRow("add scheme-3") << "hostname" << QUrl("http://hostname");
+
+ // QUrl's tolerant parser should already handle this
+ QTest::newRow("not-encoded-0") << "http://example.org/test page.html" << QUrl::fromEncoded("http://example.org/test%20page.html");
+
+ // Make sure the :80, i.e. port doesn't screw anything up
+ QUrl portUrl("http://example.org");
+ portUrl.setPort(80);
+ QTest::newRow("port-0") << "example.org:80" << portUrl;
+ QTest::newRow("port-1") << "http://example.org:80" << portUrl;
+ portUrl.setPath("path");
+ QTest::newRow("port-1") << "example.org:80/path" << portUrl;
+ QTest::newRow("port-1") << "http://example.org:80/path" << portUrl;
+
+ // mailto doesn't have a ://, but is valid
+ QUrl mailto("ben@example.net");
+ mailto.setScheme("mailto");
+ QTest::newRow("mailto") << "mailto:ben@example.net" << mailto;
+
+ // misc
+ QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80");
+ QTest::newRow("spaces-0") << " http://example.org/test page.html " << QUrl("http://example.org/test%20page.html");
+ QTest::newRow("trash-0") << "example.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded("http://example.org/test?someData=42%25&someOtherData=abcde#anchor");
+ QTest::newRow("other-scheme-0") << "spotify:track:0hO542doVbfGDAGQULMORT" << QUrl("spotify:track:0hO542doVbfGDAGQULMORT");
+ QTest::newRow("other-scheme-1") << "weirdscheme:80:otherstuff" << QUrl("weirdscheme:80:otherstuff");
+
+ // FYI: The scheme in the resulting url user
+ QUrl authUrl("user:pass@domain.com");
+ QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl;
+}
+
+void tst_QUrl::fromUserInput()
+{
+ QFETCH(QString, string);
+ QFETCH(QUrl, guessUrlFromString);
+
+ QUrl url = QUrl::fromUserInput(string);
+ QCOMPARE(url, guessUrlFromString);
+}
+
+void tst_QUrl::task_199967()
+{
+ {
+ QUrl url;
+ url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
+ QVERIFY( url.isValid() );
+ QCOMPARE( url.path(), QString("LABEL=USB_STICK") );
+ QVERIFY( !url.isEmpty() );
+ }
+ {
+ QUrl url;
+ url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
+ QVERIFY( url.isValid() );
+ QVERIFY( !url.isEmpty() );
+ QCOMPARE( url.path(), QString("LABEL=USB_STICK") );
+ }
+}
+
+void tst_QUrl::task_240612()
+{
+ QUrl url;
+ url.setEncodedPath("test.txt");
+ url.setHost("example.com");
+
+ QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt");
+
+ url.path();
+ QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt");
+}
+
+void tst_QUrl::resolvedWithAbsoluteSchemes() const
+{
+ QFETCH(QUrl, base);
+ QFETCH(QUrl, relative);
+ QFETCH(QUrl, expected);
+
+ /* Check our input. */
+ QVERIFY(relative.isValid());
+ QVERIFY(base.isValid());
+ QVERIFY(expected.isValid());
+
+ const QUrl result(base.resolved(relative));
+
+ QVERIFY(result.isValid());
+ QCOMPARE(result, expected);
+}
+
+void tst_QUrl::resolvedWithAbsoluteSchemes_data() const
+{
+ QTest::addColumn<QUrl>("base");
+ QTest::addColumn<QUrl>("relative");
+ QTest::addColumn<QUrl>("expected");
+
+ QTest::newRow("Absolute file:/// against absolute FTP.")
+ << QUrl::fromEncoded("file:///foo/")
+ << QUrl::fromEncoded("ftp://example.com/")
+ << QUrl::fromEncoded("ftp://example.com/");
+
+ QTest::newRow("Absolute file:/// against absolute HTTP.")
+ << QUrl::fromEncoded("file:///foo/")
+ << QUrl::fromEncoded("http://example.com/")
+ << QUrl::fromEncoded("http://example.com/");
+
+
+ QTest::newRow("Absolute file:/// against data scheme.")
+ << QUrl::fromEncoded("file:///foo/")
+ << QUrl::fromEncoded("data:application/xml,%3Ce%2F%3E")
+ << QUrl::fromEncoded("data:application/xml,%3Ce%2F%3E");
+
+ QTest::newRow("Resolve with base url and port.")
+ << QUrl::fromEncoded("http://www.foo.com:8080/")
+ << QUrl::fromEncoded("newfile.html")
+ << QUrl::fromEncoded("http://www.foo.com:8080/newfile.html");
+}
+
+void tst_QUrl::taskQTBUG_6962()
+{
+ //bug 6962: empty authority ignored by setAuthority
+ QUrl url("http://example.com/something");
+ url.setAuthority(QString());
+ QCOMPARE(url.authority(), QString());
+}
+
+void tst_QUrl::taskQTBUG_8701()
+{
+ //bug 8701: foo:///bar mangled to foo:/bar
+ QString foo_triple_bar("foo:///bar"), foo_uni_bar("foo:/bar");
+
+ QCOMPARE(foo_triple_bar, QUrl(foo_triple_bar).toString());
+ QCOMPARE(foo_uni_bar, QUrl(foo_uni_bar).toString());
+
+ QCOMPARE(foo_triple_bar, QUrl(foo_triple_bar, QUrl::StrictMode).toString()); // fails
+ QCOMPARE(foo_uni_bar, QUrl(foo_uni_bar, QUrl::StrictMode).toString());
+}
+
+void tst_QUrl::effectiveTLDs_data()
+{
+ QTest::addColumn<QUrl>("domain");
+ QTest::addColumn<QString>("TLD");
+
+ QTest::newRow("yes0") << QUrl::fromEncoded("http://test.co.uk") << ".co.uk";
+ QTest::newRow("yes1") << QUrl::fromEncoded("http://test.com") << ".com";
+ QTest::newRow("yes2") << QUrl::fromEncoded("http://www.test.de") << ".de";
+ QTest::newRow("yes3") << QUrl::fromEncoded("http://test.ulm.museum") << ".ulm.museum";
+ QTest::newRow("yes4") << QUrl::fromEncoded("http://www.com.krodsherad.no") << ".krodsherad.no";
+ QTest::newRow("yes5") << QUrl::fromEncoded("http://www.co.uk.1.bg") << ".1.bg";
+ QTest::newRow("yes6") << QUrl::fromEncoded("http://www.com.com.cn") << ".com.cn";
+ QTest::newRow("yes7") << QUrl::fromEncoded("http://www.test.org.ws") << ".org.ws";
+ QTest::newRow("yes9") << QUrl::fromEncoded("http://www.com.co.uk.wallonie.museum") << ".wallonie.museum";
+}
+
+void tst_QUrl::effectiveTLDs()
+{
+ QFETCH(QUrl, domain);
+ QFETCH(QString, TLD);
+ QCOMPARE(domain.topLevelDomain(), TLD);
+}
+
+void tst_QUrl::removeAllEncodedQueryItems_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QByteArray>("key");
+ QTest::addColumn<QUrl>("result");
+
+ QTest::newRow("test1") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("bbb") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&ccc=c");
+ QTest::newRow("test2") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("aaa") << QUrl::fromEncoded("http://qt.nokia.com/foo?bbb=b&ccc=c");
+// QTest::newRow("test3") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("ccc") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b");
+ QTest::newRow("test4") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("b%62b") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c");
+ QTest::newRow("test5") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c") << QByteArray("b%62b") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&ccc=c");
+ QTest::newRow("test6") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c") << QByteArray("bbb") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c");
+}
+
+void tst_QUrl::removeAllEncodedQueryItems()
+{
+ QFETCH(QUrl, url);
+ QFETCH(QByteArray, key);
+ QFETCH(QUrl, result);
+ url.removeAllEncodedQueryItems(key);
+ QCOMPARE(url, result);
+}
+
+QTEST_MAIN(tst_QUrl)
+#include "tst_qurl.moc"