1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch> 5** Copyright (C) 2014 Petroules Corporation. 6** Contact: https://www.qt.io/licensing/ 7** 8** This file is part of the QtCore module of the Qt Toolkit. 9** 10** $QT_BEGIN_LICENSE:LGPL$ 11** Commercial License Usage 12** Licensees holding valid commercial Qt licenses may use this file in 13** accordance with the commercial license agreement provided with the 14** Software or, alternatively, in accordance with the terms contained in 15** a written agreement between you and The Qt Company. For licensing terms 16** and conditions see https://www.qt.io/terms-conditions. For further 17** information use the contact form at https://www.qt.io/contact-us. 18** 19** GNU Lesser General Public License Usage 20** Alternatively, this file may be used under the terms of the GNU Lesser 21** General Public License version 3 as published by the Free Software 22** Foundation and appearing in the file LICENSE.LGPL3 included in the 23** packaging of this file. Please review the following information to 24** ensure the GNU Lesser General Public License version 3 requirements 25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 26** 27** GNU General Public License Usage 28** Alternatively, this file may be used under the terms of the GNU 29** General Public License version 2.0 or (at your option) the GNU General 30** Public license version 3 or any later version approved by the KDE Free 31** Qt Foundation. The licenses are as published by the Free Software 32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 33** included in the packaging of this file. Please review the following 34** information to ensure the GNU General Public License requirements will 35** be met: https://www.gnu.org/licenses/gpl-2.0.html and 36** https://www.gnu.org/licenses/gpl-3.0.html. 37** 38** $QT_END_LICENSE$ 39** 40****************************************************************************/ 41 42#include <QtCore/qstring.h> 43#include <QtCore/qurl.h> 44#include <QtCore/qdatetime.h> 45#include <QtCore/quuid.h> 46#include <QtCore/qbytearray.h> 47#include <QtCore/qrect.h> 48 49#if QT_CONFIG(timezone) && !defined(QT_NO_SYSTEMLOCALE) 50#include <QtCore/qtimezone.h> 51#include <QtCore/private/qtimezoneprivate_p.h> 52#include <QtCore/private/qcore_mac_p.h> 53#endif 54 55#import <CoreFoundation/CoreFoundation.h> 56#import <Foundation/Foundation.h> 57 58#if defined(QT_PLATFORM_UIKIT) 59#import <CoreGraphics/CoreGraphics.h> 60#endif 61 62QT_BEGIN_NAMESPACE 63 64/*! 65 \since 5.3 66 67 Constructs a new QByteArray containing a copy of the CFData \a data. 68 69 \sa fromRawCFData(), fromRawData(), toRawCFData(), toCFData() 70*/ 71QByteArray QByteArray::fromCFData(CFDataRef data) 72{ 73 if (!data) 74 return QByteArray(); 75 76 return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data)); 77} 78 79/*! 80 \since 5.3 81 82 Constructs a QByteArray that uses the bytes of the CFData \a data. 83 84 The \a data's bytes are not copied. 85 86 The caller guarantees that the CFData will not be deleted 87 or modified as long as this QByteArray object exists. 88 89 \sa fromCFData(), fromRawData(), toRawCFData(), toCFData() 90*/ 91QByteArray QByteArray::fromRawCFData(CFDataRef data) 92{ 93 if (!data) 94 return QByteArray(); 95 96 return QByteArray::fromRawData(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data)); 97} 98 99/*! 100 \since 5.3 101 102 Creates a CFData from a QByteArray. The caller owns the CFData object 103 and is responsible for releasing it. 104 105 \sa toRawCFData(), fromCFData(), fromRawCFData(), fromRawData() 106*/ 107CFDataRef QByteArray::toCFData() const 108{ 109 return CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), length()); 110} 111 112/*! 113 \since 5.3 114 115 Constructs a CFData that uses the bytes of the QByteArray. 116 117 The QByteArray's bytes are not copied. 118 119 The caller guarantees that the QByteArray will not be deleted 120 or modified as long as this CFData object exists. 121 122 \sa toCFData(), fromRawCFData(), fromCFData(), fromRawData() 123*/ 124CFDataRef QByteArray::toRawCFData() const 125{ 126 return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), 127 length(), kCFAllocatorNull); 128} 129 130/*! 131 \since 5.3 132 133 Constructs a new QByteArray containing a copy of the NSData \a data. 134 135 \sa fromRawNSData(), fromRawData(), toNSData(), toRawNSData() 136*/ 137QByteArray QByteArray::fromNSData(const NSData *data) 138{ 139 if (!data) 140 return QByteArray(); 141 return QByteArray(reinterpret_cast<const char *>([data bytes]), [data length]); 142} 143 144/*! 145 \since 5.3 146 147 Constructs a QByteArray that uses the bytes of the NSData \a data. 148 149 The \a data's bytes are not copied. 150 151 The caller guarantees that the NSData will not be deleted 152 or modified as long as this QByteArray object exists. 153 154 \sa fromNSData(), fromRawData(), toRawNSData(), toNSData() 155*/ 156QByteArray QByteArray::fromRawNSData(const NSData *data) 157{ 158 if (!data) 159 return QByteArray(); 160 return QByteArray::fromRawData(reinterpret_cast<const char *>([data bytes]), [data length]); 161} 162 163/*! 164 \since 5.3 165 166 Creates a NSData from a QByteArray. The NSData object is autoreleased. 167 168 \sa fromNSData(), fromRawNSData(), fromRawData(), toRawNSData() 169*/ 170NSData *QByteArray::toNSData() const 171{ 172 return [NSData dataWithBytes:constData() length:size()]; 173} 174 175/*! 176 \since 5.3 177 178 Constructs a NSData that uses the bytes of the QByteArray. 179 180 The QByteArray's bytes are not copied. 181 182 The caller guarantees that the QByteArray will not be deleted 183 or modified as long as this NSData object exists. 184 185 \sa fromRawNSData(), fromNSData(), fromRawData(), toNSData() 186*/ 187NSData *QByteArray::toRawNSData() const 188{ 189 // const_cast is fine here because NSData is immutable thus will never modify bytes we're giving it 190 return [NSData dataWithBytesNoCopy:const_cast<char *>(constData()) length:size() freeWhenDone:NO]; 191} 192 193// ---------------------------------------------------------------------------- 194 195/*! 196 \since 5.2 197 198 Constructs a new QString containing a copy of the \a string CFString. 199 200 \note this function is only available on OS X and iOS. 201*/ 202QString QString::fromCFString(CFStringRef string) 203{ 204 if (!string) 205 return QString(); 206 CFIndex length = CFStringGetLength(string); 207 208 // Fast path: CFStringGetCharactersPtr does not copy but may 209 // return null for any and no reason. 210 const UniChar *chars = CFStringGetCharactersPtr(string); 211 if (chars) 212 return QString(reinterpret_cast<const QChar *>(chars), length); 213 214 QString ret(length, Qt::Uninitialized); 215 CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast<UniChar *>(ret.data())); 216 return ret; 217} 218 219/*! 220 \since 5.2 221 222 Creates a CFString from a QString. The caller owns the CFString and is 223 responsible for releasing it. 224 225 \note this function is only available on OS X and iOS. 226*/ 227CFStringRef QString::toCFString() const 228{ 229 return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(unicode()), length()); 230} 231 232/*! 233 \since 5.2 234 235 Constructs a new QString containing a copy of the \a string NSString. 236 237 \note this function is only available on OS X and iOS. 238*/ 239QString QString::fromNSString(const NSString *string) 240{ 241 if (!string) 242 return QString(); 243 QString qstring; 244 qstring.resize([string length]); 245 [string getCharacters: reinterpret_cast<unichar*>(qstring.data()) range: NSMakeRange(0, [string length])]; 246 return qstring; 247} 248 249/*! 250 \since 5.2 251 252 Creates a NSString from a QString. The NSString is autoreleased. 253 254 \note this function is only available on OS X and iOS. 255*/ 256NSString *QString::toNSString() const 257{ 258 return [NSString stringWithCharacters: reinterpret_cast<const UniChar*>(unicode()) length: length()]; 259} 260 261// ---------------------------------------------------------------------------- 262 263/*! 264 \since 5.7 265 266 Constructs a new QUuid containing a copy of the \a uuid CFUUID. 267 268 \note this function is only available on Apple platforms. 269*/ 270QUuid QUuid::fromCFUUID(CFUUIDRef uuid) 271{ 272 if (!uuid) 273 return QUuid(); 274 const CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid); 275 return QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char *>(&bytes), sizeof(bytes))); 276} 277 278/*! 279 \since 5.7 280 281 Creates a CFUUID from a QUuid. The caller owns the CFUUID and is 282 responsible for releasing it. 283 284 \note this function is only available on Apple platforms. 285*/ 286CFUUIDRef QUuid::toCFUUID() const 287{ 288 const QByteArray bytes = toRfc4122(); 289 return CFUUIDCreateFromUUIDBytes(0, *reinterpret_cast<const CFUUIDBytes *>(bytes.constData())); 290} 291 292/*! 293 \since 5.7 294 295 Constructs a new QUuid containing a copy of the \a uuid NSUUID. 296 297 \note this function is only available on Apple platforms. 298*/ 299QUuid QUuid::fromNSUUID(const NSUUID *uuid) 300{ 301 if (!uuid) 302 return QUuid(); 303 uuid_t bytes; 304 [uuid getUUIDBytes:bytes]; 305 return QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char *>(bytes), sizeof(bytes))); 306} 307 308/*! 309 \since 5.7 310 311 Creates a NSUUID from a QUuid. The NSUUID is autoreleased. 312 313 \note this function is only available on Apple platforms. 314*/ 315NSUUID *QUuid::toNSUUID() const 316{ 317 const QByteArray bytes = toRfc4122(); 318 return [[[NSUUID alloc] initWithUUIDBytes:*reinterpret_cast<const uuid_t *>(bytes.constData())] autorelease]; 319} 320 321// ---------------------------------------------------------------------------- 322 323 324/*! 325 \since 5.2 326 327 Constructs a QUrl containing a copy of the CFURL \a url. 328*/ 329QUrl QUrl::fromCFURL(CFURLRef url) 330{ 331 if (!url) 332 return QUrl(); 333 return QUrl(QString::fromCFString(CFURLGetString(url))); 334} 335 336/*! 337 \since 5.2 338 339 Creates a CFURL from a QUrl. The caller owns the CFURL and is 340 responsible for releasing it. 341*/ 342CFURLRef QUrl::toCFURL() const 343{ 344 CFURLRef url = 0; 345 CFStringRef str = toString(FullyEncoded).toCFString(); 346 if (str) { 347 url = CFURLCreateWithString(0, str, 0); 348 CFRelease(str); 349 } 350 return url; 351} 352 353/*! 354 \since 5.2 355 356 Constructs a QUrl containing a copy of the NSURL \a url. 357*/ 358QUrl QUrl::fromNSURL(const NSURL *url) 359{ 360 if (!url) 361 return QUrl(); 362 return QUrl(QString::fromNSString([url absoluteString])); 363} 364 365/*! 366 \since 5.2 367 368 Creates a NSURL from a QUrl. The NSURL is autoreleased. 369*/ 370NSURL *QUrl::toNSURL() const 371{ 372 return [NSURL URLWithString:toString(FullyEncoded).toNSString()]; 373} 374 375// ---------------------------------------------------------------------------- 376 377 378/*! 379 \since 5.5 380 381 Constructs a new QDateTime containing a copy of the CFDate \a date. 382 383 \sa toCFDate() 384*/ 385QDateTime QDateTime::fromCFDate(CFDateRef date) 386{ 387 if (!date) 388 return QDateTime(); 389 CFAbsoluteTime sSinceEpoch = kCFAbsoluteTimeIntervalSince1970 + CFDateGetAbsoluteTime(date); 390 return QDateTime::fromMSecsSinceEpoch(qRound64(sSinceEpoch * 1000)); 391} 392 393/*! 394 \since 5.5 395 396 Creates a CFDate from a QDateTime. The caller owns the CFDate object 397 and is responsible for releasing it. 398 399 \sa fromCFDate() 400*/ 401CFDateRef QDateTime::toCFDate() const 402{ 403 return CFDateCreate(kCFAllocatorDefault, (static_cast<CFAbsoluteTime>(toMSecsSinceEpoch()) 404 / 1000) - kCFAbsoluteTimeIntervalSince1970); 405} 406 407/*! 408 \since 5.5 409 410 Constructs a new QDateTime containing a copy of the NSDate \a date. 411 412 \sa toNSDate() 413*/ 414QDateTime QDateTime::fromNSDate(const NSDate *date) 415{ 416 if (!date) 417 return QDateTime(); 418 return QDateTime::fromMSecsSinceEpoch(qRound64([date timeIntervalSince1970] * 1000)); 419} 420 421/*! 422 \since 5.5 423 424 Creates an NSDate from a QDateTime. The NSDate object is autoreleased. 425 426 \sa fromNSDate() 427*/ 428NSDate *QDateTime::toNSDate() const 429{ 430 return [NSDate 431 dateWithTimeIntervalSince1970:static_cast<NSTimeInterval>(toMSecsSinceEpoch()) / 1000]; 432} 433 434// ---------------------------------------------------------------------------- 435 436#if QT_CONFIG(timezone) && !defined(QT_NO_SYSTEMLOCALE) 437/*! 438 \since 5.9 439 440 Constructs a new QTimeZone containing a copy of the CFTimeZone \a timeZone. 441 442 \sa toCFTimeZone() 443*/ 444QTimeZone QTimeZone::fromCFTimeZone(CFTimeZoneRef timeZone) 445{ 446 if (!timeZone) 447 return QTimeZone(); 448 return QTimeZone(QString::fromCFString(CFTimeZoneGetName(timeZone)).toLatin1()); 449} 450 451/*! 452 \since 5.9 453 454 Creates a CFTimeZone from a QTimeZone. The caller owns the CFTimeZone object 455 and is responsible for releasing it. 456 457 \sa fromCFTimeZone() 458*/ 459CFTimeZoneRef QTimeZone::toCFTimeZone() const 460{ 461#ifndef QT_NO_DYNAMIC_CAST 462 Q_ASSERT(dynamic_cast<const QMacTimeZonePrivate *>(d.data())); 463#endif 464 const QMacTimeZonePrivate *p = static_cast<const QMacTimeZonePrivate *>(d.data()); 465 return reinterpret_cast<CFTimeZoneRef>([p->nsTimeZone() copy]); 466} 467 468/*! 469 \since 5.9 470 471 Constructs a new QTimeZone containing a copy of the NSTimeZone \a timeZone. 472 473 \sa toNSTimeZone() 474*/ 475QTimeZone QTimeZone::fromNSTimeZone(const NSTimeZone *timeZone) 476{ 477 if (!timeZone) 478 return QTimeZone(); 479 return QTimeZone(QString::fromNSString(timeZone.name).toLatin1()); 480} 481 482/*! 483 \since 5.9 484 485 Creates an NSTimeZone from a QTimeZone. The NSTimeZone object is autoreleased. 486 487 \sa fromNSTimeZone() 488*/ 489NSTimeZone *QTimeZone::toNSTimeZone() const 490{ 491 return [static_cast<NSTimeZone *>(toCFTimeZone()) autorelease]; 492} 493#endif 494 495// ---------------------------------------------------------------------------- 496 497/*! 498 \since 5.8 499 500 Creates a CGRect from a QRect. 501 502 \sa QRectF::fromCGRect() 503*/ 504CGRect QRect::toCGRect() const noexcept 505{ 506 return CGRectMake(x(), y(), width(), height()); 507} 508 509/*! 510 \since 5.8 511 512 Creates a CGRect from a QRectF. 513 514 \sa fromCGRect() 515*/ 516CGRect QRectF::toCGRect() const noexcept 517{ 518 return CGRectMake(x(), y(), width(), height()); 519} 520 521/*! 522 \since 5.8 523 524 Creates a QRectF from CGRect \a rect. 525 526 \sa toCGRect() 527*/ 528QRectF QRectF::fromCGRect(CGRect rect) noexcept 529{ 530 return QRectF(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); 531} 532 533// ---------------------------------------------------------------------------- 534 535/*! 536 \since 5.8 537 538 Creates a CGPoint from a QPoint. 539 540 \sa QPointF::fromCGPoint() 541*/ 542CGPoint QPoint::toCGPoint() const noexcept 543{ 544 return CGPointMake(x(), y()); 545} 546 547/*! 548 \since 5.8 549 550 Creates a CGPoint from a QPointF. 551 552 \sa fromCGPoint() 553*/ 554CGPoint QPointF::toCGPoint() const noexcept 555{ 556 return CGPointMake(x(), y()); 557} 558 559/*! 560 \since 5.8 561 562 Creates a QRectF from CGPoint \a point. 563 564 \sa toCGPoint() 565*/ 566QPointF QPointF::fromCGPoint(CGPoint point) noexcept 567{ 568 return QPointF(point.x, point.y); 569} 570 571// ---------------------------------------------------------------------------- 572 573/*! 574 \since 5.8 575 576 Creates a CGSize from a QSize. 577 578 \sa QSizeF::fromCGSize() 579*/ 580CGSize QSize::toCGSize() const noexcept 581{ 582 return CGSizeMake(width(), height()); 583} 584 585/*! 586 \since 5.8 587 588 Creates a CGSize from a QSizeF. 589 590 \sa fromCGSize() 591*/ 592CGSize QSizeF::toCGSize() const noexcept 593{ 594 return CGSizeMake(width(), height()); 595} 596 597/*! 598 \since 5.8 599 600 Creates a QRectF from \a size. 601 602 \sa toCGSize() 603*/ 604QSizeF QSizeF::fromCGSize(CGSize size) noexcept 605{ 606 return QSizeF(size.width, size.height); 607} 608 609QT_END_NAMESPACE 610