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