diff options
48 files changed, 1298 insertions, 330 deletions
diff --git a/dist/changes-4.8.0 b/dist/changes-4.8.0 index b8cc626..1703633 100644 --- a/dist/changes-4.8.0 +++ b/dist/changes-4.8.0 @@ -39,12 +39,29 @@ QtCore - Removed support for QT_NO_THREAD define for QHostInfo. - Optimized plugin loading on ELF platforms. Print failure reason at runtime with QT_DEBUG_PLUGINS=1 in environment. + - QMutexLocker: improved performence of the non contended case by inlining some function + - QThreadStorage: Added possibility to store object by value instead of by pointer [QTBUG-15033] + - QThread: fixed few race conditions [QTBUG-17257, QTBUG-15030] + - QtConcurrent: added support for c++0x lambda in few functions + - QObject: Improved performence of the signal activation + - QObject: added ways to connect signals using QMetaMethod + - QObject: deprecated qFindChild and qFindChildren + - QObject: optimize constructions and destruction of objects + - QObject: Qt::BlockingQueuedConnection can handle the return value [QTBUG-10440] + - QList/QVector/QStringList: added C++0x initilizer lists constructors. + - QVarLenghtArray: added method for consistency with QVector + - QStringBuilder: added support for QByteArray + - qSwap now uses std::swap, specialized std::swap for our container to work better with stl algoritms + - QVariant: deprecated global function qVariantSetValue, qVariantValue, qVariantCanConvert, qVariantFromValue QtGui ----- - QTabBar: reduced minimumSizeHint if ElideMode is set. - QComboBox: Fixed a color propagation issue with the lineedit. [QTBUG-5950] + - Deprecate qGenericMatrixFromMatrix4x4 and qGenericMatrixToMatrix4x4 + - QListView diverses optimisations [QTBUG-11438] + - QTreeWidget/QListWidget: use localeAwareCompare for string comparisons [QTBUG-10839] QtOpenGL -------- @@ -54,6 +71,10 @@ QtGui - Including <QtOpenGL> will not work in combination with GLEW, as QGLFunctions will undefine GLEW's defines. +QtScript +-------- + - Deprecated qScriptValueFromQMetaObject, qScriptValueToValue, qScriptValueFromValue + **************************************************************************** * Database Drivers * @@ -136,6 +157,7 @@ Qt for Windows CE - qtconfig + * removed Qt3support dependency - qt3to4 diff --git a/src/corelib/concurrent/qtconcurrentcompilertest.h b/src/corelib/concurrent/qtconcurrentcompilertest.h index 884badb..c139c7a 100644 --- a/src/corelib/concurrent/qtconcurrentcompilertest.h +++ b/src/corelib/concurrent/qtconcurrentcompilertest.h @@ -57,6 +57,20 @@ QT_MODULE(Core) # define QT_TYPENAME typename #endif +namespace QtPrivate { + +template<class T> +class HasResultType { + typedef char Yes; + typedef void *No; + template<typename U> static Yes test(int, const typename U::result_type * = 0); + template<typename U> static No test(double); +public: + enum { Value = (sizeof(test<T>(0)) == sizeof(Yes)) }; +}; + +} + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h index a79ad1c..4bf2736 100644 --- a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h @@ -195,17 +195,10 @@ QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); } - -template<typename T> -void *lazyResultType_helper(int, typename T::result_type * = 0); -template<typename T> -char lazyResultType_helper(double); - -template <typename Functor, bool foo = sizeof(lazyResultType_helper<Functor>(0)) != sizeof(void*)> +template <typename Functor, bool foo = HasResultType<Functor>::Value> struct LazyResultType { typedef typename Functor::result_type Type; }; template <typename Functor> -struct LazyResultType<Functor, true> { typedef void Type; }; - +struct LazyResultType<Functor, false> { typedef void Type; }; template <class T> struct ReduceResultType; diff --git a/src/corelib/concurrent/qtconcurrentrun.h b/src/corelib/concurrent/qtconcurrentrun.h index 8611fba..ef51b2a 100644 --- a/src/corelib/concurrent/qtconcurrentrun.h +++ b/src/corelib/concurrent/qtconcurrentrun.h @@ -71,63 +71,114 @@ namespace QtConcurrent { template <typename T> QFuture<T> run(T (*functionPointer)()) { - return (new QT_TYPENAME SelectStoredFunctorCall0<T, T (*)()>::type(functionPointer))->start(); + return (new StoredFunctorCall0<T, T (*)()>(functionPointer))->start(); } template <typename T, typename Param1, typename Arg1> QFuture<T> run(T (*functionPointer)(Param1), const Arg1 &arg1) { - return (new QT_TYPENAME SelectStoredFunctorCall1<T, T (*)(Param1), Arg1>::type(functionPointer, arg1))->start(); + return (new StoredFunctorCall1<T, T (*)(Param1), Arg1>(functionPointer, arg1))->start(); } template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2> QFuture<T> run(T (*functionPointer)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2) { - return (new QT_TYPENAME SelectStoredFunctorCall2<T, T (*)(Param1, Param2), Arg1, Arg2>::type(functionPointer, arg1, arg2))->start(); + return (new StoredFunctorCall2<T, T (*)(Param1, Param2), Arg1, Arg2>(functionPointer, arg1, arg2))->start(); } template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3> QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) { - return (new QT_TYPENAME SelectStoredFunctorCall3<T, T (*)(Param1, Param2, Param3), Arg1, Arg2, Arg3>::type(functionPointer, arg1, arg2, arg3))->start(); + return (new StoredFunctorCall3<T, T (*)(Param1, Param2, Param3), Arg1, Arg2, Arg3>(functionPointer, arg1, arg2, arg3))->start(); } template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4> QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4) { - return (new QT_TYPENAME SelectStoredFunctorCall4<T, T (*)(Param1, Param2, Param3, Param4), Arg1, Arg2, Arg3, Arg4>::type(functionPointer, arg1, arg2, arg3, arg4))->start(); + return (new StoredFunctorCall4<T, T (*)(Param1, Param2, Param3, Param4), Arg1, Arg2, Arg3, Arg4>(functionPointer, arg1, arg2, arg3, arg4))->start(); } template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5> QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5) { - return (new QT_TYPENAME SelectStoredFunctorCall5<T, T (*)(Param1, Param2, Param3, Param4, Param5), Arg1, Arg2, Arg3, Arg4, Arg5>::type(functionPointer, arg1, arg2, arg3, arg4, arg5))->start(); + return (new StoredFunctorCall5<T, T (*)(Param1, Param2, Param3, Param4, Param5), Arg1, Arg2, Arg3, Arg4, Arg5>(functionPointer, arg1, arg2, arg3, arg4, arg5))->start(); } +#ifdef Q_COMPILER_DECLTYPE + +template <typename Functor> +auto run(Functor functor) -> typename QtPrivate::QEnableIf<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor())> >::Type +{ + typedef decltype(functor()) result_type; + return (new StoredFunctorCall0<result_type, Functor>(functor))->start(); +} + +template <typename Functor, typename Arg1> +auto run(Functor functor, const Arg1 &arg1) + -> typename QtPrivate::QEnableIf<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1))> >::Type +{ + typedef decltype(functor(arg1)) result_type; + return (new StoredFunctorCall1<result_type, Functor, Arg1>(functor, arg1))->start(); +} + +template <typename Functor, typename Arg1, typename Arg2> +auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2) + -> typename QtPrivate::QEnableIf<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2))> >::Type +{ + typedef decltype(functor(arg1, arg2)) result_type; + return (new StoredFunctorCall2<result_type, Functor, Arg1, Arg2>(functor, arg1, arg2))->start(); +} + +template <typename Functor, typename Arg1, typename Arg2, typename Arg3> +auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) + -> typename QtPrivate::QEnableIf<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3))> >::Type +{ + typedef decltype(functor(arg1, arg2, arg3)) result_type; + return (new StoredFunctorCall3<result_type, Functor, Arg1, Arg2, Arg3>(functor, arg1, arg2, arg3))->start(); +} + +template <typename Functor, typename Arg1, typename Arg2, typename Arg3, typename Arg4> +auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4) + -> typename QtPrivate::QEnableIf<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3, arg4))> >::Type +{ + typedef decltype(functor(arg1, arg2, arg3, arg4)) result_type; + return (new StoredFunctorCall4<result_type, Functor, Arg1, Arg2, Arg3, Arg4>(functor, arg1, arg2, arg3, arg4))->start(); +} + +template <typename Functor, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> +auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5) + -> typename QtPrivate::QEnableIf<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3, arg4, arg5))> >::Type +{ + typedef decltype(functor(arg1, arg2, arg3, arg4, arg5)) result_type; + return (new StoredFunctorCall5<result_type, Functor, Arg1, Arg2, Arg3, Arg4, Arg5>(functor, arg1, arg2, arg3, arg4, arg5))->start(); +} + +#endif + template <typename FunctionObject> QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject) { - return (new QT_TYPENAME SelectStoredFunctorCall0<QT_TYPENAME FunctionObject::result_type, FunctionObject>::type(functionObject))->start(); + return (new StoredFunctorCall0<QT_TYPENAME FunctionObject::result_type, FunctionObject>(functionObject))->start(); } template <typename FunctionObject, typename Arg1> QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1) { - return (new QT_TYPENAME SelectStoredFunctorCall1<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1>::type(functionObject, arg1))->start(); + return (new StoredFunctorCall1<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1>(functionObject, arg1))->start(); } template <typename FunctionObject, typename Arg1, typename Arg2> QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2) { - return (new QT_TYPENAME SelectStoredFunctorCall2<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2>::type(functionObject, arg1, arg2))->start(); + return (new StoredFunctorCall2<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2>(functionObject, arg1, arg2))->start(); } template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3> QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) { - return (new QT_TYPENAME SelectStoredFunctorCall3<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3>::type(functionObject, arg1, arg2, arg3))->start(); + return (new StoredFunctorCall3<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3>(functionObject, arg1, arg2, arg3))->start(); } template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4> QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4) { - return (new QT_TYPENAME SelectStoredFunctorCall4<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4>::type(functionObject, arg1, arg2, arg3, arg4))->start(); + return (new StoredFunctorCall4<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4>(functionObject, arg1, arg2, arg3, arg4))->start(); } template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5) { - return (new QT_TYPENAME SelectStoredFunctorCall5<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4, Arg5>::type(functionObject, arg1, arg2, arg3, arg4, arg5))->start(); + return (new StoredFunctorCall5<QT_TYPENAME FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4, Arg5>(functionObject, arg1, arg2, arg3, arg4, arg5))->start(); } template <typename FunctionObject> diff --git a/src/corelib/concurrent/qtconcurrentstoredfunctioncall.h b/src/corelib/concurrent/qtconcurrentstoredfunctioncall.h index c61f9b8..9beb0b9 100644 --- a/src/corelib/concurrent/qtconcurrentstoredfunctioncall.h +++ b/src/corelib/concurrent/qtconcurrentstoredfunctioncall.h @@ -66,10 +66,10 @@ struct StoredFunctorCall0: public RunFunctionTask<T> }; -template <typename T, typename FunctionPointer> -struct VoidStoredFunctorCall0: public RunFunctionTask<T> +template <typename FunctionPointer> +struct StoredFunctorCall0<void, FunctionPointer>: public RunFunctionTask<void> { - inline VoidStoredFunctorCall0(FunctionPointer _function) + inline StoredFunctorCall0(FunctionPointer _function) : function(_function) {} void runFunctor() { function(); } FunctionPointer function; @@ -77,13 +77,6 @@ struct VoidStoredFunctorCall0: public RunFunctionTask<T> }; template <typename T, typename FunctionPointer> -struct SelectStoredFunctorCall0 -{ - typedef typename SelectSpecialization<T>::template - Type<StoredFunctorCall0 <T, FunctionPointer>, - VoidStoredFunctorCall0<T, FunctionPointer> >::type type; -}; -template <typename T, typename FunctionPointer> struct StoredFunctorPointerCall0: public RunFunctionTask<T> { inline StoredFunctorPointerCall0(FunctionPointer * _function) @@ -276,10 +269,10 @@ struct StoredFunctorCall1: public RunFunctionTask<T> Arg1 arg1; }; -template <typename T, typename FunctionPointer, typename Arg1> -struct VoidStoredFunctorCall1: public RunFunctionTask<T> +template <typename FunctionPointer, typename Arg1> +struct StoredFunctorCall1<void, FunctionPointer, Arg1>: public RunFunctionTask<void> { - inline VoidStoredFunctorCall1(FunctionPointer _function, const Arg1 &_arg1) + inline StoredFunctorCall1(FunctionPointer _function, const Arg1 &_arg1) : function(_function), arg1(_arg1) {} void runFunctor() { function(arg1); } FunctionPointer function; @@ -287,13 +280,6 @@ struct VoidStoredFunctorCall1: public RunFunctionTask<T> }; template <typename T, typename FunctionPointer, typename Arg1> -struct SelectStoredFunctorCall1 -{ - typedef typename SelectSpecialization<T>::template - Type<StoredFunctorCall1 <T, FunctionPointer, Arg1>, - VoidStoredFunctorCall1<T, FunctionPointer, Arg1> >::type type; -}; -template <typename T, typename FunctionPointer, typename Arg1> struct StoredFunctorPointerCall1: public RunFunctionTask<T> { inline StoredFunctorPointerCall1(FunctionPointer * _function, const Arg1 &_arg1) @@ -486,10 +472,10 @@ struct StoredFunctorCall2: public RunFunctionTask<T> Arg1 arg1; Arg2 arg2; }; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2> -struct VoidStoredFunctorCall2: public RunFunctionTask<T> +template <typename FunctionPointer, typename Arg1, typename Arg2> +struct StoredFunctorCall2<void, FunctionPointer, Arg1, Arg2>: public RunFunctionTask<void> { - inline VoidStoredFunctorCall2(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2) + inline StoredFunctorCall2(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2) : function(_function), arg1(_arg1), arg2(_arg2) {} void runFunctor() { function(arg1, arg2); } FunctionPointer function; @@ -497,13 +483,6 @@ struct VoidStoredFunctorCall2: public RunFunctionTask<T> }; template <typename T, typename FunctionPointer, typename Arg1, typename Arg2> -struct SelectStoredFunctorCall2 -{ - typedef typename SelectSpecialization<T>::template - Type<StoredFunctorCall2 <T, FunctionPointer, Arg1, Arg2>, - VoidStoredFunctorCall2<T, FunctionPointer, Arg1, Arg2> >::type type; -}; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2> struct StoredFunctorPointerCall2: public RunFunctionTask<T> { inline StoredFunctorPointerCall2(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2) @@ -696,10 +675,10 @@ struct StoredFunctorCall3: public RunFunctionTask<T> Arg1 arg1; Arg2 arg2; Arg3 arg3; }; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3> -struct VoidStoredFunctorCall3: public RunFunctionTask<T> +template <typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3> +struct StoredFunctorCall3<void, FunctionPointer, Arg1, Arg2, Arg3>: public RunFunctionTask<void> { - inline VoidStoredFunctorCall3(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3) + inline StoredFunctorCall3(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3) : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3) {} void runFunctor() { function(arg1, arg2, arg3); } FunctionPointer function; @@ -707,13 +686,6 @@ struct VoidStoredFunctorCall3: public RunFunctionTask<T> }; template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3> -struct SelectStoredFunctorCall3 -{ - typedef typename SelectSpecialization<T>::template - Type<StoredFunctorCall3 <T, FunctionPointer, Arg1, Arg2, Arg3>, - VoidStoredFunctorCall3<T, FunctionPointer, Arg1, Arg2, Arg3> >::type type; -}; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3> struct StoredFunctorPointerCall3: public RunFunctionTask<T> { inline StoredFunctorPointerCall3(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3) @@ -906,10 +878,10 @@ struct StoredFunctorCall4: public RunFunctionTask<T> Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; }; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4> -struct VoidStoredFunctorCall4: public RunFunctionTask<T> +template <typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4> +struct StoredFunctorCall4<void, FunctionPointer, Arg1, Arg2, Arg3, Arg4>: public RunFunctionTask<void> { - inline VoidStoredFunctorCall4(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4) + inline StoredFunctorCall4(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4) : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4) {} void runFunctor() { function(arg1, arg2, arg3, arg4); } FunctionPointer function; @@ -917,13 +889,6 @@ struct VoidStoredFunctorCall4: public RunFunctionTask<T> }; template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4> -struct SelectStoredFunctorCall4 -{ - typedef typename SelectSpecialization<T>::template - Type<StoredFunctorCall4 <T, FunctionPointer, Arg1, Arg2, Arg3, Arg4>, - VoidStoredFunctorCall4<T, FunctionPointer, Arg1, Arg2, Arg3, Arg4> >::type type; -}; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct StoredFunctorPointerCall4: public RunFunctionTask<T> { inline StoredFunctorPointerCall4(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4) @@ -1116,10 +1081,10 @@ struct StoredFunctorCall5: public RunFunctionTask<T> Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5; }; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> -struct VoidStoredFunctorCall5: public RunFunctionTask<T> +template <typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> +struct StoredFunctorCall5<void, FunctionPointer, Arg1, Arg2, Arg3, Arg4, Arg5>: public RunFunctionTask<void> { - inline VoidStoredFunctorCall5(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5) + inline StoredFunctorCall5(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5) : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5) {} void runFunctor() { function(arg1, arg2, arg3, arg4, arg5); } FunctionPointer function; @@ -1127,13 +1092,6 @@ struct VoidStoredFunctorCall5: public RunFunctionTask<T> }; template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> -struct SelectStoredFunctorCall5 -{ - typedef typename SelectSpecialization<T>::template - Type<StoredFunctorCall5 <T, FunctionPointer, Arg1, Arg2, Arg3, Arg4, Arg5>, - VoidStoredFunctorCall5<T, FunctionPointer, Arg1, Arg2, Arg3, Arg4, Arg5> >::type type; -}; -template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct StoredFunctorPointerCall5: public RunFunctionTask<T> { inline StoredFunctorPointerCall5(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5) @@ -1316,6 +1274,33 @@ struct SelectStoredConstMemberFunctionPointerCall5 Type<StoredConstMemberFunctionPointerCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>, VoidStoredConstMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type; }; + +template <typename T, typename Functor> +class StoredFunctorCall : public RunFunctionTask<T> +{ +public: + StoredFunctorCall(const Functor &f) : functor(f) { } + void runFunctor() + { + this->result = functor(); + } +private: + Functor functor; +}; +template <typename Functor> +class StoredFunctorCall<void, Functor> : public RunFunctionTask<void> +{ +public: + StoredFunctorCall(const Functor &f) : functor(f) { } + void runFunctor() + { + functor(); + } +private: + Functor functor; +}; + + } //namespace QtConcurrent #endif // qdoc diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 4e3f4e3..8a17af5 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -363,6 +363,11 @@ template <typename T> inline void qToLittleEndian(T src, uchar *dest) #endif // Q_BYTE_ORDER == Q_BIG_ENDIAN +template <> inline quint8 qbswap<quint8>(quint8 source) +{ + return source; +} + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 78b8443..1454cb3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -425,14 +425,11 @@ namespace QT_NAMESPACE {} #if defined(Q_CC_MSVC) && _MSC_VER >= 1600 # define Q_COMPILER_RVALUE_REFS -# define Q_COMPILER_INITIALIZER_LISTS # define Q_COMPILER_AUTO_TYPE # define Q_COMPILER_LAMBDA -//# define Q_COMPILER_VARIADIC_TEMPLATES -//# define Q_COMPILER_CLASS_ENUM -//# define Q_COMPILER_DEFAULT_DELETE_MEMBERS -//# define Q_COMPILER_UNICODE_STRINGS -//# define Q_COMPILER_EXTERN_TEMPLATES +# define Q_COMPILER_DECLTYPE +// MSCV has std::initilizer_list, but do not support the braces initialization +//# define Q_COMPILER_INITIALIZER_LISTS # endif @@ -524,6 +521,7 @@ namespace QT_NAMESPACE {} # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 /* C++0x features supported in GCC 4.3: */ # define Q_COMPILER_RVALUE_REFS +# define Q_COMPILER_DECLTYPE # endif # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 /* C++0x features supported in GCC 4.4: */ @@ -791,6 +789,7 @@ namespace QT_NAMESPACE {} # if __INTEL_COMPILER >= 1100 # define Q_COMPILER_RVALUE_REFS # define Q_COMPILER_EXTERN_TEMPLATES +# define Q_COMPILER_DECLTYPE # elif __INTEL_COMPILER >= 1200 # define Q_COMPILER_VARIADIC_TEMPLATES # define Q_COMPILER_AUTO_TYPE @@ -2770,6 +2769,12 @@ QT_LICENSED_MODULE(DBus) # define QT_NO_RAWFONT #endif +namespace QtPrivate { +//like std::enable_if +template <bool B, typename T = void> struct QEnableIf; +template <typename T> struct QEnableIf<true, T> { typedef T Type; }; +} + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index f67600d..e411f8f 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -24,6 +24,8 @@ HEADERS += \ io/qresource_p.h \ io/qresource_iterator_p.h \ io/qurl.h \ + io/qurltlds_p.h \ + io/qtldurl_p.h \ io/qsettings.h \ io/qsettings_p.h \ io/qfsfileengine.h \ @@ -41,6 +43,7 @@ SOURCES += \ io/qbuffer.cpp \ io/qdatastream.cpp \ io/qdataurl.cpp \ + io/qtldurl.cpp \ io/qdebug.cpp \ io/qdir.cpp \ io/qdiriterator.cpp \ diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp new file mode 100644 index 0000000..7db4bbd --- /dev/null +++ b/src/corelib/io/qtldurl.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformdefs.h" +#include "qurl.h" +#include "private/qurltlds_p.h" +#include "private/qtldurl_p.h" +#include "QtCore/qstringlist.h" + +QT_BEGIN_NAMESPACE + +static bool containsTLDEntry(const QString &entry) +{ + int index = qHash(entry) % tldCount; + int currentDomainIndex = tldIndices[index]; + while (currentDomainIndex < tldIndices[index+1]) { + QString currentEntry = QString::fromUtf8(tldData + currentDomainIndex); + if (currentEntry == entry) + return true; + currentDomainIndex += qstrlen(tldData + currentDomainIndex) + 1; // +1 for the ending \0 + } + return false; +} + +/*! + \internal + + Return the top-level-domain per Qt's copy of the Mozilla public suffix list of + \a domain. +*/ + +Q_CORE_EXPORT QString qTopLevelDomain(const QString &domain) +{ + QStringList sections = domain.toLower().split(QLatin1Char('.'), QString::SkipEmptyParts); + if (sections.isEmpty()) + return QString(); + + QString level, tld; + for (int j = sections.count() - 1; j >= 0; --j) { + level.prepend(QLatin1Char('.') + sections.at(j)); + if (qIsEffectiveTLD(level.right(level.size() - 1))) + tld = level; + } + return tld; +} + +/*! + \internal + + Return true if \a domain is a top-level-domain per Qt's copy of the Mozilla public suffix list. +*/ + +Q_CORE_EXPORT bool qIsEffectiveTLD(const QString &domain) +{ + // for domain 'foo.bar.com': + // 1. return if TLD table contains 'foo.bar.com' + if (containsTLDEntry(domain)) + return true; + + if (domain.contains(QLatin1Char('.'))) { + int count = domain.size() - domain.indexOf(QLatin1Char('.')); + QString wildCardDomain; + wildCardDomain.reserve(count + 1); + wildCardDomain.append(QLatin1Char('*')); + wildCardDomain.append(domain.right(count)); + // 2. if table contains '*.bar.com', + // test if table contains '!foo.bar.com' + if (containsTLDEntry(wildCardDomain)) { + QString exceptionDomain; + exceptionDomain.reserve(domain.size() + 1); + exceptionDomain.append(QLatin1Char('!')); + exceptionDomain.append(domain); + return (! containsTLDEntry(exceptionDomain)); + } + } + return false; +} + +QT_END_NAMESPACE diff --git a/src/corelib/io/qtldurl_p.h b/src/corelib/io/qtldurl_p.h new file mode 100644 index 0000000..152ffa0 --- /dev/null +++ b/src/corelib/io/qtldurl_p.h @@ -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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLDURL_P_H +#define QTLDURL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qDecodeDataUrl. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qurl.h" +#include "QtCore/qstring.h" + +QT_BEGIN_NAMESPACE + +Q_CORE_EXPORT QString qTopLevelDomain(const QString &domain); +Q_CORE_EXPORT bool qIsEffectiveTLD(const QString &domain); + +QT_END_NAMESPACE + +#endif // QDATAURL_P_H diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index c00fc68..83b49ce 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -192,7 +192,9 @@ #if defined QT3_SUPPORT #include "qfileinfo.h" #endif - +#ifndef QT_BOOTSTRAPPED +#include "qtldurl_p.h" +#endif #if defined(Q_OS_WINCE_WM) #pragma optimize("g", off) #endif @@ -5593,6 +5595,21 @@ bool QUrl::hasFragment() const } /*! + \since 4.8 + + Returns the TLD (Top-Level Domain) of the URL, (e.g. .co.uk, .net). + Note that the return value is prefixed with a '.' unless the + URL does not contain a valid TLD, in which case the function returns + an empty string. +*/ +#ifndef QT_BOOTSTRAPPED +QString QUrl::topLevelDomain() const +{ + return qTopLevelDomain(host()); +} +#endif + +/*! Returns the result of the merge of this URL with \a relative. This URL is used as a base to convert \a relative to an absolute URL. diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index 96b23d1..d57a0c7 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -181,6 +181,9 @@ public: void setEncodedFragment(const QByteArray &fragment); QByteArray encodedFragment() const; bool hasFragment() const; +#ifndef QT_BOOTSTRAPPED + QString topLevelDomain() const; +#endif QUrl resolved(const QUrl &relative) const; diff --git a/src/network/access/qnetworkcookiejartlds_p.h b/src/corelib/io/qurltlds_p.h index b06d881..f4f525c 100644 --- a/src/network/access/qnetworkcookiejartlds_p.h +++ b/src/corelib/io/qurltlds_p.h @@ -38,15 +38,15 @@ // the terms of any one of the MPL, the GPL or the LGPL. // -#ifndef QNETWORKCOOKIEJARTLD_P_H -#define QNETWORKCOOKIEJARTLD_P_H +#ifndef QURLTLD_P_H +#define QURLTLD_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience -// of the Network Access framework. This header file may change from +// of the Network Access and Core framework. This header file may change from // version to version without notice, or even be removed. // // We mean it. @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE // note to maintainer: // this file should be updated before each release -> // for instructions see the program at -// util/network/cookiejar-generateTLDs +// util/corelib/qurl-generateTLDs static const quint16 tldCount = 3949; static const quint16 tldIndices[] = { @@ -6478,4 +6478,4 @@ static const char tldData[] = { QT_END_NAMESPACE -#endif // QNETWORKCOOKIEJARTLD_P_H +#endif // QURLTLD_P_H diff --git a/src/network/access/qnetworkcookiejartlds_p.h.INFO b/src/corelib/io/qurltlds_p.h.INFO index 57a8d0e..5781c2c 100644 --- a/src/network/access/qnetworkcookiejartlds_p.h.INFO +++ b/src/corelib/io/qurltlds_p.h.INFO @@ -1,15 +1,15 @@ -The file qnetworkcookiejartlds_p.h is generated from the Public Suffix +The file qurltlds_p.h is generated from the Public Suffix List (see [1] and [2]), by the program residing at -util/network/cookiejar-generateTLDs in the Qt source tree. +util/corelib/qurl-generateTLDs in the Qt source tree. That program generates a character array and an index array from the list to provide fast lookups of elements within C++. -Those arrays in qnetworkcookiejartlds_p.h are derived from the Public +Those arrays in qurltlds_p.h are derived from the Public Suffix List ([2]), which was originally provided by Jo Hermans <jo.hermans@gmail.com>. -The file qnetworkcookiejartlds_p.h was last generated Friday, +The file qurltlds_p.h was last generated Friday, November 19th 15:24 2010. ---- diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 9cd353a..eb29e6e 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -42,9 +42,96 @@ #include "quuid.h" #include "qdatastream.h" +#include "qendian.h" QT_BEGIN_NAMESPACE +#ifndef QT_NO_QUUID_STRING +template <class Char, class Integral> +void _q_toHex(Char *&dst, Integral value) +{ + static const char digits[] = "0123456789abcdef"; + + value = qToBigEndian(value); + + const char* p = reinterpret_cast<const char*>(&value); + + for (uint i = 0; i < sizeof(Integral); ++i, dst += 2) { + uint j = (p[i] >> 4) & 0xf; + dst[0] = Char(digits[j]); + j = p[i] & 0xf; + dst[1] = Char(digits[j]); + } +} + +template <class Char, class Integral> +bool _q_fromHex(const Char *&src, Integral &value) +{ + value = 0; + + for (uint i = 0; i < sizeof(Integral) * 2; ++i) { + int ch = *src++; + int tmp; + if (ch >= '0' && ch <= '9') + tmp = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + tmp = ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + tmp = ch - 'A' + 10; + else + return false; + + value = value * 16 + tmp; + } + + return true; +} + +template <class Char> +void _q_uuidToHex(Char *&dst, const uint &d1, const ushort &d2, const ushort &d3, const uchar (&d4)[8]) +{ + *dst++ = Char('{'); + _q_toHex(dst, d1); + *dst++ = Char('-'); + _q_toHex(dst, d2); + *dst++ = Char('-'); + _q_toHex(dst, d3); + *dst++ = Char('-'); + for (int i = 0; i < 2; i++) + _q_toHex(dst, d4[i]); + *dst++ = Char('-'); + for (int i = 2; i < 8; i++) + _q_toHex(dst, d4[i]); + *dst = Char('}'); +} + +template <class Char> +bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&d4)[8]) +{ + if (*src == Char('{')) + src++; + if (!_q_fromHex(src, d1) + || *src++ != Char('-') + || !_q_fromHex(src, d2) + || *src++ != Char('-') + || !_q_fromHex(src, d3) + || *src++ != Char('-') + || !_q_fromHex(src, d4[0]) + || !_q_fromHex(src, d4[1]) + || *src++ != Char('-') + || !_q_fromHex(src, d4[2]) + || !_q_fromHex(src, d4[3]) + || !_q_fromHex(src, d4[4]) + || !_q_fromHex(src, d4[5]) + || !_q_fromHex(src, d4[6]) + || !_q_fromHex(src, d4[7])) { + return false; + } + + return true; +} +#endif + /*! \class QUuid \brief The QUuid class stores a Universally Unique Identifier (UUID). @@ -231,60 +318,112 @@ QT_BEGIN_NAMESPACE */ QUuid::QUuid(const QString &text) { - bool ok; - if (text.isEmpty()) { + if (text.length() < 36) { *this = QUuid(); return; } - QString temp = text.toUpper(); - if (temp[0] != QLatin1Char('{')) - temp = QLatin1Char('{') + text; - if (text[(int)text.length()-1] != QLatin1Char('}')) - temp += QLatin1Char('}'); - - data1 = temp.mid(1, 8).toULongLong(&ok, 16); - if (!ok) { + + const ushort *data = reinterpret_cast<const ushort *>(text.unicode()); + + if (*data == '{' && text.length() < 37) { *this = QUuid(); return; } - data2 = temp.mid(10, 4).toUInt(&ok, 16); - if (!ok) { + if (!_q_uuidFromHex(data, data1, data2, data3, data4)) { *this = QUuid(); return; } - data3 = temp.mid(15, 4).toUInt(&ok, 16); - if (!ok) { +} + +/*! + \internal +*/ +QUuid::QUuid(const char *text) +{ + if (!text) { *this = QUuid(); return; } - data4[0] = temp.mid(20, 2).toUInt(&ok, 16); - if (!ok) { + + if (!_q_uuidFromHex(text, data1, data2, data3, data4)) { *this = QUuid(); return; } - data4[1] = temp.mid(22, 2).toUInt(&ok, 16); - if (!ok) { +} + +/*! + Creates a QUuid object from the QByteArray \a text, which must be + formatted as five hex fields separated by '-', e.g., + "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where 'x' is a hex + digit. The curly braces shown here are optional, but it is normal to + include them. If the conversion fails, a null UUID is created. See + toByteArray() for an explanation of how the five hex fields map to the + public data members in QUuid. + + \since 4.8 + + \sa toByteArray(), QUuid() +*/ +QUuid::QUuid(const QByteArray &text) +{ + if (text.length() < 36) { *this = QUuid(); return; } - for (int i = 2; i<8; i++) { - data4[i] = temp.mid(25 + (i-2)*2, 2).toUShort(&ok, 16); - if (!ok) { - *this = QUuid(); - return; - } + + const char *data = text.constData(); + + if (*data == '{' && text.length() < 37) { + *this = QUuid(); + return; + } + + if (!_q_uuidFromHex(data, data1, data2, data3, data4)) { + *this = QUuid(); + return; } } +#endif /*! - \internal + Creates a QUuid object from the binary representation of the UUID, as + specified by RFC 4122 section 4.1.2. See toRfc4122() for a further + explanation of the order of bytes required. + + The byte array accepted is NOT a human readable format. + + If the conversion fails, a null UUID is created. + + \since 4.8 + + \sa toRfc4122(), QUuid() */ -QUuid::QUuid(const char *text) +QUuid QUuid::fromRfc4122(const QByteArray &bytes) { - *this = QUuid(QString::fromLatin1(text)); + if (bytes.isEmpty() || bytes.length() != 16) + return QUuid(); + + uint d1; + ushort d2, d3; + uchar d4[8]; + + const uchar *data = reinterpret_cast<const uchar *>(bytes.constData()); + + d1 = qFromBigEndian<quint32>(data); + data += sizeof(quint32); + d2 = qFromBigEndian<quint16>(data); + data += sizeof(quint16); + d3 = qFromBigEndian<quint16>(data); + data += sizeof(quint16); + + for (int i = 0; i < 8; ++i) { + d4[i] = *(data); + data++; + } + + return QUuid(d1, d2, d3, d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7]); } -#endif /*! \fn bool QUuid::operator==(const QUuid &other) const @@ -308,11 +447,6 @@ QUuid::QUuid(const char *text) \sa toString() */ -static QString uuidhex(uint data, int digits) -{ - return QString::number(data, 16).rightJustified(digits, QLatin1Char('0')); -} - /*! Returns the string representation of this QUuid. The string is formatted as five hex fields separated by '-' and enclosed in @@ -349,25 +483,114 @@ static QString uuidhex(uint data, int digits) */ QString QUuid::toString() const { - QString result; - - QChar dash = QLatin1Char('-'); - result = QLatin1Char('{') + uuidhex(data1,8); - result += dash; - result += uuidhex(data2,4); - result += dash; - result += uuidhex(data3,4); - result += dash; - result += uuidhex(data4[0],2); - result += uuidhex(data4[1],2); - result += dash; - for (int i = 2; i < 8; i++) - result += uuidhex(data4[i],2); + QString result(38, Qt::Uninitialized); + ushort *data = (ushort *)result.unicode(); + + _q_uuidToHex(data, data1, data2, data3, data4); - return result + QLatin1Char('}'); + return result; +} + +/*! + Returns the binary representation of this QUuid. The byte array is + formatted as five hex fields separated by '-' and enclosed in + curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where + 'x' is a hex digit. From left to right, the five hex fields are + obtained from the four public data members in QUuid as follows: + + \table + \header + \o Field # + \o Source + + \row + \o 1 + \o data1 + + \row + \o 2 + \o data2 + + \row + \o 3 + \o data3 + + \row + \o 4 + \o data4[0] .. data4[1] + + \row + \o 5 + \o data4[2] .. data4[7] + + \endtable + + \since 4.8 +*/ +QByteArray QUuid::toByteArray() const +{ + QByteArray result(38, Qt::Uninitialized); + char *data = result.data(); + + _q_uuidToHex(data, data1, data2, data3, data4); + + return result; } #endif +/*! + Returns the binary representation of this QUuid. The byte array is in big + endian format, and formatted according to RFC 4122, section 4.1.2 - + "Layout and byte order". + + The order is as follows: + + \table + \header + \o Field # + \o Source + + \row + \o 1 + \o data1 + + \row + \o 2 + \o data2 + + \row + \o 3 + \o data3 + + \row + \o 4 + \o data4[0] .. data4[7] + + \endtable + + \since 4.8 +*/ +QByteArray QUuid::toRfc4122() const +{ + // we know how many bytes a UUID has, I hope :) + QByteArray bytes(16, Qt::Uninitialized); + uchar *data = reinterpret_cast<uchar*>(bytes.data()); + + qToBigEndian(data1, data); + data += sizeof(quint32); + qToBigEndian(data2, data); + data += sizeof(quint16); + qToBigEndian(data3, data); + data += sizeof(quint16); + + for (int i = 0; i < 8; ++i) { + *(data) = data4[i]; + data++; + } + + return bytes; +} + #ifndef QT_NO_DATASTREAM /*! \relates QUuid @@ -375,11 +598,30 @@ QString QUuid::toString() const */ QDataStream &operator<<(QDataStream &s, const QUuid &id) { - s << (quint32)id.data1; - s << (quint16)id.data2; - s << (quint16)id.data3; - for (int i = 0; i < 8; i++) - s << (quint8)id.data4[i]; + QByteArray bytes; + if (s.byteOrder() == QDataStream::BigEndian) { + bytes = id.toRfc4122(); + } else { + // we know how many bytes a UUID has, I hope :) + bytes = QByteArray(16, Qt::Uninitialized); + uchar *data = reinterpret_cast<uchar*>(bytes.data()); + + qToLittleEndian(id.data1, data); + data += sizeof(quint32); + qToLittleEndian(id.data2, data); + data += sizeof(quint16); + qToLittleEndian(id.data3, data); + data += sizeof(quint16); + + for (int i = 0; i < 8; ++i) { + *(data) = id.data4[i]; + data++; + } + } + + if (s.writeRawData(bytes.data(), 16) != 16) { + s.setStatus(QDataStream::WriteFailed); + } return s; } @@ -389,19 +631,30 @@ QDataStream &operator<<(QDataStream &s, const QUuid &id) */ QDataStream &operator>>(QDataStream &s, QUuid &id) { - quint32 u32; - quint16 u16; - quint8 u8; - s >> u32; - id.data1 = u32; - s >> u16; - id.data2 = u16; - s >> u16; - id.data3 = u16; - for (int i = 0; i < 8; i++) { - s >> u8; - id.data4[i] = u8; + QByteArray bytes(16, Qt::Uninitialized); + if (s.readRawData(bytes.data(), 16) != 16) { + s.setStatus(QDataStream::ReadPastEnd); + return s; } + + if (s.byteOrder() == QDataStream::BigEndian) { + id = QUuid::fromRfc4122(bytes); + } else { + const uchar *data = reinterpret_cast<const uchar *>(bytes.constData()); + + id.data1 = qFromLittleEndian<quint32>(data); + data += sizeof(quint32); + id.data2 = qFromLittleEndian<quint16>(data); + data += sizeof(quint16); + id.data3 = qFromLittleEndian<quint16>(data); + data += sizeof(quint16); + + for (int i = 0; i < 8; ++i) { + id.data4[i] = *(data); + data++; + } + } + return s; } #endif // QT_NO_DATASTREAM diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index f42ca91..832d5bc 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -108,8 +108,12 @@ struct Q_CORE_EXPORT QUuid QUuid(const QString &); QUuid(const char *); QString toString() const; - operator QString() const { return toString(); } + operator QString() const { return toString(); } // ### Qt5 remove + QUuid(const QByteArray &); + QByteArray toByteArray() const; #endif + QByteArray toRfc4122() const; + static QUuid fromRfc4122(const QByteArray &); bool isNull() const; bool operator==(const QUuid &orig) const diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ef49906..cde93d6 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -942,19 +942,32 @@ QLocale::Country QLocale::country() const QString QLocale::name() const { - Language l = language(); + const QLocalePrivate *dd = d(); - QString result = d()->languageCode(); + if (dd->m_language_id == QLocale::AnyLanguage) + return QString(); + if (dd->m_language_id == QLocale::C) + return QLatin1String("C"); - if (l == C) - return result; + const unsigned char *c = language_code_list + 3*(uint(dd->m_language_id)); - Country c = country(); - if (c == AnyCountry) - return result; + QString result(7, Qt::Uninitialized); + ushort *data = (ushort *)result.unicode(); + const ushort *begin = data; - result.append(QLatin1Char('_')); - result.append(d()->countryCode()); + *data++ = ushort(c[0]); + *data++ = ushort(c[1]); + if (c[2] != 0) + *data++ = ushort(c[2]); + if (dd->m_country_id != AnyCountry) { + *data++ = '_'; + const unsigned char *c = country_code_list + 3*(uint(dd->m_country_id)); + *data++ = ushort(c[0]); + *data++ = ushort(c[1]); + if (c[2] != 0) + *data++ = ushort(c[2]); + } + result.resize(data - begin); return result; } diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index 750ddf8..0c683b4 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -1166,12 +1166,20 @@ void QX11Data::xdndHandleDrop(QWidget *, const XEvent * xe, bool passive) // some XEMBEDding, so try to find the real QMimeData used // based on the timestamp for this drop. QMimeData *dropData = 0; - int at = findXdndDropTransactionByTime(qt_xdnd_target_current_time); - if (at != -1) + const int at = findXdndDropTransactionByTime(qt_xdnd_target_current_time); + if (at != -1) { dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data; + // Can't use the source QMimeData if we need the image conversion code from xdndObtainData + if (dropData && dropData->hasImage()) + dropData = 0; + } // if we can't find it, then use the data in the drag manager - if (!dropData) - dropData = (manager->object) ? manager->dragPrivate()->data : manager->dropData; + if (!dropData) { + if (manager->object && !manager->dragPrivate()->data->hasImage()) + dropData = manager->dragPrivate()->data; + else + dropData = manager->dropData; + } // Drop coming from another app? Update keyboard modifiers. if (!qt_xdnd_dragging) { @@ -1855,8 +1863,16 @@ static QVariant xdndObtainData(const char *format, QVariant::Type requestedType) && (!(w->windowType() == Qt::Desktop) || w->acceptDrops())) { QDragPrivate * o = QDragManager::self()->dragPrivate(); - if (o->data->hasFormat(QLatin1String(format))) - result = o->data->data(QLatin1String(format)); + const QString mimeType = QString::fromLatin1(format); + if (o->data->hasFormat(mimeType)) { + result = o->data->data(mimeType); + } else if (mimeType.startsWith(QLatin1String("image/")) && o->data->hasImage()) { + // ### duplicated from QInternalMimeData::renderDataHelper + QImage image = qvariant_cast<QImage>(o->data->imageData()); + QBuffer buf(&result); + buf.open(QBuffer::WriteOnly); + image.save(&buf, mimeType.mid(mimeType.indexOf(QLatin1Char('/')) + 1).toLatin1().toUpper()); + } return result; } diff --git a/src/network/access/access.pri b/src/network/access/access.pri index 5ead3ad..99e861e 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -22,7 +22,6 @@ HEADERS += \ access/qnetworkcookie_p.h \ access/qnetworkcookiejar.h \ access/qnetworkcookiejar_p.h \ - access/qnetworkcookiejartlds_p.h \ access/qnetworkrequest.h \ access/qnetworkrequest_p.h \ access/qnetworkreply.h \ diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 291bdec..a2fa689 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -40,12 +40,12 @@ ****************************************************************************/ #include "qnetworkcookiejar.h" -#include "qnetworkcookiejartlds_p.h" #include "qnetworkcookiejar_p.h" #include "QtNetwork/qnetworkcookie.h" #include "QtCore/qurl.h" #include "QtCore/qdatetime.h" +#include "private/qtldurl_p.h" QT_BEGIN_NAMESPACE @@ -216,7 +216,7 @@ bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieLis // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2 // redundant; the "leading dot" rule has been relaxed anyway, see above // we remove the leading dot for this check - if (QNetworkCookieJarPrivate::isEffectiveTLD(domain.remove(0, 1))) + if (qIsEffectiveTLD(domain.remove(0, 1))) continue; // not accepted } @@ -304,43 +304,4 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const return result; } -bool QNetworkCookieJarPrivate::isEffectiveTLD(const QString &domain) -{ - // for domain 'foo.bar.com': - // 1. return if TLD table contains 'foo.bar.com' - if (containsTLDEntry(domain)) - return true; - - if (domain.contains(QLatin1Char('.'))) { - int count = domain.size() - domain.indexOf(QLatin1Char('.')); - QString wildCardDomain; - wildCardDomain.reserve(count + 1); - wildCardDomain.append(QLatin1Char('*')); - wildCardDomain.append(domain.right(count)); - // 2. if table contains '*.bar.com', - // test if table contains '!foo.bar.com' - if (containsTLDEntry(wildCardDomain)) { - QString exceptionDomain; - exceptionDomain.reserve(domain.size() + 1); - exceptionDomain.append(QLatin1Char('!')); - exceptionDomain.append(domain); - return (! containsTLDEntry(exceptionDomain)); - } - } - return false; -} - -bool QNetworkCookieJarPrivate::containsTLDEntry(const QString &entry) -{ - int index = qHash(entry) % tldCount; - int currentDomainIndex = tldIndices[index]; - while (currentDomainIndex < tldIndices[index+1]) { - QString currentEntry = QString::fromUtf8(tldData + currentDomainIndex); - if (currentEntry == entry) - return true; - currentDomainIndex += qstrlen(tldData + currentDomainIndex) + 1; // +1 for the ending \0 - } - return false; -} - QT_END_NAMESPACE diff --git a/src/network/access/qnetworkcookiejar_p.h b/src/network/access/qnetworkcookiejar_p.h index 912847b..34858d9 100644 --- a/src/network/access/qnetworkcookiejar_p.h +++ b/src/network/access/qnetworkcookiejar_p.h @@ -63,9 +63,6 @@ class QNetworkCookieJarPrivate: public QObjectPrivate public: QList<QNetworkCookie> allCookies; - static bool Q_AUTOTEST_EXPORT isEffectiveTLD(const QString &domain); - static bool containsTLDEntry(const QString &entry); - Q_DECLARE_PUBLIC(QNetworkCookieJar) }; diff --git a/src/network/kernel/qhostaddress_p.h b/src/network/kernel/qhostaddress_p.h index 255d706..0349ff3 100644 --- a/src/network/kernel/qhostaddress_p.h +++ b/src/network/kernel/qhostaddress_p.h @@ -71,6 +71,11 @@ public: void setPrefixLength(QAbstractSocket::NetworkLayerProtocol proto, int len); }; +#ifdef Q_OS_SYMBIAN +class TInetAddr; +QHostAddress qt_QHostAddressFromTInetAddr(const TInetAddr& addr); +#endif + QT_END_NAMESPACE #endif diff --git a/src/network/kernel/qhostinfo_symbian.cpp b/src/network/kernel/qhostinfo_symbian.cpp index 042899d..86c157c 100644 --- a/src/network/kernel/qhostinfo_symbian.cpp +++ b/src/network/kernel/qhostinfo_symbian.cpp @@ -52,6 +52,7 @@ #include <private/qcore_symbian_p.h> #include <private/qsystemerror_p.h> #include <private/qnetworksession_p.h> +#include <private/qhostaddress_p.h> // Header does not exist in the S60 5.0 SDK //#include <networking/dnd_err.h> @@ -152,23 +153,17 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetw QList<QHostAddress> hostAddresses; TInetAddr hostAdd = nameResult().iAddr; - // 39 is the maximum length of an IPv6 address. - TBuf<39> ipAddr; - // Fill ipAddr with the IP address from hostAdd - hostAdd.Output(ipAddr); - if (ipAddr.Length() > 0) - hostAddresses.append(QHostAddress(qt_TDesC2QString(ipAddr))); + if (!(nameResult().iFlags & TNameRecord::EAlias) && !(hostAdd.IsUnspecified())) + hostAddresses.append(qt_QHostAddressFromTInetAddr(hostAdd)); // Check if there's more than one IP address linkd to this name while (hostResolver.Next(nameResult) == KErrNone) { hostAdd = nameResult().iAddr; - hostAdd.Output(ipAddr); // Ensure that record is valid (not an alias and with length greater than 0) - if (!(nameResult().iFlags & TNameRecord::EAlias) && !(hostAdd.IsUnspecified())) { - hostAddresses.append(QHostAddress(qt_TDesC2QString(ipAddr))); - } + if (!(nameResult().iFlags & TNameRecord::EAlias) && !(hostAdd.IsUnspecified())) + hostAddresses.append(qt_QHostAddressFromTInetAddr(hostAdd)); } hostResolver.Close(); @@ -414,14 +409,10 @@ void QSymbianHostResolver::processNameResult() { if (iStatus.Int() == KErrNone) { TInetAddr hostAdd = iNameResult().iAddr; - // 39 is the maximum length of an IPv6 address. - TBuf<39> ipAddr; - - hostAdd.Output(ipAddr); // Ensure that record is valid (not an alias and with length greater than 0) if (!(iNameResult().iFlags & TNameRecord::EAlias) && !(hostAdd.IsUnspecified())) { - iHostAddresses.append(QHostAddress(qt_TDesC2QString(ipAddr))); + iHostAddresses.append(qt_QHostAddressFromTInetAddr(hostAdd)); } iState = EGetByName; diff --git a/src/network/kernel/qnetworkinterface_symbian.cpp b/src/network/kernel/qnetworkinterface_symbian.cpp index e7d3ca9..dca6cf4 100644 --- a/src/network/kernel/qnetworkinterface_symbian.cpp +++ b/src/network/kernel/qnetworkinterface_symbian.cpp @@ -67,10 +67,8 @@ static QNetworkInterface::InterfaceFlags convertFlags(const TSoInetInterfaceInfo return flags; } -//TODO: share this, at least QHostInfo needs to do the same thing -static QHostAddress qt_QHostAddressFromTInetAddr(const TInetAddr& addr) +QHostAddress qt_QHostAddressFromTInetAddr(const TInetAddr& addr) { - //TODO: do we want to call v4 mapped addresses v4 or v6 outside of this file? if (addr.IsV4Mapped() || addr.Family() == KAfInet) { //convert v4 host address return QHostAddress(addr.Address()); diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 328c5c2..76b7d41 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -127,7 +127,7 @@ QT_BEGIN_NAMESPACE // forward declaration -static QMap<QString, QString> _q_mapFromOnelineName(char *name); +static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name); /*! Constructs a QSslCertificate by reading \a format encoded data @@ -324,7 +324,7 @@ QString QSslCertificate::issuerInfo(SubjectInfo info) const // lazy init if (d->issuerInfo.isEmpty() && d->x509) d->issuerInfo = - _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); + _q_mapFromX509Name(q_X509_get_issuer_name(d->x509)); return d->issuerInfo.value(_q_SubjectInfoToString(info)); } @@ -341,7 +341,7 @@ QString QSslCertificate::issuerInfo(const QByteArray &tag) const // lazy init if (d->issuerInfo.isEmpty() && d->x509) d->issuerInfo = - _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); + _q_mapFromX509Name(q_X509_get_issuer_name(d->x509)); return d->issuerInfo.value(QString::fromLatin1(tag)); } @@ -360,7 +360,7 @@ QString QSslCertificate::subjectInfo(SubjectInfo info) const // lazy init if (d->subjectInfo.isEmpty() && d->x509) d->subjectInfo = - _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); + _q_mapFromX509Name(q_X509_get_subject_name(d->x509)); return d->subjectInfo.value(_q_SubjectInfoToString(info)); } @@ -376,7 +376,7 @@ QString QSslCertificate::subjectInfo(const QByteArray &tag) const // lazy init if (d->subjectInfo.isEmpty() && d->x509) d->subjectInfo = - _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); + _q_mapFromX509Name(q_X509_get_subject_name(d->x509)); return d->subjectInfo.value(QString::fromLatin1(tag)); } @@ -666,37 +666,17 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n"; } -static QMap<QString, QString> _q_mapFromOnelineName(char *name) +static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name) { QMap<QString, QString> info; - QString infoStr = QString::fromLocal8Bit(name); - q_CRYPTO_free(name); - - // ### The right-hand encoding seems to allow hex (Regulierungsbeh\xC8orde) - //entry.replace(QLatin1String("\\x"), QLatin1String("%")); - //entry = QUrl::fromPercentEncoding(entry.toLatin1()); - // ### See RFC-4630 for more details! - - QRegExp rx(QLatin1String("/([A-Za-z]+)=(.+)")); - - int pos = 0; - while ((pos = rx.indexIn(infoStr, pos)) != -1) { - const QString name = rx.cap(1); - - QString value = rx.cap(2); - const int valuePos = rx.pos(2); - - const int next = rx.indexIn(value); - if (next == -1) { - info.insert(name, value); - break; - } - - value = value.left(next); - info.insert(name, value); - pos = valuePos + value.length(); + for (int i = 0; i < q_X509_NAME_entry_count(name); ++i) { + X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i); + const char *obj = q_OBJ_nid2sn(q_OBJ_obj2nid(q_X509_NAME_ENTRY_get_object(e))); + unsigned char *data = 0; + int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e)); + info[QString::fromUtf8(obj)] = QString::fromUtf8((char*)data, size); + q_CRYPTO_free(data); } - return info; } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index a730eb2..a4cc3c4 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -101,6 +101,7 @@ DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return) DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return) DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return) +DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return); DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return) DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return) DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return) @@ -248,7 +249,10 @@ DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return) DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return) DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return) -DEFINEFUNC3(char *, X509_NAME_oneline, X509_NAME *a, a, char *b, b, int c, c, return 0, return) +DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return) +DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return) +DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return) +DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return) DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return) DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG) DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return) @@ -518,6 +522,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(ASN1_INTEGER_get, 48, libs.second ) RESOLVEFUNC(ASN1_STRING_data, 71, libs.second ) RESOLVEFUNC(ASN1_STRING_length, 76, libs.second ) + RESOLVEFUNC(ASN1_STRING_to_UTF8, 86, libs.second ) RESOLVEFUNC(BIO_ctrl, 184, libs.second ) RESOLVEFUNC(BIO_free, 209, libs.second ) RESOLVEFUNC(BIO_new, 222, libs.second ) @@ -608,7 +613,10 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSLv23_server_method, 191, libs.first ) RESOLVEFUNC(TLSv1_server_method, 200, libs.first ) RESOLVEFUNC(SSL_CTX_load_verify_locations, 34, libs.first ) - RESOLVEFUNC(X509_NAME_oneline, 1830, libs.second ) + RESOLVEFUNC(X509_NAME_entry_count, 1821, libs.second ) + RESOLVEFUNC(X509_NAME_get_entry, 1823, libs.second ) + RESOLVEFUNC(X509_NAME_ENTRY_get_data, 1808, libs.second ) + RESOLVEFUNC(X509_NAME_ENTRY_get_object, 1809, libs.second ) RESOLVEFUNC(X509_PUBKEY_get, 1844, libs.second ) RESOLVEFUNC(X509_STORE_free, 1939, libs.second ) RESOLVEFUNC(X509_STORE_new, 1942, libs.second ) @@ -647,6 +655,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(ASN1_INTEGER_get) RESOLVEFUNC(ASN1_STRING_data) RESOLVEFUNC(ASN1_STRING_length) + RESOLVEFUNC(ASN1_STRING_to_UTF8) RESOLVEFUNC(BIO_ctrl) RESOLVEFUNC(BIO_free) RESOLVEFUNC(BIO_new) @@ -736,7 +745,10 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSLv3_server_method) RESOLVEFUNC(SSLv23_server_method) RESOLVEFUNC(TLSv1_server_method) - RESOLVEFUNC(X509_NAME_oneline) + RESOLVEFUNC(X509_NAME_entry_count) + RESOLVEFUNC(X509_NAME_get_entry) + RESOLVEFUNC(X509_NAME_ENTRY_get_data) + RESOLVEFUNC(X509_NAME_ENTRY_get_object) RESOLVEFUNC(X509_PUBKEY_get) RESOLVEFUNC(X509_STORE_free) RESOLVEFUNC(X509_STORE_new) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index e20deb8..c0a3b4d 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -204,6 +204,7 @@ bool q_resolveOpenSslSymbols(); long q_ASN1_INTEGER_get(ASN1_INTEGER *a); unsigned char * q_ASN1_STRING_data(ASN1_STRING *a); int q_ASN1_STRING_length(ASN1_STRING *a); +int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b); long q_BIO_ctrl(BIO *a, int b, long c, void *d); int q_BIO_free(BIO *a); BIO *q_BIO_new(BIO_METHOD *a); @@ -360,7 +361,10 @@ void *q_X509_get_ext_d2i(X509 *a, int b, int *c, int *d); X509_NAME *q_X509_get_issuer_name(X509 *a); X509_NAME *q_X509_get_subject_name(X509 *a); int q_X509_verify_cert(X509_STORE_CTX *ctx); -char *q_X509_NAME_oneline(X509_NAME *a, char *b, int c); +int q_X509_NAME_entry_count(X509_NAME *a); +X509_NAME_ENTRY *q_X509_NAME_get_entry(X509_NAME *a,int b); +ASN1_STRING *q_X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *a); +ASN1_OBJECT *q_X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *a); EVP_PKEY *q_X509_PUBKEY_get(X509_PUBKEY *a); void q_X509_STORE_free(X509_STORE *store); X509_STORE *q_X509_STORE_new(); diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 2686a00..335e832 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -177,7 +177,7 @@ void tst_Headers::allSourceFilesData() || sourceFile.endsWith("/src/corelib/global/qconfig.h") || sourceFile.endsWith("/src/corelib/global/qconfig.cpp") || sourceFile.endsWith("/src/tools/uic/qclass_lib_map.h") - || sourceFile.endsWith("src/network/access/qnetworkcookiejartlds_p.h") + || sourceFile.endsWith("src/corelib/io/qurltlds_p.h") ) continue; diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index c21fd03..b2ce5ca 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -371,11 +371,18 @@ void tst_NetworkSelfTest::initTestCase() { #ifndef QT_NO_BEARERMANAGEMENT netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); networkConfiguration = netConfMan->defaultConfiguration(); - networkSession.reset(new QNetworkSession(networkConfiguration)); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); } #endif } diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index e4372c5..aefe0b9 100644 --- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -141,11 +141,18 @@ void tst_QAbstractNetworkCache::initTestCase() { #ifndef QT_NO_BEARERMANAGEMENT netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); networkConfiguration = netConfMan->defaultConfiguration(); - networkSession.reset(new QNetworkSession(networkConfiguration)); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); } #endif } diff --git a/tests/auto/qftp/tst_qftp.cpp b/tests/auto/qftp/tst_qftp.cpp index 1fa0787..7e431cf 100644 --- a/tests/auto/qftp/tst_qftp.cpp +++ b/tests/auto/qftp/tst_qftp.cpp @@ -155,6 +155,7 @@ private: QFtp *ftp; #ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; QSharedPointer<QNetworkSession> networkSessionExplicit; QSharedPointer<QNetworkSession> networkSessionImplicit; #endif @@ -225,10 +226,20 @@ void tst_QFtp::initTestCase_data() void tst_QFtp::initTestCase() { #ifndef QT_NO_BEARERMANAGEMENT - QNetworkConfigurationManager manager; - networkSessionImplicit = QSharedPointer<QNetworkSession>(new QNetworkSession(manager.defaultConfiguration())); - networkSessionImplicit->open(); - QVERIFY(networkSessionImplicit->waitForOpened(60000)); //there may be user prompt on 1st connect + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QNetworkConfiguration networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSessionImplicit = QSharedPointer<QNetworkSession>(new QNetworkSession(networkConfiguration)); + if (!networkSessionImplicit->isOpen()) { + networkSessionImplicit->open(); + QVERIFY(networkSessionImplicit->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } #endif } @@ -254,6 +265,8 @@ void tst_QFtp::init() } #ifndef QT_NO_BEARERMANAGEMENT if (setSession) { + if (!networkSessionImplicit) + QSKIP("test requires a valid default network configuration", SkipSingle); networkSessionExplicit = networkSessionImplicit; if (!networkSessionExplicit->isOpen()) { networkSessionExplicit->open(); diff --git a/tests/auto/qhostinfo/tst_qhostinfo.cpp b/tests/auto/qhostinfo/tst_qhostinfo.cpp index c528a5c..2fa5e76 100644 --- a/tests/auto/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/qhostinfo/tst_qhostinfo.cpp @@ -197,13 +197,19 @@ tst_QHostInfo::~tst_QHostInfo() void tst_QHostInfo::initTestCase() { #ifndef QT_NO_BEARERMANAGEMENT - //start the default network netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); networkConfiguration = netConfMan->defaultConfiguration(); - networkSession.reset(new QNetworkSession(networkConfiguration)); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); } #endif @@ -213,6 +219,13 @@ void tst_QHostInfo::initTestCase() #else ipv6Available = false; ipv6LookupsAvailable = false; + + QTcpServer server; + if (server.listen(QHostAddress("::1"))) { + // We have IPv6 support + ipv6Available = true; + } + #if !defined(QT_NO_GETADDRINFO) // check if the system getaddrinfo can do IPv6 lookups struct addrinfo hint, *result = 0; @@ -235,13 +248,6 @@ void tst_QHostInfo::initTestCase() #endif #endif - QTcpServer server; - if (server.listen(QHostAddress("::1"))) { - // We have IPv6 support - ipv6Available = true; - } - - // run each testcase with and without test enabled QTest::addColumn<bool>("cache"); QTest::newRow("WithCache") << true; diff --git a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index d59a510..1b4256b 100644 --- a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -42,7 +42,7 @@ #include <QtTest/QtTest> #include <QtNetwork/QNetworkCookieJar> -#include "private/qnetworkcookiejar_p.h" +#include "private/qtldurl_p.h" class tst_QNetworkCookieJar: public QObject { @@ -438,7 +438,7 @@ void tst_QNetworkCookieJar::effectiveTLDs() #endif QFETCH(QString, domain); QFETCH(bool, isTLD); - QCOMPARE(QNetworkCookieJarPrivate::isEffectiveTLD(domain), isTLD); + QCOMPARE(qIsEffectiveTLD(domain), isTLD); } QTEST_MAIN(tst_QNetworkCookieJar) diff --git a/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp index ae3436d..2077717 100644 --- a/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp @@ -89,11 +89,18 @@ void tst_QNetworkInterface::initTestCase() { #ifndef QT_NO_BEARERMANAGEMENT netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); networkConfiguration = netConfMan->defaultConfiguration(); - networkSession.reset(new QNetworkSession(networkConfiguration)); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); } #endif } diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 782e2a0..25925bd 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -1290,11 +1290,18 @@ void tst_QNetworkReply::initTestCase() #endif #ifndef QT_NO_BEARERMANAGEMENT netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); networkConfiguration = netConfMan->defaultConfiguration(); - networkSession.reset(new QNetworkSession(networkConfiguration)); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); } #endif } diff --git a/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem new file mode 100644 index 0000000..e1b731d --- /dev/null +++ b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICkTCCAfqgAwIBAgIJAL1nF+PLAF2KMA0GCSqGSIb3DQEBBQUAMGkxKzApBgNV +BAoMIkjElcSCxrLDvyDKjeG6v8qI4bq34bi7IFLDqWPDtnJkxZ0xFTATBgNVBAsM +DOOIp0HjiYHvvatCQzEWMBQGA1UEAwwNSm9obm55IEd1aXRhcjELMAkGA1UEBhMC +Tk8wHhcNMTEwNTA1MDgxMzEwWhcNMTEwNjA0MDgxMzEwWjBpMSswKQYDVQQKDCJI +xJXEgsayw78gyo3hur/KiOG6t+G4uyBSw6ljw7ZyZMWdMRUwEwYDVQQLDAzjiKdB +44mB772rQkMxFjAUBgNVBAMMDUpvaG5ueSBHdWl0YXIxCzAJBgNVBAYTAk5PMIGf +MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2zSxS17I6596dJE/VAmGz+06D9S8n +3C0hnIGNVu+LwbgDJTvOw0SzNj4UP72UGgd3UI1KLBg5XWIsRNmE3COJMMh6syjI +L1Ept+tVXxGL6n4gl+0nZ7dkUyxJmeFtigYrL+qCH1yd5rmf3sC3jO4IosuAiG66 +IDkJEVo64NT8ZQIDAQABo0EwPzA9BgNVHREENjA0gQ9hcm5lQGZvb2Jhci5vcmeC +Dnd3dy5mb29iYXIub3JngRFiamFybmVAZm9vYmFyLm9yZzANBgkqhkiG9w0BAQUF +AAOBgQAqVhbC0/EUFdnKlYV3PrknwGX1dPEPGJuIQHa0KpoicvNiOhs1HxBDYbzc +F6wcAMEynq4YwGKhcQLZOs2mo0LreAjA9rU/yBnqrnUW/4gxtUUvmJKK+62IjfLp +eO1L+1NcEMJiaZf8fip4VXhXdOYUhgE8WUZ1UJRC6w3T/yAgcQ== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem.san b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem.san new file mode 100644 index 0000000..f46a637 --- /dev/null +++ b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem.san @@ -0,0 +1,5 @@ +[subj_alt_name] +subjectAltName=\ + email:arne@foobar.org,\ + DNS:www.foobar.org,\ + email:bjarne@foobar.org diff --git a/tests/auto/qsslcertificate/certificates/gencertificates.sh b/tests/auto/qsslcertificate/certificates/gencertificates.sh index 9f873d9..0bac191 100755 --- a/tests/auto/qsslcertificate/certificates/gencertificates.sh +++ b/tests/auto/qsslcertificate/certificates/gencertificates.sh @@ -90,5 +90,15 @@ openssl req -x509 -in req-san.pem -out $outname -key rsa-pri-1024.pem \ -config san.cnf -extensions subj_alt_name /bin/cp san.cnf $outname.san +#--- Non-ASCII Subject --------------------------------------------------------------------- +echo -e "\n generating self signed root cert. with Subject containing UTF-8 characters ..." +outname=cert-ss-san-utf8.pem +#subject="/O=HĕĂƲÿ ʍếʈặḻ Récördŝ/OU=㈧A㉁ォBC/CN=Johnny Guitar/C=NO" +subject=$'/O=H\xc4\x95\xc4\x82\xc6\xb2\xc3\xbf \xca\x8d\xe1\xba\xbf\xca\x88\xe1\xba\xb7\xe1\xb8\xbb R\xc3\xa9c\xc3\xb6rd\xc5\x9d/OU=\xe3\x88\xa7A\xe3\x89\x81\xef\xbd\xabBC/CN=Johnny Guitar/C=NO' +openssl req -out req-san.pem -new -key rsa-pri-1024.pem -utf8 -subj "$subject" +openssl req -x509 -in req-san.pem -out $outname -key rsa-pri-1024.pem \ + -config san.cnf -extensions subj_alt_name -nameopt multiline,utf8,-esc_msb +/bin/cp san.cnf $outname.san + echo -e "\n cleaning up ..." /bin/rm rsa-pri-1024.pem rsa-pub-1024.* req*.pem diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index c38147d..9276685 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -96,6 +96,7 @@ private slots: void digest_data(); void digest(); void alternateSubjectNames_data(); + void utf8SubjectNames(); void alternateSubjectNames(); void publicKey_data(); void publicKey(); @@ -407,6 +408,27 @@ void tst_QSslCertificate::alternateSubjectNames() } } +void tst_QSslCertificate::utf8SubjectNames() +{ + QSslCertificate cert = QSslCertificate::fromPath("certificates/cert-ss-san-utf8.pem", QSsl::Pem, + QRegExp::FixedString).first(); + QVERIFY(!cert.isNull()); + + // O is "Heavy Metal Records" with heavy use of "decorations" like accents, umlauts etc., + // OU uses arabian / asian script letters near codepoint 64K. + // strings split where the compiler would otherwise find three-digit hex numbers + static const char *o = "H\xc4\x95\xc4\x82\xc6\xb2\xc3\xbf \xca\x8d\xe1\xba\xbf\xca\x88\xe1\xba" + "\xb7\xe1\xb8\xbb R\xc3\xa9" "c" "\xc3\xb6rd\xc5\x9d"; + static const char *ou = "\xe3\x88\xa7" "A" "\xe3\x89\x81\xef\xbd\xab" "BC"; + + // the following two tests should help find "\x"-literal encoding bugs in the test itself + QCOMPARE(cert.subjectInfo("O").length(), QString::fromUtf8(o).length()); + QCOMPARE (cert.subjectInfo("O").toUtf8().toHex(), QByteArray(o).toHex()); + + QCOMPARE(cert.subjectInfo("O"), QString::fromUtf8(o)); + QCOMPARE(cert.subjectInfo("OU"), QString::fromUtf8(ou)); +} + void tst_QSslCertificate::publicKey_data() { QTest::addColumn<QString>("certFilePath"); @@ -519,13 +541,13 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"certificates/*\" fixed der") << QString("certificates/*") << int(QRegExp::FixedString) << false << 0; QTest::newRow("\"certificates/*\" regexp pem") << QString("certificates/*") << int(QRegExp::RegExp) << true << 0; QTest::newRow("\"certificates/*\" regexp der") << QString("certificates/*") << int(QRegExp::RegExp) << false << 0; - QTest::newRow("\"certificates/*\" wildcard pem") << QString("certificates/*") << int(QRegExp::Wildcard) << true << 4; + QTest::newRow("\"certificates/*\" wildcard pem") << QString("certificates/*") << int(QRegExp::Wildcard) << true << 5; QTest::newRow("\"certificates/*\" wildcard der") << QString("certificates/*") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("\"c*/c*.pem\" fixed pem") << QString("c*/c*.pem") << int(QRegExp::FixedString) << true << 0; QTest::newRow("\"c*/c*.pem\" fixed der") << QString("c*/c*.pem") << int(QRegExp::FixedString) << false << 0; QTest::newRow("\"c*/c*.pem\" regexp pem") << QString("c*/c*.pem") << int(QRegExp::RegExp) << true << 0; QTest::newRow("\"c*/c*.pem\" regexp der") << QString("c*/c*.pem") << int(QRegExp::RegExp) << false << 0; - QTest::newRow("\"c*/c*.pem\" wildcard pem") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << true << 4; + QTest::newRow("\"c*/c*.pem\" wildcard pem") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << true << 5; QTest::newRow("\"c*/c*.pem\" wildcard der") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("\"d*/c*.pem\" fixed pem") << QString("d*/c*.pem") << int(QRegExp::FixedString) << true << 0; QTest::newRow("\"d*/c*.pem\" fixed der") << QString("d*/c*.pem") << int(QRegExp::FixedString) << false << 0; @@ -535,7 +557,7 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"d*/c*.pem\" wildcard der") << QString("d*/c*.pem") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("\"c.*/c.*.pem\" fixed pem") << QString("c.*/c.*.pem") << int(QRegExp::FixedString) << true << 0; QTest::newRow("\"c.*/c.*.pem\" fixed der") << QString("c.*/c.*.pem") << int(QRegExp::FixedString) << false << 0; - QTest::newRow("\"c.*/c.*.pem\" regexp pem") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << true << 4; + QTest::newRow("\"c.*/c.*.pem\" regexp pem") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << true << 5; QTest::newRow("\"c.*/c.*.pem\" regexp der") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << false << 0; QTest::newRow("\"c.*/c.*.pem\" wildcard pem") << QString("c.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0; QTest::newRow("\"c.*/c.*.pem\" wildcard der") << QString("c.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0; @@ -546,7 +568,7 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"d.*/c.*.pem\" wildcard pem") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0; QTest::newRow("\"d.*/c.*.pem\" wildcard der") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0; #ifdef Q_OS_LINUX - QTest::newRow("absolute path wildcard pem") << QString(QDir::currentPath() + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 4; + QTest::newRow("absolute path wildcard pem") << QString(QDir::currentPath() + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 5; #endif QTest::newRow("trailing-whitespace") << QString("more-certificates/trailing-whitespace.pem") << int(QRegExp::FixedString) << true << 1; @@ -769,7 +791,7 @@ void tst_QSslCertificate::nulInCN() QString cn = cert.subjectInfo(QSslCertificate::CommonName); QVERIFY(cn != "www.bank.com"); - static const char realCN[] = "www.bank.com\\x00.badguy.com"; + static const char realCN[] = "www.bank.com\0.badguy.com"; QCOMPARE(cn, QString::fromLatin1(realCN, sizeof realCN - 1)); } diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp index 22a90cf..f4249ab 100644 --- a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -146,6 +146,15 @@ void tst_QtConcurrentMap::map() QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6); QtConcurrent::map(numberList.begin(), numberList.end(), &Number::multiplyBy2).waitForFinished(); QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12); + +#ifdef Q_COMPILER_LAMBDA + // lambda + QtConcurrent::map(list, [](int &x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 128 << 256 << 384); + QtConcurrent::map(list.begin(), list.end(), [](int &x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 256 << 512 << 768); +#endif + } // functors don't take arguments by reference, making these no-ops @@ -170,6 +179,14 @@ void tst_QtConcurrentMap::map() QCOMPARE(list, QList<int>() << 1 << 2 << 3); QtConcurrent::map(list.begin(), list.end(), multiplyBy2Immutable).waitForFinished(); QCOMPARE(list, QList<int>() << 1 << 2 << 3); + +#ifdef Q_COMPILER_LAMBDA + // lambda + QtConcurrent::map(list, [](int x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::map(list.begin(), list.end(), [](int x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); +#endif } // Linked lists and forward iterators @@ -2303,6 +2320,10 @@ void tst_QtConcurrentMap::stlContainers() { #ifdef QT_NO_STL QSKIP("Qt compiled without STL support", SkipAll); +#elif defined(Q_COMPILER_RVALUE_REFS) + //mapped uses &Container::push_back, but in c++0x, std::vector has two overload of it + // meaning it is not possible to take the address of that function anymore. + QSKIP("mapped do not work with c++0x stl vector", SkipAll); #else std::vector<int> vector; vector.push_back(1); diff --git a/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp index e4e9479..cacb09a 100644 --- a/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -67,6 +67,8 @@ private slots: #if 0 void createFunctor(); #endif + void functor(); + void lambda(); }; #if 0 @@ -444,6 +446,71 @@ void tst_QtConcurrentRun::createFunctor() } #endif +struct Functor { + int operator()() { return 42; } + double operator()(double a, double b) { return a/b; } + int operator()(int a, int b) { return a/b; } + void operator()(int) { } + void operator()(int, int, int) { } + void operator()(int, int, int, int) { } + void operator()(int, int, int, int, int) { } + void operator()(int, int, int, int, int, int) { } +}; + +void tst_QtConcurrentRun::functor() +{ + //this test functor without result_type, decltype need to be supported by the compiler +#ifndef Q_COMPILER_DECLTYPE + QSKIP("Compiler do not suport decltype", SkipAll); +#else + Functor f; + { + QFuture<int> fut = QtConcurrent::run(f); + QCOMPARE(fut.result(), 42); + } + { + QFuture<double> fut = QtConcurrent::run(f, 8.5, 1.8); + QCOMPARE(fut.result(), (8.5/1.8)); + } + { + QFuture<int> fut = QtConcurrent::run(f, 19, 3); + QCOMPARE(fut.result(), int(19/3)); + } + { + QtConcurrent::run(f, 1).waitForFinished(); + QtConcurrent::run(f, 1,2).waitForFinished(); + QtConcurrent::run(f, 1,2,3).waitForFinished(); + QtConcurrent::run(f, 1,2,3,4).waitForFinished(); + QtConcurrent::run(f, 1,2,3,4,5).waitForFinished(); + } +#endif +} + + +void tst_QtConcurrentRun::lambda() +{ +#ifndef Q_COMPILER_LAMBDA + QSKIP("Compiler do not suport lambda", SkipAll); +#else + + QCOMPARE(QtConcurrent::run([](){ return 45; }).result(), 45); + QCOMPARE(QtConcurrent::run([](int a){ return a+15; }, 12).result(), 12+15); + QCOMPARE(QtConcurrent::run([](int a, double b){ return a + b; }, 12, 15).result(), double(12+15)); + QCOMPARE(QtConcurrent::run([](int a , int, int, int, int b){ return a + b; }, 1, 2, 3, 4, 5).result(), 1 + 5); + +#ifdef Q_COMPILER_INITIALIZER_LISTS + { + QString str { "Hello World Foo" }; + QFuture<QStringList> f1 = QtConcurrent::run([&](){ return str.split(' '); }); + auto r = f1.result(); + QCOMPARE(r, QStringList({"Hello", "World", "Foo"})); + } +#endif + +#endif +} + + #include "tst_qtconcurrentrun.moc" #else diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp index 3416a7c..a7c2604 100644 --- a/tests/auto/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp @@ -116,6 +116,7 @@ private slots: private: #ifndef QT_NO_BEARERMANAGEMENT QNetworkSession *networkSession; + QNetworkConfigurationManager *netConfMan; #endif }; @@ -154,10 +155,20 @@ void tst_QTcpServer::initTestCase_data() void tst_QTcpServer::initTestCase() { #ifndef QT_NO_BEARERMANAGEMENT - QNetworkConfigurationManager man; - networkSession = new QNetworkSession(man.defaultConfiguration(), this); - networkSession->open(); - QVERIFY(networkSession->waitForOpened()); + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QNetworkConfiguration networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession = new QNetworkSession(networkConfiguration); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } #endif } diff --git a/tests/auto/qudpsocket/tst_qudpsocket.cpp b/tests/auto/qudpsocket/tst_qudpsocket.cpp index 9ca049b..a38082e 100644 --- a/tests/auto/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/qudpsocket/tst_qudpsocket.cpp @@ -148,11 +148,18 @@ void tst_QUdpSocket::initTestCase_data() #ifndef QT_NO_BEARERMANAGEMENT netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); networkConfiguration = netConfMan->defaultConfiguration(); - networkSession = QSharedPointer<QNetworkSession>(new QNetworkSession(networkConfiguration)); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); + if (networkConfiguration.isValid()) { + networkSession = QSharedPointer<QNetworkSession>(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); } #endif } diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 613053b..ae27c4a 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -49,6 +49,7 @@ #include <qurl.h> #include <qtextcodec.h> #include <qmap.h> +#include "private/qtldurl_p.h" // For testsuites #define IDNA_ACE_PREFIX "xn--" @@ -88,6 +89,8 @@ public slots: void init(); void cleanup(); private slots: + void effectiveTLDs_data(); + void effectiveTLDs(); void getSetCheck(); void constructing(); void assignment(); @@ -4005,5 +4008,28 @@ void tst_QUrl::taskQTBUG_8701() 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); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" diff --git a/tests/auto/quuid/tst_quuid.cpp b/tests/auto/quuid/tst_quuid.cpp index 6333e83..4948312 100644 --- a/tests/auto/quuid/tst_quuid.cpp +++ b/tests/auto/quuid/tst_quuid.cpp @@ -60,7 +60,14 @@ public: tst_QUuid(); private slots: + void fromChar(); void toString(); + void fromString(); + void toByteArray(); + void fromByteArray(); + void toRfc4122(); + void fromRfc4122(); + void check_QDataStream(); void isNull(); void equal(); void notEqual(); @@ -83,16 +90,106 @@ public: tst_QUuid::tst_QUuid() { - uuidA = "{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"; - uuidB = "{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"; + //"{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"; + uuidA = QUuid(0xfc69b59e, 0xcc34 ,0x4436 ,0xa4 ,0x3c ,0xee ,0x95 ,0xd1 ,0x28 ,0xb8 ,0xc5); + + //"{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"; + uuidB = QUuid(0x1ab6e93a ,0xb1cb ,0x4a87 ,0xba ,0x47 ,0xec ,0x7e ,0x99 ,0x03 ,0x9a ,0x7b); } +void tst_QUuid::fromChar() +{ + QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5")); + QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5")); + QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c")); + QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34")); + QCOMPARE(QUuid(), QUuid("fc69b59e-cc34-")); + QCOMPARE(QUuid(), QUuid("fc69b59e-cc34")); + QCOMPARE(QUuid(), QUuid("cc34")); + QCOMPARE(QUuid(), QUuid(NULL)); + + QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); +} void tst_QUuid::toString() { QCOMPARE(uuidA.toString(), QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + + QCOMPARE(uuidB.toString(), QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")); +} + +void tst_QUuid::fromString() +{ + QCOMPARE(uuidA, QUuid(QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QString("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(uuidA, QUuid(QString("fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(QUuid(), QUuid(QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c"))); + + QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); +} + +void tst_QUuid::toByteArray() +{ + QCOMPARE(uuidA.toByteArray(), QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + + QCOMPARE(uuidB.toByteArray(), QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")); +} + +void tst_QUuid::fromByteArray() +{ + QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(QUuid(), QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c"))); + + QCOMPARE(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); +} + +void tst_QUuid::toRfc4122() +{ + QCOMPARE(uuidA.toRfc4122(), QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")); + + QCOMPARE(uuidB.toRfc4122(), QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")); } +void tst_QUuid::fromRfc4122() +{ + QCOMPARE(uuidA, QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5"))); + + QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b"))); +} + +void tst_QUuid::check_QDataStream() +{ + QUuid tmp; + QByteArray ar; + { + QDataStream out(&ar,QIODevice::WriteOnly); + out.setByteOrder(QDataStream::BigEndian); + out << uuidA; + } + { + QDataStream in(&ar,QIODevice::ReadOnly); + in.setByteOrder(QDataStream::BigEndian); + in >> tmp; + QCOMPARE(uuidA, tmp); + } + { + QDataStream out(&ar,QIODevice::WriteOnly); + out.setByteOrder(QDataStream::LittleEndian); + out << uuidA; + } + { + QDataStream in(&ar,QIODevice::ReadOnly); + in.setByteOrder(QDataStream::LittleEndian); + in >> tmp; + QCOMPARE(uuidA, tmp); + } +} void tst_QUuid::isNull() { diff --git a/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp b/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp index dbec65c..a035cf3 100644 --- a/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp @@ -53,6 +53,18 @@ public: private slots: void createUuid(); + void fromChar(); + void toString(); + void fromString(); + void toByteArray(); + void fromByteArray(); + void toRfc4122(); + void fromRfc4122(); + void toDataStream(); + void fromDataStream(); + void isNull(); + void operatorLess(); + void operatorMore(); }; void tst_bench_QUuid::createUuid() @@ -62,5 +74,118 @@ void tst_bench_QUuid::createUuid() } } +void tst_bench_QUuid::fromChar() +{ + QBENCHMARK { + QUuid uuid("{67C8770B-44F1-410A-AB9A-F9B5446F13EE}"); + } +} + +void tst_bench_QUuid::toString() +{ + QUuid uuid = QUuid::createUuid(); + QBENCHMARK { + uuid.toString(); + } +} + +void tst_bench_QUuid::fromString() +{ + QString string = "{67C8770B-44F1-410A-AB9A-F9B5446F13EE}"; + QBENCHMARK { + QUuid uuid(string); + } +} + +void tst_bench_QUuid::toByteArray() +{ + QUuid uuid = QUuid::createUuid(); + QBENCHMARK { + uuid.toByteArray(); + } +} + +void tst_bench_QUuid::fromByteArray() +{ + QByteArray string = "{67C8770B-44F1-410A-AB9A-F9B5446F13EE}"; + QBENCHMARK { + QUuid uuid(string); + } +} + +void tst_bench_QUuid::toRfc4122() +{ + QUuid uuid = QUuid::createUuid(); + QBENCHMARK { + uuid.toRfc4122(); + } +} + +void tst_bench_QUuid::fromRfc4122() +{ + QByteArray string = QByteArray::fromHex("67C8770B44F1410AAB9AF9B5446F13EE"); + QBENCHMARK { + QUuid uuid = QUuid::fromRfc4122(string); + } +} + +void tst_bench_QUuid::toDataStream() +{ + QUuid uuid1, uuid2; + uuid1 = QUuid::createUuid(); + QByteArray ar; + { + QDataStream out(&ar,QIODevice::WriteOnly); + QBENCHMARK { + out << uuid1; + } + } +} + +void tst_bench_QUuid::fromDataStream() +{ + QUuid uuid1, uuid2; + uuid1 = QUuid::createUuid(); + QByteArray ar; + { + QDataStream out(&ar,QIODevice::WriteOnly); + out << uuid1; + } + { + QDataStream in(&ar,QIODevice::ReadOnly); + QBENCHMARK { + in >> uuid2; + } + } +} + +void tst_bench_QUuid::isNull() +{ + QUuid uuid = QUuid(); + QBENCHMARK { + uuid.isNull(); + } +} + +void tst_bench_QUuid::operatorLess() +{ + QUuid uuid1, uuid2; + uuid1 = QUuid::createUuid(); + uuid2 = QUuid::createUuid(); + QBENCHMARK { + uuid1 < uuid2; + } +} + +void tst_bench_QUuid::operatorMore() +{ + QUuid uuid1, uuid2; + uuid1 = QUuid::createUuid(); + uuid2 = QUuid::createUuid(); + QBENCHMARK { + uuid1 > uuid2; + } +} + QTEST_MAIN(tst_bench_QUuid); #include "tst_quuid.moc" diff --git a/util/network/cookiejar-generateTLDs/main.cpp b/util/corelib/qurl-generateTLDs/main.cpp index b369ece..861546c 100644 --- a/util/network/cookiejar-generateTLDs/main.cpp +++ b/util/corelib/qurl-generateTLDs/main.cpp @@ -77,7 +77,7 @@ int main(int argc, char **argv) { printf(" wget http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 -O effective_tld_names.dat\n"); printf(" grep '^[^\\/\\/]' effective_tld_names.dat > effective_tld_names.dat.trimmed\n"); printf(" %s effective_tld_names.dat.trimmed effective_tld_names.dat.qt\n\n", argv[0]); - printf("Now copy the data from effective_tld_names.dat.qt to the file src/network/access/qnetworkcookiejartlds_p.h in your Qt repo\n\n"); + printf("Now copy the data from effective_tld_names.dat.qt to the file src/corelib/io/qurltlds_p.h in your Qt repo\n\n"); exit(1); } QFile file(argv[1]); @@ -156,6 +156,6 @@ int main(int argc, char **argv) { outFile.write(outDataBufferBA); outFile.write("};\n"); outFile.close(); - printf("data generated to %s . Now copy the data from this file to src/network/access/qnetworkcookiejartlds_p.h in your Qt repo\n", argv[2]); + printf("data generated to %s . Now copy the data from this file to src/corelib/io/qurltlds_p.h in your Qt repo\n", argv[2]); exit(0); } diff --git a/util/network/cookiejar-generateTLDs/cookiejar-generateTLDs.pro b/util/corelib/qurl-generateTLDs/qurl-generateTLDs.pro index 9d5f1cf..9d5f1cf 100644 --- a/util/network/cookiejar-generateTLDs/cookiejar-generateTLDs.pro +++ b/util/corelib/qurl-generateTLDs/qurl-generateTLDs.pro |