src/corelib/kernel/qvariant.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtCore module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qvariant.h"
00025 #include "qbitarray.h"
00026 #include "qbytearray.h"
00027 #include "qdatastream.h"
00028 #include "qdebug.h"
00029 #include "qmap.h"
00030 #include "qdatetime.h"
00031 #include "qlist.h"
00032 #include "qstring.h"
00033 #include "qstringlist.h"
00034 #include "qurl.h"
00035 #include "qlocale.h"
00036 #include "private/qvariant_p.h"
00037 
00038 #ifndef QT_NO_GEOM_VARIANT
00039 #include "qsize.h"
00040 #include "qpoint.h"
00041 #include "qrect.h"
00042 #include "qline.h"
00043 #endif
00044 
00045 #include <float.h>
00046 
00047 #ifndef DBL_DIG
00048 #  define DBL_DIG 10
00049 #endif
00050 #ifndef FLT_DIG
00051 #  define FLT_DIG 6
00052 #endif
00053 
00054 
00055 static const void *constData(const QVariant::Private &d)
00056 {
00057     switch (d.type) {
00058     case QVariant::Int:
00059         return &d.data.i;
00060     case QVariant::UInt:
00061         return &d.data.u;
00062     case QVariant::Bool:
00063         return &d.data.b;
00064     case QVariant::LongLong:
00065         return &d.data.ll;
00066     case QVariant::ULongLong:
00067         return &d.data.ull;
00068     case QVariant::Double:
00069         return &d.data.d;
00070     default:
00071         return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
00072     }
00073 }
00074 
00075 static void construct(QVariant::Private *x, const void *copy)
00076 {
00077     x->is_shared = false;
00078 
00079     switch (x->type) {
00080     case QVariant::String:
00081         v_construct<QString>(x, copy);
00082         break;
00083     case QVariant::Char:
00084         v_construct<QChar>(x, copy);
00085         break;
00086     case QVariant::StringList:
00087         v_construct<QStringList>(x, copy);
00088         break;
00089     case QVariant::Map:
00090         v_construct<QVariantMap>(x, copy);
00091         break;
00092     case QVariant::List:
00093         v_construct<QVariantList>(x, copy);
00094         break;
00095     case QVariant::Date:
00096         v_construct<QDate>(x, copy);
00097         break;
00098     case QVariant::Time:
00099         v_construct<QTime>(x, copy);
00100         break;
00101     case QVariant::DateTime:
00102         v_construct<QDateTime>(x, copy);
00103         break;
00104     case QVariant::ByteArray:
00105         v_construct<QByteArray>(x, copy);
00106         break;
00107     case QVariant::BitArray:
00108         v_construct<QBitArray>(x, copy);
00109         break;
00110 #ifndef QT_NO_GEOM_VARIANT
00111     case QVariant::Size:
00112         v_construct<QSize>(x, copy);
00113         break;
00114     case QVariant::SizeF:
00115         v_construct<QSizeF>(x, copy);
00116         break;
00117     case QVariant::Rect:
00118         v_construct<QRect>(x, copy);
00119         break;
00120     case QVariant::LineF:
00121         v_construct<QLineF>(x, copy);
00122         break;
00123     case QVariant::Line:
00124         v_construct<QLine>(x, copy);
00125         break;
00126     case QVariant::RectF:
00127         v_construct<QRectF>(x, copy);
00128         break;
00129     case QVariant::Point:
00130         v_construct<QPoint>(x, copy);
00131         break;
00132     case QVariant::PointF:
00133         v_construct<QPointF>(x, copy);
00134         break;
00135 #endif
00136     case QVariant::Url:
00137         v_construct<QUrl>(x, copy);
00138         break;
00139     case QVariant::Locale:
00140         v_construct<QLocale>(x, copy);
00141         break;
00142     case QVariant::RegExp:
00143         v_construct<QRegExp>(x, copy);
00144         break;
00145     case QVariant::Int:
00146         x->data.i = copy ? *static_cast<const int *>(copy) : 0;
00147         break;
00148     case QVariant::UInt:
00149         x->data.u = copy ? *static_cast<const uint *>(copy) : 0u;
00150         break;
00151     case QVariant::Bool:
00152         x->data.b = copy ? *static_cast<const bool *>(copy) : false;
00153         break;
00154     case QVariant::Double:
00155         x->data.d = copy ? *static_cast<const double*>(copy) : 0.0;
00156         break;
00157     case QVariant::LongLong:
00158         x->data.ll = copy ? *static_cast<const qlonglong *>(copy) : Q_INT64_C(0);
00159         break;
00160     case QVariant::ULongLong:
00161         x->data.ull = copy ? *static_cast<const qulonglong *>(copy) : Q_UINT64_C(0);
00162         break;
00163     case QVariant::Invalid:
00164     case QVariant::UserType:
00165         break;
00166     default:
00167         x->is_shared = true;
00168         x->data.shared = new QVariant::PrivateShared(QMetaType::construct(x->type, copy));
00169         if (!x->data.shared->ptr)
00170              Q_ASSERT_X(x->type > 62, "QVariant::construct()", "Unknown datatype");
00171         break;
00172     }
00173     x->is_null = !copy;
00174 }
00175 
00176 static void clear(QVariant::Private *d)
00177 {
00178     switch (d->type) {
00179     case QVariant::String:
00180         v_clear<QString>(d);
00181         break;
00182     case QVariant::Char:
00183         v_clear<QChar>(d);
00184         break;
00185     case QVariant::StringList:
00186         v_clear<QStringList>(d);
00187         break;
00188     case QVariant::Map:
00189         v_clear<QVariantMap>(d);
00190         break;
00191     case QVariant::List:
00192         v_clear<QVariantList>(d);
00193         break;
00194     case QVariant::Date:
00195         v_clear<QDate>(d);
00196         break;
00197     case QVariant::Time:
00198         v_clear<QTime>(d);
00199         break;
00200     case QVariant::DateTime:
00201         v_clear<QDateTime>(d);
00202         break;
00203     case QVariant::ByteArray:
00204         v_clear<QByteArray>(d);
00205         break;
00206     case QVariant::BitArray:
00207         v_clear<QBitArray>(d);
00208         break;
00209 #ifndef QT_NO_GEOM_VARIANT
00210     case QVariant::Point:
00211         v_clear<QPoint>(d);
00212         break;
00213     case QVariant::PointF:
00214         v_clear<QPointF>(d);
00215         break;
00216     case QVariant::Size:
00217         v_clear<QSize>(d);
00218         break;
00219     case QVariant::SizeF:
00220         v_clear<QSizeF>(d);
00221         break;
00222     case QVariant::Rect:
00223         v_clear<QRect>(d);
00224         break;
00225     case QVariant::LineF:
00226         v_clear<QLineF>(d);
00227         break;
00228     case QVariant::Line:
00229         v_clear<QLine>(d);
00230         break;
00231     case QVariant::RectF:
00232         v_clear<QRectF>(d);
00233         break;
00234 #endif
00235     case QVariant::Url:
00236         v_clear<QUrl>(d);
00237         break;
00238     case QVariant::Locale:
00239         v_clear<QLocale>(d);
00240         break;
00241     case QVariant::RegExp:
00242         v_clear<QRegExp>(d);
00243         break;
00244     case QVariant::LongLong:
00245     case QVariant::ULongLong:
00246     case QVariant::Double:
00247         break;
00248     case QVariant::Invalid:
00249     case QVariant::UserType:
00250     case QVariant::Int:
00251     case QVariant::UInt:
00252     case QVariant::Bool:
00253         break;
00254     default:
00255         QMetaType::destroy(d->type, d->data.shared->ptr);
00256         delete d->data.shared;
00257         break;
00258     }
00259 
00260     d->type = QVariant::Invalid;
00261     d->is_null = true;
00262     d->is_shared = false;
00263 }
00264 
00265 static bool isNull(const QVariant::Private *d)
00266 {
00267     switch(d->type) {
00268     case QVariant::String:
00269         return v_cast<QString>(d)->isNull();
00270     case QVariant::Char:
00271         return v_cast<QChar>(d)->isNull();
00272     case QVariant::Date:
00273         return v_cast<QDate>(d)->isNull();
00274     case QVariant::Time:
00275         return v_cast<QTime>(d)->isNull();
00276     case QVariant::DateTime:
00277         return v_cast<QDateTime>(d)->isNull();
00278     case QVariant::ByteArray:
00279         return v_cast<QByteArray>(d)->isNull();
00280     case QVariant::BitArray:
00281         return v_cast<QBitArray>(d)->isNull();
00282 #ifndef QT_NO_GEOM_VARIANT
00283     case QVariant::Size:
00284         return v_cast<QSize>(d)->isNull();
00285     case QVariant::SizeF:
00286         return v_cast<QSizeF>(d)->isNull();
00287     case QVariant::Rect:
00288         return v_cast<QRect>(d)->isNull();
00289     case QVariant::Line:
00290         return v_cast<QLine>(d)->isNull();
00291     case QVariant::LineF:
00292         return v_cast<QLineF>(d)->isNull();
00293     case QVariant::RectF:
00294         return v_cast<QRectF>(d)->isNull();
00295     case QVariant::Point:
00296         return v_cast<QPoint>(d)->isNull();
00297     case QVariant::PointF:
00298         return v_cast<QPointF>(d)->isNull();
00299 #endif
00300     case QVariant::Url:
00301     case QVariant::Locale:
00302     case QVariant::RegExp:
00303     case QVariant::StringList:
00304     case QVariant::Map:
00305     case QVariant::List:
00306     case QVariant::Invalid:
00307     case QVariant::UserType:
00308     case QVariant::Int:
00309     case QVariant::UInt:
00310     case QVariant::LongLong:
00311     case QVariant::ULongLong:
00312     case QVariant::Bool:
00313     case QVariant::Double:
00314         break;
00315     }
00316     return d->is_null;
00317 }
00318 
00319 static bool compare(const QVariant::Private *a, const QVariant::Private *b)
00320 {
00321     switch(a->type) {
00322     case QVariant::List:
00323         return *v_cast<QVariantList>(a) == *v_cast<QVariantList>(b);
00324     case QVariant::Map: {
00325         const QVariantMap *m1 = v_cast<QVariantMap>(a);
00326         const QVariantMap *m2 = v_cast<QVariantMap>(b);
00327         if (m1->count() != m2->count())
00328             return false;
00329         QVariantMap::ConstIterator it = m1->constBegin();
00330         QVariantMap::ConstIterator it2 = m2->constBegin();
00331         while (it != m1->constEnd()) {
00332             if (*it != *it2)
00333                 return false;
00334             ++it;
00335             ++it2;
00336         }
00337         return true;
00338     }
00339     case QVariant::String:
00340         return *v_cast<QString>(a) == *v_cast<QString>(b);
00341     case QVariant::Char:
00342         return *v_cast<QChar>(a) == *v_cast<QChar>(b);
00343     case QVariant::StringList:
00344         return *v_cast<QStringList>(a) == *v_cast<QStringList>(b);
00345 #ifndef QT_NO_GEOM_VARIANT
00346     case QVariant::Size:
00347         return *v_cast<QSize>(a) == *v_cast<QSize>(b);
00348     case QVariant::SizeF:
00349         return *v_cast<QSizeF>(a) == *v_cast<QSizeF>(b);
00350     case QVariant::Rect:
00351         return *v_cast<QRect>(a) == *v_cast<QRect>(b);
00352     case QVariant::Line:
00353         return *v_cast<QLine>(a) == *v_cast<QLine>(b);
00354     case QVariant::LineF:
00355         return *v_cast<QLineF>(a) == *v_cast<QLineF>(b);
00356     case QVariant::RectF:
00357         return *v_cast<QRectF>(a) == *v_cast<QRectF>(b);
00358     case QVariant::Point:
00359         return *v_cast<QPoint>(a) == *v_cast<QPoint>(b);
00360     case QVariant::PointF:
00361         return *v_cast<QPointF>(a) == *v_cast<QPointF>(b);
00362 #endif
00363     case QVariant::Url:
00364         return *v_cast<QUrl>(a) == *v_cast<QUrl>(b);
00365     case QVariant::Locale:
00366         return *v_cast<QLocale>(a) == *v_cast<QLocale>(b);
00367     case QVariant::RegExp:
00368         return *v_cast<QRegExp>(a) == *v_cast<QRegExp>(b);
00369     case QVariant::Int:
00370         return a->data.i == b->data.i;
00371     case QVariant::UInt:
00372         return a->data.u == b->data.u;
00373     case QVariant::LongLong:
00374         return a->data.ll == b->data.ll;
00375     case QVariant::ULongLong:
00376         return a->data.ull == b->data.ull;
00377     case QVariant::Bool:
00378         return a->data.b == b->data.b;
00379     case QVariant::Double:
00380         return a->data.d == b->data.d;
00381     case QVariant::Date:
00382         return *v_cast<QDate>(a) == *v_cast<QDate>(b);
00383     case QVariant::Time:
00384         return *v_cast<QTime>(a) == *v_cast<QTime>(b);
00385     case QVariant::DateTime:
00386         return *v_cast<QDateTime>(a) == *v_cast<QDateTime>(b);
00387     case QVariant::ByteArray:
00388         return *v_cast<QByteArray>(a) == *v_cast<QByteArray>(b);
00389     case QVariant::BitArray:
00390         return *v_cast<QBitArray>(a) == *v_cast<QBitArray>(b);
00391     case QVariant::Invalid:
00392         return true;
00393     default:
00394         break;
00395     }
00396     if (!QMetaType::isRegistered(a->type))
00397         qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
00398     return a->data.shared->ptr == b->data.shared->ptr;
00399 }
00400 
00401 static qlonglong qMetaTypeNumber(const QVariant::Private *d)
00402 {
00403     switch (d->type) {
00404     case QMetaType::Int:
00405         return d->data.i;
00406     case QMetaType::LongLong:
00407         return d->data.ll;
00408     case QMetaType::Char:
00409         return qlonglong(*static_cast<signed char *>(d->data.shared->ptr));
00410     case QMetaType::Short:
00411         return qlonglong(*static_cast<short *>(d->data.shared->ptr));
00412     case QMetaType::Long:
00413         return qlonglong(*static_cast<long *>(d->data.shared->ptr));
00414     case QMetaType::Float:
00415         return qRound64(*static_cast<float *>(d->data.shared->ptr));
00416     case QVariant::Double:
00417         return qRound64(d->data.d);
00418     }
00419     Q_ASSERT(false);
00420     return 0;
00421 }
00422 
00423 static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
00424 {
00425     switch (d->type) {
00426     case QVariant::UInt:
00427         return d->data.u;
00428     case QVariant::ULongLong:
00429         return d->data.ull;
00430     case QMetaType::UChar:
00431         return qulonglong(*static_cast<unsigned char *>(d->data.shared->ptr));
00432     case QMetaType::UShort:
00433         return qulonglong(*static_cast<ushort *>(d->data.shared->ptr));
00434     case QMetaType::ULong:
00435         return qulonglong(*static_cast<ulong *>(d->data.shared->ptr));
00436     }
00437     Q_ASSERT(false);
00438     return 0;
00439 }
00440 
00441 static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
00442 {
00443     *ok = true;
00444 
00445     switch (uint(d->type)) {
00446     case QVariant::String:
00447         return v_cast<QString>(d)->toLongLong(ok);
00448     case QVariant::Char:
00449         return v_cast<QChar>(d)->unicode();
00450     case QVariant::ByteArray:
00451         return v_cast<QByteArray>(d)->toLongLong(ok);
00452     case QVariant::Bool:
00453         return qlonglong(d->data.b);
00454     case QVariant::Double:
00455     case QVariant::Int:
00456     case QMetaType::Char:
00457     case QMetaType::Short:
00458     case QMetaType::Long:
00459     case QMetaType::Float:
00460     case QMetaType::LongLong:
00461         return qMetaTypeNumber(d);
00462     case QVariant::ULongLong:
00463     case QVariant::UInt:
00464     case QMetaType::UChar:
00465     case QMetaType::UShort:
00466     case QMetaType::ULong:
00467         return qlonglong(qMetaTypeUNumber(d));
00468     }
00469 
00470     *ok = false;
00471     return Q_INT64_C(0);
00472 }
00473 
00474 static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
00475 {
00476     *ok = true;
00477 
00478     switch (uint(d->type)) {
00479     case QVariant::String:
00480         return v_cast<QString>(d)->toULongLong(ok);
00481     case QVariant::Char:
00482         return v_cast<QChar>(d)->unicode();
00483     case QVariant::ByteArray:
00484         return v_cast<QByteArray>(d)->toULongLong(ok);
00485     case QVariant::Bool:
00486         return qulonglong(d->data.b);
00487     case QVariant::Double:
00488     case QVariant::Int:
00489     case QMetaType::Char:
00490     case QMetaType::Short:
00491     case QMetaType::Long:
00492     case QMetaType::Float:
00493     case QMetaType::LongLong:
00494         return qulonglong(qMetaTypeNumber(d));
00495     case QVariant::ULongLong:
00496     case QVariant::UInt:
00497     case QMetaType::UChar:
00498     case QMetaType::UShort:
00499     case QMetaType::ULong:
00500         return qMetaTypeUNumber(d);
00501     }
00502 
00503     *ok = false;
00504     return Q_UINT64_C(0);
00505 }
00506 
00507 static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, bool *ok)
00508 {
00509     Q_ASSERT(d->type != uint(t));
00510 
00511     bool dummy;
00512     if (!ok)
00513         ok = &dummy;
00514 
00515     switch (uint(t)) {
00516     case QVariant::String: {
00517         QString *str = static_cast<QString *>(result);
00518         switch (d->type) {
00519         case QVariant::Char:
00520             *str = QString(*v_cast<QChar>(d));
00521             break;
00522         case QMetaType::Char:
00523         case QMetaType::UChar:
00524             *str = QChar::fromAscii(*static_cast<char *>(d->data.shared->ptr));
00525             break;
00526         case QMetaType::Short:
00527         case QMetaType::Long:
00528         case QVariant::Int:
00529         case QVariant::LongLong:
00530             *str = QString::number(qMetaTypeNumber(d));
00531             break;
00532         case QVariant::UInt:
00533         case QVariant::ULongLong:
00534         case QMetaType::UShort:
00535         case QMetaType::ULong:
00536             *str = QString::number(qMetaTypeUNumber(d));
00537             break;
00538         case QMetaType::Float:
00539             *str = QString::number(*static_cast<float *>(d->data.shared->ptr), 'g', FLT_DIG);
00540             break;
00541         case QVariant::Double:
00542             *str = QString::number(d->data.d, 'g', DBL_DIG);
00543             break;
00544 #if !defined(QT_NO_DATESTRING)
00545         case QVariant::Date:
00546             *str = v_cast<QDate>(d)->toString(Qt::ISODate);
00547             break;
00548         case QVariant::Time:
00549             *str = v_cast<QTime>(d)->toString(Qt::ISODate);
00550             break;
00551         case QVariant::DateTime:
00552             *str = v_cast<QDateTime>(d)->toString(Qt::ISODate);
00553             break;
00554 #endif
00555         case QVariant::Bool:
00556             *str = QLatin1String(d->data.b ? "true" : "false");
00557             break;
00558         case QVariant::ByteArray:
00559             *str = QString::fromAscii(v_cast<QByteArray>(d)->constData());
00560             break;
00561         case QVariant::StringList:
00562             if (v_cast<QStringList>(d)->count() == 1)
00563                 *str = v_cast<QStringList>(d)->at(0);
00564             break;
00565         default:
00566             return false;
00567         }
00568         break;
00569     }
00570     case QVariant::Char: {
00571         QChar *c = static_cast<QChar *>(result);
00572         switch (d->type) {
00573         case QVariant::Int:
00574         case QVariant::LongLong:
00575         case QMetaType::Char:
00576         case QMetaType::Short:
00577         case QMetaType::Long:
00578         case QMetaType::Float:
00579             *c = QChar(ushort(qMetaTypeNumber(d)));
00580             break;
00581         case QVariant::UInt:
00582         case QVariant::ULongLong:
00583         case QMetaType::UChar:
00584         case QMetaType::UShort:
00585         case QMetaType::ULong:
00586             *c = QChar(ushort(qMetaTypeUNumber(d)));
00587             break;
00588         default:
00589             return false;
00590         }
00591         break;
00592     }
00593 #ifndef QT_NO_GEOM_VARIANT
00594     case QVariant::Size: {
00595         QSize *s = static_cast<QSize *>(result);
00596         switch (d->type) {
00597         case QVariant::SizeF:
00598             *s = v_cast<QSizeF>(d)->toSize();
00599             break;
00600         default:
00601             return false;
00602         }
00603         break;
00604     }
00605 
00606     case QVariant::SizeF: {
00607         QSizeF *s = static_cast<QSizeF *>(result);
00608         switch (d->type) {
00609         case QVariant::Size:
00610             *s = QSizeF(*(v_cast<QSize>(d)));
00611             break;
00612         default:
00613             return false;
00614         }
00615         break;
00616     }
00617 
00618     case QVariant::Line: {
00619         QLine *s = static_cast<QLine *>(result);
00620         switch (d->type) {
00621         case QVariant::LineF:
00622             *s = v_cast<QLineF>(d)->toLine();
00623             break;
00624         default:
00625             return false;
00626         }
00627         break;
00628     }
00629 
00630     case QVariant::LineF: {
00631         QLineF *s = static_cast<QLineF *>(result);
00632         switch (d->type) {
00633         case QVariant::Line:
00634             *s = QLineF(*(v_cast<QLine>(d)));
00635             break;
00636         default:
00637             return false;
00638         }
00639         break;
00640     }
00641 #endif
00642     case QVariant::StringList:
00643         if (d->type == QVariant::List) {
00644             QStringList *slst = static_cast<QStringList *>(result);
00645             const QVariantList *list = v_cast<QVariantList >(d);
00646             for (int i = 0; i < list->size(); ++i)
00647                 slst->append(list->at(i).toString());
00648         } else if (d->type == QVariant::String) {
00649             QStringList *slst = static_cast<QStringList *>(result);
00650             *slst = QStringList(*v_cast<QString>(d));
00651         } else {
00652             return false;
00653         }
00654         break;
00655     case QVariant::Date: {
00656         QDate *dt = static_cast<QDate *>(result);
00657         if (d->type == QVariant::DateTime)
00658             *dt = v_cast<QDateTime>(d)->date();
00659 #ifndef QT_NO_DATESTRING
00660         else if (d->type == QVariant::String)
00661             *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
00662 #endif
00663         else
00664             return false;
00665         break;
00666     }
00667     case QVariant::Time: {
00668         QTime *t = static_cast<QTime *>(result);
00669         switch (d->type) {
00670         case QVariant::DateTime:
00671             *t = v_cast<QDateTime>(d)->time();
00672             break;
00673 #ifndef QT_NO_DATESTRING
00674         case QVariant::String:
00675             *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
00676             break;
00677 #endif
00678         default:
00679             return false;
00680         }
00681         break;
00682     }
00683     case QVariant::DateTime: {
00684         QDateTime *dt = static_cast<QDateTime *>(result);
00685         switch (d->type) {
00686 #ifndef QT_NO_DATESTRING
00687         case QVariant::String:
00688             *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
00689             break;
00690 #endif
00691         case QVariant::Date:
00692             *dt = QDateTime(*v_cast<QDate>(d));
00693             break;
00694         default:
00695             return false;
00696         }
00697         break;
00698     }
00699     case QVariant::ByteArray: {
00700         QByteArray *ba = static_cast<QByteArray *>(result);
00701         switch (d->type) {
00702         case QVariant::String:
00703             *ba = v_cast<QString>(d)->toAscii();
00704             break;
00705         case QVariant::Double:
00706             *ba = QByteArray::number(d->data.d, 'g', DBL_DIG);
00707             break;
00708         case QMetaType::Float:
00709             *ba = QByteArray::number(*static_cast<float *>(d->data.shared->ptr), 'g', FLT_DIG);
00710             break;
00711         case QMetaType::Char:
00712         case QMetaType::UChar:
00713             *ba = QByteArray(1, *static_cast<char *>(d->data.shared->ptr));
00714             break;
00715         case QVariant::Int:
00716         case QVariant::LongLong:
00717         case QMetaType::Short:
00718         case QMetaType::Long:
00719             *ba = QByteArray::number(qMetaTypeNumber(d));
00720             break;
00721         case QVariant::UInt:
00722         case QVariant::ULongLong:
00723         case QMetaType::UShort:
00724         case QMetaType::ULong:
00725             *ba = QByteArray::number(qMetaTypeUNumber(d));
00726             break;
00727         default:
00728             return false;
00729         }
00730     }
00731     break;
00732     case QMetaType::Short:
00733         *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
00734         return *ok;
00735     case QMetaType::Long:
00736         *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
00737         return *ok;
00738     case QMetaType::UShort:
00739         *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
00740         return *ok;
00741     case QMetaType::ULong:
00742         *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
00743         return *ok;
00744     case QVariant::Int:
00745         *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
00746         return *ok;
00747     case QVariant::UInt:
00748         *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
00749         return *ok;
00750     case QVariant::LongLong:
00751         *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
00752         return *ok;
00753     case QVariant::ULongLong: {
00754         *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
00755         return *ok;
00756     }
00757     case QVariant::Bool: {
00758         bool *b = static_cast<bool *>(result);
00759         switch(d->type) {
00760         case QVariant::String:
00761         {
00762             QString str = v_cast<QString>(d)->toLower();
00763             *b = !(str == QLatin1String("0") || str == QLatin1String("false") || str.isEmpty());
00764             break;
00765         }
00766         case QVariant::Char:
00767             *b = !v_cast<QChar>(d)->isNull();
00768             break;
00769         case QVariant::Double:
00770         case QVariant::Int:
00771         case QVariant::LongLong:
00772         case QMetaType::Char:
00773         case QMetaType::Short:
00774         case QMetaType::Long:
00775         case QMetaType::Float:
00776             *b = qMetaTypeNumber(d) != Q_INT64_C(0);
00777             break;
00778         case QVariant::UInt:
00779         case QVariant::ULongLong:
00780         case QMetaType::UChar:
00781         case QMetaType::UShort:
00782         case QMetaType::ULong:
00783             *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
00784             break;
00785         default:
00786             *b = false;
00787             return false;
00788         }
00789         break;
00790     }
00791     case QVariant::Double: {
00792         double *f = static_cast<double *>(result);
00793         switch (d->type) {
00794         case QVariant::String:
00795             *f = v_cast<QString>(d)->toDouble(ok);
00796             break;
00797         case QVariant::ByteArray:
00798             *f = v_cast<QByteArray>(d)->toDouble(ok);
00799             break;
00800         case QVariant::Bool:
00801             *f = double(d->data.b);
00802             break;
00803         case QMetaType::Float:
00804             *f = *static_cast<float *>(d->data.shared->ptr);
00805             break;
00806         case QVariant::LongLong:
00807         case QVariant::Int:
00808         case QMetaType::Char:
00809         case QMetaType::Short:
00810         case QMetaType::Long:
00811             *f = double(qMetaTypeNumber(d));
00812             break;
00813         case QVariant::UInt:
00814         case QVariant::ULongLong:
00815         case QMetaType::UChar:
00816         case QMetaType::UShort:
00817         case QMetaType::ULong:
00818 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
00819             *f = (double)(qlonglong)qMetaTypeUNumber(d);
00820 #else
00821             *f = double(qMetaTypeUNumber(d));
00822 #endif
00823             break;
00824         default:
00825             *f = 0.0;
00826             return false;
00827         }
00828         break;
00829     }
00830     case QMetaType::Float: {
00831         float *f = static_cast<float *>(result);
00832         switch (d->type) {
00833         case QVariant::String:
00834             *f = float(v_cast<QString>(d)->toDouble(ok));
00835             break;
00836         case QVariant::ByteArray:
00837             *f = float(v_cast<QByteArray>(d)->toDouble(ok));
00838             break;
00839         case QVariant::Bool:
00840             *f = float(d->data.b);
00841             break;
00842         case QVariant::Double:
00843             *f = float(d->data.d);
00844             break;
00845         case QVariant::LongLong:
00846         case QVariant::Int:
00847         case QMetaType::Char:
00848         case QMetaType::Short:
00849         case QMetaType::Long:
00850             *f = float(qMetaTypeNumber(d));
00851             break;
00852         case QVariant::UInt:
00853         case QVariant::ULongLong:
00854         case QMetaType::UChar:
00855         case QMetaType::UShort:
00856         case QMetaType::ULong:
00857 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
00858             *f = (float)(qlonglong)qMetaTypeUNumber(d);
00859 #else
00860             *f = float(qMetaTypeUNumber(d));
00861 #endif
00862             break;
00863         default:
00864             *f = 0.0f;
00865             return false;
00866         }
00867         break;
00868     }
00869     case QVariant::List:
00870         if (d->type == QVariant::StringList) {
00871             QVariantList *lst = static_cast<QVariantList *>(result);
00872             const QStringList *slist = v_cast<QStringList>(d);
00873             for (int i = 0; i < slist->size(); ++i)
00874                 lst->append(QVariant(slist->at(i)));
00875         } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
00876             *static_cast<QVariantList *>(result) =
00877                 *static_cast<QList<QVariant> *>(d->data.shared->ptr);
00878         } else {
00879             return false;
00880         }
00881         break;
00882     case QVariant::Map:
00883         if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
00884             *static_cast<QVariantMap *>(result) =
00885                 *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
00886         } else {
00887             return false;
00888         }
00889         break;
00890 #ifndef QT_NO_GEOM_VARIANT
00891     case QVariant::Rect:
00892         if (d->type == QVariant::RectF)
00893             *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
00894         else
00895             return false;
00896         break;
00897     case QVariant::RectF:
00898         if (d->type == QVariant::Rect)
00899             *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
00900         else
00901             return false;
00902         break;
00903     case QVariant::PointF:
00904         if (d->type == QVariant::Point)
00905             *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
00906         else
00907             return false;
00908         break;
00909     case QVariant::Point:
00910         if (d->type == QVariant::PointF)
00911             *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
00912         else
00913             return false;
00914         break;
00915 #endif
00916     default:
00917         return false;
00918     }
00919     return true;
00920 }
00921 
00922 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
00923 static void streamDebug(QDebug dbg, const QVariant &v)
00924 {
00925     switch (v.type()) {
00926     case QVariant::Int:
00927         dbg.nospace() << v.toInt();
00928         break;
00929     case QVariant::UInt:
00930         dbg.nospace() << v.toUInt();
00931         break;
00932     case QVariant::LongLong:
00933         dbg.nospace() << v.toLongLong();
00934         break;
00935     case QVariant::ULongLong:
00936         dbg.nospace() << v.toULongLong();
00937         break;
00938     case QVariant::Double:
00939         dbg.nospace() << v.toDouble();
00940         break;
00941     case QVariant::Bool:
00942         dbg.nospace() << v.toBool();
00943         break;
00944     case QVariant::String:
00945         dbg.nospace() << v.toString();
00946         break;
00947     case QVariant::Char:
00948         dbg.nospace() << v.toChar();
00949         break;
00950     case QVariant::StringList:
00951         dbg.nospace() << v.toStringList();
00952         break;
00953     case QVariant::Map:
00954         dbg.nospace() << v.toMap();
00955         break;
00956     case QVariant::List:
00957         dbg.nospace() << v.toList();
00958         break;
00959     case QVariant::Date:
00960         dbg.nospace() << v.toDate();
00961         break;
00962     case QVariant::Time:
00963         dbg.nospace() << v.toTime();
00964         break;
00965     case QVariant::DateTime:
00966         dbg.nospace() << v.toDateTime();
00967         break;
00968     case QVariant::ByteArray:
00969         dbg.nospace() << v.toByteArray();
00970         break;
00971     case QVariant::Url:
00972         dbg.nospace() << v.toUrl();
00973         break;
00974 #ifndef QT_NO_GEOM_VARIANT
00975     case QVariant::Point:
00976         dbg.nospace() << v.toPoint();
00977         break;
00978     case QVariant::PointF:
00979         dbg.nospace() << v.toPointF();
00980         break;
00981     case QVariant::Rect:
00982         dbg.nospace() << v.toRect();
00983         break;
00984     case QVariant::Size:
00985         dbg.nospace() << v.toSize();
00986         break;
00987     case QVariant::SizeF:
00988         dbg.nospace() << v.toSizeF();
00989         break;
00990     case QVariant::Line:
00991         dbg.nospace() << v.toLine();
00992         break;
00993     case QVariant::LineF:
00994         dbg.nospace() << v.toLineF();
00995         break;
00996     case QVariant::RectF:
00997         dbg.nospace() << v.toRectF();
00998         break;
00999 #endif
01000     case QVariant::BitArray:
01001         //dbg.nospace() << v.toBitArray();
01002         break;
01003     default:
01004         break;
01005     }
01006 }
01007 #endif
01008 
01009 const QVariant::Handler qt_kernel_variant_handler = {
01010     construct,
01011     clear,
01012     isNull,
01013 #ifndef QT_NO_DATASTREAM
01014     0,
01015     0,
01016 #endif
01017     compare,
01018     convert,
01019     0,
01020 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
01021     streamDebug
01022 #else
01023     0
01024 #endif
01025 };
01026 
01027 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
01028 {
01029     return &qt_kernel_variant_handler;
01030 }
01031 
01032 
01033 const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
01034 
01236 void QVariant::create(int type, const void *copy)
01237 {
01238     d.type = type;
01239     handler->construct(&d, copy);
01240 }
01241 
01253 QVariant::~QVariant()
01254 {
01255     if (d.type > Char && (!d.is_shared || !d.data.shared->ref.deref()))
01256         handler->clear(&d);
01257 }
01258 
01266 QVariant::QVariant(const QVariant &p)
01267     : d(p.d)
01268 {
01269     if (d.is_shared) {
01270         d.data.shared->ref.ref();
01271     } else if (p.d.type > Char) {
01272         handler->construct(&d, p.constData());
01273         d.is_null = p.d.is_null;
01274     }
01275 }
01276 
01277 #ifndef QT_NO_DATASTREAM
01278 
01281 QVariant::QVariant(QDataStream &s)
01282 {
01283     d.is_null = true;
01284     s >> *this;
01285 }
01286 #endif //QT_NO_DATASTREAM
01287 
01314 QVariant::QVariant(const char *val)
01315 {
01316     QString s = QString::fromAscii(val);
01317     create(String, &s);
01318 }
01319 
01493 QVariant::QVariant(Type type)
01494 { create(type, 0); }
01495 QVariant::QVariant(int typeOrUserType, const void *copy)
01496 { create(typeOrUserType, copy); d.is_null = false; }
01497 QVariant::QVariant(int val)
01498 { d.is_null = false; d.type = Int; d.data.i = val; }
01499 QVariant::QVariant(uint val)
01500 { d.is_null = false; d.type = UInt; d.data.u = val; }
01501 QVariant::QVariant(qlonglong val)
01502 { d.is_null = false; d.type = LongLong; d.data.ll = val; }
01503 QVariant::QVariant(qulonglong val)
01504 { d.is_null = false; d.type = ULongLong; d.data.ull = val; }
01505 QVariant::QVariant(bool val)
01506 { d.is_null = false; d.type = Bool; d.data.b = val; }
01507 QVariant::QVariant(double val)
01508 { d.is_null = false; d.type = Double; d.data.d = val; }
01509 
01510 QVariant::QVariant(const QByteArray &val)
01511 { create(ByteArray, &val); }
01512 QVariant::QVariant(const QBitArray &val)
01513 { create(BitArray, &val); }
01514 QVariant::QVariant(const QString &val)
01515 { create(String, &val); }
01516 QVariant::QVariant(const QChar &val)
01517 { create (Char, &val); }
01518 QVariant::QVariant(const QLatin1String &val)
01519 { QString str(val); create(String, &str); }
01520 QVariant::QVariant(const QStringList &val)
01521 { create(StringList, &val); }
01522 
01523 QVariant::QVariant(const QDate &val)
01524 { create(Date, &val); }
01525 QVariant::QVariant(const QTime &val)
01526 { create(Time, &val); }
01527 QVariant::QVariant(const QDateTime &val)
01528 { create(DateTime, &val); }
01529 QVariant::QVariant(const QList<QVariant> &list)
01530 { create(List, &list); }
01531 QVariant::QVariant(const QMap<QString, QVariant> &map)
01532 { create(Map, &map); }
01533 #ifndef QT_NO_GEOM_VARIANT
01534 QVariant::QVariant(const QPoint &pt) { create(Point, &pt); }
01535 QVariant::QVariant(const QPointF &pt) { create (PointF, &pt); }
01536 QVariant::QVariant(const QRectF &r) { create (RectF, &r); }
01537 QVariant::QVariant(const QLineF &l) { create (LineF, &l); }
01538 QVariant::QVariant(const QLine &l) { create (Line, &l); }
01539 QVariant::QVariant(const QRect &r) { create(Rect, &r); }
01540 QVariant::QVariant(const QSize &s) { create(Size, &s); }
01541 QVariant::QVariant(const QSizeF &s) { create(SizeF, &s); }
01542 #endif
01543 QVariant::QVariant(const QUrl &u) { create(Url, &u); }
01544 QVariant::QVariant(const QLocale &l) { create(Locale, &l); }
01545 QVariant::QVariant(const QRegExp &regExp) { create(RegExp, &regExp); }
01546 QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); }
01547 
01554 QVariant::Type QVariant::type() const
01555 {
01556     return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
01557 }
01558 
01566 int QVariant::userType() const
01567 {
01568     return d.type;
01569 }
01570 
01574 QVariant& QVariant::operator=(const QVariant &variant)
01575 {
01576     if (this == &variant)
01577         return *this;
01578 
01579     clear();
01580     if (variant.d.is_shared) {
01581         variant.d.data.shared->ref.ref();
01582         d = variant.d;
01583     } else if (variant.d.type > Char) {
01584         d.type = variant.d.type;
01585         handler->construct(&d, variant.constData());
01586         d.is_null = variant.d.is_null;
01587     } else {
01588         d = variant.d;
01589     }
01590 
01591     return *this;
01592 }
01593 
01600 void QVariant::detach()
01601 {
01602     if (!d.is_shared || d.data.shared->ref == 1)
01603         return;
01604 
01605     Private dd;
01606     dd.type = d.type;
01607     handler->construct(&dd, constData());
01608     dd.data.shared = qAtomicSetPtr(&d.data.shared, dd.data.shared);
01609     if (!dd.data.shared->ref.deref())
01610         handler->clear(&dd);
01611 }
01612 
01625 const char *QVariant::typeName() const
01626 {
01627     return typeToName(Type(d.type));
01628 }
01629 
01634 void QVariant::clear()
01635 {
01636     if (!d.is_shared || !d.data.shared->ref.deref())
01637         handler->clear(&d);
01638     d.type = Invalid;
01639     d.is_null = true;
01640     d.is_shared = false;
01641 }
01642 
01649 const char *QVariant::typeToName(Type typ)
01650 {
01651     if (typ == Invalid)
01652         return 0;
01653     if (typ == UserType)
01654         return "UserType";
01655 
01656     return QMetaType::typeName(typ);
01657 }
01658 
01659 
01667 QVariant::Type QVariant::nameToType(const char *name)
01668 {
01669     if (!name || !*name)
01670         return Invalid;
01671     if (strcmp(name, "Q3CString") == 0)
01672         return ByteArray;
01673     if (strcmp(name, "Q_LLONG") == 0)
01674         return LongLong;
01675     if (strcmp(name, "Q_ULLONG") == 0)
01676         return ULongLong;
01677     if (strcmp(name, "QIconSet") == 0)
01678         return Icon;
01679     if (strcmp(name, "UserType") == 0)
01680         return UserType;
01681 
01682     int metaType = QMetaType::type(name);
01683     return metaType <= int(LastGuiType) ? QVariant::Type(metaType) : UserType;
01684 }
01685 
01686 #ifndef QT_NO_DATASTREAM
01687 enum { MapFromThreeCount = 35 };
01688 static const uint map_from_three[MapFromThreeCount] =
01689 {
01690     QVariant::Invalid,
01691     QVariant::Map,
01692     QVariant::List,
01693     QVariant::String,
01694     QVariant::StringList,
01695     QVariant::Font,
01696     QVariant::Pixmap,
01697     QVariant::Brush,
01698     QVariant::Rect,
01699     QVariant::Size,
01700     QVariant::Color,
01701     QVariant::Palette,
01702     63, // ColorGroup
01703     QVariant::Icon,
01704     QVariant::Point,
01705     QVariant::Image,
01706     QVariant::Int,
01707     QVariant::UInt,
01708     QVariant::Bool,
01709     QVariant::Double,
01710     QVariant::ByteArray,
01711     QVariant::Polygon,
01712     QVariant::Region,
01713     QVariant::Bitmap,
01714     QVariant::Cursor,
01715     QVariant::SizePolicy,
01716     QVariant::Date,
01717     QVariant::Time,
01718     QVariant::DateTime,
01719     QVariant::ByteArray,
01720     QVariant::BitArray,
01721     QVariant::KeySequence,
01722     QVariant::Pen,
01723     QVariant::LongLong,
01724     QVariant::ULongLong
01725 };
01726 
01733 void QVariant::load(QDataStream &s)
01734 {
01735     clear();
01736 
01737     quint32 u;
01738     s >> u;
01739     if (s.version() < QDataStream::Qt_4_0) {
01740         if (u >= MapFromThreeCount)
01741             return;
01742         u = map_from_three[u];
01743     }
01744     qint8 is_null = false;
01745     if (s.version() >= QDataStream::Qt_4_2)
01746         s >> is_null;
01747     if (u >= QVariant::UserType) {
01748         QByteArray name;
01749         s >> name;
01750         u = QMetaType::type(name);
01751         if (!u)
01752             qFatal("QVariant::load(QDataStream &s): type %s unknown to QVariant.", name.data());
01753     }
01754     create(static_cast<int>(u), 0);
01755     d.is_null = is_null;
01756 
01757     if (d.type == QVariant::Invalid) {
01758         // Since we wrote something, we should read something
01759         QString x;
01760         s >> x;
01761         d.is_null = true;
01762         return;
01763     }
01764 
01765     // const cast is save since we operate on a newly constructed variant
01766     if (!QMetaType::load(s, d.type, const_cast<void *>(::constData(d)))) {
01767         Q_ASSERT_X(false, "QVariant::load", "Invalid type to load");
01768         qWarning("QVariant::load: unable to load type %d.", d.type);
01769     }
01770 }
01771 
01778 void QVariant::save(QDataStream &s) const
01779 {
01780     quint32 tp = type();
01781     if (s.version() < QDataStream::Qt_4_0) {
01782         int i;
01783         for (i = 0; i < MapFromThreeCount; ++i) {
01784             if (map_from_three[i] == tp) {
01785                 tp = i;
01786                 break;
01787             }
01788         }
01789         if (i == MapFromThreeCount) {
01790             s << QVariant();
01791             return;
01792         }
01793     }
01794     s << tp;
01795     if (s.version() >= QDataStream::Qt_4_2)
01796         s << qint8(d.is_null);
01797     if (tp == QVariant::UserType) {
01798         s << QMetaType::typeName(userType());
01799     }
01800 
01801     if (d.type == QVariant::Invalid) {
01802         s << QString();
01803         return;
01804     }
01805 
01806     if (!QMetaType::save(s, d.type, ::constData(d))) {
01807         Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
01808         qWarning("QVariant::save: unable to save type %d.", d.type);
01809     }
01810 }
01811 
01818 QDataStream& operator>>(QDataStream &s, QVariant &p)
01819 {
01820     p.load(s);
01821     return s;
01822 }
01823 
01830 QDataStream& operator<<(QDataStream &s, const QVariant &p)
01831 {
01832     p.save(s);
01833     return s;
01834 }
01835 
01839 QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
01840 {
01841     quint32 u;
01842     s >> u;
01843     p = (QVariant::Type)u;
01844 
01845     return s;
01846 }
01847 
01851 QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
01852 {
01853     s << static_cast<quint32>(p);
01854 
01855     return s;
01856 }
01857 
01858 #endif //QT_NO_DATASTREAM
01859 
01867 template <typename T>
01868 inline T qVariantToHelper(const QVariant::Private &d, QVariant::Type t,
01869                           const QVariant::Handler *handler, T * = 0)
01870 {
01871     if (d.type == t)
01872         return *v_cast<T>(&d);
01873 
01874     T ret;
01875     handler->convert(&d, t, &ret, 0);
01876     return ret;
01877 }
01878 
01888 QStringList QVariant::toStringList() const
01889 {
01890     return qVariantToHelper<QStringList>(d, StringList, handler);
01891 }
01892 
01901 QString QVariant::toString() const
01902 {
01903     return qVariantToHelper<QString>(d, String, handler);
01904 }
01905 
01912 QVariantMap QVariant::toMap() const
01913 {
01914     return qVariantToHelper<QVariantMap>(d, Map, handler);
01915 }
01916 
01928 QDate QVariant::toDate() const
01929 {
01930     return qVariantToHelper<QDate>(d, Date, handler);
01931 }
01932 
01944 QTime QVariant::toTime() const
01945 {
01946     return qVariantToHelper<QTime>(d, Time, handler);
01947 }
01948 
01961 QDateTime QVariant::toDateTime() const
01962 {
01963     return qVariantToHelper<QDateTime>(d, DateTime, handler);
01964 }
01965 
01975 QByteArray QVariant::toByteArray() const
01976 {
01977     return qVariantToHelper<QByteArray>(d, ByteArray, handler);
01978 }
01979 
01980 #ifndef QT_NO_GEOM_VARIANT
01981 
01989 QPoint QVariant::toPoint() const
01990 {
01991     return qVariantToHelper<QPoint>(d, Point, handler);
01992 }
01993 
02002 QRect QVariant::toRect() const
02003 {
02004     return qVariantToHelper<QRect>(d, Rect, handler);
02005 }
02006 
02015 QSize QVariant::toSize() const
02016 {
02017     return qVariantToHelper<QSize>(d, Size, handler);
02018 }
02019 
02028 QSizeF QVariant::toSizeF() const
02029 {
02030     return qVariantToHelper<QSizeF>(d, SizeF, handler);
02031 }
02032 
02041 QRectF QVariant::toRectF() const
02042 {
02043     return qVariantToHelper<QRectF>(d, RectF, handler);
02044 }
02045 
02054 QLineF QVariant::toLineF() const
02055 {
02056     return qVariantToHelper<QLineF>(d, LineF, handler);
02057 }
02058 
02067 QLine QVariant::toLine() const
02068 {
02069     return qVariantToHelper<QLine>(d, Line, handler);
02070 }
02071 
02080 QPointF QVariant::toPointF() const
02081 {
02082     return qVariantToHelper<QPointF>(d, PointF, handler);
02083 }
02084 
02085 #endif // QT_NO_GEOM_VARIANT
02086 
02095 QUrl QVariant::toUrl() const
02096 {
02097     return qVariantToHelper<QUrl>(d, Url, handler);
02098 }
02099 
02108 QLocale QVariant::toLocale() const
02109 {
02110     return qVariantToHelper<QLocale>(d, Locale, handler);
02111 }
02112 
02122 QRegExp QVariant::toRegExp() const
02123 {
02124     return qVariantToHelper<QRegExp>(d, RegExp, handler);
02125 }
02126 
02135 QChar QVariant::toChar() const
02136 {
02137     return qVariantToHelper<QChar>(d, Char, handler);
02138 }
02139 
02146 QBitArray QVariant::toBitArray() const
02147 {
02148     return qVariantToHelper<QBitArray>(d, BitArray, handler);
02149 }
02150 
02151 template <typename T>
02152 inline T qNumVariantToHelper(const QVariant::Private &d, QVariant::Type t,
02153                              const QVariant::Handler *handler, bool *ok, const T& val)
02154 {
02155     if (ok)
02156         *ok = true;
02157     if (d.type == t)
02158         return val;
02159 
02160     T ret;
02161     if (!handler->convert(&d, t, &ret, ok) && ok)
02162         *ok = false;
02163     return ret;
02164 }
02165 
02176 int QVariant::toInt(bool *ok) const
02177 {
02178     return qNumVariantToHelper<int>(d, Int, handler, ok, d.data.i);
02179 }
02180 
02191 uint QVariant::toUInt(bool *ok) const
02192 {
02193     return qNumVariantToHelper<uint>(d, UInt, handler, ok, d.data.u);
02194 }
02195 
02206 qlonglong QVariant::toLongLong(bool *ok) const
02207 {
02208     return qNumVariantToHelper<qlonglong>(d, LongLong, handler, ok, d.data.ll);
02209 }
02210 
02222 qulonglong QVariant::toULongLong(bool *ok) const
02223 {
02224     return qNumVariantToHelper<qulonglong>(d, ULongLong, handler, ok, d.data.ull);
02225 }
02226 
02237 bool QVariant::toBool() const
02238 {
02239     if (d.type == Bool)
02240         return d.data.b;
02241 
02242     bool res = false;
02243     handler->convert(&d, Bool, &res, 0);
02244 
02245     return res;
02246 }
02247 
02258 double QVariant::toDouble(bool *ok) const
02259 {
02260     return qNumVariantToHelper<double>(d, Double, handler, ok, d.data.d);
02261 }
02262 
02269 QVariantList QVariant::toList() const
02270 {
02271     return qVariantToHelper<QVariantList>(d, List, handler);
02272 }
02273 
02283 static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
02284 {
02285 /*Invalid*/     0,
02286 
02287 /*Bool*/          1 << QVariant::Double     | 1 << QVariant::Int        | 1 << QVariant::UInt
02288                 | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
02289                 | 1 << QVariant::String     | 1 << QVariant::Char,
02290 
02291 /*Int*/           1 << QVariant::UInt       | 1 << QVariant::String     | 1 << QVariant::Double
02292                 | 1 << QVariant::Bool       | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
02293                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
02294 
02295 /*UInt*/          1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
02296                 | 1 << QVariant::Bool       | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
02297                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
02298 
02299 /*LLong*/         1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
02300                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::ULongLong
02301                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
02302 
02303 /*ULlong*/        1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
02304                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::LongLong
02305                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
02306 
02307 /*double*/        1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::ULongLong
02308                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::LongLong
02309                 | 1 << QVariant::ByteArray,
02310 
02311 /*QChar*/         1 << QVariant::Int        | 1 << QVariant::UInt       | 1 << QVariant::LongLong
02312                 | 1 << QVariant::ULongLong,
02313 
02314 /*QMap*/          0,
02315 
02316 /*QList*/         1 << QVariant::StringList,
02317 
02318 /*QString*/       1 << QVariant::StringList | 1 << QVariant::ByteArray  | 1 << QVariant::Int
02319                 | 1 << QVariant::UInt       | 1 << QVariant::Bool       | 1 << QVariant::Double
02320                 | 1 << QVariant::Date       | 1 << QVariant::Time       | 1 << QVariant::DateTime
02321                 | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong  | 1 << QVariant::Char,
02322 
02323 /*QStringList*/   1 << QVariant::List       | 1 << QVariant::String,
02324 
02325 /*QByteArray*/    1 << QVariant::String     | 1 << QVariant::Int        | 1 << QVariant::UInt
02326                 | 1 << QVariant::Double     | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong,
02327 
02328 /*QBitArray*/     0,
02329 
02330 /*QDate*/         1 << QVariant::String     | 1 << QVariant::DateTime,
02331 
02332 /*QTime*/         1 << QVariant::String     | 1 << QVariant::DateTime,
02333 
02334 /*QDateTime*/     1 << QVariant::String     | 1 << QVariant::Date,
02335 
02336 /*QUrl*/          0,
02337 
02338 /*QLocale*/       0,
02339 
02340 /*QRect*/         1 << QVariant::RectF,
02341 
02342 /*QRectF*/        1 << QVariant::Rect,
02343 
02344 /*QSize*/         1 << QVariant::SizeF,
02345 
02346 /*QSizeF*/        1 << QVariant::Size,
02347 
02348 /*QLine*/         1 << QVariant::LineF,
02349 
02350 /*QLineF*/        1 << QVariant::Line,
02351 
02352 /*QPoint*/        1 << QVariant::PointF,
02353 
02354 /*QPointF*/       1 << QVariant::Point,
02355 
02356 /*QRegExp*/       0
02357 
02358 };
02359 
02394 bool QVariant::canConvert(Type t) const
02395 {
02396     if (d.type == uint(t))
02397         return true;
02398 
02399     if (d.type > QVariant::LastCoreType || t > QVariant::LastCoreType) {
02400         switch (uint(t)) {
02401         case QVariant::Int:
02402             return d.type == QVariant::KeySequence;
02403         case QVariant::Image:
02404             return d.type == QVariant::Pixmap || d.type == QVariant::Bitmap;
02405         case QVariant::Pixmap:
02406             return d.type == QVariant::Image || d.type == QVariant::Bitmap
02407                               || d.type == QVariant::Brush;
02408         case QVariant::Bitmap:
02409             return d.type == QVariant::Pixmap || d.type == QVariant::Image;
02410         case QVariant::ByteArray:
02411             return d.type == QVariant::Color;
02412         case QVariant::String:
02413             return d.type == QVariant::KeySequence || d.type == QVariant::Font
02414                               || d.type == QVariant::Color;
02415         case QVariant::KeySequence:
02416             return d.type == QVariant::String || d.type == QVariant::Int;
02417         case QVariant::Font:
02418             return d.type == QVariant::String;
02419         case QVariant::Color:
02420             return d.type == QVariant::String || d.type == QVariant::ByteArray
02421                               || d.type == QVariant::Brush;
02422         case QVariant::Brush:
02423             return d.type == QVariant::Color || d.type == QVariant::Pixmap;
02424         case QMetaType::Char:
02425         case QMetaType::UChar:
02426         case QMetaType::Long:
02427         case QMetaType::ULong:
02428         case QMetaType::Short:
02429         case QMetaType::UShort:
02430         case QMetaType::Float:
02431             return qCanConvertMatrix[QVariant::Int] & (1 << d.type) || d.type == QVariant::Int;
02432         default:
02433             return false;
02434         }
02435     }
02436 
02437     return qCanConvertMatrix[t] & (1 << d.type);
02438 }
02439 
02451 bool QVariant::convert(Type t)
02452 {
02453     if (d.type == uint(t))
02454         return true;
02455 
02456     QVariant oldValue = *this;
02457 
02458     clear();
02459     if (!oldValue.canConvert(t))
02460         return false;
02461 
02462     create(t, 0);
02463     if (oldValue.isNull())
02464         return false;
02465 
02466     bool isOk = true;
02467     if (!handler->convert(&oldValue.d, t, data(), &isOk))
02468         isOk = false;
02469     d.is_null = !isOk;
02470     return isOk;
02471 }
02472 
02513 static bool qIsNumericType(uint tp)
02514 {
02515     return (tp >= QVariant::Bool && tp <= QVariant::Double)
02516            || (tp >= QMetaType::Long && tp <= QMetaType::Float);
02517 }
02518 
02519 static bool qIsFloatingPoint(uint tp)
02520 {
02521     return tp == QVariant::Double || tp == QMetaType::Float;
02522 }
02523 
02526 bool QVariant::cmp(const QVariant &v) const
02527 {
02528     QVariant v2 = v;
02529     if (d.type != v2.d.type) {
02530         if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
02531             if (qIsFloatingPoint(d.type) || qIsFloatingPoint(v.d.type))
02532                 return qFuzzyCompare(toDouble(), v.toDouble());
02533             else
02534                 return toLongLong() == v.toLongLong();
02535         }
02536         if (!v2.canConvert(Type(d.type)) || !v2.convert(Type(d.type)))
02537             return false;
02538     }
02539     return handler->compare(&d, &v2.d);
02540 }
02541 
02545 const void *QVariant::constData() const
02546 {
02547     return ::constData(d);
02548 }
02549 
02557 void* QVariant::data()
02558 {
02559     detach();
02560     return const_cast<void *>(::constData(d));
02561 }
02562 
02563 
02564 #ifdef QT3_SUPPORT
02565 
02567 void *QVariant::castOrDetach(Type t)
02568 {
02569     if (d.type != uint(t)) {
02570         if (!convert(t))
02571             create(t, 0);
02572     } else {
02573         detach();
02574     }
02575     return data();
02576 }
02577 #endif
02578 
02582 bool QVariant::isNull() const
02583 {
02584     return handler->isNull(&d);
02585 }
02586 
02587 #ifndef QT_NO_DEBUG_STREAM
02588 QDebug operator<<(QDebug dbg, const QVariant &v)
02589 {
02590 #ifndef Q_BROKEN_DEBUG_STREAM
02591     dbg.nospace() << "QVariant(" << v.typeName() << ", ";
02592     QVariant::handler->debugStream(dbg, v);
02593     dbg.nospace() << ')';
02594     return dbg.space();
02595 #else
02596     qWarning("This compiler doesn't support streaming QVariant to QDebug");
02597     return dbg;
02598     Q_UNUSED(v);
02599 #endif
02600 }
02601 
02602 QDebug operator<<(QDebug dbg, const QVariant::Type p)
02603 {
02604 #ifndef Q_BROKEN_DEBUG_STREAM
02605     dbg.nospace() << "QVariant::" << QVariant::typeToName(p);
02606     return dbg.space();
02607 #else
02608     qWarning("This compiler doesn't support streaming QVariant::Type to QDebug");
02609     return dbg;
02610     Q_UNUSED(p);
02611 #endif
02612 }
02613 #endif
02614 

Generated on Thu Mar 15 11:53:35 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1