Add Objective-C specific type converters to QByteArray

This patch adds the Objective-C NSData/CDataRef converters to
QByteArray

This will replace the current converters offered in QMacExtras

[ChangeLog][QtCore][Objective-C] Added NSData/CDataRef converters for
QByteArray

Change-Id: I7a0f14bee4271798db345f3c5efd26ac671a3ea4
Reviewed-by: Jake Petroules <jake.petroules@petroules.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Samuel Gaist 2014-02-28 23:48:24 +01:00 committed by The Qt Project
parent 7625c51ef4
commit be81c58845
7 changed files with 337 additions and 1 deletions

View File

@ -4186,6 +4186,91 @@ QByteArray QByteArray::fromPercentEncoding(const QByteArray &input, char percent
return tmp;
}
/*! \fn QByteArray QByteArray::fromCFData(CFDataRef data)
\since 5.3
Constructs a new QByteArray containing a copy of the CFData \a data.
\sa fromRawCFData(), fromRawData(), toRawCFData(), toCFData()
*/
/*! \fn QByteArray QByteArray::fromRawCFData(CFDataRef data)
\since 5.3
Constructs a QByteArray that uses the bytes of the CFData \a data.
The \a data's bytes are not copied.
The caller guarantees that the CFData will not be deleted
or modified as long as this QByteArray object exists.
\sa fromCFData(), fromRawData(), toRawCFData(), toCFData()
*/
/*! \fn CFDataRef QByteArray::toCFData() const
\since 5.3
Creates a CFData from a QByteArray. The caller owns the CFData object
and is responsible for releasing it.
\sa toRawCFData(), fromCFData(), fromRawCFData(), fromRawData()
*/
/*! \fn CFDataRef QByteArray::toRawCFData() const
\since 5.3
Constructs a CFData that uses the bytes of the QByteArray.
The QByteArray's bytes are not copied.
The caller guarantees that the QByteArray will not be deleted
or modified as long as this CFData object exists.
\sa toCFData(), fromRawCFData(), fromCFData(), fromRawData()
*/
/*! \fn QByteArray QByteArray::fromNSData(const NSData *data)
\since 5.3
Constructs a new QByteArray containing a copy of the NSData \a data.
\sa fromRawNSData(), fromRawData(), toNSData(), toRawNSData()
*/
/*! \fn QByteArray QByteArray::fromRawNSData(const NSData *data)
\since 5.3
Constructs a QByteArray that uses the bytes of the NSData \a data.
The \a data's bytes are not copied.
The caller guarantees that the NSData will not be deleted
or modified as long as this QByteArray object exists.
\sa fromNSData(), fromRawData(), toRawNSData(), toNSData()
*/
/*! \fn NSData QByteArray::toNSData() const
\since 5.3
Creates a NSData from a QByteArray. The NSData object is autoreleased.
\sa fromNSData(), fromRawNSData(), fromRawData(), toRawNSData()
*/
/*! \fn NSData QByteArray::toRawNSData() const
\since 5.3
Constructs a NSData that uses the bytes of the QByteArray.
The QByteArray's bytes are not copied.
The caller guarantees that the QByteArray will not be deleted
or modified as long as this NSData object exists.
\sa fromRawNSData(), fromNSData(), fromRawData(), toNSData()
*/
static inline bool q_strchr(const char str[], char chr)
{
if (!str) return false;

View File

@ -65,6 +65,12 @@
#endif
#ifdef Q_OS_MAC
Q_FORWARD_DECLARE_CF_TYPE(CFData);
# ifdef __OBJC__
Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
# endif
#endif
QT_BEGIN_NAMESPACE
@ -354,6 +360,18 @@ public:
static QByteArray fromHex(const QByteArray &hexEncoded);
static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
#if defined(Q_OS_MAC) || defined(Q_QDOC)
static QByteArray fromCFData(CFDataRef data);
static QByteArray fromRawCFData(CFDataRef data);
CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED;
CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED;
# if defined(__OBJC__) || defined(Q_QDOC)
static QByteArray fromNSData(const NSData *data);
static QByteArray fromRawNSData(const NSData *data);
NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
# endif
#endif
typedef char *iterator;
typedef const char *const_iterator;

View File

@ -0,0 +1,101 @@
/****************************************************************************
**
** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qbytearray.h"
#import <Foundation/Foundation.h>
QT_BEGIN_NAMESPACE
QByteArray QByteArray::fromCFData(CFDataRef data)
{
if (!data)
return QByteArray();
return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data));
}
QByteArray QByteArray::fromRawCFData(CFDataRef data)
{
if (!data)
return QByteArray();
return QByteArray::fromRawData(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data));
}
CFDataRef QByteArray::toCFData() const
{
return CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), length());
}
CFDataRef QByteArray::toRawCFData() const
{
return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()),
length(), kCFAllocatorNull);
}
QByteArray QByteArray::fromNSData(const NSData *data)
{
if (!data)
return QByteArray();
return QByteArray(reinterpret_cast<const char *>([data bytes]), [data length]);
}
QByteArray QByteArray::fromRawNSData(const NSData *data)
{
if (!data)
return QByteArray();
return QByteArray::fromRawData(reinterpret_cast<const char *>([data bytes]), [data length]);
}
NSData *QByteArray::toNSData() const
{
return [NSData dataWithBytes:constData() length:size()];
}
NSData *QByteArray::toRawNSData() const
{
// const_cast is fine here because NSData is immutable thus will never modify bytes we're giving it
return [NSData dataWithBytesNoCopy:const_cast<char *>(constData()) length:size() freeWhenDone:NO];
}
QT_END_NAMESPACE

View File

@ -127,7 +127,8 @@ false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator
SOURCES += tools/qelapsedtimer_mac.cpp
OBJECTIVE_SOURCES += tools/qlocale_mac.mm \
tools/qtimezoneprivate_mac.mm \
tools/qstring_mac.mm
tools/qstring_mac.mm \
tools/qbytearray_mac.mm
}
else:blackberry {
SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_blackberry.cpp tools/qtimezoneprivate_tz.cpp

View File

@ -5,3 +5,8 @@ SOURCES = tst_qbytearray.cpp
TESTDATA += rfc3252.txt
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
mac {
OBJECTIVE_SOURCES += tst_qbytearray_mac.mm
LIBS += -framework Foundation
}

View File

@ -151,6 +151,8 @@ private slots:
#if defined(Q_COMPILER_LAMBDA)
void literals();
#endif
void macTypes();
};
static const struct StaticByteArrays {
@ -1980,6 +1982,16 @@ void tst_QByteArray::literals()
}
#endif
void tst_QByteArray::macTypes()
{
#ifndef Q_OS_MAC
QSKIP("This is a Apple-only test");
#else
extern void tst_QByteArray_macTypes(); // in qbytearray_mac.mm
tst_QByteArray_macTypes();
#endif
}
const char globalChar = '1';
QTEST_MAIN(tst_QByteArray)

View File

@ -0,0 +1,114 @@
/****************************************************************************
**
** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/QByteArray>
#include <QtTest/QtTest>
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
void tst_QByteArray_macTypes()
{
// QByteArray <-> CFData
{
QByteArray qtByteArray("test bytearray");
const CFDataRef cfData = qtByteArray.toCFData();
QCOMPARE(QByteArray::fromCFData(cfData), qtByteArray);
CFRelease(cfData);
}
{
QByteArray qtByteArray("test bytearray");
const CFDataRef cfData = qtByteArray.toCFData();
QByteArray qtByteArrayCopy(qtByteArray);
qtByteArray = qtByteArray.toUpper(); // modify
QCOMPARE(QByteArray::fromCFData(cfData), qtByteArrayCopy);
}
// QByteArray <-> CFData Raw
{
QByteArray qtByteArray("test bytearray");
const CFDataRef cfData = qtByteArray.toRawCFData();
const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
CFRelease(cfData);
}
{
const UInt8 data[] = "cfdata test";
const CFDataRef cfData = CFDataCreate(kCFAllocatorDefault, data, sizeof(data));
const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
QByteArray qtByteArray = QByteArray::fromRawCFData(cfData);
QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
CFRelease(cfData);
}
// QByteArray <-> NSData
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
QByteArray qtByteArray("test bytearray");
const NSData *nsData = qtByteArray.toNSData();
QCOMPARE(QByteArray::fromNSData(nsData), qtByteArray);
[autoreleasepool release];
}
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
QByteArray qtByteArray("test bytearray");
const NSData *nsData = qtByteArray.toNSData();
QByteArray qtByteArrayCopy(qtByteArray);
qtByteArray = qtByteArray.toUpper(); // modify
QCOMPARE(QByteArray::fromNSData(nsData), qtByteArrayCopy);
[autoreleasepool release];
}
// QByteArray <-> NSData Raw
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
QByteArray qtByteArray("test bytearray");
const NSData *nsData = qtByteArray.toRawNSData();
QCOMPARE([nsData bytes], qtByteArray.constData());
[autoreleasepool release];
}
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
const char data[] = "nsdata test";
const NSData *nsData = [NSData dataWithBytes:data length:sizeof(data)];
QByteArray qtByteArray = QByteArray::fromRawNSData(nsData);
QCOMPARE(qtByteArray.constData(), [nsData bytes]);
[autoreleasepool release];
}
}