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