00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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 ®Exp) { create(RegExp, ®Exp); }
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,
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
01759 QString x;
01760 s >> x;
01761 d.is_null = true;
01762 return;
01763 }
01764
01765
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 0,
02286
02287 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 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 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 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 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 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 1 << QVariant::Int | 1 << QVariant::UInt | 1 << QVariant::LongLong
02312 | 1 << QVariant::ULongLong,
02313
02314 0,
02315
02316 1 << QVariant::StringList,
02317
02318 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 1 << QVariant::List | 1 << QVariant::String,
02324
02325 1 << QVariant::String | 1 << QVariant::Int | 1 << QVariant::UInt
02326 | 1 << QVariant::Double | 1 << QVariant::LongLong | 1 << QVariant::ULongLong,
02327
02328 0,
02329
02330 1 << QVariant::String | 1 << QVariant::DateTime,
02331
02332 1 << QVariant::String | 1 << QVariant::DateTime,
02333
02334 1 << QVariant::String | 1 << QVariant::Date,
02335
02336 0,
02337
02338 0,
02339
02340 1 << QVariant::RectF,
02341
02342 1 << QVariant::Rect,
02343
02344 1 << QVariant::SizeF,
02345
02346 1 << QVariant::Size,
02347
02348 1 << QVariant::LineF,
02349
02350 1 << QVariant::Line,
02351
02352 1 << QVariant::PointF,
02353
02354 1 << QVariant::Point,
02355
02356 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