Commit 7f8d17b6 authored by Denis Shienkov's avatar Denis Shienkov
Browse files

Fix QSPI::isNull()


The method QSPI::isNull() should return false when QSPI is empty.

Tested on Winsows 8 and Linux with on-board, virtual and USB serial
ports using Qt5 and then Qt4.

Task-number: QTBUG-41262
Change-Id: Ic9e0afc5549311283aef7ec2ed841f5e418b7edf
Reviewed-by: default avatarSergey Belyashov <Sergey.Belyashov@gmail.com>
Showing with 206 additions and 78 deletions
......@@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE
\sa isNull()
*/
QSerialPortInfo::QSerialPortInfo()
: d_ptr(new QSerialPortInfoPrivate)
{
}
......@@ -81,7 +80,6 @@ QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo &other)
Constructs a QSerialPortInfo object from serial \a port.
*/
QSerialPortInfo::QSerialPortInfo(const QSerialPort &port)
: d_ptr(new QSerialPortInfoPrivate)
{
foreach (const QSerialPortInfo &serialPortInfo, availablePorts()) {
if (port.portName() == serialPortInfo.portName()) {
......@@ -99,7 +97,6 @@ QSerialPortInfo::QSerialPortInfo(const QSerialPort &port)
instance for that port.
*/
QSerialPortInfo::QSerialPortInfo(const QString &name)
: d_ptr(new QSerialPortInfoPrivate)
{
foreach (const QSerialPortInfo &serialPortInfo, availablePorts()) {
if (name == serialPortInfo.portName()) {
......@@ -109,6 +106,11 @@ QSerialPortInfo::QSerialPortInfo(const QString &name)
}
}
QSerialPortInfo::QSerialPortInfo(const QSerialPortInfoPrivate &dd)
: d_ptr(new QSerialPortInfoPrivate(dd))
{
}
/*!
Destroys the QSerialPortInfo object. References to the values in the
object become invalid.
......
......@@ -81,6 +81,7 @@ public:
static QList<QSerialPortInfo> availablePorts();
private:
QSerialPortInfo(const QSerialPortInfoPrivate &dd);
friend QList<QSerialPortInfo> availablePortsByUdev();
friend QList<QSerialPortInfo> availablePortsBySysfs();
friend QList<QSerialPortInfo> availablePortsByFiltersOfDevices();
......
......@@ -78,15 +78,15 @@ static quint16 searchShortIntProperty(io_registry_entry_t ioRegistryEntry,
return value;
}
static bool isCompleteInfo(const QSerialPortInfo &portInfo)
static bool isCompleteInfo(const QSerialPortInfoPrivate &priv)
{
return !portInfo.portName().isEmpty()
&& !portInfo.systemLocation().isEmpty()
&& !portInfo.manufacturer().isEmpty()
&& !portInfo.description().isEmpty()
&& !portInfo.serialNumber().isEmpty()
&& portInfo.hasProductIdentifier()
&& portInfo.hasVendorIdentifier();
return !priv.portName.isEmpty()
&& !priv.device.isEmpty()
&& !priv.manufacturer.isEmpty()
&& !priv.description.isEmpty()
&& !priv.serialNumber.isEmpty()
&& priv.hasProductIdentifier
&& priv.hasVendorIdentifier;
}
static QString devicePortName(io_registry_entry_t ioRegistryEntry)
......@@ -160,37 +160,37 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
if (!serialPortService)
break;
QSerialPortInfo serialPortInfo;
QSerialPortInfoPrivate priv;
forever {
if (serialPortInfo.portName().isEmpty())
serialPortInfo.d_ptr->portName = devicePortName(serialPortService);
if (priv.portName.isEmpty())
priv.portName = devicePortName(serialPortService);
if (serialPortInfo.systemLocation().isEmpty())
serialPortInfo.d_ptr->device = deviceSystemLocation(serialPortService);
if (priv.device.isEmpty())
priv.device = deviceSystemLocation(serialPortService);
if (serialPortInfo.description().isEmpty())
serialPortInfo.d_ptr->description = deviceDescription(serialPortService);
if (priv.description.isEmpty())
priv.description = deviceDescription(serialPortService);
if (serialPortInfo.manufacturer().isEmpty())
serialPortInfo.d_ptr->manufacturer = deviceManufacturer(serialPortService);
if (priv.manufacturer.isEmpty())
priv.manufacturer = deviceManufacturer(serialPortService);
if (serialPortInfo.serialNumber().isEmpty())
serialPortInfo.d_ptr->serialNumber = deviceSerialNumber(serialPortService);
if (priv.serialNumber.isEmpty())
priv.serialNumber = deviceSerialNumber(serialPortService);
if (!serialPortInfo.hasVendorIdentifier()) {
serialPortInfo.d_ptr->vendorIdentifier =
if (!priv.hasVendorIdentifier) {
priv.vendorIdentifier =
deviceVendorIdentifier(serialPortService,
serialPortInfo.d_ptr->hasVendorIdentifier);
priv.hasVendorIdentifier);
}
if (!serialPortInfo.hasProductIdentifier()) {
serialPortInfo.d_ptr->productIdentifier =
if (!priv.hasProductIdentifier) {
priv.productIdentifier =
deviceProductIdentifier(serialPortService,
serialPortInfo.d_ptr->hasProductIdentifier);
priv.hasProductIdentifier);
}
if (isCompleteInfo(serialPortInfo)) {
if (isCompleteInfo(priv)) {
::IOObjectRelease(serialPortService);
break;
}
......@@ -200,7 +200,7 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
break;
}
serialPortInfoList.append(serialPortInfo);
serialPortInfoList.append(priv);
}
::IOObjectRelease(serialPortIterator);
......
......@@ -98,10 +98,10 @@ QList<QSerialPortInfo> availablePortsByFiltersOfDevices()
QList<QSerialPortInfo> serialPortInfoList;
foreach (const QString &deviceFilePath, filteredDeviceFilePaths()) {
QSerialPortInfo serialPortInfo;
serialPortInfo.d_ptr->device = deviceFilePath;
serialPortInfo.d_ptr->portName = QSerialPortPrivate::portNameFromSystemLocation(deviceFilePath);
serialPortInfoList.append(serialPortInfo);
QSerialPortInfoPrivate priv;
priv.device = deviceFilePath;
priv.portName = QSerialPortPrivate::portNameFromSystemLocation(deviceFilePath);
serialPortInfoList.append(priv);
}
return serialPortInfoList;
......@@ -125,7 +125,7 @@ QList<QSerialPortInfo> availablePortsBySysfs()
if (lastIndexOfSlash == -1)
continue;
QSerialPortInfo serialPortInfo;
QSerialPortInfoPrivate priv;
if (targetPath.contains(QStringLiteral("pnp"))) {
// TODO: Obtain more information
#ifndef Q_OS_ANDROID
......@@ -155,26 +155,26 @@ QList<QSerialPortInfo> availablePortsBySysfs()
QFile description(QFileInfo(targetDir, QStringLiteral("product")).absoluteFilePath());
if (description.open(QIODevice::ReadOnly | QIODevice::Text))
serialPortInfo.d_ptr->description = QString::fromLatin1(description.readAll()).simplified();
priv.description = QString::fromLatin1(description.readAll()).simplified();
QFile manufacturer(QFileInfo(targetDir, QStringLiteral("manufacturer")).absoluteFilePath());
if (manufacturer.open(QIODevice::ReadOnly | QIODevice::Text))
serialPortInfo.d_ptr->manufacturer = QString::fromLatin1(manufacturer.readAll()).simplified();
priv.manufacturer = QString::fromLatin1(manufacturer.readAll()).simplified();
QFile serialNumber(QFileInfo(targetDir, QStringLiteral("serial")).absoluteFilePath());
if (serialNumber.open(QIODevice::ReadOnly | QIODevice::Text))
serialPortInfo.d_ptr->serialNumber = QString::fromLatin1(serialNumber.readAll()).simplified();
priv.serialNumber = QString::fromLatin1(serialNumber.readAll()).simplified();
QFile vendorIdentifier(QFileInfo(targetDir, QStringLiteral("idVendor")).absoluteFilePath());
if (vendorIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
serialPortInfo.d_ptr->vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
.toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16);
priv.vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
.toInt(&priv.hasVendorIdentifier, 16);
}
QFile productIdentifier(QFileInfo(targetDir, QStringLiteral("idProduct")).absoluteFilePath());
if (productIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
serialPortInfo.d_ptr->productIdentifier = QString::fromLatin1(productIdentifier.readAll())
.toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16);
priv.productIdentifier = QString::fromLatin1(productIdentifier.readAll())
.toInt(&priv.hasProductIdentifier, 16);
}
break;
......@@ -185,13 +185,13 @@ QList<QSerialPortInfo> availablePortsBySysfs()
QDir targetDir(targetPath + QStringLiteral("/device"));
QFile vendorIdentifier(QFileInfo(targetDir, QStringLiteral("vendor")).absoluteFilePath());
if (vendorIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
serialPortInfo.d_ptr->vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
.toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16);
priv.vendorIdentifier = QString::fromLatin1(vendorIdentifier.readAll())
.toInt(&priv.hasVendorIdentifier, 16);
}
QFile productIdentifier(QFileInfo(targetDir, QStringLiteral("device")).absoluteFilePath());
if (productIdentifier.open(QIODevice::ReadOnly | QIODevice::Text)) {
serialPortInfo.d_ptr->productIdentifier = QString::fromLatin1(productIdentifier.readAll())
.toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16);
priv.productIdentifier = QString::fromLatin1(productIdentifier.readAll())
.toInt(&priv.hasProductIdentifier, 16);
}
// TODO: Obtain more information about the device
} else if (targetPath.contains(QStringLiteral(".serial/tty/tty"))) {
......@@ -201,9 +201,9 @@ QList<QSerialPortInfo> availablePortsBySysfs()
continue;
}
serialPortInfo.d_ptr->portName = targetPath.mid(lastIndexOfSlash + 1);
serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(serialPortInfo.d_ptr->portName);
serialPortInfoList.append(serialPortInfo);
priv.portName = targetPath.mid(lastIndexOfSlash + 1);
priv.device = QSerialPortPrivate::portNameToSystemLocation(priv.portName);
serialPortInfoList.append(priv);
}
return serialPortInfoList;
......@@ -318,25 +318,25 @@ QList<QSerialPortInfo> availablePortsByUdev()
if (!dev)
return serialPortInfoList;
QSerialPortInfo serialPortInfo;
QSerialPortInfoPrivate priv;
serialPortInfo.d_ptr->device = QString::fromLatin1(::udev_device_get_devnode(dev.data()));
serialPortInfo.d_ptr->portName = QString::fromLatin1(::udev_device_get_sysname(dev.data()));
priv.device = QString::fromLatin1(::udev_device_get_devnode(dev.data()));
priv.portName = QString::fromLatin1(::udev_device_get_sysname(dev.data()));
udev_device *parentdev = ::udev_device_get_parent(dev.data());
if (parentdev) {
if (checkUdevForSerial8250Driver(parentdev))
continue;
serialPortInfo.d_ptr->description = getUdevModelName(dev.data());
serialPortInfo.d_ptr->manufacturer = getUdevVendorName(dev.data());
serialPortInfo.d_ptr->serialNumber = getUdevSerialNumber(dev.data());
serialPortInfo.d_ptr->vendorIdentifier = getUdevVendorIdentifier(dev.data(), serialPortInfo.d_ptr->hasVendorIdentifier);
serialPortInfo.d_ptr->productIdentifier = getUdevModelIdentifier(dev.data(), serialPortInfo.d_ptr->hasProductIdentifier);
priv.description = getUdevModelName(dev.data());
priv.manufacturer = getUdevVendorName(dev.data());
priv.serialNumber = getUdevSerialNumber(dev.data());
priv.vendorIdentifier = getUdevVendorIdentifier(dev.data(), priv.hasVendorIdentifier);
priv.productIdentifier = getUdevModelIdentifier(dev.data(), priv.hasProductIdentifier);
} else {
if (serialPortInfo.d_ptr->portName.startsWith(rfcommDeviceName)) {
if (priv.portName.startsWith(rfcommDeviceName)) {
bool ok;
int portNumber = serialPortInfo.d_ptr->portName.mid(rfcommDeviceName.length()).toInt(&ok);
int portNumber = priv.portName.mid(rfcommDeviceName.length()).toInt(&ok);
if (!ok || (portNumber < 0) || (portNumber > 255))
continue;
} else {
......@@ -344,7 +344,7 @@ QList<QSerialPortInfo> availablePortsByUdev()
}
}
serialPortInfoList.append(serialPortInfo);
serialPortInfoList.append(priv);
}
return serialPortInfoList;
......
......@@ -312,23 +312,23 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
continue;
}
QSerialPortInfo serialPortInfo;
QSerialPortInfoPrivate priv;
serialPortInfo.d_ptr->portName = portName;
serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(portName);
serialPortInfo.d_ptr->description = deviceDescription(deviceInfoSet, &deviceInfoData);
serialPortInfo.d_ptr->manufacturer = deviceManufacturer(deviceInfoSet, &deviceInfoData);
priv.portName = portName;
priv.device = QSerialPortPrivate::portNameToSystemLocation(portName);
priv.description = deviceDescription(deviceInfoSet, &deviceInfoData);
priv.manufacturer = deviceManufacturer(deviceInfoSet, &deviceInfoData);
const QString instanceIdentifier = deviceInstanceIdentifier(deviceInfoData.DevInst);
serialPortInfo.d_ptr->serialNumber =
priv.serialNumber =
deviceSerialNumber(instanceIdentifier, deviceInfoData.DevInst);
serialPortInfo.d_ptr->vendorIdentifier =
deviceVendorIdentifier(instanceIdentifier, serialPortInfo.d_ptr->hasVendorIdentifier);
serialPortInfo.d_ptr->productIdentifier =
deviceProductIdentifier(instanceIdentifier, serialPortInfo.d_ptr->hasProductIdentifier);
priv.vendorIdentifier =
deviceVendorIdentifier(instanceIdentifier, priv.hasVendorIdentifier);
priv.productIdentifier =
deviceProductIdentifier(instanceIdentifier, priv.hasProductIdentifier);
serialPortInfoList.append(serialPortInfo);
serialPortInfoList.append(priv);
}
::SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
......
......@@ -105,13 +105,13 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
&di);
if (hSearch != INVALID_HANDLE_VALUE) {
do {
QSerialPortInfo serialPortInfo;
serialPortInfo.d_ptr->device = QString::fromWCharArray(di.szLegacyName);
serialPortInfo.d_ptr->portName = QSerialPortPrivate::portNameFromSystemLocation(serialPortInfo.d_ptr->device);
serialPortInfo.d_ptr->description = findDescription(HKEY_LOCAL_MACHINE,
QString::fromWCharArray(di.szDeviceKey));
QSerialPortInfoPrivate priv;
priv.device = QString::fromWCharArray(di.szLegacyName);
priv.portName = QSerialPortPrivate::portNameFromSystemLocation(priv.device);
priv.description = findDescription(HKEY_LOCAL_MACHINE,
QString::fromWCharArray(di.szDeviceKey));
serialPortInfoList.append(serialPortInfo);
serialPortInfoList.append(priv);
} while (::FindNextDevice(hSearch, &di));
::FindClose(hSearch);
......
TEMPLATE = subdirs
SUBDIRS += qserialport cmake
SUBDIRS += qserialport qserialportinfo cmake
QT = core testlib
TARGET = tst_qserialportinfo
#CONFIG += testcase
greaterThan(QT_MAJOR_VERSION, 4) {
QT += serialport
} else {
include($$QTSERIALPORT_PROJECT_ROOT/src/serialport/qt4support/serialport.prf)
}
SOURCES = tst_qserialportinfo.cpp
/****************************************************************************
**
** Copyright (C) 2014 Denis Shienkov <denis.shienkov@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSerialPort 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 <QtTest/QtTest>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
class tst_QSerialPortInfo : public QObject
{
Q_OBJECT
public:
explicit tst_QSerialPortInfo();
private slots:
void initTestCase();
void constructors();
void assignment();
private:
QString m_senderPortName;
QString m_receiverPortName;
QStringList m_availablePortNames;
};
tst_QSerialPortInfo::tst_QSerialPortInfo()
{
}
void tst_QSerialPortInfo::initTestCase()
{
m_senderPortName = QString::fromLocal8Bit(qgetenv("QTEST_SERIALPORT_SENDER"));
m_receiverPortName = QString::fromLocal8Bit(qgetenv("QTEST_SERIALPORT_RECEIVER"));
if (m_senderPortName.isEmpty() || m_receiverPortName.isEmpty()) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QSKIP("Test doesn't work because the names of serial ports aren't found in env.");
#else
QSKIP("Test doesn't work because the names of serial ports aren't set found env.", SkipAll);
#endif
} else {
m_availablePortNames << m_senderPortName << m_receiverPortName;
}
}
void tst_QSerialPortInfo::constructors()
{
QSerialPortInfo empty;
QVERIFY(empty.isNull());
QSerialPortInfo empty2(QLatin1String("ABCD"));
QVERIFY(empty2.isNull());
QSerialPortInfo empty3(empty);
QVERIFY(empty3.isNull());
QSerialPortInfo exist(m_senderPortName);
QVERIFY(!exist.isNull());
QSerialPortInfo exist2(exist);
QVERIFY(!exist2.isNull());
}
void tst_QSerialPortInfo::assignment()
{
QSerialPortInfo empty;
QVERIFY(empty.isNull());
QSerialPortInfo empty2;
empty2 = empty;
QVERIFY(empty2.isNull());
QSerialPortInfo exist(m_senderPortName);
QVERIFY(!exist.isNull());
QSerialPortInfo exist2;
exist2 = exist;
QVERIFY(!exist2.isNull());
}
QTEST_MAIN(tst_QSerialPortInfo)
#include "tst_qserialportinfo.moc"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment