/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtBluetooth 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 The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef OSXBTUTILITY_P_H #define OSXBTUTILITY_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "osxbluetooth_p.h" #include #include #include #include QT_BEGIN_NAMESPACE class QLowEnergyCharacteristicData; class QBluetoothAddress; class QBluetoothUuid; namespace OSXBluetooth { struct NSObjectDeleter { static void cleanup(NSObject *obj) { [obj release]; } }; template class ObjCScopedPointer : public QScopedPointer { public: // TODO: remove default argument, add 'retain' parameter, // add a default ctor??? This will make the semantics more // transparent + will simplify the future transition to ARC // (if it will ever happen). explicit ObjCScopedPointer(T *ptr = Q_NULLPTR) : QScopedPointer(ptr){} operator T*() const { return data(); } T *data()const { return static_cast(QScopedPointer::data()); } T *take() { return static_cast(QScopedPointer::take()); } }; #define QT_BT_MAC_AUTORELEASEPOOL const QMacAutoReleasePool pool; template class ObjCStrongReference { public: ObjCStrongReference() : m_ptr(nil) { } ObjCStrongReference(T *obj, bool retain) { if (retain) m_ptr = [obj retain]; else m_ptr = obj; // For example, created with initWithXXXX. } ObjCStrongReference(const ObjCStrongReference &rhs) { m_ptr = [rhs.m_ptr retain]; } ObjCStrongReference &operator = (const ObjCStrongReference &rhs) { // "Old-style" implementation: if (this != &rhs && m_ptr != rhs.m_ptr) { [m_ptr release]; m_ptr = [rhs.m_ptr retain]; } return *this; } #ifdef Q_COMPILER_RVALUE_REFS ObjCStrongReference(ObjCStrongReference &&xval) { m_ptr = xval.m_ptr; xval.m_ptr = nil; } ObjCStrongReference &operator = (ObjCStrongReference &&xval) { m_ptr = xval.m_ptr; xval.m_ptr = nil; return *this; } #endif ~ObjCStrongReference() { [m_ptr release]; } void reset(T *newVal) { if (m_ptr != newVal) { [m_ptr release]; m_ptr = [newVal retain]; } } void resetWithoutRetain(T *newVal) { if (m_ptr != newVal) { [m_ptr release]; m_ptr = newVal; } } operator T *() const { return m_ptr; } T *data() const { return m_ptr; } T *take() { T * p = m_ptr; m_ptr = nil; return p; } private: T *m_ptr; }; // The type 'T' is some XXXRef from CoreFoundation and co. // In principle, we can do a trick removing a pointer from a type // when template is instantiated, but it's quite a lot of ugly pp-tokens // like OSXBluetooth::CFStrongReference > strongReference; // so instead we use 'T' everywhere, not 'T *' as can expected // from a smart pointer. template class CFStrongReference { public: CFStrongReference() : m_ptr(Q_NULLPTR) { } CFStrongReference(T obj, bool retain) : m_ptr(obj) { if (m_ptr && retain) CFRetain(m_ptr); } CFStrongReference(const CFStrongReference &rhs) { if ((m_ptr = rhs.m_ptr)) CFRetain(m_ptr); } CFStrongReference &operator = (const CFStrongReference &rhs) { // "Old-style" implementation: if (this != &rhs && m_ptr != rhs.m_ptr) { if (m_ptr) CFRelease(m_ptr); if ((m_ptr = rhs.m_ptr)) CFRetain(m_ptr); } return *this; } #ifdef Q_COMPILER_RVALUE_REFS CFStrongReference(CFStrongReference &&xval) { m_ptr = xval.m_ptr; xval.m_ptr = Q_NULLPTR; } CFStrongReference &operator = (CFStrongReference &&xval) { m_ptr = xval.m_ptr; xval.m_ptr = Q_NULLPTR; return *this; } #endif ~CFStrongReference() { if (m_ptr) CFRelease(m_ptr); } void reset(T newVal) { if (m_ptr != newVal) { if (m_ptr) CFRelease(m_ptr); if ((m_ptr = newVal)) CFRetain(m_ptr); } } operator T() const { return m_ptr; } T data() const { return m_ptr; } T take() { T p = m_ptr; m_ptr = Q_NULLPTR; return p; } private: T m_ptr; }; QString qt_address(NSString *address); #ifndef QT_IOS_BLUETOOTH QBluetoothAddress qt_address(const BluetoothDeviceAddress *address); BluetoothDeviceAddress iobluetooth_address(const QBluetoothAddress &address); ObjCStrongReference iobluetooth_uuid(const QBluetoothUuid &uuid); QBluetoothUuid qt_uuid(IOBluetoothSDPUUID *uuid); QString qt_error_string(IOReturn errorCode); #endif QBluetoothUuid qt_uuid(CBUUID *uuid); CFStrongReference cf_uuid(const QBluetoothUuid &qtUuid); ObjCStrongReference cb_uuid(const QBluetoothUuid &qtUuid); bool equal_uuids(const QBluetoothUuid &qtUuid, CBUUID *cbUuid); bool equal_uuids(CBUUID *cbUuid, const QBluetoothUuid &qtUuid); QByteArray qt_bytearray(NSData *data); QByteArray qt_bytearray(NSObject *data); ObjCStrongReference data_from_bytearray(const QByteArray &qtData); ObjCStrongReference mutable_data_from_bytearray(const QByteArray &qtData); dispatch_queue_t qt_LE_queue(); extern const int defaultLEScanTimeoutMS; extern const int maxValueLength; } // namespace OSXBluetooth // Logging category for both OS X and iOS. Q_DECLARE_LOGGING_CATEGORY(QT_BT_OSX) QT_END_NAMESPACE #endif